From 2f2e3c33ba60242667a8636b586396089deaa0f9 Mon Sep 17 00:00:00 2001 From: krunchington Date: Sat, 15 Mar 2025 13:45:01 -0700 Subject: [PATCH 1/2] Update testbed_ui to use Improved Spawning API --- examples/testbed/ui.rs | 343 ++++++++++++++++++++--------------------- 1 file changed, 167 insertions(+), 176 deletions(-) diff --git a/examples/testbed/ui.rs b/examples/testbed/ui.rs index 0693a4d098c18..490c0eb58cfb1 100644 --- a/examples/testbed/ui.rs +++ b/examples/testbed/ui.rs @@ -105,26 +105,24 @@ mod grid { pub fn setup(mut commands: Commands) { commands.spawn((Camera2d, StateScoped(super::Scene::Grid))); // Top-level grid (app frame) - commands - .spawn(( - Node { - display: Display::Grid, - width: Val::Percent(100.0), - height: Val::Percent(100.0), - grid_template_columns: vec![GridTrack::min_content(), GridTrack::flex(1.0)], - grid_template_rows: vec![ - GridTrack::auto(), - GridTrack::flex(1.0), - GridTrack::px(40.), - ], - ..default() - }, - BackgroundColor(Color::WHITE), - StateScoped(super::Scene::Grid), - )) - .with_children(|builder| { + commands.spawn(( + Node { + display: Display::Grid, + width: Val::Percent(100.0), + height: Val::Percent(100.0), + grid_template_columns: vec![GridTrack::min_content(), GridTrack::flex(1.0)], + grid_template_rows: vec![ + GridTrack::auto(), + GridTrack::flex(1.0), + GridTrack::px(40.), + ], + ..default() + }, + BackgroundColor(Color::WHITE), + StateScoped(super::Scene::Grid), + children![ // Header - builder.spawn(( + ( Node { display: Display::Grid, grid_column: GridPlacement::span(2), @@ -132,34 +130,32 @@ mod grid { ..default() }, BackgroundColor(RED.into()), - )); - + ), // Main content grid (auto placed in row 2, column 1) - builder - .spawn(( - Node { - height: Val::Percent(100.0), - aspect_ratio: Some(1.0), - display: Display::Grid, - grid_template_columns: RepeatedGridTrack::flex(3, 1.0), - grid_template_rows: RepeatedGridTrack::flex(2, 1.0), - row_gap: Val::Px(12.0), - column_gap: Val::Px(12.0), - ..default() - }, - BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), - )) - .with_children(|builder| { - builder.spawn((Node::default(), BackgroundColor(ORANGE.into()))); - builder.spawn((Node::default(), BackgroundColor(BISQUE.into()))); - builder.spawn((Node::default(), BackgroundColor(BLUE.into()))); - builder.spawn((Node::default(), BackgroundColor(CRIMSON.into()))); - builder.spawn((Node::default(), BackgroundColor(AQUA.into()))); - }); - + ( + Node { + height: Val::Percent(100.0), + aspect_ratio: Some(1.0), + display: Display::Grid, + grid_template_columns: RepeatedGridTrack::flex(3, 1.0), + grid_template_rows: RepeatedGridTrack::flex(2, 1.0), + row_gap: Val::Px(12.0), + column_gap: Val::Px(12.0), + ..default() + }, + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + children![ + (Node::default(), BackgroundColor(ORANGE.into())), + (Node::default(), BackgroundColor(BISQUE.into())), + (Node::default(), BackgroundColor(BLUE.into())), + (Node::default(), BackgroundColor(CRIMSON.into())), + (Node::default(), BackgroundColor(AQUA.into())), + ] + ), // Right side bar (auto placed in row 2, column 2) - builder.spawn((Node::DEFAULT, BackgroundColor(BLACK.into()))); - }); + (Node::DEFAULT, BackgroundColor(BLACK.into())), + ], + )); } } @@ -257,26 +253,23 @@ mod borders { } mod box_shadow { - use bevy::{color::palettes::css::*, prelude::*}; + use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*}; pub fn setup(mut commands: Commands) { commands.spawn((Camera2d, StateScoped(super::Scene::BoxShadow))); - - commands - .spawn(( - Node { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - padding: UiRect::all(Val::Px(30.)), - column_gap: Val::Px(200.), - flex_wrap: FlexWrap::Wrap, - ..default() - }, - BackgroundColor(GREEN.into()), - StateScoped(super::Scene::BoxShadow), - )) - .with_children(|commands| { - let example_nodes = [ + commands.spawn(( + Node { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + padding: UiRect::all(Val::Px(30.)), + column_gap: Val::Px(200.), + flex_wrap: FlexWrap::Wrap, + ..default() + }, + BackgroundColor(GREEN.into()), + StateScoped(super::Scene::BoxShadow), + Children::spawn(SpawnIter( + [ ( Vec2::splat(100.), Vec2::ZERO, @@ -313,10 +306,10 @@ mod box_shadow { 10., BorderRadius::MAX, ), - ]; - - for (size, offset, spread, blur, border_radius) in example_nodes { - commands.spawn(( + ] + .into_iter() + .map(|(size, offset, spread, blur, border_radius)| { + ( Node { width: Val::Px(size.x), height: Val::Px(size.y), @@ -333,9 +326,10 @@ mod box_shadow { Val::Percent(spread), Val::Px(blur), ), - )); - } - }); + ) + }), + )), + )); } } @@ -382,71 +376,68 @@ mod text_wrap { } mod overflow { - use bevy::{color::palettes::css::*, prelude::*}; + use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*}; pub fn setup(mut commands: Commands, asset_server: Res) { commands.spawn((Camera2d, StateScoped(super::Scene::Overflow))); let image = asset_server.load("branding/icon.png"); + let overflow_params = [ + (Overflow::visible(), image.clone()), + (Overflow::clip_x(), image.clone()), + (Overflow::clip_y(), image.clone()), + (Overflow::clip(), image.clone()), + ]; - commands - .spawn(( - Node { - width: Val::Percent(100.), - height: Val::Percent(100.), - align_items: AlignItems::Center, - justify_content: JustifyContent::SpaceAround, - ..Default::default() - }, - BackgroundColor(BLUE.into()), - StateScoped(super::Scene::Overflow), - )) - .with_children(|parent| { - for overflow in [ - Overflow::visible(), - Overflow::clip_x(), - Overflow::clip_y(), - Overflow::clip(), - ] { - parent - .spawn(( + commands.spawn(( + Node { + width: Val::Percent(100.), + height: Val::Percent(100.), + align_items: AlignItems::Center, + justify_content: JustifyContent::SpaceAround, + ..Default::default() + }, + BackgroundColor(BLUE.into()), + StateScoped(super::Scene::Overflow), + Children::spawn(SpawnIter(overflow_params.into_iter().map( + |(overflow, image)| { + ( + Node { + width: Val::Px(100.), + height: Val::Px(100.), + padding: UiRect { + left: Val::Px(25.), + top: Val::Px(25.), + ..Default::default() + }, + border: UiRect::all(Val::Px(5.)), + overflow, + ..default() + }, + BorderColor(RED.into()), + BackgroundColor(Color::WHITE), + children![( + ImageNode::new(image), Node { - width: Val::Px(100.), - height: Val::Px(100.), - padding: UiRect { - left: Val::Px(25.), - top: Val::Px(25.), - ..Default::default() - }, - border: UiRect::all(Val::Px(5.)), - overflow, + min_width: Val::Px(100.), + min_height: Val::Px(100.), ..default() }, - BorderColor(RED.into()), - BackgroundColor(Color::WHITE), - )) - .with_children(|parent| { - parent.spawn(( - ImageNode::new(image.clone()), - Node { - min_width: Val::Px(100.), - min_height: Val::Px(100.), - ..default() - }, - Interaction::default(), - Outline { - width: Val::Px(2.), - offset: Val::Px(2.), - color: Color::NONE, - }, - )); - }); - } - }); + Interaction::default(), + Outline { + width: Val::Px(2.), + offset: Val::Px(2.), + color: Color::NONE, + }, + )], + ) + }, + ))), + )); } } mod slice { - use bevy::prelude::*; + use bevy::{ecs::spawn::SpawnIter, prelude::*}; pub fn setup(mut commands: Commands, asset_server: Res) { commands.spawn((Camera2d, StateScoped(super::Scene::Slice))); @@ -458,24 +449,27 @@ mod slice { sides_scale_mode: SliceScaleMode::Tile { stretch_value: 1.0 }, ..default() }; - commands - .spawn(( - Node { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - align_items: AlignItems::Center, - justify_content: JustifyContent::SpaceAround, - ..default() - }, - StateScoped(super::Scene::Slice), - )) - .with_children(|parent| { - for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] { - parent.spawn(( + let slice_params = [ + (150.0, 150.0, image.clone(), slicer.clone()), + (300.0, 150.0, image.clone(), slicer.clone()), + (150.0, 300.0, image.clone(), slicer.clone()), + ]; + commands.spawn(( + Node { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::SpaceAround, + ..default() + }, + StateScoped(super::Scene::Slice), + Children::spawn(SpawnIter(slice_params.into_iter().map( + |(w, h, image, slicer)| { + ( Button, ImageNode { - image: image.clone(), - image_mode: NodeImageMode::Sliced(slicer.clone()), + image, + image_mode: NodeImageMode::Sliced(slicer), ..default() }, Node { @@ -483,51 +477,48 @@ mod slice { height: Val::Px(h), ..default() }, - )); - } - }); + ) + }, + ))), + )); } } mod layout_rounding { - use bevy::{color::palettes::css::*, prelude::*}; + use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*}; pub fn setup(mut commands: Commands) { commands.spawn((Camera2d, StateScoped(super::Scene::LayoutRounding))); - commands - .spawn(( - Node { - display: Display::Grid, - width: Val::Percent(100.), - height: Val::Percent(100.), - grid_template_rows: vec![RepeatedGridTrack::fr(10, 1.)], - ..Default::default() - }, - BackgroundColor(Color::WHITE), - StateScoped(super::Scene::LayoutRounding), - )) - .with_children(|commands| { - for i in 2..12 { - commands - .spawn(Node { - display: Display::Grid, - grid_template_columns: vec![RepeatedGridTrack::fr(i, 1.)], - ..Default::default() - }) - .with_children(|commands| { - for _ in 0..i { - commands.spawn(( - Node { - border: UiRect::all(Val::Px(5.)), - ..Default::default() - }, - BackgroundColor(MAROON.into()), - BorderColor(DARK_BLUE.into()), - )); - } - }); - } - }); + commands.spawn(( + Node { + display: Display::Grid, + width: Val::Percent(100.), + height: Val::Percent(100.), + grid_template_rows: vec![RepeatedGridTrack::fr(10, 1.)], + ..Default::default() + }, + BackgroundColor(Color::WHITE), + StateScoped(super::Scene::LayoutRounding), + Children::spawn(SpawnIter((2..12).map(|i| { + ( + Node { + display: Display::Grid, + grid_template_columns: vec![RepeatedGridTrack::fr(i, 1.)], + ..Default::default() + }, + Children::spawn(SpawnIter((0..i).map(|_| { + ( + Node { + border: UiRect::all(Val::Px(5.)), + ..Default::default() + }, + BackgroundColor(MAROON.into()), + BorderColor(DARK_BLUE.into()), + ) + }))), + ) + }))), + )); } } From f57e1d6267f15bf8c94e63d610ee15458eabe91f Mon Sep 17 00:00:00 2001 From: krunchington Date: Sun, 16 Mar 2025 20:16:22 -0700 Subject: [PATCH 2/2] Revert SpawnIter changes --- examples/testbed/ui.rs | 257 +++++++++++++++++++++-------------------- 1 file changed, 131 insertions(+), 126 deletions(-) diff --git a/examples/testbed/ui.rs b/examples/testbed/ui.rs index 490c0eb58cfb1..0f2a9d86ec678 100644 --- a/examples/testbed/ui.rs +++ b/examples/testbed/ui.rs @@ -253,23 +253,26 @@ mod borders { } mod box_shadow { - use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*}; + use bevy::{color::palettes::css::*, prelude::*}; pub fn setup(mut commands: Commands) { commands.spawn((Camera2d, StateScoped(super::Scene::BoxShadow))); - commands.spawn(( - Node { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - padding: UiRect::all(Val::Px(30.)), - column_gap: Val::Px(200.), - flex_wrap: FlexWrap::Wrap, - ..default() - }, - BackgroundColor(GREEN.into()), - StateScoped(super::Scene::BoxShadow), - Children::spawn(SpawnIter( - [ + + commands + .spawn(( + Node { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + padding: UiRect::all(Val::Px(30.)), + column_gap: Val::Px(200.), + flex_wrap: FlexWrap::Wrap, + ..default() + }, + BackgroundColor(GREEN.into()), + StateScoped(super::Scene::BoxShadow), + )) + .with_children(|commands| { + let example_nodes = [ ( Vec2::splat(100.), Vec2::ZERO, @@ -306,10 +309,10 @@ mod box_shadow { 10., BorderRadius::MAX, ), - ] - .into_iter() - .map(|(size, offset, spread, blur, border_radius)| { - ( + ]; + + for (size, offset, spread, blur, border_radius) in example_nodes { + commands.spawn(( Node { width: Val::Px(size.x), height: Val::Px(size.y), @@ -326,10 +329,9 @@ mod box_shadow { Val::Percent(spread), Val::Px(blur), ), - ) - }), - )), - )); + )); + } + }); } } @@ -376,68 +378,71 @@ mod text_wrap { } mod overflow { - use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*}; + use bevy::{color::palettes::css::*, prelude::*}; pub fn setup(mut commands: Commands, asset_server: Res) { commands.spawn((Camera2d, StateScoped(super::Scene::Overflow))); let image = asset_server.load("branding/icon.png"); - let overflow_params = [ - (Overflow::visible(), image.clone()), - (Overflow::clip_x(), image.clone()), - (Overflow::clip_y(), image.clone()), - (Overflow::clip(), image.clone()), - ]; - commands.spawn(( - Node { - width: Val::Percent(100.), - height: Val::Percent(100.), - align_items: AlignItems::Center, - justify_content: JustifyContent::SpaceAround, - ..Default::default() - }, - BackgroundColor(BLUE.into()), - StateScoped(super::Scene::Overflow), - Children::spawn(SpawnIter(overflow_params.into_iter().map( - |(overflow, image)| { - ( - Node { - width: Val::Px(100.), - height: Val::Px(100.), - padding: UiRect { - left: Val::Px(25.), - top: Val::Px(25.), - ..Default::default() - }, - border: UiRect::all(Val::Px(5.)), - overflow, - ..default() - }, - BorderColor(RED.into()), - BackgroundColor(Color::WHITE), - children![( - ImageNode::new(image), + commands + .spawn(( + Node { + width: Val::Percent(100.), + height: Val::Percent(100.), + align_items: AlignItems::Center, + justify_content: JustifyContent::SpaceAround, + ..Default::default() + }, + BackgroundColor(BLUE.into()), + StateScoped(super::Scene::Overflow), + )) + .with_children(|parent| { + for overflow in [ + Overflow::visible(), + Overflow::clip_x(), + Overflow::clip_y(), + Overflow::clip(), + ] { + parent + .spawn(( Node { - min_width: Val::Px(100.), - min_height: Val::Px(100.), + width: Val::Px(100.), + height: Val::Px(100.), + padding: UiRect { + left: Val::Px(25.), + top: Val::Px(25.), + ..Default::default() + }, + border: UiRect::all(Val::Px(5.)), + overflow, ..default() }, - Interaction::default(), - Outline { - width: Val::Px(2.), - offset: Val::Px(2.), - color: Color::NONE, - }, - )], - ) - }, - ))), - )); + BorderColor(RED.into()), + BackgroundColor(Color::WHITE), + )) + .with_children(|parent| { + parent.spawn(( + ImageNode::new(image.clone()), + Node { + min_width: Val::Px(100.), + min_height: Val::Px(100.), + ..default() + }, + Interaction::default(), + Outline { + width: Val::Px(2.), + offset: Val::Px(2.), + color: Color::NONE, + }, + )); + }); + } + }); } } mod slice { - use bevy::{ecs::spawn::SpawnIter, prelude::*}; + use bevy::prelude::*; pub fn setup(mut commands: Commands, asset_server: Res) { commands.spawn((Camera2d, StateScoped(super::Scene::Slice))); @@ -449,27 +454,24 @@ mod slice { sides_scale_mode: SliceScaleMode::Tile { stretch_value: 1.0 }, ..default() }; - let slice_params = [ - (150.0, 150.0, image.clone(), slicer.clone()), - (300.0, 150.0, image.clone(), slicer.clone()), - (150.0, 300.0, image.clone(), slicer.clone()), - ]; - commands.spawn(( - Node { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - align_items: AlignItems::Center, - justify_content: JustifyContent::SpaceAround, - ..default() - }, - StateScoped(super::Scene::Slice), - Children::spawn(SpawnIter(slice_params.into_iter().map( - |(w, h, image, slicer)| { - ( + commands + .spawn(( + Node { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::SpaceAround, + ..default() + }, + StateScoped(super::Scene::Slice), + )) + .with_children(|parent| { + for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] { + parent.spawn(( Button, ImageNode { - image, - image_mode: NodeImageMode::Sliced(slicer), + image: image.clone(), + image_mode: NodeImageMode::Sliced(slicer.clone()), ..default() }, Node { @@ -477,48 +479,51 @@ mod slice { height: Val::Px(h), ..default() }, - ) - }, - ))), - )); + )); + } + }); } } mod layout_rounding { - use bevy::{color::palettes::css::*, ecs::spawn::SpawnIter, prelude::*}; + use bevy::{color::palettes::css::*, prelude::*}; pub fn setup(mut commands: Commands) { commands.spawn((Camera2d, StateScoped(super::Scene::LayoutRounding))); - commands.spawn(( - Node { - display: Display::Grid, - width: Val::Percent(100.), - height: Val::Percent(100.), - grid_template_rows: vec![RepeatedGridTrack::fr(10, 1.)], - ..Default::default() - }, - BackgroundColor(Color::WHITE), - StateScoped(super::Scene::LayoutRounding), - Children::spawn(SpawnIter((2..12).map(|i| { - ( - Node { - display: Display::Grid, - grid_template_columns: vec![RepeatedGridTrack::fr(i, 1.)], - ..Default::default() - }, - Children::spawn(SpawnIter((0..i).map(|_| { - ( - Node { - border: UiRect::all(Val::Px(5.)), - ..Default::default() - }, - BackgroundColor(MAROON.into()), - BorderColor(DARK_BLUE.into()), - ) - }))), - ) - }))), - )); + commands + .spawn(( + Node { + display: Display::Grid, + width: Val::Percent(100.), + height: Val::Percent(100.), + grid_template_rows: vec![RepeatedGridTrack::fr(10, 1.)], + ..Default::default() + }, + BackgroundColor(Color::WHITE), + StateScoped(super::Scene::LayoutRounding), + )) + .with_children(|commands| { + for i in 2..12 { + commands + .spawn(Node { + display: Display::Grid, + grid_template_columns: vec![RepeatedGridTrack::fr(i, 1.)], + ..Default::default() + }) + .with_children(|commands| { + for _ in 0..i { + commands.spawn(( + Node { + border: UiRect::all(Val::Px(5.)), + ..Default::default() + }, + BackgroundColor(MAROON.into()), + BorderColor(DARK_BLUE.into()), + )); + } + }); + } + }); } }