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 fn as_drawable(&self) -> &dyn Drawable {
121 self
122 }
123}
124
125struct StormBlink {
126 points: Vec<Vertex>,
127 shader: FBox<Shader<'static>>,
128}
129
130impl StormBlink {
131 fn new() -> SfResult<Self> {
132 use rand::{thread_rng, Rng};
133 let mut rng = thread_rng();
134
135 let mut points = Vec::new();
136 for _ in 0..40_000 {
137 let x = rng.gen_range(0.0..800.);
138 let y = rng.gen_range(0.0..600.);
139 let (red, green, blue) = (rng.r#gen(), rng.r#gen(), rng.r#gen());
140 points.push(Vertex::with_pos_color(
141 Vector2f::new(x, y),
142 Color::rgb(red, green, blue),
143 ));
144 }
145
146 let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
147 Ok(Self { points, shader })
148 }
149}
150
151impl Drawable for StormBlink {
152 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
153 &'a self,
154 target: &mut dyn RenderTarget,
155 states: &RenderStates<'texture, 'shader, 'shader_texture>,
156 ) {
157 let mut states = *states;
158 states.shader = Some(&self.shader);
159 target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
160 }
161}
162
163impl Effect for StormBlink {
164 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
165 let radius = 200. + t.cos() * 150.;
166 self.shader
167 .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
168 self.shader
169 .set_uniform_float("storm_inner_radius", radius / 3.)?;
170 self.shader
171 .set_uniform_float("storm_total_radius", radius)?;
172 self.shader
173 .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
174 }
175 fn name(&self) -> &str {
176 "storm + blink"
177 }
178 fn as_drawable(&self) -> &dyn Drawable {
179 self
180 }
181}
182
183struct Edge<'t> {
184 surface: FBox<RenderTexture>,
185 bg_sprite: Sprite<'t>,
186 entities: Vec<Sprite<'t>>,
187 shader: FBox<Shader<'static>>,
188}
189
190impl<'t> Edge<'t> {
191 fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
192 let mut surface = RenderTexture::new(800, 600)?;
193 surface.set_smooth(true);
194 let mut bg_sprite = Sprite::with_texture(bg_texture);
195 bg_sprite.set_position((135., 100.));
196 let mut entities = Vec::new();
197
198 for i in 0..6 {
199 entities.push(Sprite::with_texture_and_rect(
200 entity_texture,
201 IntRect::new(96 * i, 0, 96, 96),
202 ));
203 }
204
205 let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
206 shader.set_uniform_current_texture("texture")?;
207
208 Ok(Self {
209 surface,
210 bg_sprite,
211 entities,
212 shader,
213 })
214 }
215}
216
217impl Drawable for Edge<'_> {
218 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
219 &'a self,
220 target: &mut dyn RenderTarget,
221 states: &RenderStates<'texture, 'shader, 'shader_texture>,
222 ) {
223 let mut states = *states;
224 states.shader = Some(&self.shader);
225 target.draw_with_renderstates(&Sprite::with_texture(self.surface.texture()), &states);
226 }
227}
228
229impl Effect for Edge<'_> {
230 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
231 self.shader
232 .set_uniform_float("edge_threshold", 1. - (x + y) / 2.)?;
233 let entities_len = self.entities.len() as f32;
234
235 for (i, en) in self.entities.iter_mut().enumerate() {
236 let pos = (
237 (0.25 * (t * i as f32 + (entities_len - i as f32))).cos() * 300. + 350.,
238 (0.25 * (t * (entities_len - i as f32) + i as f32)).cos() * 200. + 250.,
239 );
240 en.set_position(pos);
241 }
242 self.surface.clear(Color::WHITE);
243 self.surface.draw(&self.bg_sprite);
244 for en in &self.entities {
245 self.surface.draw(en);
246 }
247 self.surface.display();
248 Ok(())
249 }
250 fn as_drawable(&self) -> &dyn Drawable {
251 self
252 }
253 fn name(&self) -> &str {
254 "edge post-effect"
255 }
256}
257
258fn main() -> SfResult<()> {
259 example_ensure_right_working_dir();
260
261 let mut window = RenderWindow::new(
262 (800, 600),
263 "SFML Shader",
264 Style::TITLEBAR | Style::CLOSE,
265 &Default::default(),
266 )?;
267 window.set_vertical_sync_enabled(true);
268 let font = Font::from_file("sansation.ttf")?;
269 let bg = Texture::from_file("background.jpg")?;
270 let mut bg_texture = Texture::from_file("sfml.png")?;
271 bg_texture.set_smooth(true);
272 let mut entity_texture = Texture::from_file("devices.png")?;
273 entity_texture.set_smooth(true);
274 let effects: [&mut dyn Effect; 4] = [
275 &mut Pixelate::new(&bg)?,
276 &mut WaveBlur::new(&font)?,
277 &mut StormBlink::new()?,
278 &mut Edge::new(&bg_texture, &entity_texture)?,
279 ];
280 let mut current = 0;
281 let text_bg_texture = Texture::from_file("text-background.png")?;
282 let mut text_bg = Sprite::with_texture(&text_bg_texture);
283 text_bg.set_position((0., 520.));
284 text_bg.set_color(Color::rgba(255, 255, 255, 200));
285 let msg = format!("Current effect: {}", effects[current].name());
286 let mut desc = Text::new(&msg, &font, 20);
287 desc.set_position((10., 530.));
288 desc.set_fill_color(Color::rgb(80, 80, 80));
289 let msg = "Press left and right arrows to change the current shader";
290 let mut instructions = Text::new(msg, &font, 20);
291 instructions.set_position((280., 555.));
292 instructions.set_fill_color(Color::rgb(80, 80, 80));
293 let clock = Clock::start()?;
294
295 while window.is_open() {
296 while let Some(event) = window.poll_event() {
297 use crate::Event::*;
298 match event {
299 Closed => window.close(),
300 KeyPressed { code, .. } => match code {
301 Key::Escape => window.close(),
302 Key::Left => {
303 if current == 0 {
304 current = effects.len() - 1;
305 } else {
306 current -= 1;
307 }
308 desc.set_string(&format!("Current effect: {}", effects[current].name()));
309 }
310 Key::Right => {
311 if current == effects.len() - 1 {
312 current = 0;
313 } else {
314 current += 1;
315 }
316 desc.set_string(&format!("Current effect: {}", effects[current].name()));
317 }
318 _ => {}
319 },
320 _ => {}
321 }
322 }
323
324 let x = window.mouse_position().x as f32 / window.size().x as f32;
325 let y = window.mouse_position().y as f32 / window.size().y as f32;
326
327 effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
328
329 window.clear(Color::rgb(255, 128, 0));
330 window.draw(effects[current].as_drawable());
331 window.draw(&text_bg);
332 window.draw(&instructions);
333 window.draw(&desc);
334 window.display();
335 }
336 Ok(())
337}
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}
258fn main() -> SfResult<()> {
259 example_ensure_right_working_dir();
260
261 let mut window = RenderWindow::new(
262 (800, 600),
263 "SFML Shader",
264 Style::TITLEBAR | Style::CLOSE,
265 &Default::default(),
266 )?;
267 window.set_vertical_sync_enabled(true);
268 let font = Font::from_file("sansation.ttf")?;
269 let bg = Texture::from_file("background.jpg")?;
270 let mut bg_texture = Texture::from_file("sfml.png")?;
271 bg_texture.set_smooth(true);
272 let mut entity_texture = Texture::from_file("devices.png")?;
273 entity_texture.set_smooth(true);
274 let effects: [&mut dyn Effect; 4] = [
275 &mut Pixelate::new(&bg)?,
276 &mut WaveBlur::new(&font)?,
277 &mut StormBlink::new()?,
278 &mut Edge::new(&bg_texture, &entity_texture)?,
279 ];
280 let mut current = 0;
281 let text_bg_texture = Texture::from_file("text-background.png")?;
282 let mut text_bg = Sprite::with_texture(&text_bg_texture);
283 text_bg.set_position((0., 520.));
284 text_bg.set_color(Color::rgba(255, 255, 255, 200));
285 let msg = format!("Current effect: {}", effects[current].name());
286 let mut desc = Text::new(&msg, &font, 20);
287 desc.set_position((10., 530.));
288 desc.set_fill_color(Color::rgb(80, 80, 80));
289 let msg = "Press left and right arrows to change the current shader";
290 let mut instructions = Text::new(msg, &font, 20);
291 instructions.set_position((280., 555.));
292 instructions.set_fill_color(Color::rgb(80, 80, 80));
293 let clock = Clock::start()?;
294
295 while window.is_open() {
296 while let Some(event) = window.poll_event() {
297 use crate::Event::*;
298 match event {
299 Closed => window.close(),
300 KeyPressed { code, .. } => match code {
301 Key::Escape => window.close(),
302 Key::Left => {
303 if current == 0 {
304 current = effects.len() - 1;
305 } else {
306 current -= 1;
307 }
308 desc.set_string(&format!("Current effect: {}", effects[current].name()));
309 }
310 Key::Right => {
311 if current == effects.len() - 1 {
312 current = 0;
313 } else {
314 current += 1;
315 }
316 desc.set_string(&format!("Current effect: {}", effects[current].name()));
317 }
318 _ => {}
319 },
320 _ => {}
321 }
322 }
323
324 let x = window.mouse_position().x as f32 / window.size().x as f32;
325 let y = window.mouse_position().y as f32 / window.size().y as f32;
326
327 effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
328
329 window.clear(Color::rgb(255, 128, 0));
330 window.draw(effects[current].as_drawable());
331 window.draw(&text_bg);
332 window.draw(&instructions);
333 window.draw(&desc);
334 window.display();
335 }
336 Ok(())
337}
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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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 = thread_rng();
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.gen_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.gen_range(0.0..20.) * PI / 180.;
234 } else {
235 ball_angle = PI - ball_angle - rng.gen_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.gen_range(0.0..20.) * PI / 180.;
253 } else {
254 ball_angle = PI - ball_angle - rng.gen_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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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 = thread_rng();
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.gen_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.gen_range(0.0..20.) * PI / 180.;
234 } else {
235 ball_angle = PI - ball_angle - rng.gen_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.gen_range(0.0..20.) * PI / 180.;
253 } else {
254 ball_angle = PI - ball_angle - rng.gen_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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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}
258fn main() -> SfResult<()> {
259 example_ensure_right_working_dir();
260
261 let mut window = RenderWindow::new(
262 (800, 600),
263 "SFML Shader",
264 Style::TITLEBAR | Style::CLOSE,
265 &Default::default(),
266 )?;
267 window.set_vertical_sync_enabled(true);
268 let font = Font::from_file("sansation.ttf")?;
269 let bg = Texture::from_file("background.jpg")?;
270 let mut bg_texture = Texture::from_file("sfml.png")?;
271 bg_texture.set_smooth(true);
272 let mut entity_texture = Texture::from_file("devices.png")?;
273 entity_texture.set_smooth(true);
274 let effects: [&mut dyn Effect; 4] = [
275 &mut Pixelate::new(&bg)?,
276 &mut WaveBlur::new(&font)?,
277 &mut StormBlink::new()?,
278 &mut Edge::new(&bg_texture, &entity_texture)?,
279 ];
280 let mut current = 0;
281 let text_bg_texture = Texture::from_file("text-background.png")?;
282 let mut text_bg = Sprite::with_texture(&text_bg_texture);
283 text_bg.set_position((0., 520.));
284 text_bg.set_color(Color::rgba(255, 255, 255, 200));
285 let msg = format!("Current effect: {}", effects[current].name());
286 let mut desc = Text::new(&msg, &font, 20);
287 desc.set_position((10., 530.));
288 desc.set_fill_color(Color::rgb(80, 80, 80));
289 let msg = "Press left and right arrows to change the current shader";
290 let mut instructions = Text::new(msg, &font, 20);
291 instructions.set_position((280., 555.));
292 instructions.set_fill_color(Color::rgb(80, 80, 80));
293 let clock = Clock::start()?;
294
295 while window.is_open() {
296 while let Some(event) = window.poll_event() {
297 use crate::Event::*;
298 match event {
299 Closed => window.close(),
300 KeyPressed { code, .. } => match code {
301 Key::Escape => window.close(),
302 Key::Left => {
303 if current == 0 {
304 current = effects.len() - 1;
305 } else {
306 current -= 1;
307 }
308 desc.set_string(&format!("Current effect: {}", effects[current].name()));
309 }
310 Key::Right => {
311 if current == effects.len() - 1 {
312 current = 0;
313 } else {
314 current += 1;
315 }
316 desc.set_string(&format!("Current effect: {}", effects[current].name()));
317 }
318 _ => {}
319 },
320 _ => {}
321 }
322 }
323
324 let x = window.mouse_position().x as f32 / window.size().x as f32;
325 let y = window.mouse_position().y as f32 / window.size().y as f32;
326
327 effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
328
329 window.clear(Color::rgb(255, 128, 0));
330 window.draw(effects[current].as_drawable());
331 window.draw(&text_bg);
332 window.draw(&instructions);
333 window.draw(&desc);
334 window.display();
335 }
336 Ok(())
337}
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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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 = thread_rng();
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.gen_range(-3.0..3.0), 0.0),
124 image_id: click_counter % N_IMAGES,
125 angle: 0.0,
126 rot_speed: rng.gen_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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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 = thread_rng();
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.gen_range(-3.0..3.0), 0.0),
124 image_id: click_counter % N_IMAGES,
125 angle: 0.0,
126 rot_speed: rng.gen_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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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, fc.g, fc.b, fc.a,
112 oc.r, oc.g, oc.b, oc.a,
113 text.outline_thickness(),
114 text.style(),
115 show_cursor,
116 font.info().family
117 )
118 };
119 status_text.set_string(&status_string);
120
121 window.clear(Color::BLACK);
122 window.draw(&text);
123 if show_cursor {
124 let mut end = text.find_character_pos(usize::MAX);
125 end.x += 2.0;
126 end.y += 2.0;
127 let mut rs = RectangleShape::new();
128 rs.set_fill_color(Color::TRANSPARENT);
129 rs.set_outline_color(Color::YELLOW);
130 rs.set_outline_thickness(-3.0);
131 rs.set_position(end);
132 rs.set_size((8.0, 24.0));
133 window.draw(&rs);
134 }
135 window.draw(&status_text);
136 window.display();
137 }
138 println!("The final text is {:?}", text.string().to_rust_string());
139 Ok(())
140}
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.