From eb19a9ea0b175cec25400860fee71c5efb9a4602 Mon Sep 17 00:00:00 2001 From: VitalyR Date: Fri, 18 Oct 2024 05:11:02 +0800 Subject: [PATCH] Migrate UI bundles to required components (#15898) # Objective - Migrate UI bundles to required components, fixes #15889 ## Solution - deprecate `NodeBundle` in favor of `Node` - deprecate `ImageBundle` in favor of `UiImage` - deprecate `ButtonBundle` in favor of `Button` ## Testing CI. ## Migration Guide - Replace all uses of `NodeBundle` with `Node`. e.g. ```diff commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) ``` - Replace all uses of `ButtonBundle` with `Button`. e.g. ```diff .spawn(( - ButtonBundle { - style: Style { - width: Val::Px(w), - height: Val::Px(h), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - margin: UiRect::all(Val::Px(20.0)), - ..default() - }, - image: image.clone().into(), + Button, + Style { + width: Val::Px(w), + height: Val::Px(h), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + margin: UiRect::all(Val::Px(20.0)), ..default() }, + UiImage::from(image.clone()), ImageScaleMode::Sliced(slicer.clone()), )) ``` - Replace all uses of `ImageBundle` with `UiImage`. e.g. ```diff - commands.spawn(ImageBundle { - image: UiImage { + commands.spawn(( + UiImage { texture: metering_mask, ..default() }, - style: Style { + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), ..default() }, - ..default() - }); + )); ``` --------- Co-authored-by: Carter Anderson --- crates/bevy_dev_tools/src/fps_overlay.rs | 14 +- .../src/experimental/ghost_hierarchy.rs | 23 +- crates/bevy_ui/src/focus.rs | 2 +- crates/bevy_ui/src/layout/mod.rs | 116 ++++---- crates/bevy_ui/src/lib.rs | 4 +- crates/bevy_ui/src/node_bundles.rs | 23 +- crates/bevy_ui/src/render/mod.rs | 21 +- .../src/render/ui_material_pipeline.rs | 27 +- crates/bevy_ui/src/ui_material.rs | 31 ++- crates/bevy_ui/src/ui_node.rs | 69 +++-- crates/bevy_ui/src/widget/button.rs | 2 + crates/bevy_ui/src/widget/text.rs | 23 +- examples/3d/auto_exposure.rs | 9 +- examples/3d/blend_modes.rs | 8 +- examples/3d/color_grading.rs | 91 +++--- examples/3d/pcss.rs | 5 +- examples/3d/shadow_biases.rs | 12 +- examples/3d/split_screen.rs | 38 ++- examples/animation/animated_ui.rs | 8 +- examples/animation/animation_graph.rs | 56 ++-- examples/animation/animation_masks.rs | 70 +++-- examples/app/log_layers_ecs.rs | 14 +- examples/camera/first_person_view_model.rs | 8 +- examples/games/alien_cake_addict.rs | 8 +- examples/games/game_menu.rs | 263 ++++++++---------- examples/games/loading_screen.rs | 26 +- examples/helpers/widgets.rs | 22 +- examples/math/cubic_splines.rs | 8 +- examples/math/render_primitives.rs | 10 +- examples/mobile/src/lib.rs | 8 +- .../movement/physics_in_fixed_timestep.rs | 8 +- examples/state/computed_states.rs | 163 +++++------ examples/state/custom_transitions.rs | 18 +- examples/state/states.rs | 18 +- examples/state/sub_states.rs | 48 ++-- examples/stress_tests/bevymark.rs | 12 +- examples/stress_tests/many_buttons.rs | 80 +++--- examples/stress_tests/many_glyphs.rs | 16 +- examples/time/virtual_time.rs | 8 +- examples/ui/borders.rs | 156 +++++------ examples/ui/box_shadow.rs | 30 +- examples/ui/button.rs | 22 +- examples/ui/display_and_visibility.rs | 235 ++++++++-------- examples/ui/flex_layout.rs | 62 ++--- examples/ui/font_atlas_debug.rs | 19 +- examples/ui/ghost_nodes.rs | 36 ++- examples/ui/grid.rs | 77 +++-- examples/ui/overflow.rs | 55 ++-- examples/ui/overflow_clip_margin.rs | 71 +++-- examples/ui/overflow_debug.rs | 59 ++-- examples/ui/relative_cursor_position.rs | 18 +- examples/ui/render_ui_to_texture.rs | 20 +- examples/ui/scroll.rs | 115 ++++---- examples/ui/size_constraints.rs | 175 ++++++------ examples/ui/text_debug.rs | 39 +-- examples/ui/text_wrap_debug.rs | 34 +-- examples/ui/transparency_ui.rs | 28 +- examples/ui/ui.rs | 195 ++++++------- examples/ui/ui_material.rs | 32 +-- examples/ui/ui_scaling.rs | 39 ++- examples/ui/ui_texture_atlas.rs | 21 +- examples/ui/ui_texture_atlas_slice.rs | 30 +- examples/ui/ui_texture_slice.rs | 30 +- examples/ui/ui_texture_slice_flip_and_tile.rs | 23 +- examples/ui/viewport_debug.rs | 168 ++++++----- examples/ui/z_index.rs | 92 +++--- examples/window/scale_factor_override.rs | 18 +- examples/window/window_drag_move.rs | 12 +- examples/window/window_resizing.rs | 8 +- 69 files changed, 1578 insertions(+), 1731 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 6b020910fb2da..efba70a2106f1 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -15,8 +15,8 @@ use bevy_ecs::{ use bevy_hierarchy::{BuildChildren, ChildBuild}; use bevy_render::view::Visibility; use bevy_text::{Font, TextColor, TextFont, TextSpan}; +use bevy_ui::Node; use bevy_ui::{ - node_bundles::NodeBundle, widget::{Text, TextUiWriter}, GlobalZIndex, PositionType, Style, }; @@ -89,15 +89,13 @@ struct FpsText; fn setup(mut commands: Commands, overlay_config: Res) { commands .spawn(( - NodeBundle { - style: Style { - // We need to make sure the overlay doesn't affect the position of other UI nodes - position_type: PositionType::Absolute, - ..default() - }, - // Render overlay on top of everything + Node::default(), + Style { + // We need to make sure the overlay doesn't affect the position of other UI nodes + position_type: PositionType::Absolute, ..default() }, + // Render overlay on top of everything GlobalZIndex(FPS_OVERLAY_ZINDEX), )) .with_children(|p| { diff --git a/crates/bevy_ui/src/experimental/ghost_hierarchy.rs b/crates/bevy_ui/src/experimental/ghost_hierarchy.rs index 067952e9f1a0f..42832c0483500 100644 --- a/crates/bevy_ui/src/experimental/ghost_hierarchy.rs +++ b/crates/bevy_ui/src/experimental/ghost_hierarchy.rs @@ -170,8 +170,7 @@ mod tests { }; use bevy_hierarchy::{BuildChildren, ChildBuild}; - use super::{GhostNode, UiChildren, UiRootNodes}; - use crate::prelude::NodeBundle; + use super::{GhostNode, Node, UiChildren, UiRootNodes}; #[derive(Component, PartialEq, Debug)] struct A(usize); @@ -182,22 +181,22 @@ mod tests { // Normal root world - .spawn((A(1), NodeBundle::default())) + .spawn((A(1), Node::default())) .with_children(|parent| { - parent.spawn((A(2), NodeBundle::default())); + parent.spawn((A(2), Node::default())); parent .spawn((A(3), GhostNode::new())) - .with_child((A(4), NodeBundle::default())); + .with_child((A(4), Node::default())); }); // Ghost root world .spawn((A(5), GhostNode::new())) .with_children(|parent| { - parent.spawn((A(6), NodeBundle::default())); + parent.spawn((A(6), Node::default())); parent .spawn((A(7), GhostNode::new())) - .with_child((A(8), NodeBundle::default())) + .with_child((A(8), Node::default())) .with_child(A(9)); }); @@ -213,17 +212,17 @@ mod tests { fn iterate_ui_children() { let world = &mut World::new(); - let n1 = world.spawn((A(1), NodeBundle::default())).id(); + let n1 = world.spawn((A(1), Node::default())).id(); let n2 = world.spawn((A(2), GhostNode::new())).id(); let n3 = world.spawn((A(3), GhostNode::new())).id(); - let n4 = world.spawn((A(4), NodeBundle::default())).id(); - let n5 = world.spawn((A(5), NodeBundle::default())).id(); + let n4 = world.spawn((A(4), Node::default())).id(); + let n5 = world.spawn((A(5), Node::default())).id(); let n6 = world.spawn((A(6), GhostNode::new())).id(); let n7 = world.spawn((A(7), GhostNode::new())).id(); - let n8 = world.spawn((A(8), NodeBundle::default())).id(); + let n8 = world.spawn((A(8), Node::default())).id(); let n9 = world.spawn((A(9), GhostNode::new())).id(); - let n10 = world.spawn((A(10), NodeBundle::default())).id(); + let n10 = world.spawn((A(10), Node::default())).id(); let no_ui = world.spawn_empty().id(); diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 9e67d4d6f97ff..823fa36e7454a 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -39,7 +39,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// # See also /// -/// - [`ButtonBundle`](crate::node_bundles::ButtonBundle) which includes this component +/// - [`Button`](crate::widget::Button) which requires this component /// - [`RelativeCursorPosition`] to obtain the position of the cursor relative to current node #[derive(Component, Copy, Clone, Eq, PartialEq, Debug, Reflect)] #[reflect(Component, Default, PartialEq, Debug)] diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 7f191fcf1b35b..0a4c748051af0 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -581,25 +581,25 @@ mod tests { // spawn a root entity with width and height set to fill 100% of its parent let ui_root = world - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), ..default() }, - ..default() - }) + )) .id(); let ui_child = world - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), ..default() }, - ..default() - }) + )) .id(); world.entity_mut(ui_root).add_child(ui_child); @@ -624,7 +624,7 @@ mod tests { let ui_surface = world.resource::(); assert!(ui_surface.entity_to_taffy.is_empty()); - let ui_entity = world.spawn(NodeBundle::default()).id(); + let ui_entity = world.spawn(Node::default()).id(); // `ui_layout_system` should map `ui_entity` to a ui node in `UiSurface::entity_to_taffy` ui_schedule.run(&mut world); @@ -666,7 +666,7 @@ mod tests { let camera_entity = world.spawn(Camera2d).id(); let ui_entity = world - .spawn((NodeBundle::default(), TargetCamera(camera_entity))) + .spawn((Node::default(), TargetCamera(camera_entity))) .id(); // `ui_layout_system` should map `camera_entity` to a ui node in `UiSurface::camera_entity_to_taffy` @@ -696,7 +696,7 @@ mod tests { fn despawning_a_ui_entity_should_remove_its_corresponding_ui_node() { let (mut world, mut ui_schedule) = setup_ui_test_world(); - let ui_entity = world.spawn(NodeBundle::default()).id(); + let ui_entity = world.spawn(Node::default()).id(); // `ui_layout_system` will insert a ui node into the internal layout tree corresponding to `ui_entity` ui_schedule.run(&mut world); @@ -721,7 +721,7 @@ mod tests { fn changes_to_children_of_a_ui_entity_change_its_corresponding_ui_nodes_children() { let (mut world, mut ui_schedule) = setup_ui_test_world(); - let ui_parent_entity = world.spawn(NodeBundle::default()).id(); + let ui_parent_entity = world.spawn(Node::default()).id(); // `ui_layout_system` will insert a ui node into the internal layout tree corresponding to `ui_entity` ui_schedule.run(&mut world); @@ -734,7 +734,7 @@ mod tests { let mut ui_child_entities = (0..10) .map(|_| { - let child = world.spawn(NodeBundle::default()).id(); + let child = world.spawn(Node::default()).id(); world.entity_mut(ui_parent_entity).add_child(child); child }) @@ -828,40 +828,40 @@ mod tests { let mut size = 150.; - world.spawn(NodeBundle { - style: Style { + world.spawn(( + Node::default(), + Style { // test should pass without explicitly requiring position_type to be set to Absolute // position_type: PositionType::Absolute, width: Val::Px(size), height: Val::Px(size), ..default() }, - ..default() - }); + )); size -= 50.; - world.spawn(NodeBundle { - style: Style { + world.spawn(( + Node::default(), + Style { // position_type: PositionType::Absolute, width: Val::Px(size), height: Val::Px(size), ..default() }, - ..default() - }); + )); size -= 50.; - world.spawn(NodeBundle { - style: Style { + world.spawn(( + Node::default(), + Style { // position_type: PositionType::Absolute, width: Val::Px(size), height: Val::Px(size), ..default() }, - ..default() - }); + )); ui_schedule.run(&mut world); @@ -996,13 +996,11 @@ mod tests { )); world.spawn(( - NodeBundle { - style: Style { - position_type: PositionType::Absolute, - top: Val::Px(0.), - left: Val::Px(0.), - ..default() - }, + Node::default(), + Style { + position_type: PositionType::Absolute, + top: Val::Px(0.), + left: Val::Px(0.), ..default() }, MovingUiNode, @@ -1052,12 +1050,10 @@ mod tests { let ui_entity = world .spawn(( - NodeBundle { - style: Style { - align_self: AlignSelf::Start, - ..Default::default() - }, - ..Default::default() + Node::default(), + Style { + align_self: AlignSelf::Start, + ..default() }, ContentSize::fixed_size(content_size), )) @@ -1080,11 +1076,9 @@ mod tests { let content_size = Vec2::new(50., 25.); let ui_entity = world .spawn(( - NodeBundle { - style: Style { - align_self: AlignSelf::Start, - ..Default::default() - }, + Node::default(), + Style { + align_self: AlignSelf::Start, ..Default::default() }, ContentSize::fixed_size(content_size), @@ -1121,26 +1115,26 @@ mod tests { let (mut world, mut ui_schedule) = setup_ui_test_world(); let parent = world - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Grid, grid_template_columns: RepeatedGridTrack::min_content(2), margin: UiRect::all(Val::Px(4.0)), - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|commands| { for _ in 0..2 { - commands.spawn(NodeBundle { - style: Style { + commands.spawn(( + Node::default(), + Style { display: Display::Grid, width: Val::Px(160.), height: Val::Px(160.), - ..Default::default() + ..default() }, - ..Default::default() - }); + )); } }) .id(); @@ -1211,25 +1205,25 @@ mod tests { ); let ui_root = world - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), ..default() }, - ..default() - }) + )) .id(); let ui_child = world - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), ..default() }, - ..default() - }) + )) .id(); world.entity_mut(ui_root).add_child(ui_child); diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 1da41b7ab5189..1493090be9743 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -8,7 +8,7 @@ //! This crate contains Bevy's UI system, which can be used to create UI for both 2D and 3D games //! # Basic usage -//! Spawn UI elements with [`node_bundles::ButtonBundle`], [`node_bundles::ImageBundle`], [`Text`](prelude::Text) and [`node_bundles::NodeBundle`] +//! Spawn UI elements with [`widget::Button`], [`UiImage`], [`Text`](prelude::Text) and [`Node`] //! This UI is laid out with the Flexbox and CSS Grid layout models (see ) pub mod measurement; @@ -59,7 +59,7 @@ pub mod prelude { ui_material::*, ui_node::*, widget::{Button, Label}, - Interaction, UiMaterialHandle, UiMaterialPlugin, UiScale, + Interaction, MaterialNode, UiMaterialPlugin, UiScale, }, // `bevy_sprite` re-exports for texture slicing bevy_sprite::{BorderRect, ImageScaleMode, SliceScaleMode, TextureSlicer}, diff --git a/crates/bevy_ui/src/node_bundles.rs b/crates/bevy_ui/src/node_bundles.rs index 184f9dbffbb21..7d768274f60fe 100644 --- a/crates/bevy_ui/src/node_bundles.rs +++ b/crates/bevy_ui/src/node_bundles.rs @@ -1,9 +1,10 @@ //! This module contains basic node bundles used to build UIs +#![expect(deprecated)] use crate::{ widget::{Button, UiImageSize}, - BackgroundColor, BorderColor, BorderRadius, ContentSize, FocusPolicy, Interaction, Node, - ScrollPosition, Style, UiImage, UiMaterial, UiMaterialHandle, ZIndex, + BackgroundColor, BorderColor, BorderRadius, ContentSize, FocusPolicy, Interaction, + MaterialNode, Node, ScrollPosition, Style, UiImage, UiMaterial, ZIndex, }; use bevy_ecs::bundle::Bundle; use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility}; @@ -15,6 +16,10 @@ use bevy_transform::prelude::{GlobalTransform, Transform}; /// /// See [`node_bundles`](crate::node_bundles) for more specialized bundles like [`ImageBundle`]. #[derive(Bundle, Clone, Debug, Default)] +#[deprecated( + since = "0.15.0", + note = "Use the `Node` component instead. Inserting `Node` will also insert the other components required automatically." +)] pub struct NodeBundle { /// Describes the logical size of the node pub node: Node, @@ -59,6 +64,10 @@ pub struct NodeBundle { /// - [`ImageScaleMode`](bevy_sprite::ImageScaleMode) to enable either slicing or tiling of the texture /// - [`TextureAtlas`](bevy_sprite::TextureAtlas) to draw a specific section of the texture #[derive(Bundle, Debug, Default)] +#[deprecated( + since = "0.15.0", + note = "Use the `UiImage` component instead. Inserting `UiImage` will also insert the other components required automatically." +)] pub struct ImageBundle { /// Describes the logical size of the node pub node: Node, @@ -108,6 +117,10 @@ pub struct ImageBundle { /// - [`ImageScaleMode`](bevy_sprite::ImageScaleMode) to enable either slicing or tiling of the texture /// - [`TextureAtlas`](bevy_sprite::TextureAtlas) to draw a specific section of the texture #[derive(Bundle, Clone, Debug)] +#[deprecated( + since = "0.15.0", + note = "Use the `Button` component instead. Inserting `Button` will also insert the other components required automatically." +)] pub struct ButtonBundle { /// Describes the logical size of the node pub node: Node, @@ -174,6 +187,10 @@ impl Default for ButtonBundle { /// Adding a `BackgroundColor` component to an entity with this bundle will ignore the custom /// material and use the background color instead. #[derive(Bundle, Clone, Debug)] +#[deprecated( + since = "0.15.0", + note = "Use the `MaterialNode` component instead. Inserting `MaterialNode` will also insert the other components required automatically." +)] pub struct MaterialNodeBundle { /// Describes the logical size of the node pub node: Node, @@ -181,7 +198,7 @@ pub struct MaterialNodeBundle { /// In some cases these styles also affect how the node drawn/painted. pub style: Style, /// The [`UiMaterial`] used to render the node. - pub material: UiMaterialHandle, + pub material: MaterialNode, /// Whether this node should block interaction with lower nodes pub focus_policy: FocusPolicy, /// The transform of the node diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 6a98bd76f28d6..ab86e7b51d4ac 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -65,6 +65,25 @@ pub mod graph { } } +/// Z offsets of "extracted nodes" for a given entity. These exist to allow rendering multiple "extracted nodes" +/// for a given source entity (ex: render both a background color _and_ a custom material for a given node). +/// +/// When possible these offsets should be defined in _this_ module to ensure z-index coordination across contexts. +/// When this is _not_ possible, pick a suitably unique index unlikely to clash with other things (ex: `0.1826823` not `0.1`). +/// +/// Offsets should be unique for a given node entity to avoid z fighting. +/// These should pretty much _always_ be larger than -1.0 and smaller than 1.0 to avoid clipping into nodes +/// above / below the current node in the stack. +/// +/// A z-index of 0.0 is the baseline, which is used as the primary "background color" of the node. +/// +/// Note that nodes "stack" on each other, so a negative offset on the node above could clip _into_ +/// a positive offset on a node below. +pub mod stack_z_offsets { + pub const BACKGROUND_COLOR: f32 = 0.0; + pub const MATERIAL: f32 = 0.18267; +} + pub const UI_SHADER_HANDLE: Handle = Handle::weak_from_u128(13012847047162779583); #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] @@ -823,7 +842,7 @@ pub fn queue_uinodes( pipeline, entity: (*entity, extracted_uinode.main_entity), sort_key: ( - FloatOrd(extracted_uinode.stack_index as f32), + FloatOrd(extracted_uinode.stack_index as f32 + stack_z_offsets::BACKGROUND_COLOR), entity.index(), ), // batch_range will be calculated in prepare_uinodes diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index 8ca8d390f87fe..bbd4d9e4de84d 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -60,9 +60,9 @@ where Shader::from_wgsl ); app.init_asset::() - .register_type::>() + .register_type::>() .add_plugins(( - ExtractComponentPlugin::>::extract_visible(), + ExtractComponentPlugin::>::extract_visible(), RenderAssetPlugin::>::default(), )); @@ -363,18 +363,15 @@ pub fn extract_ui_material_nodes( materials: Extract>>, default_ui_camera: Extract, uinode_query: Extract< - Query< - ( - Entity, - &Node, - &GlobalTransform, - &UiMaterialHandle, - &ViewVisibility, - Option<&CalculatedClip>, - Option<&TargetCamera>, - ), - Without, - >, + Query<( + Entity, + &Node, + &GlobalTransform, + &MaterialNode, + &ViewVisibility, + Option<&CalculatedClip>, + Option<&TargetCamera>, + )>, >, render_entity_lookup: Extract>, ) { @@ -652,7 +649,7 @@ pub fn queue_ui_material_nodes( pipeline, entity: (*entity, extracted_uinode.main_entity), sort_key: ( - FloatOrd(extracted_uinode.stack_index as f32), + FloatOrd(extracted_uinode.stack_index as f32 + stack_z_offsets::MATERIAL), entity.index(), ), batch_range: 0..0, diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index b57e65865e54e..56bf58f37151f 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -1,5 +1,6 @@ use core::hash::Hash; +use crate::Node; use bevy_asset::{Asset, AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{component::Component, reflect::ReflectComponent}; @@ -10,7 +11,7 @@ use bevy_render::{ }; use derive_more::derive::From; -/// Materials are used alongside [`UiMaterialPlugin`](crate::UiMaterialPlugin) and [`MaterialNodeBundle`](crate::prelude::MaterialNodeBundle) +/// Materials are used alongside [`UiMaterialPlugin`](crate::UiMaterialPlugin) and [`MaterialNode`] /// to spawn entities that are rendered with a specific [`UiMaterial`] type. They serve as an easy to use high level /// way to render `Node` entities with custom shader logic. /// @@ -58,17 +59,16 @@ use derive_more::derive::From; /// /// // Spawn an entity using `CustomMaterial`. /// fn setup(mut commands: Commands, mut materials: ResMut>, asset_server: Res) { -/// commands.spawn(MaterialNodeBundle { -/// style: Style { -/// width: Val::Percent(100.0), -/// ..Default::default() -/// }, -/// material: UiMaterialHandle(materials.add(CustomMaterial { +/// commands.spawn(( +/// MaterialNode(materials.add(CustomMaterial { /// color: LinearRgba::RED, /// color_texture: asset_server.load("some_image.png"), /// })), -/// ..Default::default() -/// }); +/// Style { +/// width: Val::Percent(100.0), +/// ..Default::default() +/// }, +/// )); /// } /// ``` /// In WGSL shaders, the material's binding would look like this: @@ -157,22 +157,23 @@ where Component, Clone, Debug, Deref, DerefMut, Reflect, PartialEq, Eq, ExtractComponent, From, )] #[reflect(Component, Default)] -pub struct UiMaterialHandle(pub Handle); +#[require(Node)] +pub struct MaterialNode(pub Handle); -impl Default for UiMaterialHandle { +impl Default for MaterialNode { fn default() -> Self { Self(Handle::default()) } } -impl From> for AssetId { - fn from(material: UiMaterialHandle) -> Self { +impl From> for AssetId { + fn from(material: MaterialNode) -> Self { material.id() } } -impl From<&UiMaterialHandle> for AssetId { - fn from(material: &UiMaterialHandle) -> Self { +impl From<&MaterialNode> for AssetId { + fn from(material: &MaterialNode) -> Self { material.id() } } diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index f6ebd0f0d5b95..2b95bf118a286 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -1,4 +1,4 @@ -use crate::{UiRect, Val}; +use crate::{widget::UiImageSize, ContentSize, FocusPolicy, UiRect, Val}; use bevy_asset::Handle; use bevy_color::Color; use bevy_ecs::{prelude::*, system::SystemParam}; @@ -7,8 +7,10 @@ use bevy_reflect::prelude::*; use bevy_render::{ camera::{Camera, RenderTarget}, texture::{Image, TRANSPARENT_IMAGE_HANDLE}, + view::Visibility, }; use bevy_sprite::BorderRect; +use bevy_transform::components::Transform; use bevy_utils::warn_once; use bevy_window::{PrimaryWindow, WindowRef}; use core::num::NonZero; @@ -25,6 +27,18 @@ use smallvec::SmallVec; /// - [`Interaction`](crate::Interaction) to obtain the interaction state of this node #[derive(Component, Debug, Copy, Clone, PartialEq, Reflect)] #[reflect(Component, Default, Debug)] +#[require( + Style, + BackgroundColor, + BorderColor, + BorderRadius, + ContentSize, + FocusPolicy, + ScrollPosition, + Transform, + Visibility, + ZIndex +)] pub struct Node { /// The order of the node in the UI layout. /// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices. @@ -883,7 +897,7 @@ pub enum Display { /// Use no layout, don't render this node and its children. /// /// If you want to hide a node and its children, - /// but keep its layout in place, set its [`Visibility`](bevy_render::view::Visibility) component instead. + /// but keep its layout in place, set its [`Visibility`] component instead. None, } @@ -1955,22 +1969,20 @@ impl Default for BorderColor { /// The [`Outline`] component adds an outline outside the edge of a UI node. /// Outlines do not take up space in the layout. /// -/// To add an [`Outline`] to a ui node you can spawn a `(NodeBundle, Outline)` tuple bundle: +/// To add an [`Outline`] to a ui node you can spawn a `(Node, Outline)` tuple bundle: /// ``` /// # use bevy_ecs::prelude::*; /// # use bevy_ui::prelude::*; /// # use bevy_color::palettes::basic::{RED, BLUE}; /// fn setup_ui(mut commands: Commands) { /// commands.spawn(( -/// NodeBundle { -/// style: Style { -/// width: Val::Px(100.), -/// height: Val::Px(100.), -/// ..Default::default() -/// }, -/// background_color: BLUE.into(), +/// Node::default(), +/// Style { +/// width: Val::Px(100.), +/// height: Val::Px(100.), /// ..Default::default() /// }, +/// BackgroundColor(BLUE.into()), /// Outline::new(Val::Px(10.), Val::ZERO, RED.into()) /// )); /// } @@ -2032,6 +2044,7 @@ impl Outline { /// The 2D texture displayed for this UI node #[derive(Component, Clone, Debug, Reflect)] #[reflect(Component, Default, Debug)] +#[require(Node, UiImageSize)] pub struct UiImage { /// The tint color used to draw the image. /// @@ -2173,32 +2186,30 @@ pub struct GlobalZIndex(pub i32); /// dimension, either width or height. /// /// # Example -/// ``` +/// ```rust /// # use bevy_ecs::prelude::*; /// # use bevy_ui::prelude::*; /// # use bevy_color::palettes::basic::{BLUE}; /// fn setup_ui(mut commands: Commands) { /// commands.spawn(( -/// NodeBundle { -/// style: Style { -/// width: Val::Px(100.), -/// height: Val::Px(100.), -/// border: UiRect::all(Val::Px(2.)), -/// ..Default::default() -/// }, -/// background_color: BLUE.into(), -/// border_radius: BorderRadius::new( -/// // top left -/// Val::Px(10.), -/// // top right -/// Val::Px(20.), -/// // bottom right -/// Val::Px(30.), -/// // bottom left -/// Val::Px(40.), -/// ), +/// Node::default(), +/// Style { +/// width: Val::Px(100.), +/// height: Val::Px(100.), +/// border: UiRect::all(Val::Px(2.)), /// ..Default::default() /// }, +/// BackgroundColor(BLUE.into()), +/// BorderRadius::new( +/// // top left +/// Val::Px(10.), +/// // top right +/// Val::Px(20.), +/// // bottom right +/// Val::Px(30.), +/// // bottom left +/// Val::Px(40.), +/// ), /// )); /// } /// ``` diff --git a/crates/bevy_ui/src/widget/button.rs b/crates/bevy_ui/src/widget/button.rs index 19fe728b681c3..82ca41b021c31 100644 --- a/crates/bevy_ui/src/widget/button.rs +++ b/crates/bevy_ui/src/widget/button.rs @@ -1,7 +1,9 @@ +use crate::{FocusPolicy, Interaction, Node}; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; /// Marker struct for buttons #[derive(Component, Debug, Default, Clone, Copy, PartialEq, Eq, Reflect)] #[reflect(Component, Default, Debug, PartialEq)] +#[require(Node, FocusPolicy(|| FocusPolicy::Block), Interaction)] pub struct Button; diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 2ffa18a54ad0c..5002eff8ded6f 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -1,6 +1,6 @@ use crate::{ - ContentSize, DefaultUiCamera, FixedMeasure, FocusPolicy, Measure, MeasureArgs, Node, - NodeMeasure, Style, TargetCamera, UiScale, ZIndex, + ContentSize, DefaultUiCamera, FixedMeasure, Measure, MeasureArgs, Node, NodeMeasure, + TargetCamera, UiScale, }; use bevy_asset::Assets; use bevy_color::Color; @@ -16,14 +16,13 @@ use bevy_ecs::{ }; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::{camera::Camera, texture::Image, view::Visibility}; +use bevy_render::{camera::Camera, texture::Image}; use bevy_sprite::TextureAtlasLayout; use bevy_text::{ scale_value, ComputedTextBlock, CosmicFontSystem, Font, FontAtlasSets, LineBreak, SwashCache, TextBounds, TextColor, TextError, TextFont, TextLayout, TextLayoutInfo, TextMeasureInfo, TextPipeline, TextReader, TextRoot, TextSpanAccess, TextWriter, YAxisOrientation, }; -use bevy_transform::components::Transform; use bevy_utils::{tracing::error, Entry}; use taffy::style::AvailableSpace; @@ -67,7 +66,7 @@ pub struct TextBundle {} /// The string in this component is the first 'text span' in a hierarchy of text spans that are collected into /// a [`ComputedTextBlock`]. See [`TextSpan`](bevy_text::TextSpan) for the component used by children of entities with [`Text`]. /// -/// Note that [`Transform`] on this entity is managed automatically by the UI layout system. +/// Note that [`Transform`](bevy_transform::components::Transform) on this entity is managed automatically by the UI layout system. /// /// /// ``` @@ -103,19 +102,7 @@ pub struct TextBundle {} /// ``` #[derive(Component, Debug, Default, Clone, Deref, DerefMut, Reflect)] #[reflect(Component, Default, Debug)] -#[require( - TextLayout, - TextFont, - TextColor, - TextNodeFlags, - Node, - Style, // TODO: Remove when Node uses required components. - ContentSize, // TODO: Remove when Node uses required components. - FocusPolicy, // TODO: Remove when Node uses required components. - ZIndex, // TODO: Remove when Node uses required components. - Visibility, // TODO: Remove when Node uses required components. - Transform // TODO: Remove when Node uses required components. -)] +#[require(TextLayout, TextFont, TextColor, TextNodeFlags, Node)] pub struct Text(pub String); impl Text { diff --git a/examples/3d/auto_exposure.rs b/examples/3d/auto_exposure.rs index 4078d9ccaf986..d7b8b30e29b70 100644 --- a/examples/3d/auto_exposure.rs +++ b/examples/3d/auto_exposure.rs @@ -114,18 +114,17 @@ fn setup( Transform::from_xyz(0.0, 0.0, 0.0), )); - commands.spawn(ImageBundle { - image: UiImage { + commands.spawn(( + UiImage { texture: metering_mask, ..default() }, - style: Style { + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), ..default() }, - ..default() - }); + )); let text_style = TextFont::default(); diff --git a/examples/3d/blend_modes.rs b/examples/3d/blend_modes.rs index bc5e0ae6975d1..797e35c0ddd10 100644 --- a/examples/3d/blend_modes.rs +++ b/examples/3d/blend_modes.rs @@ -192,11 +192,9 @@ fn setup( let mut label = |entity: Entity, label: &str| { commands .spawn(( - NodeBundle { - style: Style { - position_type: PositionType::Absolute, - ..default() - }, + Node::default(), + Style { + position_type: PositionType::Absolute, ..default() }, ExampleLabel { entity }, diff --git a/examples/3d/color_grading.rs b/examples/3d/color_grading.rs index 9aa171a71389f..024c64246da86 100644 --- a/examples/3d/color_grading.rs +++ b/examples/3d/color_grading.rs @@ -138,8 +138,9 @@ fn setup( fn add_buttons(commands: &mut Commands, font: &Handle, color_grading: &ColorGrading) { // Spawn the parent node that contains all the buttons. commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, position_type: PositionType::Absolute, row_gap: Val::Px(6.0), @@ -147,8 +148,7 @@ fn add_buttons(commands: &mut Commands, font: &Handle, color_grading: &Col bottom: Val::Px(12.0), ..default() }, - ..default() - }) + )) .with_children(|parent| { // Create the first row, which contains the global controls. add_buttons_for_global_controls(parent, color_grading, font); @@ -172,36 +172,31 @@ fn add_buttons_for_global_controls( font: &Handle, ) { // Add the parent node for the row. - parent - .spawn(NodeBundle { - style: Style::default(), - ..default() - }) - .with_children(|parent| { - // Add some placeholder text to fill this column. - parent.spawn(NodeBundle { - style: Style { - width: Val::Px(125.0), - ..default() - }, + parent.spawn(Node::default()).with_children(|parent| { + // Add some placeholder text to fill this column. + parent.spawn(( + Node::default(), + Style { + width: Val::Px(125.0), ..default() - }); - - // Add each global color grading option button. - for option in [ - SelectedGlobalColorGradingOption::Exposure, - SelectedGlobalColorGradingOption::Temperature, - SelectedGlobalColorGradingOption::Tint, - SelectedGlobalColorGradingOption::Hue, - ] { - add_button_for_value( - parent, - SelectedColorGradingOption::Global(option), - color_grading, - font, - ); - } - }); + }, + )); + + // Add each global color grading option button. + for option in [ + SelectedGlobalColorGradingOption::Exposure, + SelectedGlobalColorGradingOption::Temperature, + SelectedGlobalColorGradingOption::Tint, + SelectedGlobalColorGradingOption::Hue, + ] { + add_button_for_value( + parent, + SelectedColorGradingOption::Global(option), + color_grading, + font, + ); + } + }); } /// Adds the buttons that control color grading for individual sections @@ -214,13 +209,13 @@ fn add_buttons_for_section( ) { // Spawn the row container. parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { // Spawn the label ("Highlights", etc.) add_text(parent, §ion.to_string(), font, Color::WHITE).insert(Style { @@ -255,8 +250,9 @@ fn add_button_for_value( ) { // Add the button node. parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { border: UiRect::all(Val::Px(1.0)), width: Val::Px(200.0), justify_content: JustifyContent::Center, @@ -265,11 +261,10 @@ fn add_button_for_value( margin: UiRect::right(Val::Px(12.0)), ..default() }, - border_color: BorderColor(Color::WHITE), - border_radius: BorderRadius::MAX, - background_color: Color::BLACK.into(), - ..default() - }) + BorderColor(Color::WHITE), + BorderRadius::MAX, + BackgroundColor(Color::BLACK), + )) .insert(ColorGradingOptionWidget { widget_type: ColorGradingOptionWidgetType::Button, option, @@ -286,13 +281,13 @@ fn add_button_for_value( }); // Add a spacer. - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { flex_grow: 1.0, ..default() }, - ..default() - }); + )); // Add the value text. add_text( diff --git a/examples/3d/pcss.rs b/examples/3d/pcss.rs index 88be6f1e3065c..49b3c93863c50 100644 --- a/examples/3d/pcss.rs +++ b/examples/3d/pcss.rs @@ -209,10 +209,7 @@ fn spawn_gltf_scene(commands: &mut Commands, asset_server: &AssetServer) { /// Spawns all the buttons at the bottom of the screen. fn spawn_buttons(commands: &mut Commands) { commands - .spawn(NodeBundle { - style: widgets::main_ui_style(), - ..default() - }) + .spawn((Node::default(), widgets::main_ui_style())) .with_children(|parent| { widgets::spawn_option_buttons( parent, diff --git a/examples/3d/shadow_biases.rs b/examples/3d/shadow_biases.rs index a35ddcc57797f..640a15c14cd47 100644 --- a/examples/3d/shadow_biases.rs +++ b/examples/3d/shadow_biases.rs @@ -98,15 +98,13 @@ fn setup( commands .spawn(( - NodeBundle { - style: Style { - position_type: PositionType::Absolute, - padding: UiRect::all(Val::Px(5.0)), - ..default() - }, - background_color: Color::BLACK.with_alpha(0.75).into(), + Node::default(), + Style { + position_type: PositionType::Absolute, + padding: UiRect::all(Val::Px(5.0)), ..default() }, + BackgroundColor(Color::BLACK.with_alpha(0.75)), GlobalZIndex(i32::MAX), )) .with_children(|p| { diff --git a/examples/3d/split_screen.rs b/examples/3d/split_screen.rs index f9aaf1aa3b825..c4a0504362eaf 100644 --- a/examples/3d/split_screen.rs +++ b/examples/3d/split_screen.rs @@ -85,12 +85,10 @@ fn setup( commands .spawn(( TargetCamera(camera), - NodeBundle { - style: Style { - width: Val::Percent(100.), - height: Val::Percent(100.), - ..default() - }, + Node::default(), + Style { + width: Val::Percent(100.), + height: Val::Percent(100.), ..default() }, )) @@ -110,8 +108,9 @@ fn setup( fn buttons_panel(parent: &mut ChildBuilder) { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, width: Val::Percent(100.), height: Val::Percent(100.), @@ -122,8 +121,7 @@ fn setup( padding: UiRect::all(Val::Px(20.)), ..default() }, - ..default() - }) + )) .with_children(|parent| { rotate_button(parent, "<", Direction::Left); rotate_button(parent, ">", Direction::Right); @@ -134,19 +132,17 @@ fn setup( parent .spawn(( RotateCamera(direction), - ButtonBundle { - style: Style { - width: Val::Px(40.), - height: Val::Px(40.), - border: UiRect::all(Val::Px(2.)), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, - ..default() - }, - border_color: Color::WHITE.into(), - background_color: Color::srgb(0.25, 0.25, 0.25).into(), + Button, + Style { + width: Val::Px(40.), + height: Val::Px(40.), + border: UiRect::all(Val::Px(2.)), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, ..default() }, + BorderColor(Color::WHITE), + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), )) .with_children(|parent| { parent.spawn(Text::new(caption)); diff --git a/examples/animation/animated_ui.rs b/examples/animation/animated_ui.rs index 76a68c735d9c4..4d66c1e2c3724 100644 --- a/examples/animation/animated_ui.rs +++ b/examples/animation/animated_ui.rs @@ -150,9 +150,10 @@ fn setup( // contains the `AnimationPlayer`, as well as a child node that contains the // text to be animated. commands - .spawn(NodeBundle { + .spawn(( + Node::default(), // Cover the whole screen, and center contents. - style: Style { + Style { position_type: PositionType::Absolute, top: Val::Px(0.0), left: Val::Px(0.0), @@ -162,8 +163,7 @@ fn setup( align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .insert(animation_player) .insert(AnimationGraphHandle(animation_graph)) .with_children(|builder| { diff --git a/examples/animation/animation_graph.rs b/examples/animation/animation_graph.rs index 0f219392a5575..4d181608f53dd 100644 --- a/examples/animation/animation_graph.rs +++ b/examples/animation/animation_graph.rs @@ -283,22 +283,20 @@ fn setup_node_rects(commands: &mut Commands) { let container = { let mut container = commands.spawn(( - NodeBundle { - style: Style { - position_type: PositionType::Absolute, - bottom: Val::Px(node_rect.bottom), - left: Val::Px(node_rect.left), - height: Val::Px(node_rect.height), - width: Val::Px(node_rect.width), - align_items: AlignItems::Center, - justify_items: JustifyItems::Center, - align_content: AlignContent::Center, - justify_content: JustifyContent::Center, - ..default() - }, - border_color: WHITE.into(), + Node::default(), + Style { + position_type: PositionType::Absolute, + bottom: Val::Px(node_rect.bottom), + left: Val::Px(node_rect.left), + height: Val::Px(node_rect.height), + width: Val::Px(node_rect.width), + align_items: AlignItems::Center, + justify_items: JustifyItems::Center, + align_content: AlignContent::Center, + justify_content: JustifyContent::Center, ..default() }, + BorderColor(WHITE.into()), Outline::new(Val::Px(1.), Val::ZERO, Color::WHITE), )); @@ -316,8 +314,9 @@ fn setup_node_rects(commands: &mut Commands) { // Create the background color. if let NodeType::Clip(_) = node_type { let background = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, top: Val::Px(0.), left: Val::Px(0.), @@ -325,9 +324,8 @@ fn setup_node_rects(commands: &mut Commands) { width: Val::Px(node_rect.width), ..default() }, - background_color: DARK_GREEN.into(), - ..default() - }) + BackgroundColor(DARK_GREEN.into()), + )) .id(); commands.entity(container).add_child(background); @@ -343,8 +341,9 @@ fn setup_node_rects(commands: &mut Commands) { /// vertical and horizontal lines, respectively. fn setup_node_lines(commands: &mut Commands) { for line in &HORIZONTAL_LINES { - commands.spawn(NodeBundle { - style: Style { + commands.spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, bottom: Val::Px(line.bottom), left: Val::Px(line.left), @@ -353,14 +352,14 @@ fn setup_node_lines(commands: &mut Commands) { border: UiRect::bottom(Val::Px(1.0)), ..default() }, - border_color: WHITE.into(), - ..default() - }); + BorderColor(WHITE.into()), + )); } for line in &VERTICAL_LINES { - commands.spawn(NodeBundle { - style: Style { + commands.spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, bottom: Val::Px(line.bottom), left: Val::Px(line.left), @@ -369,9 +368,8 @@ fn setup_node_lines(commands: &mut Commands) { border: UiRect::left(Val::Px(1.0)), ..default() }, - border_color: WHITE.into(), - ..default() - }); + BorderColor(WHITE.into()), + )); } } diff --git a/examples/animation/animation_masks.rs b/examples/animation/animation_masks.rs index 6d54e224a102f..1b634142ec7f0 100644 --- a/examples/animation/animation_masks.rs +++ b/examples/animation/animation_masks.rs @@ -168,8 +168,9 @@ fn setup_ui(mut commands: Commands) { // Add the buttons that allow the user to toggle mask groups on and off. commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, position_type: PositionType::Absolute, row_gap: Val::Px(6.0), @@ -177,8 +178,7 @@ fn setup_ui(mut commands: Commands) { bottom: Val::Px(12.0), ..default() }, - ..default() - }) + )) .with_children(|parent| { let row_style = Style { flex_direction: FlexDirection::Row, @@ -189,10 +189,7 @@ fn setup_ui(mut commands: Commands) { add_mask_group_control(parent, "Head", Val::Auto, MASK_GROUP_HEAD); parent - .spawn(NodeBundle { - style: row_style.clone(), - ..default() - }) + .spawn((Node::default(), row_style.clone())) .with_children(|parent| { add_mask_group_control( parent, @@ -209,10 +206,7 @@ fn setup_ui(mut commands: Commands) { }); parent - .spawn(NodeBundle { - style: row_style, - ..default() - }) + .spawn((Node::default(), row_style)) .with_children(|parent| { add_mask_group_control( parent, @@ -251,8 +245,9 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma ); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { border: UiRect::all(Val::Px(1.0)), width, flex_direction: FlexDirection::Column, @@ -262,15 +257,15 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma margin: UiRect::ZERO, ..default() }, - border_color: BorderColor(Color::WHITE), - border_radius: BorderRadius::all(Val::Px(3.0)), - background_color: Color::BLACK.into(), - ..default() - }) + BorderColor(Color::WHITE), + BorderRadius::all(Val::Px(3.0)), + BackgroundColor(Color::BLACK), + )) .with_children(|builder| { builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { border: UiRect::ZERO, width: Val::Percent(100.0), justify_content: JustifyContent::Center, @@ -279,9 +274,8 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma margin: UiRect::ZERO, ..default() }, - background_color: Color::BLACK.into(), - ..default() - }) + BackgroundColor(Color::BLACK), + )) .with_child(( Text::new(label), label_text_style.clone(), @@ -292,8 +286,9 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma )); builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), flex_direction: FlexDirection::Row, justify_content: JustifyContent::Center, @@ -301,9 +296,8 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma border: UiRect::top(Val::Px(1.0)), ..default() }, - border_color: BorderColor(Color::WHITE), - ..default() - }) + BorderColor(Color::WHITE), + )) .with_children(|builder| { for (index, label) in [ AnimationLabel::Run, @@ -315,13 +309,14 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma .enumerate() { builder - .spawn(ButtonBundle { - background_color: if index > 0 { - Color::BLACK.into() + .spawn(( + Button, + BackgroundColor(if index > 0 { + Color::BLACK } else { - Color::WHITE.into() - }, - style: Style { + Color::WHITE + }), + Style { flex_grow: 1.0, border: if index > 0 { UiRect::left(Val::Px(1.0)) @@ -330,9 +325,8 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma }, ..default() }, - border_color: BorderColor(Color::WHITE), - ..default() - }) + BorderColor(Color::WHITE), + )) .with_child(( Text(format!("{:?}", label)), if index > 0 { diff --git a/examples/app/log_layers_ecs.rs b/examples/app/log_layers_ecs.rs index 4577f237020c5..883efde69d6c0 100644 --- a/examples/app/log_layers_ecs.rs +++ b/examples/app/log_layers_ecs.rs @@ -126,14 +126,12 @@ fn setup(mut commands: Commands) { commands.spawn(Camera2d); commands.spawn(( - NodeBundle { - style: Style { - width: Val::Vw(100.0), - height: Val::Vh(100.0), - flex_direction: FlexDirection::Column, - padding: UiRect::all(Val::Px(12.)), - ..default() - }, + Node::default(), + Style { + width: Val::Vw(100.0), + height: Val::Vh(100.0), + flex_direction: FlexDirection::Column, + padding: UiRect::all(Val::Px(12.)), ..default() }, LogViewerRoot, diff --git a/examples/camera/first_person_view_model.rs b/examples/camera/first_person_view_model.rs index bb7bc82470752..f46d518cef7f9 100644 --- a/examples/camera/first_person_view_model.rs +++ b/examples/camera/first_person_view_model.rs @@ -192,15 +192,15 @@ fn spawn_lights(mut commands: Commands) { fn spawn_text(mut commands: Commands) { commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, bottom: Val::Px(12.0), left: Val::Px(12.0), ..default() }, - ..default() - }) + )) .with_child(Text::new(concat!( "Move the camera with your mouse.\n", "Press arrow up to decrease the FOV of the world model.\n", diff --git a/examples/games/alien_cake_addict.rs b/examples/games/alien_cake_addict.rs index 859adb6abbe1e..35b3cdce57600 100644 --- a/examples/games/alien_cake_addict.rs +++ b/examples/games/alien_cake_addict.rs @@ -393,15 +393,15 @@ fn gameover_keyboard( // display the number of cake eaten before losing fn display_score(mut commands: Commands, game: Res) { commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) .with_child(( Text::new(format!("Cake eaten: {}", game.cake_eaten)), TextFont { diff --git a/examples/games/game_menu.rs b/examples/games/game_menu.rs index 6856c51898c5a..d1ba83b9d9236 100644 --- a/examples/games/game_menu.rs +++ b/examples/games/game_menu.rs @@ -75,28 +75,25 @@ mod splash { // Display the logo commands .spawn(( - NodeBundle { - style: Style { - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - width: Val::Percent(100.0), - height: Val::Percent(100.0), - ..default() - }, + Node::default(), + Style { + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + width: Val::Percent(100.0), + height: Val::Percent(100.0), ..default() }, OnSplashScreen, )) .with_children(|parent| { - parent.spawn(ImageBundle { - style: Style { + parent.spawn(( + UiImage::new(icon), + Style { // This will set the logo to be 200px wide, and auto adjust its height width: Val::Px(200.0), ..default() }, - image: UiImage::new(icon), - ..default() - }); + )); }); // Insert the timer as a resource commands.insert_resource(SplashTimer(Timer::from_seconds(1.0, TimerMode::Once))); @@ -144,24 +141,23 @@ mod game { ) { commands .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - // center children - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + // center children + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, ..default() }, OnGameScreen, )) .with_children(|parent| { - // First create a `NodeBundle` for centering what we want to display + // First create a `Node` and `Style` for centering what we want to display parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // This will display its children in a column, from top to bottom flex_direction: FlexDirection::Column, // `align_items` will align children on the cross axis. Here the main axis is @@ -170,9 +166,8 @@ mod game { align_items: AlignItems::Center, ..default() }, - background_color: Color::BLACK.into(), - ..default() - }) + BackgroundColor(Color::BLACK), + )) .with_children(|p| { p.spawn(( Text::new("Will be back to the menu shortly..."), @@ -405,29 +400,27 @@ mod menu { commands .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, ..default() }, OnMainMenuScreen, )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, ..default() }, - background_color: CRIMSON.into(), - ..default() - }) + BackgroundColor(CRIMSON.into()), + )) .with_children(|parent| { // Display the game name parent.spawn(( @@ -449,20 +442,14 @@ mod menu { // - quit parent .spawn(( - ButtonBundle { - style: button_style.clone(), - background_color: NORMAL_BUTTON.into(), - ..default() - }, + Button, + button_style.clone(), + BackgroundColor(NORMAL_BUTTON), MenuButtonAction::Play, )) .with_children(|parent| { let icon = asset_server.load("textures/Game Icons/right.png"); - parent.spawn(ImageBundle { - style: button_icon_style.clone(), - image: UiImage::new(icon), - ..default() - }); + parent.spawn((UiImage::new(icon), button_icon_style.clone())); parent.spawn(( Text::new("New Game"), button_text_font.clone(), @@ -471,20 +458,14 @@ mod menu { }); parent .spawn(( - ButtonBundle { - style: button_style.clone(), - background_color: NORMAL_BUTTON.into(), - ..default() - }, + Button, + button_style.clone(), + BackgroundColor(NORMAL_BUTTON), MenuButtonAction::Settings, )) .with_children(|parent| { let icon = asset_server.load("textures/Game Icons/wrench.png"); - parent.spawn(ImageBundle { - style: button_icon_style.clone(), - image: UiImage::new(icon), - ..default() - }); + parent.spawn((UiImage::new(icon), button_icon_style.clone())); parent.spawn(( Text::new("Settings"), button_text_font.clone(), @@ -493,20 +474,14 @@ mod menu { }); parent .spawn(( - ButtonBundle { - style: button_style, - background_color: NORMAL_BUTTON.into(), - ..default() - }, + Button, + button_style, + BackgroundColor(NORMAL_BUTTON), MenuButtonAction::Quit, )) .with_children(|parent| { let icon = asset_server.load("textures/Game Icons/exitRight.png"); - parent.spawn(ImageBundle { - style: button_icon_style, - image: UiImage::new(icon), - ..default() - }); + parent.spawn((UiImage::new(icon), button_icon_style)); parent.spawn(( Text::new("Quit"), button_text_font, @@ -537,29 +512,27 @@ mod menu { commands .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, ..default() }, OnSettingsMenuScreen, )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, ..default() }, - background_color: CRIMSON.into(), - ..default() - }) + BackgroundColor(CRIMSON.into()), + )) .with_children(|parent| { for (action, text) in [ (MenuButtonAction::SettingsDisplay, "Display"), @@ -568,11 +541,9 @@ mod menu { ] { parent .spawn(( - ButtonBundle { - style: button_style.clone(), - background_color: NORMAL_BUTTON.into(), - ..default() - }, + Button, + button_style.clone(), + BackgroundColor(NORMAL_BUTTON), action, )) .with_children(|parent| { @@ -602,41 +573,39 @@ mod menu { commands .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, ..default() }, OnDisplaySettingsMenuScreen, )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, ..default() }, - background_color: CRIMSON.into(), - ..default() - }) + BackgroundColor(CRIMSON.into()), + )) .with_children(|parent| { - // Create a new `NodeBundle`, this time not setting its `flex_direction`. It will + // Create a new `Node` and `Style` , this time not setting its `flex_direction`. It will // use the default value, `FlexDirection::Row`, from left to right. parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { align_items: AlignItems::Center, ..default() }, - background_color: CRIMSON.into(), - ..default() - }) + BackgroundColor(CRIMSON.into()), + )) .with_children(|parent| { // Display a label for the current setting parent.spawn(( @@ -650,15 +619,13 @@ mod menu { DisplayQuality::High, ] { let mut entity = parent.spawn(( - ButtonBundle { - style: Style { - width: Val::Px(150.0), - height: Val::Px(65.0), - ..button_style.clone() - }, - background_color: NORMAL_BUTTON.into(), - ..default() + Button, + Style { + width: Val::Px(150.0), + height: Val::Px(65.0), + ..button_style.clone() }, + BackgroundColor(NORMAL_BUTTON), quality_setting, )); entity.with_children(|parent| { @@ -675,11 +642,9 @@ mod menu { // Display the back button to return to the settings screen parent .spawn(( - ButtonBundle { - style: button_style, - background_color: NORMAL_BUTTON.into(), - ..default() - }, + Button, + button_style, + BackgroundColor(NORMAL_BUTTON), MenuButtonAction::BackToSettings, )) .with_children(|parent| { @@ -708,52 +673,48 @@ mod menu { commands .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, ..default() }, OnSoundSettingsMenuScreen, )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, ..default() }, - background_color: CRIMSON.into(), - ..default() - }) + BackgroundColor(CRIMSON.into()), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { align_items: AlignItems::Center, ..default() }, - background_color: CRIMSON.into(), - ..default() - }) + BackgroundColor(CRIMSON.into()), + )) .with_children(|parent| { parent.spawn((Text::new("Volume"), button_text_style.clone())); for volume_setting in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] { let mut entity = parent.spawn(( - ButtonBundle { - style: Style { - width: Val::Px(30.0), - height: Val::Px(65.0), - ..button_style.clone() - }, - background_color: NORMAL_BUTTON.into(), - ..default() + Button, + Style { + width: Val::Px(30.0), + height: Val::Px(65.0), + ..button_style.clone() }, + BackgroundColor(NORMAL_BUTTON), Volume(volume_setting), )); if *volume == Volume(volume_setting) { @@ -763,11 +724,9 @@ mod menu { }); parent .spawn(( - ButtonBundle { - style: button_style, - background_color: NORMAL_BUTTON.into(), - ..default() - }, + Button, + button_style, + BackgroundColor(NORMAL_BUTTON), MenuButtonAction::BackToSettings, )) .with_child((Text::new("Back"), button_text_style)); diff --git a/examples/games/loading_screen.rs b/examples/games/loading_screen.rs index 55fe969b48dd6..6fa7881eb3984 100644 --- a/examples/games/loading_screen.rs +++ b/examples/games/loading_screen.rs @@ -82,15 +82,15 @@ fn setup(mut commands: Commands) { ..default() }; commands - .spawn(NodeBundle { - background_color: BackgroundColor(Color::NONE), - style: Style { + .spawn(( + Node::default(), + BackgroundColor(Color::NONE), + Style { justify_self: JustifySelf::Center, align_self: AlignSelf::FlexEnd, ..default() }, - ..default() - }) + )) .with_child((Text::new("Press 1 or 2 to load a new scene."), text_style)); } @@ -257,15 +257,13 @@ fn load_loading_screen(mut commands: Commands) { // Spawn the UI that will make up the loading screen. commands .spawn(( - NodeBundle { - background_color: BackgroundColor(Color::BLACK), - style: Style { - height: Val::Percent(100.0), - width: Val::Percent(100.0), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, - ..default() - }, + Node::default(), + BackgroundColor(Color::BLACK), + Style { + height: Val::Percent(100.0), + width: Val::Percent(100.0), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, ..default() }, LoadingScreen, diff --git a/examples/helpers/widgets.rs b/examples/helpers/widgets.rs index 15ba09d934eae..aba8d9544608f 100644 --- a/examples/helpers/widgets.rs +++ b/examples/helpers/widgets.rs @@ -58,8 +58,9 @@ pub fn spawn_option_button( // Add the button node. parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { border: UiRect::all(Val::Px(1.0)).with_left(if is_first { Val::Px(1.0) } else { @@ -70,13 +71,12 @@ pub fn spawn_option_button( padding: UiRect::axes(Val::Px(12.0), Val::Px(6.0)), ..default() }, - border_color: BorderColor(Color::WHITE), - border_radius: BorderRadius::ZERO + BorderColor(Color::WHITE), + BorderRadius::ZERO .with_left(if is_first { Val::Px(6.0) } else { Val::Px(0.0) }) .with_right(if is_last { Val::Px(6.0) } else { Val::Px(0.0) }), - background_color: BackgroundColor(bg_color), - ..default() - }) + BackgroundColor(bg_color), + )) .insert(RadioButton) .insert(WidgetClickSender(option_value.clone())) .with_children(|parent| { @@ -97,13 +97,13 @@ where { // Add the parent node for the row. parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { spawn_ui_text(parent, title, Color::BLACK).insert(Style { width: Val::Px(125.0), diff --git a/examples/math/cubic_splines.rs b/examples/math/cubic_splines.rs index cff35683b6e02..d8c87dba50748 100644 --- a/examples/math/cubic_splines.rs +++ b/examples/math/cubic_splines.rs @@ -78,8 +78,9 @@ fn setup(mut commands: Commands) { let style = TextFont::default(); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, top: Val::Px(12.0), left: Val::Px(12.0), @@ -87,8 +88,7 @@ fn setup(mut commands: Commands) { row_gap: Val::Px(20.0), ..default() }, - ..default() - }) + )) .with_children(|parent| { parent.spawn((Text::new(instructions_text), style.clone())); parent.spawn((SplineModeText, Text(spline_mode_text), style.clone())); diff --git a/examples/math/render_primitives.rs b/examples/math/render_primitives.rs index 879c3320b1dc6..e652240b3428b 100644 --- a/examples/math/render_primitives.rs +++ b/examples/math/render_primitives.rs @@ -370,12 +370,10 @@ fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) { commands .spawn(( HeaderNode, - NodeBundle { - style: Style { - justify_self: JustifySelf::Center, - top: Val::Px(5.0), - ..Default::default() - }, + Node::default(), + Style { + justify_self: JustifySelf::Center, + top: Val::Px(5.0), ..Default::default() }, TargetCamera(active_camera), diff --git a/examples/mobile/src/lib.rs b/examples/mobile/src/lib.rs index 531952cff71ed..93a905c647977 100644 --- a/examples/mobile/src/lib.rs +++ b/examples/mobile/src/lib.rs @@ -114,8 +114,9 @@ fn setup_scene( // Test ui commands - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { justify_content: JustifyContent::Center, align_items: AlignItems::Center, position_type: PositionType::Absolute, @@ -124,8 +125,7 @@ fn setup_scene( bottom: Val::Px(50.0), ..default() }, - ..default() - }) + )) .with_child(( Text::new("Test Button"), TextFont { diff --git a/examples/movement/physics_in_fixed_timestep.rs b/examples/movement/physics_in_fixed_timestep.rs index 8159b49e8e50b..2b572e5962baa 100644 --- a/examples/movement/physics_in_fixed_timestep.rs +++ b/examples/movement/physics_in_fixed_timestep.rs @@ -145,15 +145,15 @@ fn spawn_player(mut commands: Commands, asset_server: Res) { /// Spawn a bit of UI text to explain how to move the player. fn spawn_text(mut commands: Commands) { commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { position_type: PositionType::Absolute, bottom: Val::Px(12.0), left: Val::Px(12.0), ..default() }, - ..default() - }) + )) .with_child(( Text::new("Move the player with WASD"), TextFont { diff --git a/examples/state/computed_states.rs b/examples/state/computed_states.rs index 54dc6b2c88ca6..96101650d7c58 100644 --- a/examples/state/computed_states.rs +++ b/examples/state/computed_states.rs @@ -336,8 +336,9 @@ mod ui { pub fn setup_menu(mut commands: Commands, tutorial_state: Res>) { let button_entity = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // center button width: Val::Percent(100.), height: Val::Percent(100.), @@ -347,24 +348,21 @@ mod ui { row_gap: Val::Px(10.), ..default() }, - ..default() - }) + )) .with_children(|parent| { parent .spawn(( - ButtonBundle { - style: Style { - width: Val::Px(200.), - height: Val::Px(65.), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - ..default() - }, - background_color: NORMAL_BUTTON.into(), + Button, + Style { + width: Val::Px(200.), + height: Val::Px(65.), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, ..default() }, + BackgroundColor(NORMAL_BUTTON), MenuButton::Play, )) .with_children(|parent| { @@ -380,23 +378,20 @@ mod ui { parent .spawn(( - ButtonBundle { - style: Style { - width: Val::Px(200.), - height: Val::Px(65.), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - ..default() - }, - background_color: match tutorial_state.get() { - TutorialState::Active => ACTIVE_BUTTON, - TutorialState::Inactive => NORMAL_BUTTON, - } - .into(), + Button, + Style { + width: Val::Px(200.), + height: Val::Px(65.), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, ..default() }, + BackgroundColor(match tutorial_state.get() { + TutorialState::Active => ACTIVE_BUTTON, + TutorialState::Inactive => NORMAL_BUTTON, + }), MenuButton::Tutorial, )) .with_children(|parent| { @@ -464,37 +459,33 @@ mod ui { commands .spawn(( StateScoped(IsPaused::Paused), - NodeBundle { - style: Style { - // center button - width: Val::Percent(100.), - height: Val::Percent(100.), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, - flex_direction: FlexDirection::Column, - row_gap: Val::Px(10.), - position_type: PositionType::Absolute, - ..default() - }, + Node::default(), + Style { + // center button + width: Val::Percent(100.), + height: Val::Percent(100.), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + flex_direction: FlexDirection::Column, + row_gap: Val::Px(10.), + position_type: PositionType::Absolute, ..default() }, )) .with_children(|parent| { parent .spawn(( - NodeBundle { - style: Style { - width: Val::Px(400.), - height: Val::Px(400.), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - ..default() - }, - background_color: NORMAL_BUTTON.into(), + Node::default(), + Style { + width: Val::Px(400.), + height: Val::Px(400.), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, ..default() }, + BackgroundColor(NORMAL_BUTTON), MenuButton::Play, )) .with_children(|parent| { @@ -514,18 +505,16 @@ mod ui { commands .spawn(( StateScoped(TurboMode), - NodeBundle { - style: Style { - // center button - width: Val::Percent(100.), - height: Val::Percent(100.), - justify_content: JustifyContent::Start, - align_items: AlignItems::Center, - flex_direction: FlexDirection::Column, - row_gap: Val::Px(10.), - position_type: PositionType::Absolute, - ..default() - }, + Node::default(), + Style { + // center button + width: Val::Percent(100.), + height: Val::Percent(100.), + justify_content: JustifyContent::Start, + align_items: AlignItems::Center, + flex_direction: FlexDirection::Column, + row_gap: Val::Px(10.), + position_type: PositionType::Absolute, ..default() }, )) @@ -556,18 +545,16 @@ mod ui { commands .spawn(( StateScoped(Tutorial::MovementInstructions), - NodeBundle { - style: Style { - // center button - width: Val::Percent(100.), - height: Val::Percent(100.), - justify_content: JustifyContent::End, - align_items: AlignItems::Center, - flex_direction: FlexDirection::Column, - row_gap: Val::Px(10.), - position_type: PositionType::Absolute, - ..default() - }, + Node::default(), + Style { + // center button + width: Val::Percent(100.), + height: Val::Percent(100.), + justify_content: JustifyContent::End, + align_items: AlignItems::Center, + flex_direction: FlexDirection::Column, + row_gap: Val::Px(10.), + position_type: PositionType::Absolute, ..default() }, )) @@ -613,18 +600,16 @@ mod ui { commands .spawn(( StateScoped(Tutorial::PauseInstructions), - NodeBundle { - style: Style { - // center button - width: Val::Percent(100.), - height: Val::Percent(100.), - justify_content: JustifyContent::End, - align_items: AlignItems::Center, - flex_direction: FlexDirection::Column, - row_gap: Val::Px(10.), - position_type: PositionType::Absolute, - ..default() - }, + Node::default(), + Style { + // center button + width: Val::Percent(100.), + height: Val::Percent(100.), + justify_content: JustifyContent::End, + align_items: AlignItems::Center, + flex_direction: FlexDirection::Column, + row_gap: Val::Px(10.), + position_type: PositionType::Absolute, ..default() }, )) diff --git a/examples/state/custom_transitions.rs b/examples/state/custom_transitions.rs index a7f7f9ddb4d4d..c52b85f7a93ff 100644 --- a/examples/state/custom_transitions.rs +++ b/examples/state/custom_transitions.rs @@ -243,8 +243,9 @@ const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35); fn setup_menu(mut commands: Commands) { let button_entity = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // center button width: Val::Percent(100.), height: Val::Percent(100.), @@ -252,12 +253,12 @@ fn setup_menu(mut commands: Commands) { align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { width: Val::Px(150.), height: Val::Px(65.), // horizontally center child text @@ -266,9 +267,8 @@ fn setup_menu(mut commands: Commands) { align_items: AlignItems::Center, ..default() }, - background_color: NORMAL_BUTTON.into(), - ..default() - }) + BackgroundColor(NORMAL_BUTTON), + )) .with_children(|parent| { parent.spawn(( Text::new("Play"), diff --git a/examples/state/states.rs b/examples/state/states.rs index 9f431fe654311..9fc7f6b362f2d 100644 --- a/examples/state/states.rs +++ b/examples/state/states.rs @@ -51,8 +51,9 @@ fn setup(mut commands: Commands) { fn setup_menu(mut commands: Commands) { let button_entity = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // center button width: Val::Percent(100.), height: Val::Percent(100.), @@ -60,12 +61,12 @@ fn setup_menu(mut commands: Commands) { align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { width: Val::Px(150.), height: Val::Px(65.), // horizontally center child text @@ -74,9 +75,8 @@ fn setup_menu(mut commands: Commands) { align_items: AlignItems::Center, ..default() }, - background_color: NORMAL_BUTTON.into(), - ..default() - }) + BackgroundColor(NORMAL_BUTTON), + )) .with_children(|parent| { parent.spawn(( Text::new("Play"), diff --git a/examples/state/sub_states.rs b/examples/state/sub_states.rs index 61b804bf0d0b9..528a9471a092e 100644 --- a/examples/state/sub_states.rs +++ b/examples/state/sub_states.rs @@ -156,8 +156,9 @@ mod ui { pub fn setup_menu(mut commands: Commands) { let button_entity = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // center button width: Val::Percent(100.), height: Val::Percent(100.), @@ -165,12 +166,12 @@ mod ui { align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { width: Val::Px(150.), height: Val::Px(65.), // horizontally center child text @@ -179,9 +180,8 @@ mod ui { align_items: AlignItems::Center, ..default() }, - background_color: NORMAL_BUTTON.into(), - ..default() - }) + BackgroundColor(NORMAL_BUTTON), + )) .with_children(|parent| { parent.spawn(( Text::new("Play"), @@ -205,24 +205,23 @@ mod ui { commands .spawn(( StateScoped(IsPaused::Paused), - NodeBundle { - style: Style { - // center button - width: Val::Percent(100.), - height: Val::Percent(100.), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, - flex_direction: FlexDirection::Column, - row_gap: Val::Px(10.), - ..default() - }, + Node::default(), + Style { + // center button + width: Val::Percent(100.), + height: Val::Percent(100.), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + flex_direction: FlexDirection::Column, + row_gap: Val::Px(10.), ..default() }, )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(400.), height: Val::Px(400.), // horizontally center child text @@ -231,9 +230,8 @@ mod ui { align_items: AlignItems::Center, ..default() }, - background_color: NORMAL_BUTTON.into(), - ..default() - }) + BackgroundColor(NORMAL_BUTTON), + )) .with_children(|parent| { parent.spawn(( Text::new("Paused"), diff --git a/examples/stress_tests/bevymark.rs b/examples/stress_tests/bevymark.rs index 83153ed898de2..f320eac0e1229 100644 --- a/examples/stress_tests/bevymark.rs +++ b/examples/stress_tests/bevymark.rs @@ -261,15 +261,13 @@ fn setup( commands.spawn(Camera2d); commands .spawn(( - NodeBundle { - style: Style { - position_type: PositionType::Absolute, - padding: UiRect::all(Val::Px(5.0)), - ..default() - }, - background_color: Color::BLACK.with_alpha(0.75).into(), + Node::default(), + Style { + position_type: PositionType::Absolute, + padding: UiRect::all(Val::Px(5.0)), ..default() }, + BackgroundColor(Color::BLACK.with_alpha(0.75)), GlobalZIndex(i32::MAX), )) .with_children(|p| { diff --git a/examples/stress_tests/many_buttons.rs b/examples/stress_tests/many_buttons.rs index f5e9c3405469b..3abe9cfd9cd24 100644 --- a/examples/stress_tests/many_buttons.rs +++ b/examples/stress_tests/many_buttons.rs @@ -138,8 +138,9 @@ fn setup_flex(mut commands: Commands, asset_server: Res, args: Res< let as_rainbow = |i: usize| Color::hsl((i as f32 / buttons_f) * 360.0, 0.9, 0.8); commands.spawn(Camera2d); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, align_items: AlignItems::Center, @@ -147,32 +148,29 @@ fn setup_flex(mut commands: Commands, asset_server: Res, args: Res< height: Val::Percent(100.), ..default() }, - ..default() - }) + )) .with_children(|commands| { for column in 0..args.buttons { - commands - .spawn(NodeBundle::default()) - .with_children(|commands| { - for row in 0..args.buttons { - let color = as_rainbow(row % column.max(1)); - let border_color = Color::WHITE.with_alpha(0.5).into(); - spawn_button( - commands, - color, - buttons_f, - column, - row, - !args.no_text, - border, - border_color, - image - .as_ref() - .filter(|_| (column + row) % args.image_freq == 0) - .cloned(), - ); - } - }); + commands.spawn(Node::default()).with_children(|commands| { + for row in 0..args.buttons { + let color = as_rainbow(row % column.max(1)); + let border_color = Color::WHITE.with_alpha(0.5).into(); + spawn_button( + commands, + color, + buttons_f, + column, + row, + !args.no_text, + border, + border_color, + image + .as_ref() + .filter(|_| (column + row) % args.image_freq == 0) + .cloned(), + ); + } + }); } }); } @@ -195,8 +193,9 @@ fn setup_grid(mut commands: Commands, asset_server: Res, args: Res< let as_rainbow = |i: usize| Color::hsl((i as f32 / buttons_f) * 360.0, 0.9, 0.8); commands.spawn(Camera2d); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Grid, width: Val::Percent(100.), height: Val::Percent(100.0), @@ -204,8 +203,7 @@ fn setup_grid(mut commands: Commands, asset_server: Res, args: Res< grid_template_rows: RepeatedGridTrack::flex(args.buttons as u16, 1.0), ..default() }, - ..default() - }) + )) .with_children(|commands| { for column in 0..args.buttons { for row in 0..args.buttons { @@ -246,20 +244,18 @@ fn spawn_button( let height = Val::Vh(90.0 / buttons); let margin = UiRect::axes(width * 0.05, height * 0.05); let mut builder = commands.spawn(( - ButtonBundle { - style: Style { - width, - height, - margin, - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - border, - ..default() - }, - background_color: background_color.into(), - border_color, + Button, + Style { + width, + height, + margin, + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + border, ..default() }, + BackgroundColor(background_color), + border_color, IdleColor(background_color), )); diff --git a/examples/stress_tests/many_glyphs.rs b/examples/stress_tests/many_glyphs.rs index 42da29b7cbf61..b02b93bef815a 100644 --- a/examples/stress_tests/many_glyphs.rs +++ b/examples/stress_tests/many_glyphs.rs @@ -56,24 +56,24 @@ fn setup(mut commands: Commands) { }; commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) .with_children(|commands| { commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(1000.), ..Default::default() }, - ..Default::default() - }) + )) .with_child((Text(text_string.clone()), text_font.clone(), text_block)); }); diff --git a/examples/time/virtual_time.rs b/examples/time/virtual_time.rs index f4ddd804afc60..ee0a87be9f105 100644 --- a/examples/time/virtual_time.rs +++ b/examples/time/virtual_time.rs @@ -77,8 +77,9 @@ fn setup(mut commands: Commands, asset_server: Res, mut time: ResMu let font_size = 33.; commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Flex, justify_content: JustifyContent::SpaceBetween, width: Val::Percent(100.), @@ -87,8 +88,7 @@ fn setup(mut commands: Commands, asset_server: Res, mut time: ResMu padding: UiRect::all(Val::Px(20.0)), ..default() }, - ..default() - }) + )) .with_children(|builder| { // real time info builder.spawn(( diff --git a/examples/ui/borders.rs b/examples/ui/borders.rs index e75bb0b897745..5df8cfaa1ebb7 100644 --- a/examples/ui/borders.rs +++ b/examples/ui/borders.rs @@ -12,8 +12,9 @@ fn main() { fn setup(mut commands: Commands) { commands.spawn(Camera2d); let root = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin: UiRect::all(Val::Px(25.0)), align_self: AlignSelf::Stretch, justify_self: JustifySelf::Stretch, @@ -21,16 +22,16 @@ fn setup(mut commands: Commands) { justify_content: JustifyContent::FlexStart, align_items: AlignItems::FlexStart, align_content: AlignContent::FlexStart, - ..Default::default() + ..default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .id(); let root_rounded = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin: UiRect::all(Val::Px(25.0)), align_self: AlignSelf::Stretch, justify_self: JustifySelf::Stretch, @@ -38,11 +39,10 @@ fn setup(mut commands: Commands) { justify_content: JustifyContent::FlexStart, align_items: AlignItems::FlexStart, align_content: AlignContent::FlexStart, - ..Default::default() + ..default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .id(); // labels for the different border edges @@ -124,32 +124,30 @@ fn setup(mut commands: Commands) { for (label, border) in border_labels.into_iter().zip(borders) { let inner_spot = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(10.), height: Val::Px(10.), - ..Default::default() + ..default() }, - background_color: YELLOW.into(), - ..Default::default() - }) + BackgroundColor(YELLOW.into()), + )) .id(); let border_node = commands .spawn(( - NodeBundle { - style: Style { - width: Val::Px(50.), - height: Val::Px(50.), - border, - margin: UiRect::all(Val::Px(20.)), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..Default::default() - }, - background_color: MAROON.into(), - border_color: RED.into(), - ..Default::default() + Node::default(), + Style { + width: Val::Px(50.), + height: Val::Px(50.), + border, + margin: UiRect::all(Val::Px(20.)), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + ..default() }, + BackgroundColor(MAROON.into()), + BorderColor(RED.into()), Outline { width: Val::Px(6.), offset: Val::Px(6.), @@ -168,14 +166,14 @@ fn setup(mut commands: Commands) { )) .id(); let container = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .add_children(&[border_node, label_node]) .id(); commands.entity(root).add_child(container); @@ -183,16 +181,16 @@ fn setup(mut commands: Commands) { for (label, border) in border_labels.into_iter().zip(borders) { let inner_spot = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(10.), height: Val::Px(10.), - ..Default::default() + ..default() }, - border_radius: BorderRadius::MAX, - background_color: YELLOW.into(), - ..Default::default() - }) + BorderRadius::MAX, + BackgroundColor(YELLOW.into()), + )) .id(); let non_zero = |x, y| x != Val::Px(0.) && y != Val::Px(0.); let border_size = |x, y| if non_zero(x, y) { f32::MAX } else { 0. }; @@ -204,21 +202,19 @@ fn setup(mut commands: Commands) { ); let border_node = commands .spawn(( - NodeBundle { - style: Style { - width: Val::Px(50.), - height: Val::Px(50.), - border, - margin: UiRect::all(Val::Px(20.)), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..Default::default() - }, - background_color: MAROON.into(), - border_color: RED.into(), - border_radius, - ..Default::default() + Node::default(), + Style { + width: Val::Px(50.), + height: Val::Px(50.), + border, + margin: UiRect::all(Val::Px(20.)), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + ..default() }, + BackgroundColor(MAROON.into()), + BorderColor(RED.into()), + border_radius, Outline { width: Val::Px(6.), offset: Val::Px(6.), @@ -237,33 +233,33 @@ fn setup(mut commands: Commands) { )) .id(); let container = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .add_children(&[border_node, label_node]) .id(); commands.entity(root_rounded).add_child(container); } let border_label = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin: UiRect { left: Val::Px(25.0), right: Val::Px(25.0), top: Val::Px(25.0), bottom: Val::Px(0.0), }, - ..Default::default() + ..default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .with_children(|builder| { builder.spawn(( Text::new("Borders"), @@ -276,19 +272,19 @@ fn setup(mut commands: Commands) { .id(); let border_rounded_label = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin: UiRect { left: Val::Px(25.0), right: Val::Px(25.0), top: Val::Px(25.0), bottom: Val::Px(0.0), }, - ..Default::default() + ..default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .with_children(|builder| { builder.spawn(( Text::new("Borders Rounded"), @@ -301,8 +297,9 @@ fn setup(mut commands: Commands) { .id(); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin: UiRect::all(Val::Px(25.0)), flex_direction: FlexDirection::Column, align_self: AlignSelf::Stretch, @@ -311,11 +308,10 @@ fn setup(mut commands: Commands) { justify_content: JustifyContent::FlexStart, align_items: AlignItems::FlexStart, align_content: AlignContent::FlexStart, - ..Default::default() + ..default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .add_child(border_label) .add_child(root) .add_child(border_rounded_label) diff --git a/examples/ui/box_shadow.rs b/examples/ui/box_shadow.rs index 0ab38518f1b63..03ece8bdfa7ba 100644 --- a/examples/ui/box_shadow.rs +++ b/examples/ui/box_shadow.rs @@ -34,8 +34,9 @@ fn setup(mut commands: Commands) { commands.spawn((Camera2d, UiBoxShadowSamples(args.samples))); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), padding: UiRect::all(Val::Px(30.)), @@ -43,9 +44,8 @@ fn setup(mut commands: Commands) { flex_wrap: FlexWrap::Wrap, ..default() }, - background_color: BackgroundColor(DEEP_SKY_BLUE.into()), - ..Default::default() - }) + BackgroundColor(DEEP_SKY_BLUE.into()), + )) .with_children(|commands| { let example_nodes = [ ( @@ -201,18 +201,16 @@ fn box_shadow_node_bundle( border_radius: BorderRadius, ) -> impl Bundle { ( - NodeBundle { - style: Style { - width: Val::Px(size.x), - height: Val::Px(size.y), - border: UiRect::all(Val::Px(4.)), - ..default() - }, - border_color: BorderColor(LIGHT_SKY_BLUE.into()), - border_radius, - background_color: BackgroundColor(DEEP_SKY_BLUE.into()), - ..Default::default() + Node::default(), + Style { + width: Val::Px(size.x), + height: Val::Px(size.y), + border: UiRect::all(Val::Px(4.)), + ..default() }, + BorderColor(LIGHT_SKY_BLUE.into()), + border_radius, + BackgroundColor(DEEP_SKY_BLUE.into()), BoxShadow { color: Color::BLACK.with_alpha(0.8), x_offset: Val::Percent(offset.x), diff --git a/examples/ui/button.rs b/examples/ui/button.rs index d465ee2f837ef..b99c110d78059 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -55,20 +55,21 @@ fn setup(mut commands: Commands, asset_server: Res) { // ui camera commands.spawn(Camera2d); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { width: Val::Px(150.0), height: Val::Px(65.0), border: UiRect::all(Val::Px(5.0)), @@ -78,11 +79,10 @@ fn setup(mut commands: Commands, asset_server: Res) { align_items: AlignItems::Center, ..default() }, - border_color: BorderColor(Color::BLACK), - border_radius: BorderRadius::MAX, - background_color: NORMAL_BUTTON.into(), - ..default() - }) + BorderColor(Color::BLACK), + BorderRadius::MAX, + BackgroundColor(NORMAL_BUTTON), + )) .with_child(( Text::new("Button"), TextFont { diff --git a/examples/ui/display_and_visibility.rs b/examples/ui/display_and_visibility.rs index e6bb42a1571c2..309e5105b212d 100644 --- a/examples/ui/display_and_visibility.rs +++ b/examples/ui/display_and_visibility.rs @@ -82,8 +82,8 @@ fn setup(mut commands: Commands, asset_server: Res) { }; commands.spawn(Camera2d); - commands.spawn(NodeBundle { - style: Style { + commands.spawn((Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), flex_direction: FlexDirection::Column, @@ -91,9 +91,8 @@ fn setup(mut commands: Commands, asset_server: Res) { justify_content: JustifyContent::SpaceEvenly, ..Default::default() }, - background_color: BackgroundColor(Color::BLACK), - ..Default::default() - }).with_children(|parent| { + BackgroundColor(Color::BLACK), + )).with_children(|parent| { parent.spawn((Text::new("Use the panel on the right to change the Display and Visibility properties for the respective nodes of the panel on the left"), text_font.clone(), TextLayout::new_with_justify(JustifyText::Center), @@ -104,48 +103,49 @@ fn setup(mut commands: Commands, asset_server: Res) { )); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|parent| { let mut target_ids = vec![]; - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Percent(50.), height: Val::Px(520.), justify_content: JustifyContent::Center, - ..Default::default() + ..default() }, - ..Default::default() - }).with_children(|parent| { + )).with_children(|parent| { target_ids = spawn_left_panel(parent, &palette); }); - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Percent(50.), justify_content: JustifyContent::Center, - ..Default::default() + ..default() }, - ..Default::default() - }).with_children(|parent| { + )).with_children(|parent| { spawn_right_panel(parent, text_font, &palette, target_ids); }); }); - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Row, align_items: AlignItems::Start, justify_content: JustifyContent::Start, column_gap: Val::Px(10.), - ..Default::default() + ..default() }, - ..default() }) + )) .with_children(|builder| { let text_font = TextFont { font: asset_server.load("fonts/FiraSans-Bold.ttf"), @@ -172,93 +172,90 @@ fn setup(mut commands: Commands, asset_server: Res) { fn spawn_left_panel(builder: &mut ChildBuilder, palette: &[Color; 4]) -> Vec { let mut target_ids = vec![]; builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { padding: UiRect::all(Val::Px(10.)), - ..Default::default() + ..default() }, - background_color: BackgroundColor(Color::WHITE), - ..Default::default() - }) + BackgroundColor(Color::WHITE), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - background_color: BackgroundColor(Color::BLACK), - ..Default::default() - }) + .spawn((Node::default(), BackgroundColor(Color::BLACK))) .with_children(|parent| { let id = parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { align_items: AlignItems::FlexEnd, justify_content: JustifyContent::FlexEnd, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[0]), - ..Default::default() - }) + BackgroundColor(palette[0]), + )) .with_children(|parent| { - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Px(100.), height: Val::Px(500.), - ..Default::default() + ..default() }, - ..Default::default() - }); + )); let id = parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { height: Val::Px(400.), align_items: AlignItems::FlexEnd, justify_content: JustifyContent::FlexEnd, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[1]), - ..Default::default() - }) + BackgroundColor(palette[1]), + )) .with_children(|parent| { - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Px(100.), height: Val::Px(400.), - ..Default::default() + ..default() }, - ..Default::default() - }); + )); let id = parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { height: Val::Px(300.), align_items: AlignItems::FlexEnd, justify_content: JustifyContent::FlexEnd, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[2]), - ..Default::default() - }) + BackgroundColor(palette[2]), + )) .with_children(|parent| { - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Px(100.), height: Val::Px(300.), - ..Default::default() + ..default() }, - ..Default::default() - }); + )); let id = parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(200.), height: Val::Px(200.), - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[3]), - ..Default::default() - }) + BackgroundColor(palette[3]), + )) .id(); target_ids.push(id); }) @@ -286,18 +283,19 @@ fn spawn_right_panel( spawn_button::(parent, text_font.clone(), target_id); }; parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { padding: UiRect::all(Val::Px(10.)), - ..Default::default() + ..default() }, - background_color: BackgroundColor(Color::WHITE), - ..Default::default() - }) + BackgroundColor(Color::WHITE), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(500.), height: Val::Px(500.), flex_direction: FlexDirection::Column, @@ -306,19 +304,19 @@ fn spawn_right_panel( padding: UiRect { left: Val::Px(5.), top: Val::Px(5.), - ..Default::default() + ..default() }, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[0]), - ..Default::default() - }) + BackgroundColor(palette[0]), + )) .with_children(|parent| { spawn_buttons(parent, target_ids.pop().unwrap()); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(400.), height: Val::Px(400.), flex_direction: FlexDirection::Column, @@ -327,19 +325,19 @@ fn spawn_right_panel( padding: UiRect { left: Val::Px(5.), top: Val::Px(5.), - ..Default::default() + ..default() }, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[1]), - ..Default::default() - }) + BackgroundColor(palette[1]), + )) .with_children(|parent| { spawn_buttons(parent, target_ids.pop().unwrap()); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(300.), height: Val::Px(300.), flex_direction: FlexDirection::Column, @@ -348,19 +346,19 @@ fn spawn_right_panel( padding: UiRect { left: Val::Px(5.), top: Val::Px(5.), - ..Default::default() + ..default() }, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[2]), - ..Default::default() - }) + BackgroundColor(palette[2]), + )) .with_children(|parent| { spawn_buttons(parent, target_ids.pop().unwrap()); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(200.), height: Val::Px(200.), align_items: AlignItems::FlexStart, @@ -369,24 +367,23 @@ fn spawn_right_panel( padding: UiRect { left: Val::Px(5.), top: Val::Px(5.), - ..Default::default() + ..default() }, - ..Default::default() + ..default() }, - background_color: BackgroundColor(palette[3]), - ..Default::default() - }) + BackgroundColor(palette[3]), + )) .with_children(|parent| { spawn_buttons(parent, target_ids.pop().unwrap()); - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Px(100.), height: Val::Px(100.), - ..Default::default() + ..default() }, - ..Default::default() - }); + )); }); }); }); @@ -401,15 +398,13 @@ where { parent .spawn(( - ButtonBundle { - style: Style { - align_self: AlignSelf::FlexStart, - padding: UiRect::axes(Val::Px(5.), Val::Px(1.)), - ..Default::default() - }, - background_color: Color::BLACK.with_alpha(0.5).into(), - ..Default::default() + Button, + Style { + align_self: AlignSelf::FlexStart, + padding: UiRect::axes(Val::Px(5.), Val::Px(1.)), + ..default() }, + BackgroundColor(Color::BLACK.with_alpha(0.5)), Target::::new(target), )) .with_children(|builder| { diff --git a/examples/ui/flex_layout.rs b/examples/ui/flex_layout.rs index 7b4ffbbb9a250..bb78f43755606 100644 --- a/examples/ui/flex_layout.rs +++ b/examples/ui/flex_layout.rs @@ -22,8 +22,9 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { let font = asset_server.load("fonts/FiraSans-Bold.ttf"); commands.spawn(Camera2d); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // fill the entire window width: Val::Percent(100.), height: Val::Percent(100.), @@ -33,19 +34,18 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { row_gap: MARGIN, ..Default::default() }, - background_color: BackgroundColor(Color::BLACK), - ..Default::default() - }) + BackgroundColor(Color::BLACK), + )) .with_children(|builder| { // spawn the key builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Row, - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|builder| { spawn_nested_text_bundle( builder, @@ -64,16 +64,16 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { }); builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), flex_direction: FlexDirection::Column, row_gap: MARGIN, - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|builder| { // spawn one child node for each combination of `AlignItems` and `JustifyContent` let justifications = [ @@ -93,16 +93,16 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { ]; for align_items in alignments { builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), flex_direction: FlexDirection::Row, column_gap: MARGIN, ..Default::default() }, - ..Default::default() - }) + )) .with_children(|builder| { for justify_content in justifications { spawn_child_node( @@ -125,18 +125,18 @@ fn spawn_child_node( justify_content: JustifyContent, ) { builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items, justify_content, width: Val::Percent(100.), height: Val::Percent(100.), - ..Default::default() + ..default() }, - background_color: BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .with_children(|builder| { let labels = [ (format!("{align_items:?}"), ALIGN_ITEMS_COLOR, 0.), @@ -163,15 +163,15 @@ fn spawn_nested_text_bundle( text: &str, ) { builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin, padding: UiRect::axes(Val::Px(5.), Val::Px(1.)), - ..Default::default() + ..default() }, - background_color: BackgroundColor(background_color), - ..Default::default() - }) + BackgroundColor(background_color), + )) .with_children(|builder| { builder.spawn(( Text::new(text), diff --git a/examples/ui/font_atlas_debug.rs b/examples/ui/font_atlas_debug.rs index 8cc54919b41e8..be415f3440ce6 100644 --- a/examples/ui/font_atlas_debug.rs +++ b/examples/ui/font_atlas_debug.rs @@ -48,16 +48,15 @@ fn atlas_render_system( } let font_atlas = &font_atlas[state.atlas_count as usize]; state.atlas_count += 1; - commands.spawn(ImageBundle { - image: font_atlas.texture.clone().into(), - style: Style { + commands.spawn(( + UiImage::new(font_atlas.texture.clone()), + Style { position_type: PositionType::Absolute, top: Val::ZERO, left: Val::Px(512.0 * x_offset), ..default() }, - ..default() - }); + )); } } } @@ -86,15 +85,15 @@ fn setup(mut commands: Commands, asset_server: Res, mut state: ResM state.handle = font_handle.clone(); commands.spawn(Camera2d); commands - .spawn(NodeBundle { - background_color: Color::NONE.into(), - style: Style { + .spawn(( + Node::default(), + BackgroundColor(Color::NONE), + Style { position_type: PositionType::Absolute, bottom: Val::ZERO, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent.spawn(( Text::new("a"), diff --git a/examples/ui/ghost_nodes.rs b/examples/ui/ghost_nodes.rs index 0460c4c30ab2e..ceb9bbe93266f 100644 --- a/examples/ui/ghost_nodes.rs +++ b/examples/ui/ghost_nodes.rs @@ -33,29 +33,27 @@ fn setup(mut commands: Commands, asset_server: Res) { commands .spawn(GhostNode::new()) .with_children(|ghost_root| { - ghost_root - .spawn(NodeBundle::default()) - .with_child(create_label( - "This text node is rendered under a ghost root", - font_handle.clone(), - )); + ghost_root.spawn(Node::default()).with_child(create_label( + "This text node is rendered under a ghost root", + font_handle.clone(), + )); }); // Normal UI root commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn((NodeBundle::default(), Counter(0))) + .spawn((Node::default(), Counter(0))) .with_children(|layout_parent| { layout_parent .spawn((GhostNode::new(), Counter(0))) @@ -78,9 +76,10 @@ fn setup(mut commands: Commands, asset_server: Res) { }); } -fn create_button() -> ButtonBundle { - ButtonBundle { - style: Style { +fn create_button() -> impl Bundle { + ( + Button, + Style { width: Val::Px(150.0), height: Val::Px(65.0), border: UiRect::all(Val::Px(5.0)), @@ -90,11 +89,10 @@ fn create_button() -> ButtonBundle { align_items: AlignItems::Center, ..default() }, - border_color: BorderColor(Color::BLACK), - border_radius: BorderRadius::MAX, - background_color: Color::srgb(0.15, 0.15, 0.15).into(), - ..default() - } + BorderColor(Color::BLACK), + BorderRadius::MAX, + BackgroundColor(Color::srgb(0.15, 0.15, 0.15)), + ) } fn create_label(text: &str, font: Handle) -> (Text, TextFont, TextColor) { diff --git a/examples/ui/grid.rs b/examples/ui/grid.rs index 21c9de01f9a89..ae50dee9d2691 100644 --- a/examples/ui/grid.rs +++ b/examples/ui/grid.rs @@ -21,8 +21,9 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { // Top-level grid (app frame) commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // Use the CSS Grid algorithm for laying out this node display: Display::Grid, // Make node fill the entirety of its parent (in this case the window) @@ -43,30 +44,30 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { ], ..default() }, - background_color: BackgroundColor(Color::WHITE), - ..default() - }) + BackgroundColor(Color::WHITE), + )) .with_children(|builder| { // Header builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Grid, // Make this node span two grid columns so that it takes up the entire top tow grid_column: GridPlacement::span(2), padding: UiRect::all(Val::Px(6.0)), ..default() }, - ..default() - }) + )) .with_children(|builder| { spawn_nested_text_bundle(builder, font.clone(), "Bevy CSS Grid Layout Example"); }); // Main content grid (auto placed in row 2, column 1) builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { // Make the height of the node fill its parent height: Val::Percent(100.0), // Make the grid have a 1:1 aspect ratio meaning it will scale as an exact square @@ -87,9 +88,8 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { column_gap: Val::Px(12.0), ..default() }, - background_color: BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), - ..default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .with_children(|builder| { // Note there is no need to specify the position for each grid item. Grid items that are // not given an explicit position will be automatically positioned into the next available @@ -116,8 +116,9 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { // Right side bar (auto placed in row 2, column 2) builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Grid, // Align content towards the start (top) in the vertical axis align_items: AlignItems::Start, @@ -132,9 +133,8 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { row_gap: Val::Px(10.), ..default() }, - background_color: BackgroundColor(BLACK.into()), - ..default() - }) + BackgroundColor(BLACK.into()), + )) .with_children(|builder| { builder.spawn((Text::new("Sidebar"), TextFont { @@ -149,24 +149,25 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { ..default() }, )); - builder.spawn(NodeBundle::default()); + builder.spawn(Node::default()); }); // Footer / status bar - builder.spawn(NodeBundle { - style: Style { + builder.spawn(( + Node::default(), + Style { // Make this node span two grid column so that it takes up the entire bottom row grid_column: GridPlacement::span(2), ..default() }, - background_color: BackgroundColor(WHITE.into()), - ..default() - }); + BackgroundColor(WHITE.into()), + )); // Modal (absolutely positioned on top of content - currently hidden: to view it, change its visibility) - builder.spawn(NodeBundle { - visibility: Visibility::Hidden, - style: Style { + builder.spawn(( + Node::default(), + Visibility::Hidden, + Style { position_type: PositionType::Absolute, margin: UiRect { top: Val::Px(100.), @@ -179,9 +180,8 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { max_width: Val::Px(600.), ..default() }, - background_color: BackgroundColor(Color::WHITE.with_alpha(0.8)), - ..default() - }); + BackgroundColor(Color::WHITE.with_alpha(0.8)), + )); }); } @@ -190,20 +190,17 @@ fn spawn_layout(mut commands: Commands, asset_server: Res) { /// which will allow it to take its size from the size of the grid area it occupies. fn item_rect(builder: &mut ChildBuilder, color: Srgba) { builder - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Grid, padding: UiRect::all(Val::Px(3.0)), ..default() }, - background_color: BackgroundColor(BLACK.into()), - ..default() - }) + BackgroundColor(BLACK.into()), + )) .with_children(|builder| { - builder.spawn(NodeBundle { - background_color: BackgroundColor(color.into()), - ..default() - }); + builder.spawn((Node::default(), BackgroundColor(color.into()))); }); } diff --git a/examples/ui/overflow.rs b/examples/ui/overflow.rs index 3bcd2e1eb5c89..2857c1edfa4a8 100644 --- a/examples/ui/overflow.rs +++ b/examples/ui/overflow.rs @@ -20,17 +20,17 @@ fn setup(mut commands: Commands, asset_server: Res) { let image = asset_server.load("branding/icon.png"); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..Default::default() }, - background_color: ANTIQUE_WHITE.into(), - ..Default::default() - }) + BackgroundColor(ANTIQUE_WHITE.into()), + )) .with_children(|parent| { for overflow in [ Overflow::visible(), @@ -39,33 +39,34 @@ fn setup(mut commands: Commands, asset_server: Res) { Overflow::clip(), ] { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, margin: UiRect::horizontal(Val::Px(25.)), ..Default::default() }, - ..Default::default() - }) + )) .with_children(|parent| { let label = format!("{overflow:#?}"); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { padding: UiRect::all(Val::Px(10.)), margin: UiRect::bottom(Val::Px(25.)), ..Default::default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .with_children(|parent| { parent.spawn((Text::new(label), text_style.clone())); }); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(100.), height: Val::Px(100.), padding: UiRect { @@ -75,22 +76,18 @@ fn setup(mut commands: Commands, asset_server: Res) { }, border: UiRect::all(Val::Px(5.)), overflow, - ..Default::default() + ..default() }, - border_color: Color::BLACK.into(), - background_color: GRAY.into(), - ..Default::default() - }) + BorderColor(Color::BLACK), + BackgroundColor(GRAY.into()), + )) .with_children(|parent| { parent.spawn(( - ImageBundle { - image: UiImage::new(image.clone()), - style: Style { - min_width: Val::Px(100.), - min_height: Val::Px(100.), - ..Default::default() - }, - ..Default::default() + UiImage::new(image.clone()), + Style { + min_width: Val::Px(100.), + min_height: Val::Px(100.), + ..default() }, Interaction::default(), Outline { diff --git a/examples/ui/overflow_clip_margin.rs b/examples/ui/overflow_clip_margin.rs index 6d5690bbfb84d..79bd636cf3301 100644 --- a/examples/ui/overflow_clip_margin.rs +++ b/examples/ui/overflow_clip_margin.rs @@ -17,19 +17,19 @@ fn setup(mut commands: Commands, asset_server: Res) { let image = asset_server.load("branding/icon.png"); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), align_items: AlignItems::Center, justify_content: JustifyContent::Center, row_gap: Val::Px(40.), flex_direction: FlexDirection::Column, - ..Default::default() + ..default() }, - background_color: ANTIQUE_WHITE.into(), - ..Default::default() - }) + BackgroundColor(ANTIQUE_WHITE.into()), + )) .with_children(|parent| { for overflow_clip_margin in [ OverflowClipMargin::border_box().with_margin(25.), @@ -38,30 +38,31 @@ fn setup(mut commands: Commands, asset_server: Res) { OverflowClipMargin::content_box(), ] { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Row, column_gap: Val::Px(20.), - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { padding: UiRect::all(Val::Px(10.)), margin: UiRect::bottom(Val::Px(25.)), - ..Default::default() + ..default() }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), + )) .with_child(Text(format!("{overflow_clip_margin:#?}"))); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { margin: UiRect::top(Val::Px(10.)), width: Val::Px(100.), height: Val::Px(100.), @@ -69,32 +70,30 @@ fn setup(mut commands: Commands, asset_server: Res) { border: UiRect::all(Val::Px(5.)), overflow: Overflow::clip(), overflow_clip_margin, - ..Default::default() + ..default() }, - border_color: Color::BLACK.into(), - background_color: GRAY.into(), - ..Default::default() - }) + BackgroundColor(GRAY.into()), + BorderColor(Color::BLACK), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { min_width: Val::Px(50.), min_height: Val::Px(50.), - ..Default::default() + ..default() }, - background_color: LIGHT_CYAN.into(), - ..Default::default() - }) - .with_child(ImageBundle { - image: UiImage::new(image.clone()), - style: Style { + BackgroundColor(LIGHT_CYAN.into()), + )) + .with_child(( + UiImage::new(image.clone()), + Style { min_width: Val::Px(100.), min_height: Val::Px(100.), - ..Default::default() + ..default() }, - ..Default::default() - }); + )); }); }); } diff --git a/examples/ui/overflow_debug.rs b/examples/ui/overflow_debug.rs index 3b3091d77bd97..6896680b9d1bf 100644 --- a/examples/ui/overflow_debug.rs +++ b/examples/ui/overflow_debug.rs @@ -105,20 +105,21 @@ fn setup(mut commands: Commands, asset_server: Res) { // Overflow Debug commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { display: Display::Grid, grid_template_columns: RepeatedGridTrack::px(3, CONTAINER_SIZE), grid_template_rows: RepeatedGridTrack::px(2, CONTAINER_SIZE), @@ -126,8 +127,7 @@ fn setup(mut commands: Commands, asset_server: Res) { column_gap: Val::Px(80.), ..default() }, - ..default() - }) + )) .with_children(|parent| { spawn_image(parent, &asset_server, Move); spawn_image(parent, &asset_server, Scale); @@ -146,17 +146,16 @@ fn spawn_image( update_transform: impl UpdateTransform + Component, ) { spawn_container(parent, update_transform, |parent| { - parent.spawn(ImageBundle { - image: UiImage::new(asset_server.load("branding/bevy_logo_dark_big.png")), - style: Style { + parent.spawn(( + UiImage::new(asset_server.load("branding/bevy_logo_dark_big.png")), + Style { height: Val::Px(100.), position_type: PositionType::Absolute, top: Val::Px(-50.), left: Val::Px(-200.), ..default() }, - ..default() - }); + )); }); } @@ -188,34 +187,30 @@ fn spawn_container( parent .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.), - height: Val::Percent(100.), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - overflow: Overflow::clip(), - ..default() - }, - background_color: Color::srgb(0.25, 0.25, 0.25).into(), + Node::default(), + Style { + width: Val::Percent(100.), + height: Val::Percent(100.), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + overflow: Overflow::clip(), ..default() }, + BackgroundColor(Color::srgb(0.25, 0.25, 0.25)), Container(0), )) .with_children(|parent| { parent .spawn(( - NodeBundle { - style: Style { - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - top: Val::Px(transform.translation.x), - left: Val::Px(transform.translation.y), - ..default() - }, - transform, + Node::default(), + Style { + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + top: Val::Px(transform.translation.x), + left: Val::Px(transform.translation.y), ..default() }, + transform, update_transform, )) .with_children(spawn_children); diff --git a/examples/ui/relative_cursor_position.rs b/examples/ui/relative_cursor_position.rs index 358a823f60d82..de4b36e939339 100644 --- a/examples/ui/relative_cursor_position.rs +++ b/examples/ui/relative_cursor_position.rs @@ -29,8 +29,9 @@ fn setup(mut commands: Commands, asset_server: Res) { )); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.0), align_items: AlignItems::Center, @@ -38,20 +39,19 @@ fn setup(mut commands: Commands, asset_server: Res) { flex_direction: FlexDirection::Column, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(250.), height: Val::Px(250.), margin: UiRect::bottom(Val::Px(15.)), ..default() }, - background_color: Color::srgb(235., 35., 12.).into(), - ..default() - }) + BackgroundColor(Color::srgb(235., 35., 12.)), + )) .insert(RelativeCursorPosition::default()); parent.spawn(( diff --git a/examples/ui/render_ui_to_texture.rs b/examples/ui/render_ui_to_texture.rs index b640101b4b72b..8a40308ad7676 100644 --- a/examples/ui/render_ui_to_texture.rs +++ b/examples/ui/render_ui_to_texture.rs @@ -65,19 +65,17 @@ fn setup( commands .spawn(( - NodeBundle { - style: Style { - // Cover the whole image - width: Val::Percent(100.), - height: Val::Percent(100.), - flex_direction: FlexDirection::Column, - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, - ..default() - }, - background_color: GOLD.into(), + Node::default(), + Style { + // Cover the whole image + width: Val::Percent(100.), + height: Val::Percent(100.), + flex_direction: FlexDirection::Column, + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, ..default() }, + BackgroundColor(GOLD.into()), TargetCamera(texture_camera), )) .with_children(|parent| { diff --git a/examples/ui/scroll.rs b/examples/ui/scroll.rs index fbc10ddb86220..5aacceb674b49 100644 --- a/examples/ui/scroll.rs +++ b/examples/ui/scroll.rs @@ -30,28 +30,28 @@ fn setup(mut commands: Commands, asset_server: Res) { // root node commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), justify_content: JustifyContent::SpaceBetween, flex_direction: FlexDirection::Column, ..default() }, - ..default() - }) + )) .insert(PickingBehavior::IGNORE) .with_children(|parent| { // horizontal scroll example parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), flex_direction: FlexDirection::Column, ..default() }, - ..default() - }) + )) .with_children(|parent| { // header parent.spawn(( @@ -66,17 +66,17 @@ fn setup(mut commands: Commands, asset_server: Res) { // horizontal scroll container parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(80.), margin: UiRect::all(Val::Px(10.)), flex_direction: FlexDirection::Row, overflow: Overflow::scroll_x(), // n.b. ..default() }, - background_color: Color::srgb(0.10, 0.10, 0.10).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), + )) .with_children(|parent| { for i in 0..100 { parent.spawn((Text(format!("Item {i}")), @@ -111,29 +111,29 @@ fn setup(mut commands: Commands, asset_server: Res) { // container for all other examples parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), flex_direction: FlexDirection::Row, justify_content: JustifyContent::SpaceBetween, ..default() }, - ..default() - }) + )) .with_children(|parent| { // vertical scroll example parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, align_items: AlignItems::Center, width: Val::Px(200.), ..default() }, - ..default() - }) + )) .with_children(|parent| { // Title parent.spawn(( @@ -147,29 +147,29 @@ fn setup(mut commands: Commands, asset_server: Res) { )); // Scrolling list parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_self: AlignSelf::Stretch, height: Val::Percent(50.), overflow: Overflow::scroll_y(), // n.b. ..default() }, - background_color: Color::srgb(0.10, 0.10, 0.10).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), + )) .with_children(|parent| { // List items for i in 0..25 { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { min_height: Val::Px(LINE_HEIGHT), max_height: Val::Px(LINE_HEIGHT), ..default() }, - ..default() - }) + )) .insert(PickingBehavior { should_block_lower: false, ..default() @@ -199,16 +199,16 @@ fn setup(mut commands: Commands, asset_server: Res) { // Bidirectional scroll example parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, align_items: AlignItems::Center, width: Val::Px(200.), ..default() }, - ..default() - }) + )) .with_children(|parent| { // Title parent.spawn(( @@ -222,28 +222,28 @@ fn setup(mut commands: Commands, asset_server: Res) { )); // Scrolling list parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_self: AlignSelf::Stretch, height: Val::Percent(50.), overflow: Overflow::scroll(), // n.b. ..default() }, - background_color: Color::srgb(0.10, 0.10, 0.10).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), + )) .with_children(|parent| { // Rows in each column for oi in 0..10 { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Row, ..default() }, - ..default() - }) + )) .insert(PickingBehavior::IGNORE) .with_children(|parent| { // Elements in each row @@ -274,16 +274,16 @@ fn setup(mut commands: Commands, asset_server: Res) { // Nested scrolls example parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, align_items: AlignItems::Center, width: Val::Px(200.), ..default() }, - ..default() - }) + )) .with_children(|parent| { // Title parent.spawn(( @@ -297,8 +297,9 @@ fn setup(mut commands: Commands, asset_server: Res) { )); // Outer, horizontal scrolling container parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { column_gap: Val::Px(20.), flex_direction: FlexDirection::Row, align_self: AlignSelf::Stretch, @@ -306,24 +307,22 @@ fn setup(mut commands: Commands, asset_server: Res) { overflow: Overflow::scroll_x(), // n.b. ..default() }, - background_color: Color::srgb(0.10, 0.10, 0.10).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), + )) .with_children(|parent| { // Inner, scrolling columns for oi in 0..30 { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_self: AlignSelf::Stretch, overflow: Overflow::scroll_y(), ..default() }, - background_color: Color::srgb(0.05, 0.05, 0.05) - .into(), - ..default() - }) + BackgroundColor(Color::srgb(0.05, 0.05, 0.05)), + )) .insert(PickingBehavior { should_block_lower: false, ..default() diff --git a/examples/ui/size_constraints.rs b/examples/ui/size_constraints.rs index 716f8bd6e3265..f4fc0fc384242 100644 --- a/examples/ui/size_constraints.rs +++ b/examples/ui/size_constraints.rs @@ -52,28 +52,28 @@ fn setup(mut commands: Commands, asset_server: Res) { ); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), justify_content: JustifyContent::Center, align_items: AlignItems::Center, - ..Default::default() + ..default() }, - background_color: Color::BLACK.into(), - ..Default::default() - }) + BackgroundColor(Color::BLACK), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Center, justify_content: JustifyContent::Center, - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|parent| { parent.spawn(( Text::new("Size Constraints Example"), @@ -87,17 +87,17 @@ fn setup(mut commands: Commands, asset_server: Res) { spawn_bar(parent); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_items: AlignItems::Stretch, padding: UiRect::all(Val::Px(10.)), margin: UiRect::top(Val::Px(50.)), - ..Default::default() + ..default() }, - background_color: YELLOW.into(), - ..Default::default() - }) + BackgroundColor(YELLOW.into()), + )) .with_children(|parent| { for constraint in [ Constraint::MinWidth, @@ -114,40 +114,31 @@ fn setup(mut commands: Commands, asset_server: Res) { fn spawn_bar(parent: &mut ChildBuilder) { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_basis: Val::Percent(100.0), align_self: AlignSelf::Stretch, padding: UiRect::all(Val::Px(10.)), - ..Default::default() + ..default() }, - background_color: YELLOW.into(), - ..Default::default() - }) + BackgroundColor(YELLOW.into()), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { align_items: AlignItems::Stretch, width: Val::Percent(100.), height: Val::Px(100.), padding: UiRect::all(Val::Px(4.)), - ..Default::default() + ..default() }, - background_color: Color::BLACK.into(), - ..Default::default() - }) + BackgroundColor(Color::BLACK), + )) .with_children(|parent| { - parent.spawn(( - NodeBundle { - style: Style { - ..Default::default() - }, - background_color: Color::WHITE.into(), - ..Default::default() - }, - Bar, - )); + parent.spawn((Node::default(), BackgroundColor(Color::WHITE), Bar)); }); }); } @@ -165,67 +156,63 @@ fn spawn_button_row( }; parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, padding: UiRect::all(Val::Px(2.)), align_items: AlignItems::Stretch, - ..Default::default() + ..default() }, - background_color: Color::BLACK.into(), - ..Default::default() - }) + BackgroundColor(Color::BLACK), + )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Row, justify_content: JustifyContent::End, padding: UiRect::all(Val::Px(2.)), - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_children(|parent| { // spawn row label parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { min_width: Val::Px(200.), max_width: Val::Px(200.), justify_content: JustifyContent::Center, align_items: AlignItems::Center, - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .with_child((Text::new(label), text_style.clone())); // spawn row buttons - parent - .spawn(NodeBundle { - ..Default::default() - }) - .with_children(|parent| { + parent.spawn(Node::default()).with_children(|parent| { + spawn_button( + parent, + constraint, + ButtonValue(Val::Auto), + "Auto".to_string(), + text_style.clone(), + true, + ); + for percent in [0., 25., 50., 75., 100., 125.] { spawn_button( parent, constraint, - ButtonValue(Val::Auto), - "Auto".to_string(), + ButtonValue(Val::Percent(percent)), + format!("{percent}%"), text_style.clone(), - true, + false, ); - for percent in [0., 25., 50., 75., 100., 125.] { - spawn_button( - parent, - constraint, - ButtonValue(Val::Percent(percent)), - format!("{percent}%"), - text_style.clone(), - false, - ); - } - }); + } + }); }); }); } @@ -240,41 +227,37 @@ fn spawn_button( ) { parent .spawn(( - ButtonBundle { - style: Style { - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - border: UiRect::all(Val::Px(2.)), - margin: UiRect::horizontal(Val::Px(2.)), - ..Default::default() - }, - border_color: if active { - ACTIVE_BORDER_COLOR - } else { - INACTIVE_BORDER_COLOR - } - .into(), + Button, + Style { + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + border: UiRect::all(Val::Px(2.)), + margin: UiRect::horizontal(Val::Px(2.)), ..Default::default() }, + BorderColor(if active { + ACTIVE_BORDER_COLOR + } else { + INACTIVE_BORDER_COLOR + }), constraint, action, )) .with_children(|parent| { parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(100.), justify_content: JustifyContent::Center, - ..Default::default() + ..default() }, - background_color: if active { + BackgroundColor(if active { ACTIVE_INNER_COLOR } else { INACTIVE_INNER_COLOR - } - .into(), - ..Default::default() - }) + }), + )) .with_child(( Text::new(label), text_style.0, diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 1a5854f04c36a..030a5df329be3 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -36,19 +36,21 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { commands.spawn(Camera2d); let root_uinode = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), justify_content: JustifyContent::SpaceBetween, ..default() }, - ..default() - }) + )) .id(); - let left_column = commands.spawn(NodeBundle { - style: Style { + let left_column = commands + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, justify_content: JustifyContent::SpaceBetween, align_items: AlignItems::Start, @@ -56,8 +58,7 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { margin: UiRect::axes(Val::Px(15.), Val::Px(5.)), ..default() }, - ..default() - }).with_children(|builder| { + )).with_children(|builder| { builder.spawn(( Text::new("This is\ntext with\nline breaks\nin the top left."), TextFont { @@ -101,17 +102,17 @@ fn infotext_system(mut commands: Commands, asset_server: Res) { ); }).id(); - let right_column = commands.spawn(NodeBundle { - style: Style { - flex_direction: FlexDirection::Column, - justify_content: JustifyContent::SpaceBetween, - align_items: AlignItems::End, - flex_grow: 1., - margin: UiRect::axes(Val::Px(15.), Val::Px(5.)), - ..default() - }, - ..default() - }).with_children(|builder| { + let right_column = commands.spawn(( + Node::default(), + Style { + flex_direction: FlexDirection::Column, + justify_content: JustifyContent::SpaceBetween, + align_items: AlignItems::End, + flex_grow: 1., + margin: UiRect::axes(Val::Px(15.), Val::Px(5.)), + ..default() + }, + )).with_children(|builder| { builder.spawn((Text::new( "This text is very long, has a limited width, is center-justified, is positioned in the top right and is also colored pink."), diff --git a/examples/ui/text_wrap_debug.rs b/examples/ui/text_wrap_debug.rs index 145749d5ed191..9b03246c8d95b 100644 --- a/examples/ui/text_wrap_debug.rs +++ b/examples/ui/text_wrap_debug.rs @@ -52,16 +52,16 @@ fn spawn(mut commands: Commands, asset_server: Res) { }; let root = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), height: Val::Percent(100.), flex_direction: FlexDirection::Column, - ..Default::default() + ..default() }, - background_color: Color::BLACK.into(), - ..Default::default() - }) + BackgroundColor(Color::BLACK), + )) .id(); for linebreak in [ @@ -71,17 +71,17 @@ fn spawn(mut commands: Commands, asset_server: Res) { LineBreak::NoWrap, ] { let row_id = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Row, justify_content: JustifyContent::SpaceAround, align_items: AlignItems::Center, width: Val::Percent(100.), height: Val::Percent(50.), - ..Default::default() + ..default() }, - ..Default::default() - }) + )) .id(); let justifications = vec![ @@ -96,18 +96,18 @@ fn spawn(mut commands: Commands, asset_server: Res) { for (i, justification) in justifications.into_iter().enumerate() { let c = 0.3 + i as f32 * 0.1; let column_id = commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { justify_content: justification, flex_direction: FlexDirection::Column, width: Val::Percent(16.), height: Val::Percent(95.), overflow: Overflow::clip_x(), - ..Default::default() + ..default() }, - background_color: Color::srgb(0.5, c, 1.0 - c).into(), - ..Default::default() - }) + BackgroundColor(Color::srgb(0.5, c, 1.0 - c)), + )) .id(); let messages = [ diff --git a/examples/ui/transparency_ui.rs b/examples/ui/transparency_ui.rs index 931d7740d20fe..1fdfc4678a8d2 100644 --- a/examples/ui/transparency_ui.rs +++ b/examples/ui/transparency_ui.rs @@ -17,29 +17,29 @@ fn setup(mut commands: Commands, asset_server: Res) { let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf"); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::SpaceAround, ..default() }, - ..default() - }) + )) .with_children(|parent| { parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { width: Val::Px(150.0), height: Val::Px(65.0), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, - background_color: Color::srgb(0.1, 0.5, 0.1).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.1, 0.5, 0.1)), + )) .with_children(|parent| { parent.spawn(( Text::new("Button 1"), @@ -56,17 +56,17 @@ fn setup(mut commands: Commands, asset_server: Res) { // Button with a different color, // to demonstrate the text looks different due to its transparency. parent - .spawn(ButtonBundle { - style: Style { + .spawn(( + Button, + Style { width: Val::Px(150.0), height: Val::Px(65.0), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, - background_color: Color::srgb(0.5, 0.1, 0.5).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.5, 0.1, 0.5)), + )) .with_children(|parent| { parent.spawn(( Text::new("Button 2"), diff --git a/examples/ui/ui.rs b/examples/ui/ui.rs index 74c2153460eb1..4c4f4725d698c 100644 --- a/examples/ui/ui.rs +++ b/examples/ui/ui.rs @@ -35,42 +35,42 @@ fn setup(mut commands: Commands, asset_server: Res) { // root node commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), justify_content: JustifyContent::SpaceBetween, ..default() }, - ..default() - }) + )) .insert(PickingBehavior::IGNORE) .with_children(|parent| { // left vertical fill (border) parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(200.), border: UiRect::all(Val::Px(2.)), ..default() }, - background_color: Color::srgb(0.65, 0.65, 0.65).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.65, 0.65, 0.65)), + )) .with_children(|parent| { // left vertical fill (content) parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), flex_direction: FlexDirection::Column, padding: UiRect::all(Val::Px(5.)), row_gap: Val::Px(5.), ..default() }, - background_color: Color::srgb(0.15, 0.15, 0.15).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.15, 0.15, 0.15)), + )) .with_children(|parent| { // text parent.spawn(( @@ -110,16 +110,16 @@ fn setup(mut commands: Commands, asset_server: Res) { }); // right vertical fill parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, align_items: AlignItems::Center, width: Val::Px(200.), ..default() }, - ..default() - }) + )) .with_children(|parent| { // Title parent.spawn(( @@ -133,17 +133,17 @@ fn setup(mut commands: Commands, asset_server: Res) { )); // Scrolling list parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { flex_direction: FlexDirection::Column, align_self: AlignSelf::Stretch, height: Val::Percent(50.), overflow: Overflow::scroll_y(), ..default() }, - background_color: Color::srgb(0.10, 0.10, 0.10).into(), - ..default() - }) + BackgroundColor(Color::srgb(0.10, 0.10, 0.10)), + )) .with_children(|parent| { // List items for i in 0..25 { @@ -166,8 +166,9 @@ fn setup(mut commands: Commands, asset_server: Res) { }); parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Px(200.0), height: Val::Px(200.0), position_type: PositionType::Absolute, @@ -176,20 +177,19 @@ fn setup(mut commands: Commands, asset_server: Res) { border: UiRect::all(Val::Px(20.)), ..default() }, - border_color: LIME.into(), - background_color: Color::srgb(0.4, 0.4, 1.).into(), - ..default() - }) + BorderColor(LIME.into()), + BackgroundColor(Color::srgb(0.4, 0.4, 1.)), + )) .with_children(|parent| { - parent.spawn(NodeBundle { - style: Style { + parent.spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), ..default() }, - background_color: Color::srgb(0.8, 0.8, 1.).into(), - ..default() - }); + BackgroundColor(Color::srgb(0.8, 0.8, 1.)), + )); }); let shadow = BoxShadow { @@ -202,8 +202,9 @@ fn setup(mut commands: Commands, asset_server: Res) { // render order test: reddest in the back, whitest in the front (flex center) parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), position_type: PositionType::Absolute, @@ -211,84 +212,73 @@ fn setup(mut commands: Commands, asset_server: Res) { justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) .insert(PickingBehavior::IGNORE) .with_children(|parent| { parent .spawn(( - NodeBundle { - style: Style { - width: Val::Px(100.0), - height: Val::Px(100.0), - ..default() - }, - background_color: Color::srgb(1.0, 0.0, 0.).into(), + Node::default(), + Style { + width: Val::Px(100.0), + height: Val::Px(100.0), ..default() }, + BackgroundColor(Color::srgb(1.0, 0.0, 0.)), shadow, )) .with_children(|parent| { parent.spawn(( - NodeBundle { - style: Style { - // Take the size of the parent node. - width: Val::Percent(100.0), - height: Val::Percent(100.0), - position_type: PositionType::Absolute, - left: Val::Px(20.), - bottom: Val::Px(20.), - ..default() - }, - background_color: Color::srgb(1.0, 0.3, 0.3).into(), + Node::default(), + Style { + // Take the size of the parent node. + width: Val::Percent(100.0), + height: Val::Percent(100.0), + position_type: PositionType::Absolute, + left: Val::Px(20.), + bottom: Val::Px(20.), ..default() }, + BackgroundColor(Color::srgb(1.0, 0.3, 0.3)), shadow, )); parent.spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - position_type: PositionType::Absolute, - left: Val::Px(40.), - bottom: Val::Px(40.), - ..default() - }, - background_color: Color::srgb(1.0, 0.5, 0.5).into(), + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + position_type: PositionType::Absolute, + left: Val::Px(40.), + bottom: Val::Px(40.), ..default() }, + BackgroundColor(Color::srgb(1.0, 0.5, 0.5)), shadow, )); parent.spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - position_type: PositionType::Absolute, - left: Val::Px(60.), - bottom: Val::Px(60.), - ..default() - }, - background_color: Color::srgb(0.0, 0.7, 0.7).into(), + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + position_type: PositionType::Absolute, + left: Val::Px(60.), + bottom: Val::Px(60.), ..default() }, + BackgroundColor(Color::srgb(0.0, 0.7, 0.7)), shadow, )); // alpha test parent.spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - position_type: PositionType::Absolute, - left: Val::Px(80.), - bottom: Val::Px(80.), - ..default() - }, - background_color: Color::srgba(1.0, 0.9, 0.9, 0.4).into(), + Node::default(), + Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + position_type: PositionType::Absolute, + left: Val::Px(80.), + bottom: Val::Px(80.), ..default() }, + BackgroundColor(Color::srgba(1.0, 0.9, 0.9, 0.4)), BoxShadow { color: Color::BLACK.with_alpha(0.3), ..shadow @@ -298,44 +288,37 @@ fn setup(mut commands: Commands, asset_server: Res) { }); // bevy logo (flex center) parent - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), position_type: PositionType::Absolute, justify_content: JustifyContent::Center, align_items: AlignItems::FlexStart, ..default() }, - ..default() - }) + )) .with_children(|parent| { // bevy logo (image) - // A `NodeBundle` is used to display the logo the image as an `ImageBundle` can't automatically - // size itself with a child node present. parent .spawn(( - NodeBundle { - style: Style { - width: Val::Px(500.0), - height: Val::Px(125.0), - margin: UiRect::top(Val::VMin(5.)), - ..default() - }, + UiImage::new(asset_server.load("branding/bevy_logo_dark_big.png")), + Style { + width: Val::Px(500.0), + height: Val::Px(125.0), + margin: UiRect::top(Val::VMin(5.)), ..default() }, - UiImage::new(asset_server.load("branding/bevy_logo_dark_big.png")), )) .with_children(|parent| { // alt text // This UI node takes up no space in the layout and the `Text` component is used by the accessibility module // and is not rendered. parent.spawn(( - NodeBundle { - style: Style { - display: Display::None, - ..Default::default() - }, - ..Default::default() + Node::default(), + Style { + display: Display::None, + ..default() }, Text::new("Bevy logo"), )); diff --git a/examples/ui/ui_material.rs b/examples/ui/ui_material.rs index ff8ef8bb430c8..d22755c9bdd7f 100644 --- a/examples/ui/ui_material.rs +++ b/examples/ui/ui_material.rs @@ -1,6 +1,6 @@ //! Demonstrates the use of [`UiMaterials`](UiMaterial) and how to change material values -use bevy::{prelude::*, reflect::TypePath, render::render_resource::*}; +use bevy::{color::palettes::css::RED, prelude::*, reflect::TypePath, render::render_resource::*}; /// This example uses a shader source file from the assets subdirectory const SHADER_ASSET_PATH: &str = "shaders/custom_ui_material.wgsl"; @@ -23,34 +23,34 @@ fn setup( commands.spawn(Camera2d); commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) .with_children(|parent| { let banner_scale_factor = 0.5; - parent.spawn(MaterialNodeBundle { - style: Style { + parent.spawn(( + MaterialNode(ui_materials.add(CustomUiMaterial { + color: LinearRgba::WHITE.to_f32_array().into(), + slider: 0.5, + color_texture: asset_server.load("branding/banner.png"), + border_color: LinearRgba::WHITE.to_f32_array().into(), + })), + Style { position_type: PositionType::Absolute, width: Val::Px(905.0 * banner_scale_factor), height: Val::Px(363.0 * banner_scale_factor), border: UiRect::all(Val::Px(10.)), ..default() }, - material: UiMaterialHandle(ui_materials.add(CustomUiMaterial { - color: LinearRgba::WHITE.to_f32_array().into(), - slider: 0.5, - color_texture: asset_server.load("branding/banner.png"), - border_color: LinearRgba::WHITE.to_f32_array().into(), - })), - ..default() - }); + BackgroundColor(RED.into()), + )); }); } @@ -82,7 +82,7 @@ impl UiMaterial for CustomUiMaterial { // Also updates the color of the image to a rainbow color fn animate( mut materials: ResMut>, - q: Query<&UiMaterialHandle>, + q: Query<&MaterialNode>, time: Res