From 68d0655be16e9cf7114bc33938d498303ec5d8ac Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sat, 16 Jul 2022 20:24:39 +0200 Subject: [PATCH 01/13] Do the thing. --- crates/bevy_text/src/text.rs | 43 ++++++++------- examples/2d/text2d.rs | 22 +++----- .../external_source_external_thread.rs | 8 ++- examples/ecs/state.rs | 3 +- examples/games/alien_cake_addict.rs | 6 +-- examples/games/game_menu.rs | 53 +++++-------------- examples/ios/src/lib.rs | 5 +- examples/scene/scene.rs | 3 +- .../transforms/global_vs_local_translation.rs | 6 +-- examples/ui/button.rs | 3 +- examples/ui/font_atlas_debug.rs | 3 +- examples/ui/text.rs | 13 +++-- examples/ui/text_debug.rs | 24 ++++----- examples/ui/transparency_ui.rs | 6 +-- examples/ui/ui.rs | 9 ++-- examples/window/scale_factor_override.rs | 3 +- 16 files changed, 75 insertions(+), 135 deletions(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 02f41ca0e992a..b390917b3ab3e 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -14,7 +14,7 @@ pub struct Text { } impl Text { - /// Constructs a [`Text`] with (initially) one section. + /// Constructs a [`Text`] with a single section. /// /// ``` /// # use bevy_asset::{AssetServer, Handle}; @@ -23,45 +23,42 @@ impl Text { /// # /// # let font_handle: Handle = Default::default(); /// # - /// // basic usage - /// let hello_world = Text::with_section( - /// "hello world!".to_string(), + /// // Basic usage. + /// let hello_world = Text::from_section( + /// // Accepts a String or any type that converts into a String, such as &str. + /// "hello world!", /// TextStyle { /// font: font_handle.clone(), /// font_size: 60.0, /// color: Color::WHITE, /// }, - /// TextAlignment { - /// vertical: VerticalAlign::Center, - /// horizontal: HorizontalAlign::Center, - /// }, /// ); /// - /// let hello_bevy = Text::with_section( - /// // accepts a String or any type that converts into a String, such as &str + /// let hello_bevy = Text::from_section( /// "hello bevy!", /// TextStyle { /// font: font_handle, /// font_size: 60.0, /// color: Color::WHITE, /// }, - /// // you can still use Default - /// Default::default(), - /// ); + /// ) // You can still add an alignment. + /// .with_alignment(TextAlignment::CENTER); /// ``` - pub fn with_section>( - value: S, - style: TextStyle, - alignment: TextAlignment, - ) -> Self { + pub fn from_section(value: impl Into, style: TextStyle) -> Self { Self { sections: vec![TextSection { value: value.into(), style, }], - alignment, + alignment: Default::default(), } } + + /// Returns this [`Text`] with a new [`TextAlignment`]. + pub fn with_alignment(mut self, alignment: TextAlignment) -> Self { + self.alignment = alignment; + self + } } #[derive(Debug, Default, Clone, FromReflect, Reflect)] @@ -76,6 +73,14 @@ pub struct TextAlignment { pub horizontal: HorizontalAlign, } +impl TextAlignment { + /// A [`TextAlignment`] set to center on both axes. + pub const CENTER: Self = TextAlignment { + vertical: VerticalAlign::Center, + horizontal: HorizontalAlign::Center, + }; +} + impl Default for TextAlignment { fn default() -> Self { TextAlignment { diff --git a/examples/2d/text2d.rs b/examples/2d/text2d.rs index 5da6429627802..b2edf872d26a8 100644 --- a/examples/2d/text2d.rs +++ b/examples/2d/text2d.rs @@ -31,30 +31,28 @@ fn setup(mut commands: Commands, asset_server: Res) { font_size: 60.0, color: Color::WHITE, }; - let text_alignment = TextAlignment { - vertical: VerticalAlign::Center, - horizontal: HorizontalAlign::Center, - }; + let text_alignment = TextAlignment::CENTER; // 2d camera commands.spawn_bundle(Camera2dBundle::default()); // Demonstrate changing translation commands .spawn_bundle(Text2dBundle { - text: Text::with_section("translation", text_style.clone(), text_alignment), + text: Text::from_section("translation", text_style.clone()) + .with_alignment(text_alignment), ..default() }) .insert(AnimateTranslation); // Demonstrate changing rotation commands .spawn_bundle(Text2dBundle { - text: Text::with_section("rotation", text_style.clone(), text_alignment), + text: Text::from_section("rotation", text_style.clone()).with_alignment(text_alignment), ..default() }) .insert(AnimateRotation); // Demonstrate changing scale commands .spawn_bundle(Text2dBundle { - text: Text::with_section("scale", text_style.clone(), text_alignment), + text: Text::from_section("scale", text_style.clone()).with_alignment(text_alignment), ..default() }) .insert(AnimateScale); @@ -70,16 +68,8 @@ fn setup(mut commands: Commands, asset_server: Res) { transform: Transform::from_translation(box_position.extend(0.0)), ..default() }); - let text_alignment_topleft = TextAlignment { - vertical: VerticalAlign::Top, - horizontal: HorizontalAlign::Left, - }; commands.spawn_bundle(Text2dBundle { - text: Text::with_section( - "this text wraps in the box", - text_style, - text_alignment_topleft, - ), + text: Text::from_section("this text wraps in the box", text_style), text_2d_bounds: Text2dBounds { // Wrap text in the rectangle size: box_size, diff --git a/examples/async_tasks/external_source_external_thread.rs b/examples/async_tasks/external_source_external_thread.rs index 76a78f519f0e3..b4c079a9b49d2 100644 --- a/examples/async_tasks/external_source_external_thread.rs +++ b/examples/async_tasks/external_source_external_thread.rs @@ -62,13 +62,11 @@ fn spawn_text( font_size: 20.0, color: Color::WHITE, }; - let text_alignment = TextAlignment { - vertical: VerticalAlign::Center, - horizontal: HorizontalAlign::Center, - }; + for (per_frame, event) in reader.iter().enumerate() { commands.spawn_bundle(Text2dBundle { - text: Text::with_section(format!("{}", event.0), text_style.clone(), text_alignment), + text: Text::from_section(format!("{}", event.0), text_style.clone()) + .with_alignment(TextAlignment::CENTER), transform: Transform::from_xyz( per_frame as f32 * 100.0 + rand::thread_rng().gen_range(-40.0..40.0), 300.0, diff --git a/examples/ecs/state.rs b/examples/ecs/state.rs index 03e4e7e0ad8c8..6ff0facb97445 100644 --- a/examples/ecs/state.rs +++ b/examples/ecs/state.rs @@ -56,14 +56,13 @@ fn setup_menu(mut commands: Commands, asset_server: Res) { }) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "Play", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.9, 0.9, 0.9), }, - Default::default(), ), ..default() }); diff --git a/examples/games/alien_cake_addict.rs b/examples/games/alien_cake_addict.rs index 3d674382ea04b..ea5bc78d06e5b 100644 --- a/examples/games/alien_cake_addict.rs +++ b/examples/games/alien_cake_addict.rs @@ -151,14 +151,13 @@ fn setup(mut commands: Commands, asset_server: Res, mut game: ResMu // scoreboard commands.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "Score:", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.5, 0.5, 1.0), }, - Default::default(), ), style: Style { position_type: PositionType::Absolute, @@ -384,14 +383,13 @@ fn display_score(mut commands: Commands, asset_server: Res, game: R }) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( format!("Cake eaten: {}", game.cake_eaten), TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 80.0, color: Color::rgb(0.5, 0.5, 1.0), }, - Default::default(), ), ..default() }); diff --git a/examples/games/game_menu.rs b/examples/games/game_menu.rs index d07f9cf48459c..9e7570583df14 100644 --- a/examples/games/game_menu.rs +++ b/examples/games/game_menu.rs @@ -170,14 +170,13 @@ mod game { margin: UiRect::all(Val::Px(50.0)), ..default() }, - text: Text::with_section( + text: Text::from_section( "Will be back to the menu shortly...", TextStyle { font: font.clone(), font_size: 80.0, color: TEXT_COLOR, }, - Default::default(), ), ..default() }); @@ -437,14 +436,13 @@ mod menu { margin: UiRect::all(Val::Px(50.0)), ..default() }, - text: Text::with_section( + text: Text::from_section( "Bevy Game Menu UI", TextStyle { font: font.clone(), font_size: 80.0, color: TEXT_COLOR, }, - Default::default(), ), ..default() }); @@ -468,11 +466,7 @@ mod menu { ..default() }); parent.spawn_bundle(TextBundle { - text: Text::with_section( - "New Game", - button_text_style.clone(), - Default::default(), - ), + text: Text::from_section("New Game", button_text_style.clone()), ..default() }); }); @@ -491,11 +485,7 @@ mod menu { ..default() }); parent.spawn_bundle(TextBundle { - text: Text::with_section( - "Settings", - button_text_style.clone(), - Default::default(), - ), + text: Text::from_section("Settings", button_text_style.clone()), ..default() }); }); @@ -514,7 +504,7 @@ mod menu { ..default() }); parent.spawn_bundle(TextBundle { - text: Text::with_section("Quit", button_text_style, Default::default()), + text: Text::from_section("Quit", button_text_style), ..default() }); }); @@ -558,11 +548,7 @@ mod menu { .insert(MenuButtonAction::SettingsDisplay) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( - "Display", - button_text_style.clone(), - Default::default(), - ), + text: Text::from_section("Display", button_text_style.clone()), ..default() }); }); @@ -575,11 +561,7 @@ mod menu { .insert(MenuButtonAction::SettingsSound) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( - "Sound", - button_text_style.clone(), - Default::default(), - ), + text: Text::from_section("Sound", button_text_style.clone()), ..default() }); }); @@ -593,7 +575,7 @@ mod menu { .insert(MenuButtonAction::BackToMainMenu) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section("Back", button_text_style, Default::default()), + text: Text::from_section("Back", button_text_style), ..default() }); }); @@ -645,11 +627,7 @@ mod menu { .with_children(|parent| { // Display a label for the current setting parent.spawn_bundle(TextBundle { - text: Text::with_section( - "Display Quality", - button_text_style.clone(), - Default::default(), - ), + text: Text::from_section("Display Quality", button_text_style.clone()), ..default() }); // Display a button for each possible value @@ -668,10 +646,9 @@ mod menu { }); entity.insert(quality_setting).with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( format!("{:?}", quality_setting), button_text_style.clone(), - Default::default(), ), ..default() }); @@ -691,7 +668,7 @@ mod menu { .insert(MenuButtonAction::BackToSettings) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section("Back", button_text_style, Default::default()), + text: Text::from_section("Back", button_text_style), ..default() }); }); @@ -740,11 +717,7 @@ mod menu { }) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( - "Volume", - button_text_style.clone(), - Default::default(), - ), + text: Text::from_section("Volume", button_text_style.clone()), ..default() }); for volume_setting in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] { @@ -771,7 +744,7 @@ mod menu { .insert(MenuButtonAction::BackToSettings) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section("Back", button_text_style, Default::default()), + text: Text::from_section("Back", button_text_style), ..default() }); }); diff --git a/examples/ios/src/lib.rs b/examples/ios/src/lib.rs index ed03ad1bbcc57..e58f1e0e41c56 100644 --- a/examples/ios/src/lib.rs +++ b/examples/ios/src/lib.rs @@ -118,10 +118,7 @@ fn setup_scene( color: Color::BLACK, }, }], - alignment: TextAlignment { - vertical: VerticalAlign::Center, - horizontal: HorizontalAlign::Center, - }, + alignment: TextAlignment::CENTER, }, ..default() }); diff --git a/examples/scene/scene.rs b/examples/scene/scene.rs index 4b499a1b819ce..5c4947b0f53ec 100644 --- a/examples/scene/scene.rs +++ b/examples/scene/scene.rs @@ -110,14 +110,13 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { align_self: AlignSelf::FlexEnd, ..default() }, - text: Text::with_section( + text: Text::from_section( "Nothing to see in this window! Check the console output!", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 50.0, color: Color::WHITE, }, - Default::default(), ), ..default() }); diff --git a/examples/transforms/global_vs_local_translation.rs b/examples/transforms/global_vs_local_translation.rs index 815cdab22f465..376136a458b60 100644 --- a/examples/transforms/global_vs_local_translation.rs +++ b/examples/transforms/global_vs_local_translation.rs @@ -102,7 +102,7 @@ fn setup( // Add text to explain inputs and what is happening. commands.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "Press the arrow keys to move the cubes. Toggle movement for yellow (1), red (2) and green (3) cubes via number keys. Notice how the green cube will translate further in respect to the yellow in contrast to the red cube. @@ -113,10 +113,6 @@ The red cube is moved through its GlobalTransform and thus is unaffected by the font_size: 22.0, color: Color::WHITE, }, - TextAlignment { - horizontal: HorizontalAlign::Left, - ..default() - }, ), ..default() }); diff --git a/examples/ui/button.rs b/examples/ui/button.rs index 4a8ea34f11c8b..76b46aa72631e 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -63,14 +63,13 @@ fn setup(mut commands: Commands, asset_server: Res) { }) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "Button", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.9, 0.9, 0.9), }, - Default::default(), ), ..default() }); diff --git a/examples/ui/font_atlas_debug.rs b/examples/ui/font_atlas_debug.rs index 71e9808cdeb68..9684e08a09b60 100644 --- a/examples/ui/font_atlas_debug.rs +++ b/examples/ui/font_atlas_debug.rs @@ -81,14 +81,13 @@ fn setup(mut commands: Commands, asset_server: Res, mut state: ResM state.handle = font_handle.clone(); commands.spawn_bundle(Camera2dBundle::default()); commands.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "a", TextStyle { font: font_handle, font_size: 60.0, color: Color::YELLOW, }, - Default::default(), ), ..default() }); diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 8c4d2c6cbb7f0..7baa15c3561e9 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -43,7 +43,7 @@ fn setup(mut commands: Commands, asset_server: Res) { ..default() }, // Use the `Text::with_section` constructor - text: Text::with_section( + text: Text::from_section( // Accepts a `String` or any type that converts into a `String`, such as `&str` "hello\nbevy!", TextStyle { @@ -51,12 +51,11 @@ fn setup(mut commands: Commands, asset_server: Res) { font_size: 100.0, color: Color::WHITE, }, - // Note: You can use `Default::default()` in place of the `TextAlignment` - TextAlignment { - horizontal: HorizontalAlign::Center, - ..default() - }, - ), + ) + .with_alignment(TextAlignment { + horizontal: HorizontalAlign::Center, + ..default() + }), ..default() }) .insert(ColorText); diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 685eb4c639e78..81abfba588bbe 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -36,14 +36,13 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { }, ..default() }, - text: Text::with_section( + text: Text::from_section( "This is\ntext with\nline breaks\nin the top left", TextStyle { font: font.clone(), font_size: 50.0, color: Color::WHITE, }, - Default::default(), ), ..default() }); @@ -62,18 +61,14 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { }, ..default() }, - text: Text::with_section( - "This text is very long, has a limited width, is centred, is positioned in the top right and is also coloured pink.", - TextStyle { - font: font.clone(), - font_size: 50.0, - color: Color::rgb(0.8, 0.2, 0.7), - }, - TextAlignment { - horizontal: HorizontalAlign::Center, - vertical: VerticalAlign::Center, + text: Text::from_section( + "This text is very long, has a limited width, is centred, is positioned in the top right and is also coloured pink.", + TextStyle { + font: font.clone(), + font_size: 50.0, + color: Color::rgb(0.8, 0.2, 0.7), }, - ), + ).with_alignment(TextAlignment::CENTER), ..default() }); commands @@ -159,14 +154,13 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { }, ..default() }, - text: Text::with_section( + text: Text::from_section( "This\ntext has\nline breaks and also a set width in the bottom left".to_string(), TextStyle { font, font_size: 50.0, color: Color::WHITE, }, - Default::default(), ), ..default() }); diff --git a/examples/ui/transparency_ui.rs b/examples/ui/transparency_ui.rs index db96a110fe0f9..7e73db08c9c02 100644 --- a/examples/ui/transparency_ui.rs +++ b/examples/ui/transparency_ui.rs @@ -30,7 +30,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "Button 1", TextStyle { font: font_handle.clone(), @@ -38,7 +38,6 @@ fn setup(mut commands: Commands, asset_server: Res) { // Alpha channel of the color controls transparency. color: Color::rgba(1.0, 1.0, 1.0, 0.2), }, - Default::default(), ), ..default() }); @@ -60,7 +59,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }) .with_children(|parent| { parent.spawn_bundle(TextBundle { - text: Text::with_section( + text: Text::from_section( "Button 2", TextStyle { font: font_handle.clone(), @@ -68,7 +67,6 @@ fn setup(mut commands: Commands, asset_server: Res) { // Alpha channel of the color controls transparency. color: Color::rgba(1.0, 1.0, 1.0, 0.2), }, - Default::default(), ), ..default() }); diff --git a/examples/ui/ui.rs b/examples/ui/ui.rs index 2903d43dc7c3b..2a27cc4f8456d 100644 --- a/examples/ui/ui.rs +++ b/examples/ui/ui.rs @@ -62,14 +62,13 @@ fn setup(mut commands: Commands, asset_server: Res) { margin: UiRect::all(Val::Px(5.0)), ..default() }, - text: Text::with_section( + text: Text::from_section( "Text Example", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 30.0, color: Color::WHITE, }, - Default::default(), ), ..default() }); @@ -99,14 +98,13 @@ fn setup(mut commands: Commands, asset_server: Res) { }, ..default() }, - text: Text::with_section( + text: Text::from_section( "Scrolling list", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 25., color: Color::WHITE, }, - Default::default(), ), ..default() }); @@ -151,7 +149,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }, ..default() }, - text: Text::with_section( + text: Text::from_section( format!("Item {}", i), TextStyle { font: asset_server @@ -159,7 +157,6 @@ fn setup(mut commands: Commands, asset_server: Res) { font_size: 20., color: Color::WHITE, }, - Default::default(), ), ..default() }); diff --git a/examples/window/scale_factor_override.rs b/examples/window/scale_factor_override.rs index f4f179697f76c..382c233c90533 100644 --- a/examples/window/scale_factor_override.rs +++ b/examples/window/scale_factor_override.rs @@ -49,14 +49,13 @@ fn setup(mut commands: Commands, asset_server: Res) { align_self: AlignSelf::FlexEnd, ..default() }, - text: Text::with_section( + text: Text::from_section( "Example text", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 30.0, color: Color::WHITE, }, - Default::default(), ), ..default() }); From 5932baa68152540f4c00137d96beefd4eef4e559 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sat, 16 Jul 2022 20:55:41 +0200 Subject: [PATCH 02/13] Add `Text::from_sections`. --- crates/bevy_text/src/text.rs | 25 +++++++++ examples/games/breakout.rs | 34 +++++------- examples/games/contributors.rs | 34 +++++------- examples/games/game_menu.rs | 49 ++++++++--------- examples/stress_tests/bevymark.rs | 61 +++++++++------------ examples/ui/text.rs | 35 +++++------- examples/ui/text_debug.rs | 89 ++++++++++++++----------------- examples/window/low_power.rs | 61 +++++++++------------ 8 files changed, 182 insertions(+), 206 deletions(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index b390917b3ab3e..9adce44a4dfe1 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -54,6 +54,13 @@ impl Text { } } + pub fn from_sections(sections: impl IntoIterator) -> Self { + Self { + sections: sections.into_iter().collect(), + alignment: Default::default(), + } + } + /// Returns this [`Text`] with a new [`TextAlignment`]. pub fn with_alignment(mut self, alignment: TextAlignment) -> Self { self.alignment = alignment; @@ -67,6 +74,24 @@ pub struct TextSection { pub style: TextStyle, } +impl TextSection { + /// Create a [`TextSection`] from a string of text. + pub fn from_text(text: impl Into) -> Self { + Self { + value: text.into(), + style: Default::default(), + } + } + + /// Create an empty [`TextSection`] from a style. Useful when the text will be set dynamically. + pub fn from_style(style: TextStyle) -> Self{ + Self { + value: Default::default(), + style, + } + } +} + #[derive(Debug, Clone, Copy, Reflect)] pub struct TextAlignment { pub vertical: VerticalAlign, diff --git a/examples/games/breakout.rs b/examples/games/breakout.rs index c43f74421c458..5c607b8e4bba3 100644 --- a/examples/games/breakout.rs +++ b/examples/games/breakout.rs @@ -217,27 +217,21 @@ fn setup(mut commands: Commands, asset_server: Res) { // Scoreboard commands.spawn_bundle(TextBundle { - text: Text { - sections: vec![ - TextSection { - value: "Score: ".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: SCOREBOARD_FONT_SIZE, - color: TEXT_COLOR, - }, - }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraMono-Medium.ttf"), - font_size: SCOREBOARD_FONT_SIZE, - color: SCORE_COLOR, - }, + text: Text::from_sections([ + TextSection { + value: "Score: ".to_string(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: SCOREBOARD_FONT_SIZE, + color: TEXT_COLOR, }, - ], - ..default() - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraMono-Medium.ttf"), + font_size: SCOREBOARD_FONT_SIZE, + color: SCORE_COLOR, + }), + ]), style: Style { position_type: PositionType::Absolute, position: UiRect { diff --git a/examples/games/contributors.rs b/examples/games/contributors.rs index 0bad27798aea0..32fcbde5b3f6b 100644 --- a/examples/games/contributors.rs +++ b/examples/games/contributors.rs @@ -142,27 +142,21 @@ fn setup(mut commands: Commands, asset_server: Res) { align_self: AlignSelf::FlexEnd, ..default() }, - text: Text { - sections: vec![ - TextSection { - value: "Contributor showcase".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 60.0, - color: Color::WHITE, - }, + text: Text::from_sections([ + TextSection { + value: "Contributor showcase".to_string(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 60.0, + color: Color::WHITE, }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 60.0, - color: Color::WHITE, - }, - }, - ], - ..default() - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 60.0, + color: Color::WHITE, + }), + ]), ..default() }); } diff --git a/examples/games/game_menu.rs b/examples/games/game_menu.rs index 9e7570583df14..92e11f660669f 100644 --- a/examples/games/game_menu.rs +++ b/examples/games/game_menu.rs @@ -185,35 +185,32 @@ mod game { margin: UiRect::all(Val::Px(50.0)), ..default() }, - text: Text { - sections: vec![ - TextSection { - value: format!("quality: {:?}", *display_quality), - style: TextStyle { - font: font.clone(), - font_size: 60.0, - color: Color::BLUE, - }, + text: Text::from_sections([ + TextSection { + value: format!("quality: {:?}", *display_quality), + style: TextStyle { + font: font.clone(), + font_size: 60.0, + color: Color::BLUE, }, - TextSection { - value: " - ".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 60.0, - color: TEXT_COLOR, - }, + }, + TextSection { + value: " - ".to_string(), + style: TextStyle { + font: font.clone(), + font_size: 60.0, + color: TEXT_COLOR, }, - TextSection { - value: format!("volume: {:?}", *volume), - style: TextStyle { - font: font.clone(), - font_size: 60.0, - color: Color::GREEN, - }, + }, + TextSection { + value: format!("volume: {:?}", *volume), + style: TextStyle { + font: font.clone(), + font_size: 60.0, + color: Color::GREEN, }, - ], - ..default() - }, + }, + ]), ..default() }); }); diff --git a/examples/stress_tests/bevymark.rs b/examples/stress_tests/bevymark.rs index bf3955428b1d9..a9f4631974f9f 100644 --- a/examples/stress_tests/bevymark.rs +++ b/examples/stress_tests/bevymark.rs @@ -97,43 +97,34 @@ fn setup(mut commands: Commands, asset_server: Res) { commands.spawn_bundle(Camera2dBundle::default()); commands .spawn_bundle(TextBundle { - text: Text { - sections: vec![ - TextSection { - value: "Bird Count: ".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 40.0, - color: Color::rgb(0.0, 1.0, 0.0), - }, + text: Text::from_sections([ + TextSection { + value: "Bird Count: ".to_string(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 40.0, + color: Color::rgb(0.0, 1.0, 0.0), }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 40.0, - color: Color::rgb(0.0, 1.0, 1.0), - }, - }, - TextSection { - value: "\nAverage FPS: ".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 40.0, - color: Color::rgb(0.0, 1.0, 0.0), - }, - }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 40.0, - color: Color::rgb(0.0, 1.0, 1.0), - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 40.0, + color: Color::rgb(0.0, 1.0, 1.0), + }), + TextSection { + value: "\nAverage FPS: ".to_string(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 40.0, + color: Color::rgb(0.0, 1.0, 0.0), }, - ], - ..default() - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 40.0, + color: Color::rgb(0.0, 1.0, 1.0), + }), + ]), style: Style { position_type: PositionType::Absolute, position: UiRect { diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 7baa15c3561e9..35dbdec83d6fa 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -67,28 +67,21 @@ fn setup(mut commands: Commands, asset_server: Res) { ..default() }, // Use `Text` directly - text: Text { - // Construct a `Vec` of `TextSection`s - sections: vec![ - TextSection { - value: "FPS: ".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 60.0, - color: Color::WHITE, - }, + text: Text::from_sections([ + TextSection { + value: "FPS: ".to_string(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 60.0, + color: Color::WHITE, }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraMono-Medium.ttf"), - font_size: 60.0, - color: Color::GOLD, - }, - }, - ], - ..default() - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraMono-Medium.ttf"), + font_size: 60.0, + color: Color::GOLD, + }), + ]), ..default() }) .insert(FpsText); diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 81abfba588bbe..63ecb7e5b4f1d 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -83,59 +83,50 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { }, ..default() }, - text: Text { - sections: vec![ - TextSection { - value: "This text changes in the bottom right".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 30.0, - color: Color::WHITE, - }, + text: Text::from_sections([ + TextSection { + value: "This text changes in the bottom right".to_string(), + style: TextStyle { + font: font.clone(), + font_size: 30.0, + color: Color::WHITE, }, - TextSection { - value: "\nThis text changes in the bottom right - ".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 30.0, - color: Color::RED, - }, - }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 30.0, - color: Color::ORANGE_RED, - }, - }, - TextSection { - value: " fps, ".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 30.0, - color: Color::YELLOW, - }, + }, + TextSection { + value: "\nThis text changes in the bottom right - ".to_string(), + style: TextStyle { + font: font.clone(), + font_size: 30.0, + color: Color::RED, }, - TextSection { - value: "".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 30.0, - color: Color::GREEN, - }, + }, + TextSection::from_style(TextStyle { + font: font.clone(), + font_size: 30.0, + color: Color::ORANGE_RED, + }), + TextSection { + value: " fps, ".to_string(), + style: TextStyle { + font: font.clone(), + font_size: 30.0, + color: Color::YELLOW, }, - TextSection { - value: " ms/frame".to_string(), - style: TextStyle { - font: font.clone(), - font_size: 30.0, - color: Color::BLUE, - }, + }, + TextSection::from_style(TextStyle { + font: font.clone(), + font_size: 30.0, + color: Color::GREEN, + }), + TextSection { + value: " ms/frame".to_string(), + style: TextStyle { + font: font.clone(), + font_size: 30.0, + color: Color::BLUE, }, - ], - alignment: Default::default(), - }, + }, + ]), ..default() }) .insert(TextChanges); diff --git a/examples/window/low_power.rs b/examples/window/low_power.rs index 5667e310b39df..f2171fbbde419 100644 --- a/examples/window/low_power.rs +++ b/examples/window/low_power.rs @@ -176,43 +176,34 @@ pub(crate) mod test_setup { }, ..default() }, - text: Text { - sections: vec![ - TextSection { - value: "Press spacebar to cycle modes\n".into(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 50.0, - color: Color::WHITE, - }, + text: Text::from_sections([ + TextSection { + value: "Press spacebar to cycle modes\n".into(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 50.0, + color: Color::WHITE, }, - TextSection { - value: "".into(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 50.0, - color: Color::GREEN, - }, - }, - TextSection { - value: "\nFrame: ".into(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 50.0, - color: Color::YELLOW, - }, - }, - TextSection { - value: "".into(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 50.0, - color: Color::YELLOW, - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 50.0, + color: Color::GREEN, + }), + TextSection { + value: "\nFrame: ".into(), + style: TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 50.0, + color: Color::YELLOW, }, - ], - alignment: TextAlignment::default(), - }, + }, + TextSection::from_style(TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 50.0, + color: Color::YELLOW, + }), + ]), ..default() }) .insert(ModeText); From aec9e54961577aabd522052a8ab1557fde22d686 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sat, 16 Jul 2022 21:26:11 +0200 Subject: [PATCH 03/13] Add `TextSection::new`. --- crates/bevy_text/src/text.rs | 8 ++++---- examples/games/breakout.rs | 10 ++++----- examples/games/contributors.rs | 8 ++++---- examples/games/game_menu.rs | 24 +++++++++++----------- examples/ios/src/lib.rs | 20 ++++++++---------- examples/stress_tests/bevymark.rs | 18 ++++++++-------- examples/ui/text.rs | 8 ++++---- examples/ui/text_debug.rs | 34 +++++++++++++++---------------- examples/window/low_power.rs | 21 ++++++++++--------- 9 files changed, 75 insertions(+), 76 deletions(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 9adce44a4dfe1..2806c46e5a3cc 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -75,16 +75,16 @@ pub struct TextSection { } impl TextSection { - /// Create a [`TextSection`] from a string of text. - pub fn from_text(text: impl Into) -> Self { + /// Create a new [`TextSection`]. + pub fn new(text: impl Into, style: TextStyle) -> Self { Self { value: text.into(), - style: Default::default(), + style, } } /// Create an empty [`TextSection`] from a style. Useful when the text will be set dynamically. - pub fn from_style(style: TextStyle) -> Self{ + pub fn from_style(style: TextStyle) -> Self { Self { value: Default::default(), style, diff --git a/examples/games/breakout.rs b/examples/games/breakout.rs index 5c607b8e4bba3..07969fe3920ec 100644 --- a/examples/games/breakout.rs +++ b/examples/games/breakout.rs @@ -218,14 +218,14 @@ fn setup(mut commands: Commands, asset_server: Res) { // Scoreboard commands.spawn_bundle(TextBundle { text: Text::from_sections([ - TextSection { - value: "Score: ".to_string(), - style: TextStyle { + TextSection::new( + "Score: ", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: SCOREBOARD_FONT_SIZE, color: TEXT_COLOR, }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), font_size: SCOREBOARD_FONT_SIZE, @@ -345,7 +345,7 @@ fn apply_velocity(mut query: Query<(&mut Transform, &Velocity)>) { fn update_scoreboard(scoreboard: Res, mut query: Query<&mut Text>) { let mut text = query.single_mut(); - text.sections[1].value = format!("{}", scoreboard.score); + text.sections[1].value = scoreboard.score.to_string(); } fn check_for_collisions( diff --git a/examples/games/contributors.rs b/examples/games/contributors.rs index 32fcbde5b3f6b..a9ef01b1b6290 100644 --- a/examples/games/contributors.rs +++ b/examples/games/contributors.rs @@ -143,14 +143,14 @@ fn setup(mut commands: Commands, asset_server: Res) { ..default() }, text: Text::from_sections([ - TextSection { - value: "Contributor showcase".to_string(), - style: TextStyle { + TextSection::new( + "Contributor showcase", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 60.0, color: Color::WHITE, }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 60.0, diff --git a/examples/games/game_menu.rs b/examples/games/game_menu.rs index 92e11f660669f..6e9726ef0caff 100644 --- a/examples/games/game_menu.rs +++ b/examples/games/game_menu.rs @@ -186,30 +186,30 @@ mod game { ..default() }, text: Text::from_sections([ - TextSection { - value: format!("quality: {:?}", *display_quality), - style: TextStyle { + TextSection::new( + format!("quality: {:?}", *display_quality), + TextStyle { font: font.clone(), font_size: 60.0, color: Color::BLUE, }, - }, - TextSection { - value: " - ".to_string(), - style: TextStyle { + ), + TextSection::new( + " - ", + TextStyle { font: font.clone(), font_size: 60.0, color: TEXT_COLOR, }, - }, - TextSection { - value: format!("volume: {:?}", *volume), - style: TextStyle { + ), + TextSection::new( + format!("volume: {:?}", *volume), + TextStyle { font: font.clone(), font_size: 60.0, color: Color::GREEN, }, - }, + ), ]), ..default() }); diff --git a/examples/ios/src/lib.rs b/examples/ios/src/lib.rs index e58f1e0e41c56..796b5d22407e3 100644 --- a/examples/ios/src/lib.rs +++ b/examples/ios/src/lib.rs @@ -109,17 +109,15 @@ fn setup_scene( }) .with_children(|b| { b.spawn_bundle(TextBundle { - text: Text { - sections: vec![TextSection { - value: "Test Button".to_string(), - style: TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 30.0, - color: Color::BLACK, - }, - }], - alignment: TextAlignment::CENTER, - }, + text: Text::from_section( + "Test Button", + TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 30.0, + color: Color::BLACK, + }, + ) + .with_alignment(TextAlignment::CENTER), ..default() }); }); diff --git a/examples/stress_tests/bevymark.rs b/examples/stress_tests/bevymark.rs index a9f4631974f9f..9d4b54655499c 100644 --- a/examples/stress_tests/bevymark.rs +++ b/examples/stress_tests/bevymark.rs @@ -98,27 +98,27 @@ fn setup(mut commands: Commands, asset_server: Res) { commands .spawn_bundle(TextBundle { text: Text::from_sections([ - TextSection { - value: "Bird Count: ".to_string(), - style: TextStyle { + TextSection::new( + "Bird Count: ", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.0, 1.0, 0.0), }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.0, 1.0, 1.0), }), - TextSection { - value: "\nAverage FPS: ".to_string(), - style: TextStyle { + TextSection::new( + "\nAverage FPS: ", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.0, 1.0, 0.0), }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, @@ -256,7 +256,7 @@ fn counter_system( let mut text = query.single_mut(); if counter.is_changed() { - text.sections[1].value = format!("{}", counter.count); + text.sections[1].value = counter.count.to_string(); } if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) { diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 35dbdec83d6fa..63016a3020564 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -68,14 +68,14 @@ fn setup(mut commands: Commands, asset_server: Res) { }, // Use `Text` directly text: Text::from_sections([ - TextSection { - value: "FPS: ".to_string(), - style: TextStyle { + TextSection::new( + "FPS: ", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 60.0, color: Color::WHITE, }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), font_size: 60.0, diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 63ecb7e5b4f1d..92e5977f2bc54 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -84,48 +84,48 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { ..default() }, text: Text::from_sections([ - TextSection { - value: "This text changes in the bottom right".to_string(), - style: TextStyle { + TextSection::new( + "This text changes in the bottom right", + TextStyle { font: font.clone(), font_size: 30.0, color: Color::WHITE, }, - }, - TextSection { - value: "\nThis text changes in the bottom right - ".to_string(), - style: TextStyle { + ), + TextSection::new( + "\nThis text changes in the bottom right - ", + TextStyle { font: font.clone(), font_size: 30.0, color: Color::RED, }, - }, + ), TextSection::from_style(TextStyle { font: font.clone(), font_size: 30.0, color: Color::ORANGE_RED, }), - TextSection { - value: " fps, ".to_string(), - style: TextStyle { + TextSection::new( + " fps, ", + TextStyle { font: font.clone(), font_size: 30.0, color: Color::YELLOW, }, - }, + ), TextSection::from_style(TextStyle { font: font.clone(), font_size: 30.0, color: Color::GREEN, }), - TextSection { - value: " ms/frame".to_string(), - style: TextStyle { + TextSection::new( + " ms/frame", + TextStyle { font: font.clone(), font_size: 30.0, color: Color::BLUE, }, - }, + ), ]), ..default() }) @@ -146,7 +146,7 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { ..default() }, text: Text::from_section( - "This\ntext has\nline breaks and also a set width in the bottom left".to_string(), + "This\ntext has\nline breaks and also a set width in the bottom left", TextStyle { font, font_size: 50.0, diff --git a/examples/window/low_power.rs b/examples/window/low_power.rs index f2171fbbde419..295aab9199226 100644 --- a/examples/window/low_power.rs +++ b/examples/window/low_power.rs @@ -131,8 +131,9 @@ pub(crate) mod test_setup { ExampleMode::Application => "desktop_app(), reactive", ExampleMode::ApplicationWithRedraw => "desktop_app(), reactive, RequestRedraw sent", }; - query.get_single_mut().unwrap().sections[1].value = mode.to_string(); - query.get_single_mut().unwrap().sections[3].value = format!("{}", *frame); + let mut text = query.single_mut(); + text.sections[1].value = mode.to_string(); + text.sections[3].value = frame.to_string(); } /// Set up a scene with a cube and some text @@ -177,27 +178,27 @@ pub(crate) mod test_setup { ..default() }, text: Text::from_sections([ - TextSection { - value: "Press spacebar to cycle modes\n".into(), - style: TextStyle { + TextSection::new( + "Press spacebar to cycle modes\n", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 50.0, color: Color::WHITE, }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 50.0, color: Color::GREEN, }), - TextSection { - value: "\nFrame: ".into(), - style: TextStyle { + TextSection::new( + "\nFrame: ", + TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 50.0, color: Color::YELLOW, }, - }, + ), TextSection::from_style(TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 50.0, From 47ded0a11607f72c7823ac89de64293fb5ad6f2a Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sat, 16 Jul 2022 22:41:55 +0200 Subject: [PATCH 04/13] Add doc. --- crates/bevy_text/src/text.rs | 48 +++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 2806c46e5a3cc..adf0c12dedf80 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -17,7 +17,7 @@ impl Text { /// Constructs a [`Text`] with a single section. /// /// ``` - /// # use bevy_asset::{AssetServer, Handle}; + /// # use bevy_asset::Handle; /// # use bevy_render::color::Color; /// # use bevy_text::{Font, Text, TextAlignment, TextStyle, HorizontalAlign, VerticalAlign}; /// # @@ -54,6 +54,34 @@ impl Text { } } + /// Constructs a [`Text`] from a list of sections. + /// + /// ``` + /// # use bevy_asset::Handle; + /// # use bevy_render::color::Color; + /// # use bevy_text::{Font, Text, TextStyle, TextSection}; + /// # + /// # let font_handle: Handle = Default::default(); + /// # + /// let hello_world = Text::from_sections([ + /// TextSection::new( + /// "Hello, ", + /// TextStyle { + /// font: font_handle.clone(), + /// font_size: 60.0, + /// color: Color::BLUE, + /// }, + /// ), + /// TextSection::new( + /// "World!", + /// TextStyle { + /// font: font_handle, + /// font_size: 60.0, + /// color: Color::RED, + /// }, + /// ), + /// ]); + /// ``` pub fn from_sections(sections: impl IntoIterator) -> Self { Self { sections: sections.into_iter().collect(), @@ -99,6 +127,24 @@ pub struct TextAlignment { } impl TextAlignment { + /// A [`TextAlignment`] set to center on both axes. + pub const TOP_LEFT: Self = TextAlignment { + vertical: VerticalAlign::Top, + horizontal: HorizontalAlign::Left, + }; + + /// A [`TextAlignment`] set to the top center. + pub const TOP_CENTER: Self = TextAlignment { + vertical: VerticalAlign::Top, + horizontal: HorizontalAlign::Center, + }; + + /// A [`TextAlignment`] set to the top center. + pub const TOP_RIGHT: Self = TextAlignment { + vertical: VerticalAlign::Top, + horizontal: HorizontalAlign::Right, + }; + /// A [`TextAlignment`] set to center on both axes. pub const CENTER: Self = TextAlignment { vertical: VerticalAlign::Center, From 3a66e12fede969d06d1af990f6cb6a295c47ec59 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sat, 16 Jul 2022 22:48:42 +0200 Subject: [PATCH 05/13] More constants. --- crates/bevy_text/src/text.rs | 37 +++++++++++++++++++++++++++++++++--- examples/ui/text.rs | 5 +---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index adf0c12dedf80..eb81f860546c8 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -127,29 +127,60 @@ pub struct TextAlignment { } impl TextAlignment { - /// A [`TextAlignment`] set to center on both axes. + /// A [`TextAlignment`] set to the top-left. pub const TOP_LEFT: Self = TextAlignment { vertical: VerticalAlign::Top, horizontal: HorizontalAlign::Left, }; - /// A [`TextAlignment`] set to the top center. + /// A [`TextAlignment`] set to the top-center. pub const TOP_CENTER: Self = TextAlignment { vertical: VerticalAlign::Top, horizontal: HorizontalAlign::Center, }; - /// A [`TextAlignment`] set to the top center. + /// A [`TextAlignment`] set to the the top-right. pub const TOP_RIGHT: Self = TextAlignment { vertical: VerticalAlign::Top, horizontal: HorizontalAlign::Right, }; + /// A [`TextAlignment`] set to center the center-left. + pub const CENTER_LEFT: Self = TextAlignment { + vertical: VerticalAlign::Center, + horizontal: HorizontalAlign::Left, + }; + /// A [`TextAlignment`] set to center on both axes. pub const CENTER: Self = TextAlignment { vertical: VerticalAlign::Center, horizontal: HorizontalAlign::Center, }; + + /// A [`TextAlignment`] set to the center-right. + pub const CENTER_RIGHT: Self = TextAlignment { + vertical: VerticalAlign::Center, + horizontal: HorizontalAlign::Right, + }; + + /// A [`TextAlignment`] set to the bottom-left. + pub const BOTTOM_LEFT: Self = TextAlignment { + vertical: VerticalAlign::Bottom, + horizontal: HorizontalAlign::Left, + }; + + /// A [`TextAlignment`] set to the bottom-center. + pub const BOTTOM_CENTER: Self = TextAlignment { + vertical: VerticalAlign::Bottom, + horizontal: HorizontalAlign::Center, + }; + + /// A [`TextAlignment`] set to the bottom-right. + pub const BOTTOM_RIGHT: Self = TextAlignment { + vertical: VerticalAlign::Bottom, + horizontal: HorizontalAlign::Right, + }; + } impl Default for TextAlignment { diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 63016a3020564..365e34a43ad4c 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -52,10 +52,7 @@ fn setup(mut commands: Commands, asset_server: Res) { color: Color::WHITE, }, ) - .with_alignment(TextAlignment { - horizontal: HorizontalAlign::Center, - ..default() - }), + .with_alignment(TextAlignment::TOP_CENTER), ..default() }) .insert(ColorText); From b13f4801e9e06a4b4b315a7344338f29a1367761 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sat, 16 Jul 2022 22:49:01 +0200 Subject: [PATCH 06/13] Remove format! calls. --- crates/bevy_render/src/mesh/mesh/conversions.rs | 2 +- examples/async_tasks/external_source_external_thread.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/mesh/mesh/conversions.rs b/crates/bevy_render/src/mesh/mesh/conversions.rs index cb4c85db89214..9ebaa06541659 100644 --- a/crates/bevy_render/src/mesh/mesh/conversions.rs +++ b/crates/bevy_render/src/mesh/mesh/conversions.rs @@ -522,7 +522,7 @@ mod tests { Err(error) => error, }; assert_eq!( - format!("{}", error), + error.to_string(), "cannot convert VertexAttributeValues::Uint32x4 to alloc::vec::Vec" ); assert_eq!(format!("{:?}", error), diff --git a/examples/async_tasks/external_source_external_thread.rs b/examples/async_tasks/external_source_external_thread.rs index b4c079a9b49d2..679d67d6a626b 100644 --- a/examples/async_tasks/external_source_external_thread.rs +++ b/examples/async_tasks/external_source_external_thread.rs @@ -65,7 +65,7 @@ fn spawn_text( for (per_frame, event) in reader.iter().enumerate() { commands.spawn_bundle(Text2dBundle { - text: Text::from_section(format!("{}", event.0), text_style.clone()) + text: Text::from_section(event.0.to_string(), text_style.clone()) .with_alignment(TextAlignment::CENTER), transform: Transform::from_xyz( per_frame as f32 * 100.0 + rand::thread_rng().gen_range(-40.0..40.0), From 3c83943012079e6c2a53031871671dc66bf35f13 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sun, 17 Jul 2022 18:26:13 +0200 Subject: [PATCH 07/13] Cleanup. --- crates/bevy_text/src/text.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index eb81f860546c8..e318639727d3d 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -180,15 +180,11 @@ impl TextAlignment { vertical: VerticalAlign::Bottom, horizontal: HorizontalAlign::Right, }; - } impl Default for TextAlignment { fn default() -> Self { - TextAlignment { - vertical: VerticalAlign::Top, - horizontal: HorizontalAlign::Left, - } + TextAlignment::TOP_LEFT } } From fa5391779c7ab8ac4bc1abc3f99960434ab37376 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Wed, 20 Jul 2022 11:42:30 +0200 Subject: [PATCH 08/13] Add builder methods to `TextBundle`. --- crates/bevy_ui/src/entity.rs | 36 +++++++++++++++- examples/ui/text.rs | 79 ++++++++++++++++++------------------ 2 files changed, 74 insertions(+), 41 deletions(-) diff --git a/crates/bevy_ui/src/entity.rs b/crates/bevy_ui/src/entity.rs index 5345ee3dd6726..f67b06ca3ccf7 100644 --- a/crates/bevy_ui/src/entity.rs +++ b/crates/bevy_ui/src/entity.rs @@ -13,7 +13,7 @@ use bevy_render::{ camera::Camera, extract_component::ExtractComponent, prelude::ComputedVisibility, view::Visibility, }; -use bevy_text::Text; +use bevy_text::{Text, TextAlignment, TextStyle, TextSection}; use bevy_transform::prelude::{GlobalTransform, Transform}; /// The basic UI node @@ -89,6 +89,40 @@ pub struct TextBundle { pub computed_visibility: ComputedVisibility, } +impl TextBundle { + /// Create a [`TextBundle`] from a single section. + /// + /// See [`Text::from_section`] for usage. + pub fn from_section(value: impl Into, style: TextStyle) -> Self { + Self { + text: Text::from_section(value, style), + ..Default::default() + } + } + + /// Create a [`TextBundle`] from a list of sections. + /// + /// See [`Text::from_sections`] for usage. + pub fn from_sections(sections: impl IntoIterator) -> Self { + Self { + text: Text::from_sections(sections), + ..Default::default() + } + } + + /// Returns this [`TextBundle`] with a new [`TextAlignment`] on [`Text`]. + pub fn with_text_alignment(mut self, alignment: TextAlignment) -> Self { + self.text.alignment = alignment; + self + } + + /// Returns this [`TextBundle`] with a new [`Style`]. + pub fn with_style(mut self, style: Style) -> Self { + self.style = style; + self + } +} + impl Default for TextBundle { fn default() -> Self { TextBundle { diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 365e34a43ad4c..e891d16b50479 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -31,8 +31,20 @@ fn setup(mut commands: Commands, asset_server: Res) { commands.spawn_bundle(Camera2dBundle::default()); // Text with one section commands - .spawn_bundle(TextBundle { - style: Style { + .spawn_bundle( + // Create a TextBundle that has a Text with a single section. + TextBundle::from_section( + // Accepts a `String` or any type that converts into a `String`, such as `&str` + "hello\nbevy!", + TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 100.0, + color: Color::WHITE, + }, + ) // Set the alignment of the Text + .with_text_alignment(TextAlignment::TOP_CENTER) + // Set the style of the TextBundle itself. + .with_style(Style { align_self: AlignSelf::FlexEnd, position_type: PositionType::Absolute, position: UiRect { @@ -41,30 +53,14 @@ fn setup(mut commands: Commands, asset_server: Res) { ..default() }, ..default() - }, - // Use the `Text::with_section` constructor - text: Text::from_section( - // Accepts a `String` or any type that converts into a `String`, such as `&str` - "hello\nbevy!", - TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 100.0, - color: Color::WHITE, - }, - ) - .with_alignment(TextAlignment::TOP_CENTER), - ..default() - }) + }), + ) .insert(ColorText); - // Rich text with multiple sections + // Text with multiple sections commands - .spawn_bundle(TextBundle { - style: Style { - align_self: AlignSelf::FlexEnd, - ..default() - }, - // Use `Text` directly - text: Text::from_sections([ + .spawn_bundle( + // Create a TextBundle that has a Text with a list of sections. + TextBundle::from_sections([ TextSection::new( "FPS: ", TextStyle { @@ -78,28 +74,20 @@ fn setup(mut commands: Commands, asset_server: Res) { font_size: 60.0, color: Color::GOLD, }), - ]), - ..default() - }) + ]) + .with_style(Style { + align_self: AlignSelf::FlexEnd, + ..default() + }), + ) .insert(FpsText); } -fn text_update_system(diagnostics: Res, mut query: Query<&mut Text, With>) { - for mut text in &mut query { - if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) { - if let Some(average) = fps.average() { - // Update the value of the second section - text.sections[1].value = format!("{:.2}", average); - } - } - } -} - fn text_color_system(time: Res