pub struct Text<'s> { /* private fields */ }
Expand description
Graphical text
Text is a drawable type that allows to easily display some text with custom style and color on a render target.
Note:
Currently, it is not feasible to store text long term.
A common pattern with rust-sfml is to create a Text
right before you start drawing,
and draw all the text you want with it. You can change its properties using
set_font
, set_position
, set_string
, etc., before drawing it, as many times as you need
to.
Implementations§
Source§impl<'s> Text<'s>
impl<'s> Text<'s>
Sourcepub fn new<S: SfStrConv>(
string: S,
font: &'s Font,
character_size: u32,
) -> Text<'s>
pub fn new<S: SfStrConv>( string: S, font: &'s Font, character_size: u32, ) -> Text<'s>
Create a new text with initialized value
Default value for characterSize on SFML is 30.
§Arguments
- string - The string of the text
- font - The font to display the Text
- characterSize - The size of the Text
Examples found in repository?
More examples
87 fn new(font: &'fo Font) -> SfResult<Self> {
88 let mut text = Text::new(WAVEBLUR_TEXT, font, 22);
89 text.set_position((30., 20.));
90 Ok(Self {
91 text,
92 shader: Shader::from_file_vert_frag("wave.vert", "blur.frag")?,
93 })
94 }
95}
96
97impl Drawable for WaveBlur<'_> {
98 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
99 &'a self,
100 target: &mut dyn RenderTarget,
101 states: &RenderStates<'texture, 'shader, 'shader_texture>,
102 ) {
103 let mut states = *states;
104 states.shader = Some(&self.shader);
105 target.draw_with_renderstates(&self.text, &states);
106 }
107}
108
109impl Effect for WaveBlur<'_> {
110 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
111 self.shader.set_uniform_float("wave_phase", t)?;
112 self.shader
113 .set_uniform_vec2("wave_amplitude", Vector2f::new(x * 40., y * 40.))?;
114 self.shader
115 .set_uniform_float("blur_radius", (x + y) * 0.008)
116 }
117 fn name(&self) -> &str {
118 "wave + blur"
119 }
120}
121
122struct StormBlink {
123 points: Vec<Vertex>,
124 shader: FBox<Shader<'static>>,
125}
126
127impl StormBlink {
128 fn new() -> SfResult<Self> {
129 let mut rng = SmallRng::seed_from_u64(1);
130
131 let mut points = Vec::new();
132 for _ in 0..40_000 {
133 let x = rng.random_range(0.0..800.);
134 let y = rng.random_range(0.0..600.);
135 let (red, green, blue) = (rng.random(), rng.random(), rng.random());
136 points.push(Vertex::with_pos_color(
137 Vector2f::new(x, y),
138 Color::rgb(red, green, blue),
139 ));
140 }
141
142 let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
143 Ok(Self { points, shader })
144 }
145}
146
147impl Drawable for StormBlink {
148 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
149 &'a self,
150 target: &mut dyn RenderTarget,
151 states: &RenderStates<'texture, 'shader, 'shader_texture>,
152 ) {
153 let mut states = *states;
154 states.shader = Some(&self.shader);
155 target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
156 }
157}
158
159impl Effect for StormBlink {
160 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
161 let radius = 200. + t.cos() * 150.;
162 self.shader
163 .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
164 self.shader
165 .set_uniform_float("storm_inner_radius", radius / 3.)?;
166 self.shader
167 .set_uniform_float("storm_total_radius", radius)?;
168 self.shader
169 .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
170 }
171 fn name(&self) -> &str {
172 "storm + blink"
173 }
174}
175
176struct Edge<'t> {
177 surface: FBox<RenderTexture>,
178 bg_sprite: Sprite<'t>,
179 entities: Vec<Sprite<'t>>,
180 shader: FBox<Shader<'static>>,
181}
182
183impl<'t> Edge<'t> {
184 fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
185 let mut surface = RenderTexture::new(800, 600)?;
186 surface.set_smooth(true);
187 let mut bg_sprite = Sprite::with_texture(bg_texture);
188 bg_sprite.set_position((135., 100.));
189 let mut entities = Vec::new();
190
191 for i in 0..6 {
192 entities.push(Sprite::with_texture_and_rect(
193 entity_texture,
194 IntRect::new(96 * i, 0, 96, 96),
195 ));
196 }
197
198 let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
199 shader.set_uniform_current_texture("texture")?;
200
201 Ok(Self {
202 surface,
203 bg_sprite,
204 entities,
205 shader,
206 })
207 }
208}
209
210impl Drawable for Edge<'_> {
211 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
212 &'a self,
213 target: &mut dyn RenderTarget,
214 states: &RenderStates<'texture, 'shader, 'shader_texture>,
215 ) {
216 let mut states = *states;
217 states.shader = Some(&self.shader);
218 target.draw_with_renderstates(&Sprite::with_texture(self.surface.texture()), &states);
219 }
220}
221
222impl Effect for Edge<'_> {
223 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
224 self.shader
225 .set_uniform_float("edge_threshold", 1. - (x + y) / 2.)?;
226 let entities_len = self.entities.len() as f32;
227
228 for (i, en) in self.entities.iter_mut().enumerate() {
229 let pos = (
230 (0.25 * (t * i as f32 + (entities_len - i as f32))).cos() * 300. + 350.,
231 (0.25 * (t * (entities_len - i as f32) + i as f32)).cos() * 200. + 250.,
232 );
233 en.set_position(pos);
234 }
235 self.surface.clear(Color::WHITE);
236 self.surface.draw(&self.bg_sprite);
237 for en in &self.entities {
238 self.surface.draw(en);
239 }
240 self.surface.display();
241 Ok(())
242 }
243 fn name(&self) -> &str {
244 "edge post-effect"
245 }
246}
247
248struct Geometry<'tex> {
249 point_cloud: [Vertex; 10_000],
250 shader: FBox<Shader<'tex>>,
251 texture: &'tex Texture,
252 transform: Transform,
253}
254
255impl<'tex> Geometry<'tex> {
256 fn new(texture: &'tex Texture) -> SfResult<Self> {
257 if !Shader::is_geometry_available() {
258 eprintln!("Geometry shaders not available");
259 return Err(SfError::CallFailed);
260 }
261 let mut shader = Shader::from_memory_all(
262 include_str!("resources/billboard.vert"),
263 include_str!("resources/billboard.geom"),
264 include_str!("resources/billboard.frag"),
265 )?;
266 shader.set_uniform_texture("texture", texture)?;
267 shader.set_uniform_vec2("resolution", (800., 600.).into())?;
268 let mut rng = SmallRng::seed_from_u64(1);
269 Ok(Self {
270 point_cloud: std::array::from_fn(|_| {
271 Vertex::new(
272 (
273 rng.random_range(-480.0..480.0),
274 rng.random_range(-480.0..480.0),
275 )
276 .into(),
277 Color::WHITE,
278 Default::default(),
279 )
280 }),
281 shader,
282 texture,
283 transform: Transform::IDENTITY,
284 })
285 }
286}
287
288impl Drawable for Geometry<'_> {
289 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
290 &'a self,
291 target: &mut dyn RenderTarget,
292 states: &RenderStates<'texture, 'shader, 'shader_texture>,
293 ) {
294 let mut states = *states;
295 states.shader = Some(&self.shader);
296 states.texture = Some(self.texture);
297 states.transform = self.transform;
298 target.draw_primitives(&self.point_cloud, PrimitiveType::POINTS, &states);
299 }
300}
301
302impl Effect for Geometry<'_> {
303 fn update(&mut self, _t: f32, x: f32, y: f32) -> SfResult<()> {
304 self.transform = Transform::IDENTITY;
305 self.transform.translate(400., 300.);
306 self.transform.rotate(x * 360.0);
307 let size = 25. + y.abs() * 50.;
308 self.shader.set_uniform_vec2("size", size.into())?;
309 Ok(())
310 }
311
312 fn name(&self) -> &str {
313 "Geometry Shader Billboards"
314 }
315}
316
317fn main() -> SfResult<()> {
318 example_ensure_right_working_dir();
319
320 let mut window = RenderWindow::new(
321 (800, 600),
322 "SFML Shader",
323 Style::TITLEBAR | Style::CLOSE,
324 &Default::default(),
325 )?;
326 window.set_vertical_sync_enabled(true);
327 let font = Font::from_file("sansation.ttf")?;
328 let bg = Texture::from_file("background.jpg")?;
329 let mut bg_texture = Texture::from_file("sfml.png")?;
330 bg_texture.set_smooth(true);
331 let mut entity_texture = Texture::from_file("devices.png")?;
332 entity_texture.set_smooth(true);
333 let logo_texture = Texture::from_file("logo.png")?;
334 let effects: [&mut dyn Effect; 5] = [
335 &mut Pixelate::new(&bg)?,
336 &mut WaveBlur::new(&font)?,
337 &mut StormBlink::new()?,
338 &mut Edge::new(&bg_texture, &entity_texture)?,
339 &mut Geometry::new(&logo_texture)?,
340 ];
341 let mut current = 0;
342 let text_bg_texture = Texture::from_file("text-background.png")?;
343 let mut text_bg = Sprite::with_texture(&text_bg_texture);
344 text_bg.set_position((0., 520.));
345 text_bg.set_color(Color::rgba(255, 255, 255, 200));
346 let msg = format!("Current effect: {}", effects[current].name());
347 let mut desc = Text::new(&msg, &font, 20);
348 desc.set_position((10., 530.));
349 desc.set_fill_color(Color::rgb(80, 80, 80));
350 let msg = "Press left and right arrows to change the current shader";
351 let mut instructions = Text::new(msg, &font, 20);
352 instructions.set_position((280., 555.));
353 instructions.set_fill_color(Color::rgb(80, 80, 80));
354 let clock = Clock::start()?;
355
356 while window.is_open() {
357 while let Some(event) = window.poll_event() {
358 use crate::Event::*;
359 match event {
360 Closed => window.close(),
361 KeyPressed { code, .. } => match code {
362 Key::Escape => window.close(),
363 Key::Left => {
364 if current == 0 {
365 current = effects.len() - 1;
366 } else {
367 current -= 1;
368 }
369 desc.set_string(&format!("Current effect: {}", effects[current].name()));
370 }
371 Key::Right => {
372 if current == effects.len() - 1 {
373 current = 0;
374 } else {
375 current += 1;
376 }
377 desc.set_string(&format!("Current effect: {}", effects[current].name()));
378 }
379 _ => {}
380 },
381 _ => {}
382 }
383 }
384
385 let x = window.mouse_position().x as f32 / window.size().x as f32;
386 let y = window.mouse_position().y as f32 / window.size().y as f32;
387
388 effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
389
390 window.clear(Color::rgb(255, 128, 0));
391 window.draw(effects[current]);
392 window.draw(&text_bg);
393 window.draw(&instructions);
394 window.draw(&desc);
395 window.display();
396 }
397 Ok(())
398}
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "Borrowed resources",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Create a new texture. (Hey Frank!)
24 let frank = Texture::from_file("frank.jpeg")?;
25
26 // Create a font.
27 let font = Font::from_file("sansation.ttf")?;
28
29 // Create a circle with the Texture.
30 let mut circle = CircleShape::with_texture(&frank);
31 circle.set_radius(70.0);
32 circle.set_position((100.0, 100.0));
33
34 // Create a Sprite.
35 let mut sprite = Sprite::new();
36 // Have it use the same texture as the circle.
37 sprite.set_texture(&frank, true);
38 sprite.set_position((400.0, 300.0));
39 sprite.set_scale(0.5);
40
41 // Create a ConvexShape using the same texture.
42 let mut convex_shape = ConvexShape::with_texture(6, &frank);
43 convex_shape.set_point(0, (400., 100.));
44 convex_shape.set_point(1, (500., 70.));
45 convex_shape.set_point(2, (450., 100.));
46 convex_shape.set_point(3, (580., 150.));
47 convex_shape.set_point(4, (420., 230.));
48 convex_shape.set_point(5, (420., 120.));
49
50 // Create an initialized text using the font.
51 let title = Text::new("Borrowed resources example!", &font, 50);
52
53 // Create a second text using the same font.
54 // This time, we create and initialize it separately.
55 let mut second_text = Text::default();
56 second_text.set_string("This text shares the same font with the title!");
57 second_text.set_font(&font);
58 second_text.set_fill_color(Color::GREEN);
59 second_text.set_position((10.0, 350.0));
60 second_text.set_character_size(20);
61
62 // Create a third text using the same font.
63 let mut third_text = Text::new("This one too!", &font, 20);
64 third_text.set_position((300.0, 100.0));
65 third_text.set_fill_color(Color::RED);
66
67 'mainloop: loop {
68 while let Some(event) = window.poll_event() {
69 match event {
70 Event::Closed
71 | Event::KeyPressed {
72 code: Key::Escape, ..
73 } => break 'mainloop,
74 _ => {}
75 }
76 }
77
78 window.clear(Color::BLACK);
79 window.draw(&circle);
80 window.draw(&sprite);
81 window.draw(&convex_shape);
82 window.draw(&title);
83 window.draw(&second_text);
84 window.draw(&third_text);
85
86 // Little test here for `Shape::points`
87 let mut circ = CircleShape::new(4.0, 30);
88 circ.set_origin(2.0);
89 circ.set_fill_color(Color::YELLOW);
90
91 for p in convex_shape.points() {
92 circ.set_position(p);
93 window.draw(&circ);
94 }
95
96 window.display();
97 }
98 Ok(())
99}
5fn main() -> SfResult<()> {
6 example_ensure_right_working_dir();
7
8 let mut window = RenderWindow::new(
9 (800, 600),
10 "Mouse events",
11 Style::CLOSE,
12 &Default::default(),
13 )?;
14 window.set_mouse_cursor_visible(false);
15 window.set_vertical_sync_enabled(true);
16
17 let font = Font::from_file("sansation.ttf")?;
18 let mut circle = CircleShape::new(4., 30);
19 let mut texts: Vec<Text> = Vec::new();
20 let mut mp_text = Text::new("", &font, 14);
21 let mut cursor_visible = false;
22 let mut grabbed = false;
23 macro_rules! push_text {
24 ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25 let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26 text.set_position(($x as f32, $y as f32));
27 texts.push(text);
28 }
29 }
30
31 'mainloop: loop {
32 while let Some(ev) = window.poll_event() {
33 match ev {
34 Event::Closed => break 'mainloop,
35 Event::MouseWheelScrolled { wheel, delta, x, y } => {
36 push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37 }
38 Event::MouseButtonPressed { button, x, y } => {
39 push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40 }
41 Event::MouseButtonReleased { button, x, y } => {
42 push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43 }
44 Event::KeyPressed { code, .. } => {
45 if code == Key::W {
46 window.set_mouse_position(Vector2i::new(400, 300));
47 } else if code == Key::D {
48 let dm = VideoMode::desktop_mode();
49 let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50 mouse::set_desktop_position(center);
51 } else if code == Key::V {
52 cursor_visible = !cursor_visible;
53 window.set_mouse_cursor_visible(cursor_visible);
54 } else if code == Key::G {
55 grabbed = !grabbed;
56 window.set_mouse_cursor_grabbed(grabbed);
57 }
58 }
59 _ => {}
60 }
61 }
62
63 let mp = window.mouse_position();
64 let dmp = mouse::desktop_position();
65 let cur_vis_msg = if cursor_visible {
66 "visible"
67 } else {
68 "invisible"
69 };
70 let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71 mp_text.set_string(&format!(
72 "x: {}, y: {} (Window)\n\
73 x: {}, y: {} (Desktop)\n\
74 [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75 'W' to center mouse on window\n\
76 'D' to center mouse on desktop",
77 mp.x, mp.y, dmp.x, dmp.y
78 ));
79
80 circle.set_position((mp.x as f32, mp.y as f32));
81
82 window.clear(Color::BLACK);
83 // Push texts out of each other's way
84 for i in (0..texts.len()).rev() {
85 for j in (0..i).rev() {
86 if let Some(intersect) = texts[i]
87 .global_bounds()
88 .intersection(&texts[j].global_bounds())
89 {
90 texts[j].move_((0., -intersect.height));
91 }
92 }
93 }
94 texts.retain(|txt| txt.fill_color().a > 0);
95 for txt in &mut texts {
96 let mut color = txt.fill_color();
97 color.a -= 1;
98 txt.set_fill_color(color);
99 window.draw(txt);
100 }
101 if !cursor_visible {
102 window.draw(&circle);
103 }
104 window.draw(&mp_text);
105 window.display();
106 }
107 Ok(())
108}
13fn main() -> SfResult<()> {
14 let configs = [
15 WindowConfig {
16 mode: (320, 240),
17 title: "(Windowed) Retro",
18 style: Style::CLOSE,
19 },
20 WindowConfig {
21 mode: (640, 480),
22 title: "(Windowed) Classic",
23 style: Style::DEFAULT,
24 },
25 WindowConfig {
26 mode: (800, 600),
27 title: "(Windowed) Big",
28 style: Style::TITLEBAR,
29 },
30 ];
31 let mut cfg_idx = 2usize;
32 let mut rw = RenderWindow::new(
33 configs[cfg_idx].mode,
34 "Window test",
35 Style::CLOSE,
36 &ContextSettings::default(),
37 )?;
38 let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?;
39 let fs_modes = VideoMode::fullscreen_modes();
40
41 while rw.is_open() {
42 while let Some(ev) = rw.poll_event() {
43 match ev {
44 Event::Closed => rw.close(),
45 Event::KeyPressed { code, .. } => match code {
46 Key::Up => cfg_idx = cfg_idx.saturating_sub(1),
47 Key::Down => {
48 if cfg_idx + 1 < configs.len() + fs_modes.len() {
49 cfg_idx += 1
50 }
51 }
52 Key::Enter => match configs.get(cfg_idx) {
53 Some(cfg) => {
54 rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default())
55 }
56 None => match fs_modes.get(cfg_idx - configs.len()) {
57 Some(mode) => rw.recreate(
58 *mode,
59 "Fullscreen",
60 Style::FULLSCREEN,
61 &ContextSettings::default(),
62 ),
63 None => {
64 eprintln!("Invalid index: {cfg_idx}");
65 }
66 },
67 },
68 _ => {}
69 },
70 _ => {}
71 }
72 }
73 rw.clear(Color::BLACK);
74 let fontsize = 16;
75 let mut txt = Text::new("Arrow keys to select mode, enter to set.", &font, fontsize);
76 rw.draw(&txt);
77 let mut y = fontsize as f32;
78 for (i, cfg) in configs.iter().enumerate() {
79 let fc = if i == cfg_idx {
80 Color::YELLOW
81 } else {
82 Color::WHITE
83 };
84 txt.set_fill_color(fc);
85 txt.set_string(&format!(
86 "{}x{} \"{}\" ({:?})",
87 cfg.mode.0, cfg.mode.1, cfg.title, cfg.style
88 ));
89 txt.set_position((0., y));
90 rw.draw(&txt);
91 y += fontsize as f32;
92 }
93 let mut i = configs.len();
94 y += fontsize as f32;
95 txt.set_position((0., y));
96 txt.set_fill_color(Color::WHITE);
97 txt.set_string("= Fullscreen modes =");
98 rw.draw(&txt);
99 for mode in fs_modes.iter() {
100 let n_rows = 23;
101 let column = i / n_rows;
102 let row = i % n_rows;
103 let fc = if i == cfg_idx {
104 Color::YELLOW
105 } else {
106 Color::WHITE
107 };
108 txt.set_fill_color(fc);
109 let left_pad = 16.0;
110 let x = left_pad + (column * 128) as f32;
111 let gap = 16.0;
112 let y = y + gap + (row * fontsize as usize) as f32;
113 txt.set_position((x, y));
114 txt.set_string(&format!(
115 "{}x{}x{}",
116 mode.width, mode.height, mode.bits_per_pixel
117 ));
118 rw.draw(&txt);
119 i += 1;
120 }
121 rw.display();
122 }
123 Ok(())
124}
46fn main() -> Result<(), Box<dyn Error>> {
47 example_ensure_right_working_dir();
48
49 let mut rw = RenderWindow::new(
50 (800, 600),
51 "Positional audio demo",
52 Style::CLOSE,
53 &Default::default(),
54 )?;
55 rw.set_vertical_sync_enabled(true);
56 let font = Font::from_file("sansation.ttf")?;
57 let mut text = Text::new("", &font, 20);
58 let mut music = match std::env::args().nth(1) {
59 Some(music_path) => Music::from_file(&music_path)?,
60 None => Music::from_file("canary.wav")?,
61 };
62 if music.channel_count() != 1 {
63 return Err("Sorry, only sounds with 1 channel are supported.".into());
64 };
65 music.set_looping(true);
66 music.play();
67 music.set_position(Vector3::new(0., 0., 0.));
68
69 let mut listener_pos = Vector3::new(0.0, 0.0, 0.0);
70 let center = Vector2::new(400., 300.);
71 let [mut go_left, mut go_right, mut go_up, mut go_down] = [false; 4];
72 let clock = Clock::start()?;
73
74 while rw.is_open() {
75 while let Some(ev) = rw.poll_event() {
76 match ev {
77 Event::Closed => rw.close(),
78 Event::KeyPressed { code, .. } => match code {
79 Key::A => go_left = true,
80 Key::D => go_right = true,
81 Key::W => go_up = true,
82 Key::S => go_down = true,
83 _ => {}
84 },
85 Event::KeyReleased { code, .. } => match code {
86 Key::A => go_left = false,
87 Key::D => go_right = false,
88 Key::W => go_up = false,
89 Key::S => go_down = false,
90 _ => {}
91 },
92 _ => {}
93 }
94 }
95 let Vector2f { x: mx, y: my } = rw.mouse_position().as_other();
96 let speed = 0.05;
97 if go_left {
98 listener_pos.x -= speed;
99 }
100 if go_right {
101 listener_pos.x += speed;
102 }
103 if go_up {
104 listener_pos.y -= speed;
105 }
106 if go_down {
107 listener_pos.y += speed;
108 }
109 let scale = 20.0; // Scale the positions for better visualization
110 listener::set_position(listener_pos);
111 listener::set_direction(Vector3::new(
112 (mx - center.x) / scale,
113 (my - center.y) / scale,
114 -1.,
115 ));
116 let Vector3 {
117 x: lx,
118 y: ly,
119 z: lz,
120 } = listener::position();
121 let Vector3 {
122 x: dx,
123 y: dy,
124 z: dz,
125 } = listener::direction();
126 rw.clear(Color::BLACK);
127 let mut circle_shape = CircleShape::new(8.0, 32);
128 // Draw circle at center, representing position of music being played
129 circle_shape.set_position(center);
130 circle_shape.set_fill_color(Color::YELLOW);
131 let t = clock.elapsed_time().as_seconds();
132 let radius = 12.0 + t.sin() * 3.0;
133 circle_shape.set_radius(radius);
134 circle_shape.set_origin(radius);
135 rw.draw(&circle_shape);
136 // Draw circle representing listener
137 circle_shape.set_position((center.x + lx * scale, center.y + ly * scale));
138 circle_shape.set_origin(4.0);
139 circle_shape.set_radius(4.0);
140 circle_shape.set_fill_color(Color::GREEN);
141 rw.draw(&circle_shape);
142 // Draw line from listener to direction vector position
143 rw.draw_line(
144 circle_shape.position(),
145 (center.x + dx * scale, center.y + dy * scale).into(),
146 2.0,
147 );
148 text.set_string("WASD + mouse for movement of listener");
149 text.set_position(0.);
150 rw.draw(&text);
151 text.set_string(&format!("Listener position: {lx}, {ly}, {lz}"));
152 text.set_position((0., 20.0));
153 rw.draw(&text);
154 text.set_string(&format!("Listener direction: {dx}, {dy}, {dz}"));
155 text.set_position((0., 40.0));
156 rw.draw(&text);
157 rw.display();
158 }
159 Ok(())
160}
Sourcepub fn set_string<S: SfStrConv>(&mut self, string: S)
pub fn set_string<S: SfStrConv>(&mut self, string: S)
Examples found in repository?
More examples
35fn draw_button(
36 rect: &Rect<i32>,
37 shape: &mut RectangleShape,
38 text: &mut Text,
39 string: &str,
40 render_window: &mut RenderWindow,
41 style: ButtonStyle,
42) {
43 shape.set_position((rect.left as f32, rect.top as f32));
44 shape.set_size((rect.width as f32, rect.height as f32));
45 let (rect_fill, rect_outline, text_fill) = match style {
46 ButtonStyle::Normal => (Color::TRANSPARENT, Color::WHITE, Color::WHITE),
47 ButtonStyle::Highlighted => (Color::WHITE, Color::WHITE, Color::BLACK),
48 ButtonStyle::Selected => (Color::GREEN, Color::GREEN, Color::BLACK),
49 ButtonStyle::Error => (Color::RED, Color::BLACK, Color::BLACK),
50 };
51 shape.set_outline_color(rect_outline);
52 shape.set_fill_color(rect_fill);
53 text.set_position((rect.left as f32 + 12.0, rect.top as f32 + 8.0));
54 text.set_fill_color(text_fill);
55 text.set_string(string);
56 render_window.draw(shape);
57 render_window.draw(text);
58}
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "Borrowed resources",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Create a new texture. (Hey Frank!)
24 let frank = Texture::from_file("frank.jpeg")?;
25
26 // Create a font.
27 let font = Font::from_file("sansation.ttf")?;
28
29 // Create a circle with the Texture.
30 let mut circle = CircleShape::with_texture(&frank);
31 circle.set_radius(70.0);
32 circle.set_position((100.0, 100.0));
33
34 // Create a Sprite.
35 let mut sprite = Sprite::new();
36 // Have it use the same texture as the circle.
37 sprite.set_texture(&frank, true);
38 sprite.set_position((400.0, 300.0));
39 sprite.set_scale(0.5);
40
41 // Create a ConvexShape using the same texture.
42 let mut convex_shape = ConvexShape::with_texture(6, &frank);
43 convex_shape.set_point(0, (400., 100.));
44 convex_shape.set_point(1, (500., 70.));
45 convex_shape.set_point(2, (450., 100.));
46 convex_shape.set_point(3, (580., 150.));
47 convex_shape.set_point(4, (420., 230.));
48 convex_shape.set_point(5, (420., 120.));
49
50 // Create an initialized text using the font.
51 let title = Text::new("Borrowed resources example!", &font, 50);
52
53 // Create a second text using the same font.
54 // This time, we create and initialize it separately.
55 let mut second_text = Text::default();
56 second_text.set_string("This text shares the same font with the title!");
57 second_text.set_font(&font);
58 second_text.set_fill_color(Color::GREEN);
59 second_text.set_position((10.0, 350.0));
60 second_text.set_character_size(20);
61
62 // Create a third text using the same font.
63 let mut third_text = Text::new("This one too!", &font, 20);
64 third_text.set_position((300.0, 100.0));
65 third_text.set_fill_color(Color::RED);
66
67 'mainloop: loop {
68 while let Some(event) = window.poll_event() {
69 match event {
70 Event::Closed
71 | Event::KeyPressed {
72 code: Key::Escape, ..
73 } => break 'mainloop,
74 _ => {}
75 }
76 }
77
78 window.clear(Color::BLACK);
79 window.draw(&circle);
80 window.draw(&sprite);
81 window.draw(&convex_shape);
82 window.draw(&title);
83 window.draw(&second_text);
84 window.draw(&third_text);
85
86 // Little test here for `Shape::points`
87 let mut circ = CircleShape::new(4.0, 30);
88 circ.set_origin(2.0);
89 circ.set_fill_color(Color::YELLOW);
90
91 for p in convex_shape.points() {
92 circ.set_position(p);
93 window.draw(&circ);
94 }
95
96 window.display();
97 }
98 Ok(())
99}
317fn main() -> SfResult<()> {
318 example_ensure_right_working_dir();
319
320 let mut window = RenderWindow::new(
321 (800, 600),
322 "SFML Shader",
323 Style::TITLEBAR | Style::CLOSE,
324 &Default::default(),
325 )?;
326 window.set_vertical_sync_enabled(true);
327 let font = Font::from_file("sansation.ttf")?;
328 let bg = Texture::from_file("background.jpg")?;
329 let mut bg_texture = Texture::from_file("sfml.png")?;
330 bg_texture.set_smooth(true);
331 let mut entity_texture = Texture::from_file("devices.png")?;
332 entity_texture.set_smooth(true);
333 let logo_texture = Texture::from_file("logo.png")?;
334 let effects: [&mut dyn Effect; 5] = [
335 &mut Pixelate::new(&bg)?,
336 &mut WaveBlur::new(&font)?,
337 &mut StormBlink::new()?,
338 &mut Edge::new(&bg_texture, &entity_texture)?,
339 &mut Geometry::new(&logo_texture)?,
340 ];
341 let mut current = 0;
342 let text_bg_texture = Texture::from_file("text-background.png")?;
343 let mut text_bg = Sprite::with_texture(&text_bg_texture);
344 text_bg.set_position((0., 520.));
345 text_bg.set_color(Color::rgba(255, 255, 255, 200));
346 let msg = format!("Current effect: {}", effects[current].name());
347 let mut desc = Text::new(&msg, &font, 20);
348 desc.set_position((10., 530.));
349 desc.set_fill_color(Color::rgb(80, 80, 80));
350 let msg = "Press left and right arrows to change the current shader";
351 let mut instructions = Text::new(msg, &font, 20);
352 instructions.set_position((280., 555.));
353 instructions.set_fill_color(Color::rgb(80, 80, 80));
354 let clock = Clock::start()?;
355
356 while window.is_open() {
357 while let Some(event) = window.poll_event() {
358 use crate::Event::*;
359 match event {
360 Closed => window.close(),
361 KeyPressed { code, .. } => match code {
362 Key::Escape => window.close(),
363 Key::Left => {
364 if current == 0 {
365 current = effects.len() - 1;
366 } else {
367 current -= 1;
368 }
369 desc.set_string(&format!("Current effect: {}", effects[current].name()));
370 }
371 Key::Right => {
372 if current == effects.len() - 1 {
373 current = 0;
374 } else {
375 current += 1;
376 }
377 desc.set_string(&format!("Current effect: {}", effects[current].name()));
378 }
379 _ => {}
380 },
381 _ => {}
382 }
383 }
384
385 let x = window.mouse_position().x as f32 / window.size().x as f32;
386 let y = window.mouse_position().y as f32 / window.size().y as f32;
387
388 effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
389
390 window.clear(Color::rgb(255, 128, 0));
391 window.draw(effects[current]);
392 window.draw(&text_bg);
393 window.draw(&instructions);
394 window.draw(&desc);
395 window.display();
396 }
397 Ok(())
398}
5fn main() -> SfResult<()> {
6 example_ensure_right_working_dir();
7
8 let mut window = RenderWindow::new(
9 (800, 600),
10 "Mouse events",
11 Style::CLOSE,
12 &Default::default(),
13 )?;
14 window.set_mouse_cursor_visible(false);
15 window.set_vertical_sync_enabled(true);
16
17 let font = Font::from_file("sansation.ttf")?;
18 let mut circle = CircleShape::new(4., 30);
19 let mut texts: Vec<Text> = Vec::new();
20 let mut mp_text = Text::new("", &font, 14);
21 let mut cursor_visible = false;
22 let mut grabbed = false;
23 macro_rules! push_text {
24 ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25 let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26 text.set_position(($x as f32, $y as f32));
27 texts.push(text);
28 }
29 }
30
31 'mainloop: loop {
32 while let Some(ev) = window.poll_event() {
33 match ev {
34 Event::Closed => break 'mainloop,
35 Event::MouseWheelScrolled { wheel, delta, x, y } => {
36 push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37 }
38 Event::MouseButtonPressed { button, x, y } => {
39 push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40 }
41 Event::MouseButtonReleased { button, x, y } => {
42 push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43 }
44 Event::KeyPressed { code, .. } => {
45 if code == Key::W {
46 window.set_mouse_position(Vector2i::new(400, 300));
47 } else if code == Key::D {
48 let dm = VideoMode::desktop_mode();
49 let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50 mouse::set_desktop_position(center);
51 } else if code == Key::V {
52 cursor_visible = !cursor_visible;
53 window.set_mouse_cursor_visible(cursor_visible);
54 } else if code == Key::G {
55 grabbed = !grabbed;
56 window.set_mouse_cursor_grabbed(grabbed);
57 }
58 }
59 _ => {}
60 }
61 }
62
63 let mp = window.mouse_position();
64 let dmp = mouse::desktop_position();
65 let cur_vis_msg = if cursor_visible {
66 "visible"
67 } else {
68 "invisible"
69 };
70 let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71 mp_text.set_string(&format!(
72 "x: {}, y: {} (Window)\n\
73 x: {}, y: {} (Desktop)\n\
74 [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75 'W' to center mouse on window\n\
76 'D' to center mouse on desktop",
77 mp.x, mp.y, dmp.x, dmp.y
78 ));
79
80 circle.set_position((mp.x as f32, mp.y as f32));
81
82 window.clear(Color::BLACK);
83 // Push texts out of each other's way
84 for i in (0..texts.len()).rev() {
85 for j in (0..i).rev() {
86 if let Some(intersect) = texts[i]
87 .global_bounds()
88 .intersection(&texts[j].global_bounds())
89 {
90 texts[j].move_((0., -intersect.height));
91 }
92 }
93 }
94 texts.retain(|txt| txt.fill_color().a > 0);
95 for txt in &mut texts {
96 let mut color = txt.fill_color();
97 color.a -= 1;
98 txt.set_fill_color(color);
99 window.draw(txt);
100 }
101 if !cursor_visible {
102 window.draw(&circle);
103 }
104 window.draw(&mp_text);
105 window.display();
106 }
107 Ok(())
108}
13fn main() -> SfResult<()> {
14 let configs = [
15 WindowConfig {
16 mode: (320, 240),
17 title: "(Windowed) Retro",
18 style: Style::CLOSE,
19 },
20 WindowConfig {
21 mode: (640, 480),
22 title: "(Windowed) Classic",
23 style: Style::DEFAULT,
24 },
25 WindowConfig {
26 mode: (800, 600),
27 title: "(Windowed) Big",
28 style: Style::TITLEBAR,
29 },
30 ];
31 let mut cfg_idx = 2usize;
32 let mut rw = RenderWindow::new(
33 configs[cfg_idx].mode,
34 "Window test",
35 Style::CLOSE,
36 &ContextSettings::default(),
37 )?;
38 let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?;
39 let fs_modes = VideoMode::fullscreen_modes();
40
41 while rw.is_open() {
42 while let Some(ev) = rw.poll_event() {
43 match ev {
44 Event::Closed => rw.close(),
45 Event::KeyPressed { code, .. } => match code {
46 Key::Up => cfg_idx = cfg_idx.saturating_sub(1),
47 Key::Down => {
48 if cfg_idx + 1 < configs.len() + fs_modes.len() {
49 cfg_idx += 1
50 }
51 }
52 Key::Enter => match configs.get(cfg_idx) {
53 Some(cfg) => {
54 rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default())
55 }
56 None => match fs_modes.get(cfg_idx - configs.len()) {
57 Some(mode) => rw.recreate(
58 *mode,
59 "Fullscreen",
60 Style::FULLSCREEN,
61 &ContextSettings::default(),
62 ),
63 None => {
64 eprintln!("Invalid index: {cfg_idx}");
65 }
66 },
67 },
68 _ => {}
69 },
70 _ => {}
71 }
72 }
73 rw.clear(Color::BLACK);
74 let fontsize = 16;
75 let mut txt = Text::new("Arrow keys to select mode, enter to set.", &font, fontsize);
76 rw.draw(&txt);
77 let mut y = fontsize as f32;
78 for (i, cfg) in configs.iter().enumerate() {
79 let fc = if i == cfg_idx {
80 Color::YELLOW
81 } else {
82 Color::WHITE
83 };
84 txt.set_fill_color(fc);
85 txt.set_string(&format!(
86 "{}x{} \"{}\" ({:?})",
87 cfg.mode.0, cfg.mode.1, cfg.title, cfg.style
88 ));
89 txt.set_position((0., y));
90 rw.draw(&txt);
91 y += fontsize as f32;
92 }
93 let mut i = configs.len();
94 y += fontsize as f32;
95 txt.set_position((0., y));
96 txt.set_fill_color(Color::WHITE);
97 txt.set_string("= Fullscreen modes =");
98 rw.draw(&txt);
99 for mode in fs_modes.iter() {
100 let n_rows = 23;
101 let column = i / n_rows;
102 let row = i % n_rows;
103 let fc = if i == cfg_idx {
104 Color::YELLOW
105 } else {
106 Color::WHITE
107 };
108 txt.set_fill_color(fc);
109 let left_pad = 16.0;
110 let x = left_pad + (column * 128) as f32;
111 let gap = 16.0;
112 let y = y + gap + (row * fontsize as usize) as f32;
113 txt.set_position((x, y));
114 txt.set_string(&format!(
115 "{}x{}x{}",
116 mode.width, mode.height, mode.bits_per_pixel
117 ));
118 rw.draw(&txt);
119 i += 1;
120 }
121 rw.display();
122 }
123 Ok(())
124}
Sourcepub fn string(&self) -> &SfStr
pub fn string(&self) -> &SfStr
Get the string of a text
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn character_size(&self) -> u32
pub fn character_size(&self) -> u32
Get the size of the characters
Return the size of the characters
Sourcepub fn set_font(&mut self, font: &'s Font)
pub fn set_font(&mut self, font: &'s Font)
Set the font of the text
The font argument refers to a texture that must exist as long as the text uses it. Indeed, the text doesn’t store its own copy of the font, but rather keeps a pointer to the one that you passed to this function. If the font is destroyed and the text tries to use it, the behaviour is undefined.
font - New font
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "Borrowed resources",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Create a new texture. (Hey Frank!)
24 let frank = Texture::from_file("frank.jpeg")?;
25
26 // Create a font.
27 let font = Font::from_file("sansation.ttf")?;
28
29 // Create a circle with the Texture.
30 let mut circle = CircleShape::with_texture(&frank);
31 circle.set_radius(70.0);
32 circle.set_position((100.0, 100.0));
33
34 // Create a Sprite.
35 let mut sprite = Sprite::new();
36 // Have it use the same texture as the circle.
37 sprite.set_texture(&frank, true);
38 sprite.set_position((400.0, 300.0));
39 sprite.set_scale(0.5);
40
41 // Create a ConvexShape using the same texture.
42 let mut convex_shape = ConvexShape::with_texture(6, &frank);
43 convex_shape.set_point(0, (400., 100.));
44 convex_shape.set_point(1, (500., 70.));
45 convex_shape.set_point(2, (450., 100.));
46 convex_shape.set_point(3, (580., 150.));
47 convex_shape.set_point(4, (420., 230.));
48 convex_shape.set_point(5, (420., 120.));
49
50 // Create an initialized text using the font.
51 let title = Text::new("Borrowed resources example!", &font, 50);
52
53 // Create a second text using the same font.
54 // This time, we create and initialize it separately.
55 let mut second_text = Text::default();
56 second_text.set_string("This text shares the same font with the title!");
57 second_text.set_font(&font);
58 second_text.set_fill_color(Color::GREEN);
59 second_text.set_position((10.0, 350.0));
60 second_text.set_character_size(20);
61
62 // Create a third text using the same font.
63 let mut third_text = Text::new("This one too!", &font, 20);
64 third_text.set_position((300.0, 100.0));
65 third_text.set_fill_color(Color::RED);
66
67 'mainloop: loop {
68 while let Some(event) = window.poll_event() {
69 match event {
70 Event::Closed
71 | Event::KeyPressed {
72 code: Key::Escape, ..
73 } => break 'mainloop,
74 _ => {}
75 }
76 }
77
78 window.clear(Color::BLACK);
79 window.draw(&circle);
80 window.draw(&sprite);
81 window.draw(&convex_shape);
82 window.draw(&title);
83 window.draw(&second_text);
84 window.draw(&third_text);
85
86 // Little test here for `Shape::points`
87 let mut circ = CircleShape::new(4.0, 30);
88 circ.set_origin(2.0);
89 circ.set_fill_color(Color::YELLOW);
90
91 for p in convex_shape.points() {
92 circ.set_position(p);
93 window.draw(&circ);
94 }
95
96 window.display();
97 }
98 Ok(())
99}
More examples
21fn main() -> SfResult<()> {
22 example_ensure_right_working_dir();
23
24 let mut rng = SmallRng::seed_from_u64(1);
25
26 // Optional antialiasing
27 let mut aa_level = 0;
28
29 if let Some(arg) = env::args().nth(1) {
30 match arg.parse::<u32>() {
31 Ok(arg_as_num) => aa_level = arg_as_num,
32 Err(e) => println!("Didn't set AA level: {e}"),
33 }
34 }
35
36 // Define some constants
37 let game_width = 800;
38 let game_height = 600;
39 let paddle_size = Vector2f::new(25., 100.);
40 let ball_radius = 10.;
41
42 // Create the window of the application
43 let context_settings = ContextSettings {
44 antialiasing_level: aa_level,
45 ..Default::default()
46 };
47 let mut window = RenderWindow::new(
48 [game_width, game_height],
49 "SFML Pong",
50 Style::CLOSE,
51 &context_settings,
52 )?;
53 let context_settings = window.settings();
54 if context_settings.antialiasing_level > 0 {
55 println!("Using {}xAA", context_settings.antialiasing_level);
56 }
57 window.set_vertical_sync_enabled(true);
58
59 // Load the sounds used in the game
60 let ball_soundbuffer = SoundBuffer::from_file("ball.wav")?;
61 let mut ball_sound = Sound::with_buffer(&ball_soundbuffer);
62
63 // Create the left paddle
64 let mut left_paddle = RectangleShape::new();
65 left_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
66 left_paddle.set_outline_thickness(3.);
67 left_paddle.set_outline_color(Color::BLACK);
68 left_paddle.set_fill_color(Color::rgb(100, 100, 200));
69 left_paddle.set_origin(paddle_size / 2.);
70
71 // Create the right paddle
72 let mut right_paddle = RectangleShape::new();
73 right_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
74 right_paddle.set_outline_thickness(3.);
75 right_paddle.set_outline_color(Color::BLACK);
76 right_paddle.set_fill_color(Color::rgb(200, 100, 100));
77 right_paddle.set_origin(paddle_size / 2.);
78
79 // Create the ball
80 let mut ball = CircleShape::default();
81 ball.set_radius(ball_radius - 3.);
82 ball.set_outline_thickness(3.);
83 ball.set_outline_color(Color::BLACK);
84 ball.set_fill_color(Color::WHITE);
85 ball.set_origin(ball_radius / 2.);
86
87 // Load the text font
88 let font = Font::from_file("sansation.ttf")?;
89
90 // Initialize the pause message
91 let mut pause_message = Text::default();
92 pause_message.set_font(&font);
93 pause_message.set_character_size(40);
94 pause_message.set_position((170., 150.));
95 pause_message.set_fill_color(Color::WHITE);
96 pause_message.set_string("Welcome to SFML pong!\nPress space to start the game");
97
98 // Define the paddles properties
99 let mut ai_timer = Clock::start()?;
100 let paddle_speed = 400.;
101 let mut right_paddle_speed = 0.;
102 let mut ball_speed = 400.;
103 let mut ball_angle = 0.;
104
105 let mut clock = Clock::start()?;
106 let mut is_playing = false;
107 let mut up = false;
108 let mut down = false;
109
110 'mainloop: loop {
111 while let Some(event) = window.poll_event() {
112 match event {
113 Event::Closed
114 | Event::KeyPressed {
115 code: Key::Escape, ..
116 } => break 'mainloop,
117 Event::KeyPressed {
118 code: Key::Space, ..
119 } if !is_playing => {
120 // (re)start the game
121 is_playing = true;
122 ball_speed = 400.0;
123 ball_sound.set_pitch(1.0);
124 clock.restart();
125 // Reset the position of the paddles and ball
126 left_paddle.set_position((10. + paddle_size.x / 2., game_height as f32 / 2.));
127 right_paddle.set_position((
128 game_width as f32 - 10. - paddle_size.x / 2.,
129 game_height as f32 / 2.,
130 ));
131 ball.set_position((game_width as f32 / 2., game_height as f32 / 2.));
132 // Reset the ball angle
133 loop {
134 // Make sure the ball initial angle is not too much vertical
135 ball_angle = rng.random_range(0.0..360.) * 2. * PI / 360.;
136
137 if ball_angle.cos().abs() >= 0.7 {
138 break;
139 }
140 }
141 }
142 Event::KeyPressed { code: Key::Up, .. }
143 | Event::KeyPressed {
144 scan: Scancode::W, ..
145 } => up = true,
146 Event::KeyReleased { code: Key::Up, .. }
147 | Event::KeyReleased {
148 scan: Scancode::W, ..
149 } => up = false,
150 Event::KeyPressed {
151 code: Key::Down, ..
152 }
153 | Event::KeyPressed {
154 scan: Scancode::S, ..
155 } => down = true,
156 Event::KeyReleased {
157 code: Key::Down, ..
158 }
159 | Event::KeyReleased {
160 scan: Scancode::S, ..
161 } => down = false,
162 _ => {}
163 }
164 }
165 if is_playing {
166 let delta_time = clock.restart().as_seconds();
167
168 // Move the player's paddle
169 if up && (left_paddle.position().y - paddle_size.y / 2. > 5.) {
170 left_paddle.move_((0., -paddle_speed * delta_time));
171 }
172 if down && (left_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.) {
173 left_paddle.move_((0., paddle_speed * delta_time));
174 }
175
176 // Move the computer's paddle
177 if ((right_paddle_speed < 0.) && (right_paddle.position().y - paddle_size.y / 2. > 5.))
178 || ((right_paddle_speed > 0.)
179 && (right_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.))
180 {
181 right_paddle.move_((0., right_paddle_speed * delta_time));
182 }
183
184 // Update the computer's paddle direction according to the ball position
185 if ai_timer.elapsed_time() > AI_REACT_DELAY {
186 ai_timer.restart();
187 if ball.position().y + ball_radius > right_paddle.position().y + paddle_size.y / 2.
188 {
189 right_paddle_speed = paddle_speed;
190 } else if ball.position().y - ball_radius
191 < right_paddle.position().y - paddle_size.y / 2.
192 {
193 right_paddle_speed = -paddle_speed;
194 } else {
195 right_paddle_speed = 0.;
196 }
197 }
198
199 // Move the ball
200 let factor = ball_speed * delta_time;
201 ball.move_((ball_angle.cos() * factor, ball_angle.sin() * factor));
202
203 // Check collisions between the ball and the screen
204 if ball.position().x - ball_radius < 0. {
205 is_playing = false;
206 pause_message.set_string("You lost !\nPress space to restart or\nescape to exit");
207 }
208 if ball.position().x + ball_radius > game_width as f32 {
209 is_playing = false;
210 pause_message.set_string("You won !\nPress space to restart or\nescape to exit");
211 }
212 if ball.position().y - ball_radius < 0. {
213 on_bounce(&mut ball_sound, &mut ball_speed);
214 ball_angle = -ball_angle;
215 let p = ball.position().x;
216 ball.set_position((p, ball_radius + 0.1));
217 }
218 if ball.position().y + ball_radius > game_height as f32 {
219 on_bounce(&mut ball_sound, &mut ball_speed);
220 ball_angle = -ball_angle;
221 let p = ball.position().x;
222 ball.set_position((p, game_height as f32 - ball_radius - 0.1));
223 }
224
225 // Check the collisions between the ball and the paddles
226 // Left Paddle
227 let (ball_pos, paddle_pos) = (ball.position(), left_paddle.position());
228 if ball_pos.x - ball_radius < paddle_pos.x + paddle_size.x / 2.
229 && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
230 && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
231 {
232 if ball_pos.y > paddle_pos.y {
233 ball_angle = PI - ball_angle + rng.random_range(0.0..20.) * PI / 180.;
234 } else {
235 ball_angle = PI - ball_angle - rng.random_range(0.0..20.) * PI / 180.;
236 }
237
238 on_bounce(&mut ball_sound, &mut ball_speed);
239 ball.set_position((
240 paddle_pos.x + ball_radius + paddle_size.x / 2. + 0.1,
241 ball_pos.y,
242 ));
243 }
244
245 // Right Paddle
246 let (ball_pos, paddle_pos) = (ball.position(), right_paddle.position());
247 if ball_pos.x + ball_radius > paddle_pos.x - paddle_size.x / 2.
248 && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
249 && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
250 {
251 if ball_pos.y > paddle_pos.y {
252 ball_angle = PI - ball_angle + rng.random_range(0.0..20.) * PI / 180.;
253 } else {
254 ball_angle = PI - ball_angle - rng.random_range(0.0..20.) * PI / 180.;
255 }
256
257 on_bounce(&mut ball_sound, &mut ball_speed);
258 ball.set_position((
259 paddle_pos.x - ball_radius - paddle_size.x / 2. - 0.1,
260 ball_pos.y,
261 ));
262 }
263 }
264 // Clear the window
265 window.clear(Color::rgb(50, 200, 50));
266
267 if is_playing {
268 // Draw the paddles and the ball
269 window.draw(&left_paddle);
270 window.draw(&right_paddle);
271 window.draw(&ball);
272 } else {
273 // Draw the pause message
274 window.draw(&pause_message);
275 }
276
277 // Display things on screen
278 window.display()
279 }
280 Ok(())
281}
Sourcepub fn set_style(&mut self, style: TextStyle)
pub fn set_style(&mut self, style: TextStyle)
Set the style of a text
You can pass a combination of one or more styles, for example Bold | Italic. The default style is Regular.
§Arguments
- style - New style
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn set_character_size(&mut self, size: u32)
pub fn set_character_size(&mut self, size: u32)
Set the size of the characters of a text
The default size is 30.
§Arguments
- size - The new character size, in pixels
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "Borrowed resources",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Create a new texture. (Hey Frank!)
24 let frank = Texture::from_file("frank.jpeg")?;
25
26 // Create a font.
27 let font = Font::from_file("sansation.ttf")?;
28
29 // Create a circle with the Texture.
30 let mut circle = CircleShape::with_texture(&frank);
31 circle.set_radius(70.0);
32 circle.set_position((100.0, 100.0));
33
34 // Create a Sprite.
35 let mut sprite = Sprite::new();
36 // Have it use the same texture as the circle.
37 sprite.set_texture(&frank, true);
38 sprite.set_position((400.0, 300.0));
39 sprite.set_scale(0.5);
40
41 // Create a ConvexShape using the same texture.
42 let mut convex_shape = ConvexShape::with_texture(6, &frank);
43 convex_shape.set_point(0, (400., 100.));
44 convex_shape.set_point(1, (500., 70.));
45 convex_shape.set_point(2, (450., 100.));
46 convex_shape.set_point(3, (580., 150.));
47 convex_shape.set_point(4, (420., 230.));
48 convex_shape.set_point(5, (420., 120.));
49
50 // Create an initialized text using the font.
51 let title = Text::new("Borrowed resources example!", &font, 50);
52
53 // Create a second text using the same font.
54 // This time, we create and initialize it separately.
55 let mut second_text = Text::default();
56 second_text.set_string("This text shares the same font with the title!");
57 second_text.set_font(&font);
58 second_text.set_fill_color(Color::GREEN);
59 second_text.set_position((10.0, 350.0));
60 second_text.set_character_size(20);
61
62 // Create a third text using the same font.
63 let mut third_text = Text::new("This one too!", &font, 20);
64 third_text.set_position((300.0, 100.0));
65 third_text.set_fill_color(Color::RED);
66
67 'mainloop: loop {
68 while let Some(event) = window.poll_event() {
69 match event {
70 Event::Closed
71 | Event::KeyPressed {
72 code: Key::Escape, ..
73 } => break 'mainloop,
74 _ => {}
75 }
76 }
77
78 window.clear(Color::BLACK);
79 window.draw(&circle);
80 window.draw(&sprite);
81 window.draw(&convex_shape);
82 window.draw(&title);
83 window.draw(&second_text);
84 window.draw(&third_text);
85
86 // Little test here for `Shape::points`
87 let mut circ = CircleShape::new(4.0, 30);
88 circ.set_origin(2.0);
89 circ.set_fill_color(Color::YELLOW);
90
91 for p in convex_shape.points() {
92 circ.set_position(p);
93 window.draw(&circ);
94 }
95
96 window.display();
97 }
98 Ok(())
99}
More examples
21fn main() -> SfResult<()> {
22 example_ensure_right_working_dir();
23
24 let mut rng = SmallRng::seed_from_u64(1);
25
26 // Optional antialiasing
27 let mut aa_level = 0;
28
29 if let Some(arg) = env::args().nth(1) {
30 match arg.parse::<u32>() {
31 Ok(arg_as_num) => aa_level = arg_as_num,
32 Err(e) => println!("Didn't set AA level: {e}"),
33 }
34 }
35
36 // Define some constants
37 let game_width = 800;
38 let game_height = 600;
39 let paddle_size = Vector2f::new(25., 100.);
40 let ball_radius = 10.;
41
42 // Create the window of the application
43 let context_settings = ContextSettings {
44 antialiasing_level: aa_level,
45 ..Default::default()
46 };
47 let mut window = RenderWindow::new(
48 [game_width, game_height],
49 "SFML Pong",
50 Style::CLOSE,
51 &context_settings,
52 )?;
53 let context_settings = window.settings();
54 if context_settings.antialiasing_level > 0 {
55 println!("Using {}xAA", context_settings.antialiasing_level);
56 }
57 window.set_vertical_sync_enabled(true);
58
59 // Load the sounds used in the game
60 let ball_soundbuffer = SoundBuffer::from_file("ball.wav")?;
61 let mut ball_sound = Sound::with_buffer(&ball_soundbuffer);
62
63 // Create the left paddle
64 let mut left_paddle = RectangleShape::new();
65 left_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
66 left_paddle.set_outline_thickness(3.);
67 left_paddle.set_outline_color(Color::BLACK);
68 left_paddle.set_fill_color(Color::rgb(100, 100, 200));
69 left_paddle.set_origin(paddle_size / 2.);
70
71 // Create the right paddle
72 let mut right_paddle = RectangleShape::new();
73 right_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
74 right_paddle.set_outline_thickness(3.);
75 right_paddle.set_outline_color(Color::BLACK);
76 right_paddle.set_fill_color(Color::rgb(200, 100, 100));
77 right_paddle.set_origin(paddle_size / 2.);
78
79 // Create the ball
80 let mut ball = CircleShape::default();
81 ball.set_radius(ball_radius - 3.);
82 ball.set_outline_thickness(3.);
83 ball.set_outline_color(Color::BLACK);
84 ball.set_fill_color(Color::WHITE);
85 ball.set_origin(ball_radius / 2.);
86
87 // Load the text font
88 let font = Font::from_file("sansation.ttf")?;
89
90 // Initialize the pause message
91 let mut pause_message = Text::default();
92 pause_message.set_font(&font);
93 pause_message.set_character_size(40);
94 pause_message.set_position((170., 150.));
95 pause_message.set_fill_color(Color::WHITE);
96 pause_message.set_string("Welcome to SFML pong!\nPress space to start the game");
97
98 // Define the paddles properties
99 let mut ai_timer = Clock::start()?;
100 let paddle_speed = 400.;
101 let mut right_paddle_speed = 0.;
102 let mut ball_speed = 400.;
103 let mut ball_angle = 0.;
104
105 let mut clock = Clock::start()?;
106 let mut is_playing = false;
107 let mut up = false;
108 let mut down = false;
109
110 'mainloop: loop {
111 while let Some(event) = window.poll_event() {
112 match event {
113 Event::Closed
114 | Event::KeyPressed {
115 code: Key::Escape, ..
116 } => break 'mainloop,
117 Event::KeyPressed {
118 code: Key::Space, ..
119 } if !is_playing => {
120 // (re)start the game
121 is_playing = true;
122 ball_speed = 400.0;
123 ball_sound.set_pitch(1.0);
124 clock.restart();
125 // Reset the position of the paddles and ball
126 left_paddle.set_position((10. + paddle_size.x / 2., game_height as f32 / 2.));
127 right_paddle.set_position((
128 game_width as f32 - 10. - paddle_size.x / 2.,
129 game_height as f32 / 2.,
130 ));
131 ball.set_position((game_width as f32 / 2., game_height as f32 / 2.));
132 // Reset the ball angle
133 loop {
134 // Make sure the ball initial angle is not too much vertical
135 ball_angle = rng.random_range(0.0..360.) * 2. * PI / 360.;
136
137 if ball_angle.cos().abs() >= 0.7 {
138 break;
139 }
140 }
141 }
142 Event::KeyPressed { code: Key::Up, .. }
143 | Event::KeyPressed {
144 scan: Scancode::W, ..
145 } => up = true,
146 Event::KeyReleased { code: Key::Up, .. }
147 | Event::KeyReleased {
148 scan: Scancode::W, ..
149 } => up = false,
150 Event::KeyPressed {
151 code: Key::Down, ..
152 }
153 | Event::KeyPressed {
154 scan: Scancode::S, ..
155 } => down = true,
156 Event::KeyReleased {
157 code: Key::Down, ..
158 }
159 | Event::KeyReleased {
160 scan: Scancode::S, ..
161 } => down = false,
162 _ => {}
163 }
164 }
165 if is_playing {
166 let delta_time = clock.restart().as_seconds();
167
168 // Move the player's paddle
169 if up && (left_paddle.position().y - paddle_size.y / 2. > 5.) {
170 left_paddle.move_((0., -paddle_speed * delta_time));
171 }
172 if down && (left_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.) {
173 left_paddle.move_((0., paddle_speed * delta_time));
174 }
175
176 // Move the computer's paddle
177 if ((right_paddle_speed < 0.) && (right_paddle.position().y - paddle_size.y / 2. > 5.))
178 || ((right_paddle_speed > 0.)
179 && (right_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.))
180 {
181 right_paddle.move_((0., right_paddle_speed * delta_time));
182 }
183
184 // Update the computer's paddle direction according to the ball position
185 if ai_timer.elapsed_time() > AI_REACT_DELAY {
186 ai_timer.restart();
187 if ball.position().y + ball_radius > right_paddle.position().y + paddle_size.y / 2.
188 {
189 right_paddle_speed = paddle_speed;
190 } else if ball.position().y - ball_radius
191 < right_paddle.position().y - paddle_size.y / 2.
192 {
193 right_paddle_speed = -paddle_speed;
194 } else {
195 right_paddle_speed = 0.;
196 }
197 }
198
199 // Move the ball
200 let factor = ball_speed * delta_time;
201 ball.move_((ball_angle.cos() * factor, ball_angle.sin() * factor));
202
203 // Check collisions between the ball and the screen
204 if ball.position().x - ball_radius < 0. {
205 is_playing = false;
206 pause_message.set_string("You lost !\nPress space to restart or\nescape to exit");
207 }
208 if ball.position().x + ball_radius > game_width as f32 {
209 is_playing = false;
210 pause_message.set_string("You won !\nPress space to restart or\nescape to exit");
211 }
212 if ball.position().y - ball_radius < 0. {
213 on_bounce(&mut ball_sound, &mut ball_speed);
214 ball_angle = -ball_angle;
215 let p = ball.position().x;
216 ball.set_position((p, ball_radius + 0.1));
217 }
218 if ball.position().y + ball_radius > game_height as f32 {
219 on_bounce(&mut ball_sound, &mut ball_speed);
220 ball_angle = -ball_angle;
221 let p = ball.position().x;
222 ball.set_position((p, game_height as f32 - ball_radius - 0.1));
223 }
224
225 // Check the collisions between the ball and the paddles
226 // Left Paddle
227 let (ball_pos, paddle_pos) = (ball.position(), left_paddle.position());
228 if ball_pos.x - ball_radius < paddle_pos.x + paddle_size.x / 2.
229 && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
230 && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
231 {
232 if ball_pos.y > paddle_pos.y {
233 ball_angle = PI - ball_angle + rng.random_range(0.0..20.) * PI / 180.;
234 } else {
235 ball_angle = PI - ball_angle - rng.random_range(0.0..20.) * PI / 180.;
236 }
237
238 on_bounce(&mut ball_sound, &mut ball_speed);
239 ball.set_position((
240 paddle_pos.x + ball_radius + paddle_size.x / 2. + 0.1,
241 ball_pos.y,
242 ));
243 }
244
245 // Right Paddle
246 let (ball_pos, paddle_pos) = (ball.position(), right_paddle.position());
247 if ball_pos.x + ball_radius > paddle_pos.x - paddle_size.x / 2.
248 && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
249 && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
250 {
251 if ball_pos.y > paddle_pos.y {
252 ball_angle = PI - ball_angle + rng.random_range(0.0..20.) * PI / 180.;
253 } else {
254 ball_angle = PI - ball_angle - rng.random_range(0.0..20.) * PI / 180.;
255 }
256
257 on_bounce(&mut ball_sound, &mut ball_speed);
258 ball.set_position((
259 paddle_pos.x - ball_radius - paddle_size.x / 2. - 0.1,
260 ball_pos.y,
261 ));
262 }
263 }
264 // Clear the window
265 window.clear(Color::rgb(50, 200, 50));
266
267 if is_playing {
268 // Draw the paddles and the ball
269 window.draw(&left_paddle);
270 window.draw(&right_paddle);
271 window.draw(&ball);
272 } else {
273 // Draw the pause message
274 window.draw(&pause_message);
275 }
276
277 // Display things on screen
278 window.display()
279 }
280 Ok(())
281}
Sourcepub fn style(&self) -> TextStyle
pub fn style(&self) -> TextStyle
Get the style of a text
Return the current string style (see Style enum)
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn font(&self) -> Option<&'s Font>
pub fn font(&self) -> Option<&'s Font>
Get the font of a text If the text has no font attached, a None is returned. The returned pointer is const, which means that you can’t modify the font when you retrieve it with this function.
Sourcepub fn set_fill_color(&mut self, color: Color)
pub fn set_fill_color(&mut self, color: Color)
Set the fill color of the text.
By default, the text’s fill color is opaque white. Setting the fill color to a transparent color with an outline will cause the outline to be displayed in the fill area of the text.
Examples found in repository?
35fn draw_button(
36 rect: &Rect<i32>,
37 shape: &mut RectangleShape,
38 text: &mut Text,
39 string: &str,
40 render_window: &mut RenderWindow,
41 style: ButtonStyle,
42) {
43 shape.set_position((rect.left as f32, rect.top as f32));
44 shape.set_size((rect.width as f32, rect.height as f32));
45 let (rect_fill, rect_outline, text_fill) = match style {
46 ButtonStyle::Normal => (Color::TRANSPARENT, Color::WHITE, Color::WHITE),
47 ButtonStyle::Highlighted => (Color::WHITE, Color::WHITE, Color::BLACK),
48 ButtonStyle::Selected => (Color::GREEN, Color::GREEN, Color::BLACK),
49 ButtonStyle::Error => (Color::RED, Color::BLACK, Color::BLACK),
50 };
51 shape.set_outline_color(rect_outline);
52 shape.set_fill_color(rect_fill);
53 text.set_position((rect.left as f32 + 12.0, rect.top as f32 + 8.0));
54 text.set_fill_color(text_fill);
55 text.set_string(string);
56 render_window.draw(shape);
57 render_window.draw(text);
58}
More examples
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "Borrowed resources",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Create a new texture. (Hey Frank!)
24 let frank = Texture::from_file("frank.jpeg")?;
25
26 // Create a font.
27 let font = Font::from_file("sansation.ttf")?;
28
29 // Create a circle with the Texture.
30 let mut circle = CircleShape::with_texture(&frank);
31 circle.set_radius(70.0);
32 circle.set_position((100.0, 100.0));
33
34 // Create a Sprite.
35 let mut sprite = Sprite::new();
36 // Have it use the same texture as the circle.
37 sprite.set_texture(&frank, true);
38 sprite.set_position((400.0, 300.0));
39 sprite.set_scale(0.5);
40
41 // Create a ConvexShape using the same texture.
42 let mut convex_shape = ConvexShape::with_texture(6, &frank);
43 convex_shape.set_point(0, (400., 100.));
44 convex_shape.set_point(1, (500., 70.));
45 convex_shape.set_point(2, (450., 100.));
46 convex_shape.set_point(3, (580., 150.));
47 convex_shape.set_point(4, (420., 230.));
48 convex_shape.set_point(5, (420., 120.));
49
50 // Create an initialized text using the font.
51 let title = Text::new("Borrowed resources example!", &font, 50);
52
53 // Create a second text using the same font.
54 // This time, we create and initialize it separately.
55 let mut second_text = Text::default();
56 second_text.set_string("This text shares the same font with the title!");
57 second_text.set_font(&font);
58 second_text.set_fill_color(Color::GREEN);
59 second_text.set_position((10.0, 350.0));
60 second_text.set_character_size(20);
61
62 // Create a third text using the same font.
63 let mut third_text = Text::new("This one too!", &font, 20);
64 third_text.set_position((300.0, 100.0));
65 third_text.set_fill_color(Color::RED);
66
67 'mainloop: loop {
68 while let Some(event) = window.poll_event() {
69 match event {
70 Event::Closed
71 | Event::KeyPressed {
72 code: Key::Escape, ..
73 } => break 'mainloop,
74 _ => {}
75 }
76 }
77
78 window.clear(Color::BLACK);
79 window.draw(&circle);
80 window.draw(&sprite);
81 window.draw(&convex_shape);
82 window.draw(&title);
83 window.draw(&second_text);
84 window.draw(&third_text);
85
86 // Little test here for `Shape::points`
87 let mut circ = CircleShape::new(4.0, 30);
88 circ.set_origin(2.0);
89 circ.set_fill_color(Color::YELLOW);
90
91 for p in convex_shape.points() {
92 circ.set_position(p);
93 window.draw(&circ);
94 }
95
96 window.display();
97 }
98 Ok(())
99}
317fn main() -> SfResult<()> {
318 example_ensure_right_working_dir();
319
320 let mut window = RenderWindow::new(
321 (800, 600),
322 "SFML Shader",
323 Style::TITLEBAR | Style::CLOSE,
324 &Default::default(),
325 )?;
326 window.set_vertical_sync_enabled(true);
327 let font = Font::from_file("sansation.ttf")?;
328 let bg = Texture::from_file("background.jpg")?;
329 let mut bg_texture = Texture::from_file("sfml.png")?;
330 bg_texture.set_smooth(true);
331 let mut entity_texture = Texture::from_file("devices.png")?;
332 entity_texture.set_smooth(true);
333 let logo_texture = Texture::from_file("logo.png")?;
334 let effects: [&mut dyn Effect; 5] = [
335 &mut Pixelate::new(&bg)?,
336 &mut WaveBlur::new(&font)?,
337 &mut StormBlink::new()?,
338 &mut Edge::new(&bg_texture, &entity_texture)?,
339 &mut Geometry::new(&logo_texture)?,
340 ];
341 let mut current = 0;
342 let text_bg_texture = Texture::from_file("text-background.png")?;
343 let mut text_bg = Sprite::with_texture(&text_bg_texture);
344 text_bg.set_position((0., 520.));
345 text_bg.set_color(Color::rgba(255, 255, 255, 200));
346 let msg = format!("Current effect: {}", effects[current].name());
347 let mut desc = Text::new(&msg, &font, 20);
348 desc.set_position((10., 530.));
349 desc.set_fill_color(Color::rgb(80, 80, 80));
350 let msg = "Press left and right arrows to change the current shader";
351 let mut instructions = Text::new(msg, &font, 20);
352 instructions.set_position((280., 555.));
353 instructions.set_fill_color(Color::rgb(80, 80, 80));
354 let clock = Clock::start()?;
355
356 while window.is_open() {
357 while let Some(event) = window.poll_event() {
358 use crate::Event::*;
359 match event {
360 Closed => window.close(),
361 KeyPressed { code, .. } => match code {
362 Key::Escape => window.close(),
363 Key::Left => {
364 if current == 0 {
365 current = effects.len() - 1;
366 } else {
367 current -= 1;
368 }
369 desc.set_string(&format!("Current effect: {}", effects[current].name()));
370 }
371 Key::Right => {
372 if current == effects.len() - 1 {
373 current = 0;
374 } else {
375 current += 1;
376 }
377 desc.set_string(&format!("Current effect: {}", effects[current].name()));
378 }
379 _ => {}
380 },
381 _ => {}
382 }
383 }
384
385 let x = window.mouse_position().x as f32 / window.size().x as f32;
386 let y = window.mouse_position().y as f32 / window.size().y as f32;
387
388 effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
389
390 window.clear(Color::rgb(255, 128, 0));
391 window.draw(effects[current]);
392 window.draw(&text_bg);
393 window.draw(&instructions);
394 window.draw(&desc);
395 window.display();
396 }
397 Ok(())
398}
5fn main() -> SfResult<()> {
6 example_ensure_right_working_dir();
7
8 let mut window = RenderWindow::new(
9 (800, 600),
10 "Mouse events",
11 Style::CLOSE,
12 &Default::default(),
13 )?;
14 window.set_mouse_cursor_visible(false);
15 window.set_vertical_sync_enabled(true);
16
17 let font = Font::from_file("sansation.ttf")?;
18 let mut circle = CircleShape::new(4., 30);
19 let mut texts: Vec<Text> = Vec::new();
20 let mut mp_text = Text::new("", &font, 14);
21 let mut cursor_visible = false;
22 let mut grabbed = false;
23 macro_rules! push_text {
24 ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25 let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26 text.set_position(($x as f32, $y as f32));
27 texts.push(text);
28 }
29 }
30
31 'mainloop: loop {
32 while let Some(ev) = window.poll_event() {
33 match ev {
34 Event::Closed => break 'mainloop,
35 Event::MouseWheelScrolled { wheel, delta, x, y } => {
36 push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37 }
38 Event::MouseButtonPressed { button, x, y } => {
39 push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40 }
41 Event::MouseButtonReleased { button, x, y } => {
42 push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43 }
44 Event::KeyPressed { code, .. } => {
45 if code == Key::W {
46 window.set_mouse_position(Vector2i::new(400, 300));
47 } else if code == Key::D {
48 let dm = VideoMode::desktop_mode();
49 let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50 mouse::set_desktop_position(center);
51 } else if code == Key::V {
52 cursor_visible = !cursor_visible;
53 window.set_mouse_cursor_visible(cursor_visible);
54 } else if code == Key::G {
55 grabbed = !grabbed;
56 window.set_mouse_cursor_grabbed(grabbed);
57 }
58 }
59 _ => {}
60 }
61 }
62
63 let mp = window.mouse_position();
64 let dmp = mouse::desktop_position();
65 let cur_vis_msg = if cursor_visible {
66 "visible"
67 } else {
68 "invisible"
69 };
70 let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71 mp_text.set_string(&format!(
72 "x: {}, y: {} (Window)\n\
73 x: {}, y: {} (Desktop)\n\
74 [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75 'W' to center mouse on window\n\
76 'D' to center mouse on desktop",
77 mp.x, mp.y, dmp.x, dmp.y
78 ));
79
80 circle.set_position((mp.x as f32, mp.y as f32));
81
82 window.clear(Color::BLACK);
83 // Push texts out of each other's way
84 for i in (0..texts.len()).rev() {
85 for j in (0..i).rev() {
86 if let Some(intersect) = texts[i]
87 .global_bounds()
88 .intersection(&texts[j].global_bounds())
89 {
90 texts[j].move_((0., -intersect.height));
91 }
92 }
93 }
94 texts.retain(|txt| txt.fill_color().a > 0);
95 for txt in &mut texts {
96 let mut color = txt.fill_color();
97 color.a -= 1;
98 txt.set_fill_color(color);
99 window.draw(txt);
100 }
101 if !cursor_visible {
102 window.draw(&circle);
103 }
104 window.draw(&mp_text);
105 window.display();
106 }
107 Ok(())
108}
13fn main() -> SfResult<()> {
14 let configs = [
15 WindowConfig {
16 mode: (320, 240),
17 title: "(Windowed) Retro",
18 style: Style::CLOSE,
19 },
20 WindowConfig {
21 mode: (640, 480),
22 title: "(Windowed) Classic",
23 style: Style::DEFAULT,
24 },
25 WindowConfig {
26 mode: (800, 600),
27 title: "(Windowed) Big",
28 style: Style::TITLEBAR,
29 },
30 ];
31 let mut cfg_idx = 2usize;
32 let mut rw = RenderWindow::new(
33 configs[cfg_idx].mode,
34 "Window test",
35 Style::CLOSE,
36 &ContextSettings::default(),
37 )?;
38 let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?;
39 let fs_modes = VideoMode::fullscreen_modes();
40
41 while rw.is_open() {
42 while let Some(ev) = rw.poll_event() {
43 match ev {
44 Event::Closed => rw.close(),
45 Event::KeyPressed { code, .. } => match code {
46 Key::Up => cfg_idx = cfg_idx.saturating_sub(1),
47 Key::Down => {
48 if cfg_idx + 1 < configs.len() + fs_modes.len() {
49 cfg_idx += 1
50 }
51 }
52 Key::Enter => match configs.get(cfg_idx) {
53 Some(cfg) => {
54 rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default())
55 }
56 None => match fs_modes.get(cfg_idx - configs.len()) {
57 Some(mode) => rw.recreate(
58 *mode,
59 "Fullscreen",
60 Style::FULLSCREEN,
61 &ContextSettings::default(),
62 ),
63 None => {
64 eprintln!("Invalid index: {cfg_idx}");
65 }
66 },
67 },
68 _ => {}
69 },
70 _ => {}
71 }
72 }
73 rw.clear(Color::BLACK);
74 let fontsize = 16;
75 let mut txt = Text::new("Arrow keys to select mode, enter to set.", &font, fontsize);
76 rw.draw(&txt);
77 let mut y = fontsize as f32;
78 for (i, cfg) in configs.iter().enumerate() {
79 let fc = if i == cfg_idx {
80 Color::YELLOW
81 } else {
82 Color::WHITE
83 };
84 txt.set_fill_color(fc);
85 txt.set_string(&format!(
86 "{}x{} \"{}\" ({:?})",
87 cfg.mode.0, cfg.mode.1, cfg.title, cfg.style
88 ));
89 txt.set_position((0., y));
90 rw.draw(&txt);
91 y += fontsize as f32;
92 }
93 let mut i = configs.len();
94 y += fontsize as f32;
95 txt.set_position((0., y));
96 txt.set_fill_color(Color::WHITE);
97 txt.set_string("= Fullscreen modes =");
98 rw.draw(&txt);
99 for mode in fs_modes.iter() {
100 let n_rows = 23;
101 let column = i / n_rows;
102 let row = i % n_rows;
103 let fc = if i == cfg_idx {
104 Color::YELLOW
105 } else {
106 Color::WHITE
107 };
108 txt.set_fill_color(fc);
109 let left_pad = 16.0;
110 let x = left_pad + (column * 128) as f32;
111 let gap = 16.0;
112 let y = y + gap + (row * fontsize as usize) as f32;
113 txt.set_position((x, y));
114 txt.set_string(&format!(
115 "{}x{}x{}",
116 mode.width, mode.height, mode.bits_per_pixel
117 ));
118 rw.draw(&txt);
119 i += 1;
120 }
121 rw.display();
122 }
123 Ok(())
124}
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn set_outline_color(&mut self, color: Color)
pub fn set_outline_color(&mut self, color: Color)
Set the outline color of the text.
By default, the text’s outline color is opaque black.
Examples found in repository?
62fn main() -> SfResult<()> {
63 example_ensure_right_working_dir();
64
65 let native_mode = VideoMode::desktop_mode();
66 let mut window = RenderWindow::new(
67 native_mode,
68 "Spritemark",
69 Style::default(),
70 &ContextSettings::default(),
71 )?;
72 window.set_position(Vector2::new(0, 0));
73 window.set_vertical_sync_enabled(true);
74 let font = Font::from_file("sansation.ttf")?;
75 let texture = Texture::from_file("devices.png")?;
76 let mut text = Text::new("", &font, 18);
77 text.set_outline_color(Color::BLACK);
78 text.set_outline_thickness(1.0);
79 let mut click_counter = 0;
80 let mut objects = Vec::new();
81 let mut rng = SmallRng::seed_from_u64(1);
82 let mut rs = RenderStates::default();
83 let mut buf = Vec::new();
84 let mut frames_rendered = 0;
85 let mut sec_clock = Clock::start()?;
86 let mut fps = 0;
87 let mut lmb_down = false;
88 let mut view = View::new()?;
89
90 while window.is_open() {
91 while let Some(event) = window.poll_event() {
92 match event {
93 Event::Closed
94 | Event::KeyPressed {
95 code: Key::Escape, ..
96 } => window.close(),
97 Event::MouseButtonPressed {
98 button: Button::Left,
99 ..
100 } => {
101 click_counter += 1;
102 lmb_down = true;
103 }
104 Event::MouseButtonReleased {
105 button: Button::Left,
106 ..
107 } => {
108 lmb_down = false;
109 }
110 Event::Resized { width, height } => {
111 view.reset(Rect::new(0., 0., width as f32, height as f32));
112 window.set_view(&view);
113 }
114 _ => {}
115 }
116 }
117
118 if lmb_down {
119 let mp = window.mouse_position();
120 for _ in 0..25 {
121 objects.push(Object {
122 position: fconv(mp),
123 speed: Vector2f::new(rng.random_range(-3.0..3.0), 0.0),
124 image_id: click_counter % N_IMAGES,
125 angle: 0.0,
126 rot_speed: rng.random_range(-2.0..2.0),
127 });
128 }
129 }
130
131 for obj in &mut objects {
132 let size = f32::from(SUBIMAGE_SIZE);
133 let tex_x = f32::from(obj.image_id) * size;
134 let mut tf = Transform::default();
135 tf.translate(obj.position.x, obj.position.y);
136 tf.rotate_with_center(obj.angle, size / 2.0, size / 2.0);
137 buf.push(Vertex {
138 color: Color::WHITE,
139 position: tf.transform_point(Vector2f::new(0., 0.)),
140 tex_coords: Vector2f::new(tex_x, 0.),
141 });
142 buf.push(Vertex {
143 color: Color::WHITE,
144 position: tf.transform_point(Vector2f::new(0., size)),
145 tex_coords: Vector2f::new(tex_x, size),
146 });
147 buf.push(Vertex {
148 color: Color::WHITE,
149 position: tf.transform_point(Vector2f::new(size, size)),
150 tex_coords: Vector2f::new(tex_x + size, size),
151 });
152 buf.push(Vertex {
153 color: Color::WHITE,
154 position: tf.transform_point(Vector2f::new(size, 0.)),
155 tex_coords: Vector2f::new(tex_x + size, 0.),
156 });
157 obj.update(window.size().y as f32, window.size().x as f32);
158 }
159 window.clear(Color::BLACK);
160 rs.texture = Some(&texture);
161 window.draw_primitives(&buf, PrimitiveType::QUADS, &rs);
162 rs.texture = None;
163 text.set_string(&format!("{} sprites\n{fps} fps", objects.len()));
164 window.draw_text(&text, &rs);
165 window.display();
166 buf.clear();
167 frames_rendered += 1;
168 if sec_clock.elapsed_time().as_milliseconds() >= 1000 {
169 fps = frames_rendered;
170 sec_clock.restart();
171 frames_rendered = 0;
172 }
173 }
174 Ok(())
175}
More examples
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn set_outline_thickness(&mut self, thickness: f32)
pub fn set_outline_thickness(&mut self, thickness: f32)
Set the thickness of the text’s outline.
By default, the outline thickness is 0.
Be aware that using a negative value for the outline thickness will cause distorted rendering.
Examples found in repository?
62fn main() -> SfResult<()> {
63 example_ensure_right_working_dir();
64
65 let native_mode = VideoMode::desktop_mode();
66 let mut window = RenderWindow::new(
67 native_mode,
68 "Spritemark",
69 Style::default(),
70 &ContextSettings::default(),
71 )?;
72 window.set_position(Vector2::new(0, 0));
73 window.set_vertical_sync_enabled(true);
74 let font = Font::from_file("sansation.ttf")?;
75 let texture = Texture::from_file("devices.png")?;
76 let mut text = Text::new("", &font, 18);
77 text.set_outline_color(Color::BLACK);
78 text.set_outline_thickness(1.0);
79 let mut click_counter = 0;
80 let mut objects = Vec::new();
81 let mut rng = SmallRng::seed_from_u64(1);
82 let mut rs = RenderStates::default();
83 let mut buf = Vec::new();
84 let mut frames_rendered = 0;
85 let mut sec_clock = Clock::start()?;
86 let mut fps = 0;
87 let mut lmb_down = false;
88 let mut view = View::new()?;
89
90 while window.is_open() {
91 while let Some(event) = window.poll_event() {
92 match event {
93 Event::Closed
94 | Event::KeyPressed {
95 code: Key::Escape, ..
96 } => window.close(),
97 Event::MouseButtonPressed {
98 button: Button::Left,
99 ..
100 } => {
101 click_counter += 1;
102 lmb_down = true;
103 }
104 Event::MouseButtonReleased {
105 button: Button::Left,
106 ..
107 } => {
108 lmb_down = false;
109 }
110 Event::Resized { width, height } => {
111 view.reset(Rect::new(0., 0., width as f32, height as f32));
112 window.set_view(&view);
113 }
114 _ => {}
115 }
116 }
117
118 if lmb_down {
119 let mp = window.mouse_position();
120 for _ in 0..25 {
121 objects.push(Object {
122 position: fconv(mp),
123 speed: Vector2f::new(rng.random_range(-3.0..3.0), 0.0),
124 image_id: click_counter % N_IMAGES,
125 angle: 0.0,
126 rot_speed: rng.random_range(-2.0..2.0),
127 });
128 }
129 }
130
131 for obj in &mut objects {
132 let size = f32::from(SUBIMAGE_SIZE);
133 let tex_x = f32::from(obj.image_id) * size;
134 let mut tf = Transform::default();
135 tf.translate(obj.position.x, obj.position.y);
136 tf.rotate_with_center(obj.angle, size / 2.0, size / 2.0);
137 buf.push(Vertex {
138 color: Color::WHITE,
139 position: tf.transform_point(Vector2f::new(0., 0.)),
140 tex_coords: Vector2f::new(tex_x, 0.),
141 });
142 buf.push(Vertex {
143 color: Color::WHITE,
144 position: tf.transform_point(Vector2f::new(0., size)),
145 tex_coords: Vector2f::new(tex_x, size),
146 });
147 buf.push(Vertex {
148 color: Color::WHITE,
149 position: tf.transform_point(Vector2f::new(size, size)),
150 tex_coords: Vector2f::new(tex_x + size, size),
151 });
152 buf.push(Vertex {
153 color: Color::WHITE,
154 position: tf.transform_point(Vector2f::new(size, 0.)),
155 tex_coords: Vector2f::new(tex_x + size, 0.),
156 });
157 obj.update(window.size().y as f32, window.size().x as f32);
158 }
159 window.clear(Color::BLACK);
160 rs.texture = Some(&texture);
161 window.draw_primitives(&buf, PrimitiveType::QUADS, &rs);
162 rs.texture = None;
163 text.set_string(&format!("{} sprites\n{fps} fps", objects.len()));
164 window.draw_text(&text, &rs);
165 window.display();
166 buf.clear();
167 frames_rendered += 1;
168 if sec_clock.elapsed_time().as_milliseconds() >= 1000 {
169 fps = frames_rendered;
170 sec_clock.restart();
171 frames_rendered = 0;
172 }
173 }
174 Ok(())
175}
More examples
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn fill_color(&self) -> Color
pub fn fill_color(&self) -> Color
Returns the fill color of the text.
Examples found in repository?
5fn main() -> SfResult<()> {
6 example_ensure_right_working_dir();
7
8 let mut window = RenderWindow::new(
9 (800, 600),
10 "Mouse events",
11 Style::CLOSE,
12 &Default::default(),
13 )?;
14 window.set_mouse_cursor_visible(false);
15 window.set_vertical_sync_enabled(true);
16
17 let font = Font::from_file("sansation.ttf")?;
18 let mut circle = CircleShape::new(4., 30);
19 let mut texts: Vec<Text> = Vec::new();
20 let mut mp_text = Text::new("", &font, 14);
21 let mut cursor_visible = false;
22 let mut grabbed = false;
23 macro_rules! push_text {
24 ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25 let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26 text.set_position(($x as f32, $y as f32));
27 texts.push(text);
28 }
29 }
30
31 'mainloop: loop {
32 while let Some(ev) = window.poll_event() {
33 match ev {
34 Event::Closed => break 'mainloop,
35 Event::MouseWheelScrolled { wheel, delta, x, y } => {
36 push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37 }
38 Event::MouseButtonPressed { button, x, y } => {
39 push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40 }
41 Event::MouseButtonReleased { button, x, y } => {
42 push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43 }
44 Event::KeyPressed { code, .. } => {
45 if code == Key::W {
46 window.set_mouse_position(Vector2i::new(400, 300));
47 } else if code == Key::D {
48 let dm = VideoMode::desktop_mode();
49 let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50 mouse::set_desktop_position(center);
51 } else if code == Key::V {
52 cursor_visible = !cursor_visible;
53 window.set_mouse_cursor_visible(cursor_visible);
54 } else if code == Key::G {
55 grabbed = !grabbed;
56 window.set_mouse_cursor_grabbed(grabbed);
57 }
58 }
59 _ => {}
60 }
61 }
62
63 let mp = window.mouse_position();
64 let dmp = mouse::desktop_position();
65 let cur_vis_msg = if cursor_visible {
66 "visible"
67 } else {
68 "invisible"
69 };
70 let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71 mp_text.set_string(&format!(
72 "x: {}, y: {} (Window)\n\
73 x: {}, y: {} (Desktop)\n\
74 [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75 'W' to center mouse on window\n\
76 'D' to center mouse on desktop",
77 mp.x, mp.y, dmp.x, dmp.y
78 ));
79
80 circle.set_position((mp.x as f32, mp.y as f32));
81
82 window.clear(Color::BLACK);
83 // Push texts out of each other's way
84 for i in (0..texts.len()).rev() {
85 for j in (0..i).rev() {
86 if let Some(intersect) = texts[i]
87 .global_bounds()
88 .intersection(&texts[j].global_bounds())
89 {
90 texts[j].move_((0., -intersect.height));
91 }
92 }
93 }
94 texts.retain(|txt| txt.fill_color().a > 0);
95 for txt in &mut texts {
96 let mut color = txt.fill_color();
97 color.a -= 1;
98 txt.set_fill_color(color);
99 window.draw(txt);
100 }
101 if !cursor_visible {
102 window.draw(&circle);
103 }
104 window.draw(&mp_text);
105 window.display();
106 }
107 Ok(())
108}
More examples
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn outline_color(&self) -> Color
pub fn outline_color(&self) -> Color
Returns the outline color of the text.
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn outline_thickness(&self) -> f32
pub fn outline_thickness(&self) -> f32
Returns the outline thickness of the text, in pixels.
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn find_character_pos(&self, index: usize) -> Vector2f
pub fn find_character_pos(&self, index: usize) -> Vector2f
Return the position of the index-th character in a text
This function computes the visual position of a character from its index in the string. The returned position is in global coordinates (translation, rotation, scale and origin are applied). If index is out of range, the position of the end of the string is returned.
§Arguments
- index - The index of the character
Return the position of the character
Examples found in repository?
12fn main() -> SfResult<()> {
13 example_ensure_right_working_dir();
14
15 let mut window = RenderWindow::new(
16 (800, 600),
17 "◢◤ Unicode text entry ◥◣",
18 Style::CLOSE,
19 &Default::default(),
20 )?;
21 window.set_vertical_sync_enabled(true);
22
23 // Showcase delayed initialization of font
24 let mut font = Font::new()?;
25
26 match std::env::args().nth(1) {
27 Some(path) => font.load_from_file(&path)?,
28 None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29 };
30 let mut string = String::from("This text can be edited.\nTry it!");
31
32 let mut text = Text::new(&string, &font, 24);
33 text.set_fill_color(Color::RED);
34 text.set_outline_color(Color::YELLOW);
35 text.set_outline_thickness(2.0);
36 let mut status_text = Text::new("", &font, 16);
37 status_text.set_position((0., window.size().y as f32 - 64.0));
38 let mut bold = false;
39 let mut italic = false;
40 let mut underlined = false;
41 let mut strikethrough = false;
42 let mut show_cursor = true;
43
44 'mainloop: loop {
45 while let Some(ev) = window.poll_event() {
46 match ev {
47 Event::Closed => break 'mainloop,
48 Event::TextEntered { unicode } => {
49 if unicode == 0x08 as char {
50 string.pop();
51 } else if unicode == 0xD as char {
52 string.push('\n');
53 }
54 // Ignore ctrl+v/ctrl+v generated chars
55 else if unicode != 0x16 as char && unicode != 0x03 as char {
56 string.push(unicode);
57 }
58 text.set_string(&string);
59 }
60 Event::KeyPressed {
61 code: Key::V,
62 ctrl: true,
63 ..
64 } => {
65 string.push_str(&clipboard::get_string());
66 text.set_string(&string);
67 }
68 Event::KeyPressed {
69 code: Key::C,
70 ctrl: true,
71 ..
72 } => {
73 clipboard::set_string(text.string());
74 }
75 Event::KeyPressed { code, .. } => {
76 match code {
77 Key::Escape => break 'mainloop,
78 Key::F1 => bold ^= true,
79 Key::F2 => italic ^= true,
80 Key::F3 => underlined ^= true,
81 Key::F4 => strikethrough ^= true,
82 Key::F5 => show_cursor ^= true,
83 _ => {}
84 }
85 let mut style = TextStyle::default();
86 if bold {
87 style |= TextStyle::BOLD;
88 }
89 if italic {
90 style |= TextStyle::ITALIC;
91 }
92 if underlined {
93 style |= TextStyle::UNDERLINED;
94 }
95 if strikethrough {
96 style |= TextStyle::STRIKETHROUGH;
97 }
98 text.set_style(style);
99 }
100 _ => {}
101 }
102 }
103
104 let status_string = {
105 let fc = text.fill_color();
106 let oc = text.outline_color();
107 format!(
108 "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109 style: {:?} (F1-F4) cursor: {} (F5)\n\
110 font family: {}",
111 fc.r,
112 fc.g,
113 fc.b,
114 fc.a,
115 oc.r,
116 oc.g,
117 oc.b,
118 oc.a,
119 text.outline_thickness(),
120 text.style(),
121 show_cursor,
122 font.info().family
123 )
124 };
125 status_text.set_string(&status_string);
126
127 window.clear(Color::BLACK);
128 window.draw(&text);
129 if show_cursor {
130 let mut end = text.find_character_pos(usize::MAX);
131 end.x += 2.0;
132 end.y += 2.0;
133 let mut rs = RectangleShape::new();
134 rs.set_fill_color(Color::TRANSPARENT);
135 rs.set_outline_color(Color::YELLOW);
136 rs.set_outline_thickness(-3.0);
137 rs.set_position(end);
138 rs.set_size((8.0, 24.0));
139 window.draw(&rs);
140 }
141 window.draw(&status_text);
142 window.display();
143 }
144 println!("The final text is {:?}", text.string().to_rust_string());
145 Ok(())
146}
Sourcepub fn local_bounds(&self) -> FloatRect
pub fn local_bounds(&self) -> FloatRect
Get the local bounding rectangle of a text
The returned rectangle is in local coordinates, which means that it ignores the transformations (translation, rotation, scale, …) that are applied to the entity. In other words, this function returns the bounds of the entity in the entity’s coordinate system.
Return the local bounding rectangle of the entity
Sourcepub fn global_bounds(&self) -> FloatRect
pub fn global_bounds(&self) -> FloatRect
Get the global bounding rectangle of a text
The returned rectangle is in global coordinates, which means that it takes in account the transformations (translation, rotation, scale, …) that are applied to the entity. In other words, this function returns the bounds of the text in the global 2D world’s coordinate system.
Return the global bounding rectangle of the entity
Examples found in repository?
5fn main() -> SfResult<()> {
6 example_ensure_right_working_dir();
7
8 let mut window = RenderWindow::new(
9 (800, 600),
10 "Mouse events",
11 Style::CLOSE,
12 &Default::default(),
13 )?;
14 window.set_mouse_cursor_visible(false);
15 window.set_vertical_sync_enabled(true);
16
17 let font = Font::from_file("sansation.ttf")?;
18 let mut circle = CircleShape::new(4., 30);
19 let mut texts: Vec<Text> = Vec::new();
20 let mut mp_text = Text::new("", &font, 14);
21 let mut cursor_visible = false;
22 let mut grabbed = false;
23 macro_rules! push_text {
24 ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25 let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26 text.set_position(($x as f32, $y as f32));
27 texts.push(text);
28 }
29 }
30
31 'mainloop: loop {
32 while let Some(ev) = window.poll_event() {
33 match ev {
34 Event::Closed => break 'mainloop,
35 Event::MouseWheelScrolled { wheel, delta, x, y } => {
36 push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37 }
38 Event::MouseButtonPressed { button, x, y } => {
39 push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40 }
41 Event::MouseButtonReleased { button, x, y } => {
42 push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43 }
44 Event::KeyPressed { code, .. } => {
45 if code == Key::W {
46 window.set_mouse_position(Vector2i::new(400, 300));
47 } else if code == Key::D {
48 let dm = VideoMode::desktop_mode();
49 let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50 mouse::set_desktop_position(center);
51 } else if code == Key::V {
52 cursor_visible = !cursor_visible;
53 window.set_mouse_cursor_visible(cursor_visible);
54 } else if code == Key::G {
55 grabbed = !grabbed;
56 window.set_mouse_cursor_grabbed(grabbed);
57 }
58 }
59 _ => {}
60 }
61 }
62
63 let mp = window.mouse_position();
64 let dmp = mouse::desktop_position();
65 let cur_vis_msg = if cursor_visible {
66 "visible"
67 } else {
68 "invisible"
69 };
70 let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71 mp_text.set_string(&format!(
72 "x: {}, y: {} (Window)\n\
73 x: {}, y: {} (Desktop)\n\
74 [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75 'W' to center mouse on window\n\
76 'D' to center mouse on desktop",
77 mp.x, mp.y, dmp.x, dmp.y
78 ));
79
80 circle.set_position((mp.x as f32, mp.y as f32));
81
82 window.clear(Color::BLACK);
83 // Push texts out of each other's way
84 for i in (0..texts.len()).rev() {
85 for j in (0..i).rev() {
86 if let Some(intersect) = texts[i]
87 .global_bounds()
88 .intersection(&texts[j].global_bounds())
89 {
90 texts[j].move_((0., -intersect.height));
91 }
92 }
93 }
94 texts.retain(|txt| txt.fill_color().a > 0);
95 for txt in &mut texts {
96 let mut color = txt.fill_color();
97 color.a -= 1;
98 txt.set_fill_color(color);
99 window.draw(txt);
100 }
101 if !cursor_visible {
102 window.draw(&circle);
103 }
104 window.draw(&mp_text);
105 window.display();
106 }
107 Ok(())
108}
Sourcepub fn line_spacing(&self) -> f32
pub fn line_spacing(&self) -> f32
Get the size of the line spacing factor.
Sourcepub fn set_line_spacing(&mut self, factor: f32)
pub fn set_line_spacing(&mut self, factor: f32)
Set the line spacing factor.
The default spacing between lines is defined by the font. This method enables you to set a factor for the spacing between lines. By default the line spacing factor is 1.
Sourcepub fn letter_spacing(&self) -> f32
pub fn letter_spacing(&self) -> f32
Get the size of the letter spacing factor.
Sourcepub fn set_letter_spacing(&mut self, factor: f32)
pub fn set_letter_spacing(&mut self, factor: f32)
Set the letter spacing factor.
The default spacing between letters is defined by the font. This factor doesn’t directly apply to the existing spacing between each character, it rather adds a fixed space between them which is calculated from the font metrics and the character size. Note that factors below 1 (including negative numbers) bring characters closer to each other. By default the letter spacing factor is 1.