diff --git a/crates/bevy_ui/src/layout/convert.rs b/crates/bevy_ui/src/layout/convert.rs index 161fc12751650..c7e26d3b7f172 100644 --- a/crates/bevy_ui/src/layout/convert.rs +++ b/crates/bevy_ui/src/layout/convert.rs @@ -1,7 +1,8 @@ use taffy::style_helpers; use crate::{ - AlignContent, AlignItems, AlignSelf, BoxSizing, Display, FlexDirection, FlexWrap, GridAutoFlow, + AlignContent, AlignItems, AlignSelf, BlockContainer, BlockItem, BoxSizing, Display, + FlexBoxContainer, FlexBoxItem, FlexDirection, FlexWrap, GridAutoFlow, GridContainer, GridItem, GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf, MaxTrackSizingFunction, MinTrackSizingFunction, Node, OverflowAxis, PositionType, RepeatedGridTrack, UiRect, Val, @@ -63,7 +64,19 @@ impl UiRect { } } -pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> taffy::style::Style { +pub fn from_node( + node: &Node, + displays: ( + Option<&BlockItem>, + Option<&BlockContainer>, + Option<&GridItem>, + Option<&GridContainer>, + Option<&FlexBoxItem>, + Option<&FlexBoxContainer>, + ), + context: &LayoutContext, + ignore_border: bool, +) -> taffy::style::Style { taffy::style::Style { display: node.display.into(), box_sizing: node.box_sizing.into(), @@ -75,14 +88,45 @@ pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> t }, scrollbar_width: node.scrollbar_width * context.scale_factor, position: node.position_type.into(), - flex_direction: node.flex_direction.into(), - flex_wrap: node.flex_wrap.into(), - align_items: node.align_items.into(), - justify_items: node.justify_items.into(), - align_self: node.align_self.into(), - justify_self: node.justify_self.into(), - align_content: node.align_content.into(), - justify_content: node.justify_content.into(), + flex_direction: displays + .5 + .map(|flex| flex.flex_direction.into()) + .unwrap_or_default(), + flex_wrap: displays + .5 + .map(|flex| flex.flex_wrap.into()) + .unwrap_or_default(), + align_items: displays + .3 + .map(|grid| grid.align_items.into()) + .or(displays.5.map(|flex| flex.align_items.into())) + .unwrap_or_default(), + justify_items: displays + .1 + .map(|block| block.justify_items.into()) + .or(displays.3.map(|grid| grid.justify_items.into())) + .unwrap_or_default(), + align_self: displays + .2 + .map(|block| block.align_self.into()) + .or(displays.4.map(|flex| flex.align_self.into())) + .unwrap_or_default(), + justify_self: displays + .0 + .map(|block| block.justify_self.into()) + .or(displays.2.map(|grid| grid.justify_self.into())) + .unwrap_or_default(), + align_content: displays + .1 + .map(|grid| grid.align_content.into()) + .or(displays.3.map(|grid| grid.align_content.into())) + .or(displays.5.map(|flex| flex.align_content.into())) + .unwrap_or_default(), + justify_content: displays + .3 + .map(|grid| grid.justify_content.into()) + .or(displays.5.map(|flex| flex.justify_content.into())) + .unwrap_or_default(), inset: taffy::Rect { left: node.left.into_length_percentage_auto(context), right: node.right.into_length_percentage_auto(context), @@ -103,9 +147,18 @@ pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> t node.border .map_to_taffy_rect(|m| m.into_length_percentage(context)) }, - flex_grow: node.flex_grow, - flex_shrink: node.flex_shrink, - flex_basis: node.flex_basis.into_dimension(context), + flex_grow: displays + .4 + .map(|flex| flex.flex_grow.into()) + .unwrap_or_default(), + flex_shrink: displays + .4 + .map(|flex| flex.flex_shrink.into()) + .unwrap_or_default(), + flex_basis: displays + .4 + .map(|flex| flex.flex_basis.into_dimension(context)) + .unwrap_or(taffy::Dimension::Auto), size: taffy::Size { width: node.width.into_dimension(context), height: node.height.into_dimension(context), @@ -120,32 +173,71 @@ pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> t }, aspect_ratio: node.aspect_ratio, gap: taffy::Size { - width: node.column_gap.into_length_percentage(context), - height: node.row_gap.into_length_percentage(context), + width: displays + .3 + .map(|grid| grid.column_gap) + .or(displays.5.map(|flex| flex.column_gap)) + .map(|column_gap| column_gap.into_length_percentage(context)) + .unwrap_or(taffy::Style::DEFAULT.gap.width), + height: displays + .3 + .map(|grid| grid.row_gap) + .or(displays.5.map(|flex| flex.row_gap)) + .map(|column_gap| column_gap.into_length_percentage(context)) + .unwrap_or(taffy::Style::DEFAULT.gap.height), }, - grid_auto_flow: node.grid_auto_flow.into(), - grid_template_rows: node - .grid_template_rows - .iter() - .map(|track| track.clone_into_repeated_taffy_track(context)) - .collect::>(), - grid_template_columns: node - .grid_template_columns - .iter() - .map(|track| track.clone_into_repeated_taffy_track(context)) - .collect::>(), - grid_auto_rows: node - .grid_auto_rows - .iter() - .map(|track| track.into_taffy_track(context)) - .collect::>(), - grid_auto_columns: node - .grid_auto_columns - .iter() - .map(|track| track.into_taffy_track(context)) - .collect::>(), - grid_row: node.grid_row.into(), - grid_column: node.grid_column.into(), + grid_auto_flow: displays + .3 + .map(|grid| grid.grid_auto_flow.into()) + .unwrap_or_default(), + + grid_template_rows: displays + .3 + .map(|grid| { + grid.grid_template_rows + .iter() + .map(|track| track.clone_into_repeated_taffy_track(context)) + .collect::>() + }) + .unwrap_or_default(), + grid_template_columns: displays + .3 + .map(|grid| { + grid.grid_template_columns + .iter() + .map(|track| track.clone_into_repeated_taffy_track(context)) + .collect::>() + }) + .unwrap_or_default(), + grid_auto_rows: displays + .3 + .map(|grid| { + grid.grid_auto_rows + .iter() + .map(|track| track.into_taffy_track(context)) + .collect::>() + }) + .unwrap_or_default(), + grid_auto_columns: displays + .3 + .map(|grid| { + { + grid.grid_auto_columns + .iter() + .map(|track| track.into_taffy_track(context)) + } + .collect::>() + }) + .unwrap_or_default(), + grid_row: displays + .2 + .map(|grid| grid.grid_row.into()) + .unwrap_or_default(), + + grid_column: displays + .2 + .map(|grid| grid.grid_column.into()) + .unwrap_or_default(), } } diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 3de05629ff294..74005383ce7b6 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -1,8 +1,9 @@ use crate::{ experimental::{UiChildren, UiRootNodes}, ui_transform::{UiGlobalTransform, UiTransform}, - BorderRadius, ComputedNode, ComputedUiRenderTargetInfo, ContentSize, Display, LayoutConfig, - Node, Outline, OverflowAxis, ScrollPosition, + BlockContainer, BlockItem, BorderRadius, ComputedNode, ComputedUiRenderTargetInfo, ContentSize, + Display, FlexBoxContainer, FlexBoxItem, GridContainer, GridItem, LayoutConfig, Node, Outline, + OverflowAxis, ScrollPosition, }; use bevy_ecs::{ change_detection::{DetectChanges, DetectChangesMut}, @@ -77,6 +78,15 @@ pub fn ui_layout_system( mut node_query: Query<( Entity, Ref, + ( + // theroritically could only be one container and on item + Option<&BlockItem>, + Option<&BlockContainer>, + Option<&GridItem>, + Option<&GridContainer>, + Option<&FlexBoxItem>, + Option<&FlexBoxContainer>, + ), Option<&mut ContentSize>, Ref, )>, @@ -105,7 +115,7 @@ pub fn ui_layout_system( // Sync Node and ContentSize to Taffy for all nodes node_query .iter_mut() - .for_each(|(entity, node, content_size, computed_target)| { + .for_each(|(entity, node, displays, content_size, computed_target)| { if computed_target.is_changed() || node.is_changed() || content_size @@ -117,7 +127,7 @@ pub fn ui_layout_system( computed_target.physical_size.as_vec2(), ); let measure = content_size.and_then(|mut c| c.measure.take()); - ui_surface.upsert_node(&layout_context, entity, &node, measure); + ui_surface.upsert_node(&layout_context, entity, &node, displays, measure); } }); @@ -162,7 +172,7 @@ pub fn ui_layout_system( ui_root_entity, ); - let (_, _, _, computed_target) = node_query.get(ui_root_entity).unwrap(); + let (_, _, _, _, computed_target) = node_query.get(ui_root_entity).unwrap(); ui_surface.compute_layout( ui_root_entity, diff --git a/crates/bevy_ui/src/layout/ui_surface.rs b/crates/bevy_ui/src/layout/ui_surface.rs index 2df6afa947dac..5bae5b351ebe4 100644 --- a/crates/bevy_ui/src/layout/ui_surface.rs +++ b/crates/bevy_ui/src/layout/ui_surface.rs @@ -10,7 +10,10 @@ use bevy_ecs::{ use bevy_math::{UVec2, Vec2}; use bevy_utils::default; -use crate::{layout::convert, LayoutContext, LayoutError, Measure, MeasureArgs, Node, NodeMeasure}; +use crate::{ + layout::convert, BlockContainer, BlockItem, FlexBoxContainer, FlexBoxItem, GridContainer, + GridItem, LayoutContext, LayoutError, Measure, MeasureArgs, Node, NodeMeasure, +}; use bevy_text::CosmicFontSystem; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -74,6 +77,14 @@ impl UiSurface { layout_context: &LayoutContext, entity: Entity, node: &Node, + displays: ( + Option<&BlockItem>, + Option<&BlockContainer>, + Option<&GridItem>, + Option<&GridContainer>, + Option<&FlexBoxItem>, + Option<&FlexBoxContainer>, + ), mut new_node_context: Option, ) { let taffy = &mut self.taffy; @@ -93,18 +104,18 @@ impl UiSurface { taffy .set_style( taffy_node.id, - convert::from_node(node, layout_context, has_measure), + convert::from_node(node, displays, layout_context, has_measure), ) .unwrap(); } Entry::Vacant(entry) => { let taffy_node = if let Some(measure) = new_node_context.take() { taffy.new_leaf_with_context( - convert::from_node(node, layout_context, true), + convert::from_node(node, displays, layout_context, true), measure, ) } else { - taffy.new_leaf(convert::from_node(node, layout_context, false)) + taffy.new_leaf(convert::from_node(node, displays, layout_context, false)) }; entry.insert(taffy_node.unwrap().into()); } diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index df699f576011b..b35d2982a8fa8 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -498,56 +498,6 @@ pub struct Node { /// pub aspect_ratio: Option, - /// Used to control how each individual item is aligned by default within the space they're given. - /// - For Flexbox containers, sets default cross axis alignment of the child items. - /// - For CSS Grid containers, controls block (vertical) axis alignment of children of this grid container within their grid areas. - /// - /// This value is overridden if [`AlignSelf`] on the child node is set. - /// - /// - pub align_items: AlignItems, - - /// Used to control how each individual item is aligned by default within the space they're given. - /// - For Flexbox containers, this property has no effect. See `justify_content` for main axis alignment of flex items. - /// - For CSS Grid containers, sets default inline (horizontal) axis alignment of child items within their grid areas. - /// - /// This value is overridden if [`JustifySelf`] on the child node is set. - /// - /// - pub justify_items: JustifyItems, - - /// Used to control how the specified item is aligned within the space it's given. - /// - For Flexbox items, controls cross axis alignment of the item. - /// - For CSS Grid items, controls block (vertical) axis alignment of a grid item within its grid area. - /// - /// If set to `Auto`, alignment is inherited from the value of [`AlignItems`] set on the parent node. - /// - /// - pub align_self: AlignSelf, - - /// Used to control how the specified item is aligned within the space it's given. - /// - For Flexbox items, this property has no effect. See `justify_content` for main axis alignment of flex items. - /// - For CSS Grid items, controls inline (horizontal) axis alignment of a grid item within its grid area. - /// - /// If set to `Auto`, alignment is inherited from the value of [`JustifyItems`] set on the parent node. - /// - /// - pub justify_self: JustifySelf, - - /// Used to control how items are distributed. - /// - For Flexbox containers, controls alignment of lines if `flex_wrap` is set to [`FlexWrap::Wrap`] and there are multiple lines of items. - /// - For CSS Grid containers, controls alignment of grid rows. - /// - /// - pub align_content: AlignContent, - - /// Used to control how items are distributed. - /// - For Flexbox containers, controls alignment of items in the main axis. - /// - For CSS Grid containers, controls alignment of grid columns. - /// - /// - pub justify_content: JustifyContent, - /// The amount of space around a node outside its border. /// /// If a percentage value is used, the percentage is calculated based on the width of the parent node. @@ -600,47 +550,206 @@ pub struct Node { /// /// pub border: UiRect, +} +impl Node { + pub const DEFAULT: Self = Self { + aspect_ratio: None, + display: Display::DEFAULT, + box_sizing: BoxSizing::DEFAULT, + position_type: PositionType::DEFAULT, + left: Val::Auto, + right: Val::Auto, + top: Val::Auto, + bottom: Val::Auto, + margin: UiRect::DEFAULT, + padding: UiRect::DEFAULT, + border: UiRect::DEFAULT, + width: Val::Auto, + height: Val::Auto, + min_width: Val::Auto, + min_height: Val::Auto, + max_width: Val::Auto, + max_height: Val::Auto, + overflow: Overflow::DEFAULT, + overflow_clip_margin: OverflowClipMargin::DEFAULT, + scrollbar_width: 0., + }; +} - /// Whether a Flexbox container should be a row or a column. This property has no effect on Grid nodes. +impl Default for Node { + fn default() -> Self { + Self::DEFAULT + } +} +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[require(Node)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct BlockItem { + // Setting this to false is equivlant to display: None + pub display: bool, + + /// Used to control how the specified item is aligned within the space it's given. + /// - For Flexbox items, this property has no effect. See `justify_content` for main axis alignment of flex items. + /// - For CSS Grid items, controls inline (horizontal) axis alignment of a grid item within its grid area. /// - /// - pub flex_direction: FlexDirection, + /// If set to `Auto`, alignment is inherited from the value of [`JustifyItems`] set on the parent node. + /// + /// + pub justify_self: JustifySelf, +} +impl BlockItem { + const DEFAULT: Self = Self { + display: true, + justify_self: JustifySelf::DEFAULT, + }; +} +impl Default for BlockItem { + fn default() -> Self { + Self::DEFAULT + } +} +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[require(Node)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct BlockContainer { + // Setting this to false is equivlant to display: None + pub display: bool, + /// Used to control how items are distributed. + /// - For Flexbox containers, controls alignment of lines if `flex_wrap` is set to [`FlexWrap::Wrap`] and there are multiple lines of items. + /// - For CSS Grid containers, controls alignment of grid rows. + /// + /// + pub align_content: AlignContent, - /// Whether a Flexbox container should wrap its contents onto multiple lines if they overflow. This property has no effect on Grid nodes. + /// Used to control how each individual item is aligned by default within the space they're given. + /// - For Flexbox containers, this property has no effect. See `justify_content` for main axis alignment of flex items. + /// - For CSS Grid containers, sets default inline (horizontal) axis alignment of child items within their grid areas. /// - /// - pub flex_wrap: FlexWrap, + /// This value is overridden if [`JustifySelf`] on the child node is set. + /// + /// + pub justify_items: JustifyItems, +} +impl BlockContainer { + const DEFAULT: Self = Self { + display: true, + align_content: AlignContent::Default, + justify_items: JustifyItems::Default, + }; +} +impl Default for BlockContainer { + fn default() -> Self { + Self::DEFAULT + } +} - /// Defines how much a flexbox item should grow if there's space available. Defaults to 0 (don't grow at all). +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[require(Node)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct GridItem { + // Setting this to false is equivlant to display: None + pub display: bool, + + /// Used to control how the specified item is aligned within the space it's given. + /// - For Flexbox items, controls cross axis alignment of the item. + /// - For CSS Grid items, controls block (vertical) axis alignment of a grid item within its grid area. /// - /// - pub flex_grow: f32, + /// If set to `Auto`, alignment is inherited from the value of [`AlignItems`] set on the parent node. + /// + /// + pub align_self: AlignSelf, - /// Defines how much a flexbox item should shrink if there's not enough space available. Defaults to 1. + /// Used to control how the specified item is aligned within the space it's given. + /// - For Flexbox items, this property has no effect. See `justify_content` for main axis alignment of flex items. + /// - For CSS Grid items, controls inline (horizontal) axis alignment of a grid item within its grid area. /// - /// - pub flex_shrink: f32, + /// If set to `Auto`, alignment is inherited from the value of [`JustifyItems`] set on the parent node. + /// + /// + pub justify_self: JustifySelf, + /// The row in which a grid item starts and how many rows it spans. + /// + /// + pub grid_row: GridPlacement, - /// The initial length of a flexbox in the main axis, before flex growing/shrinking properties are applied. + /// The column in which a grid item starts and how many columns it spans. /// - /// `flex_basis` overrides `width` (if the main axis is horizontal) or `height` (if the main axis is vertical) when both are set, but it obeys the constraints defined by `min_width`/`min_height` and `max_width`/`max_height`. + /// + pub grid_column: GridPlacement, +} +impl GridItem { + const DEFAULT: Self = Self { + display: true, + align_self: AlignSelf::DEFAULT, + justify_self: JustifySelf::DEFAULT, + grid_row: GridPlacement::DEFAULT, + grid_column: GridPlacement::DEFAULT, + }; +} +impl Default for GridItem { + fn default() -> Self { + Self::DEFAULT + } +} + +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[require(Node)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct GridContainer { + // Setting this to false is equivlant to display: None + pub display: bool, + + /// Used to control how each individual item is aligned by default within the space they're given. + /// - For Flexbox containers, sets default cross axis alignment of the child items. + /// - For CSS Grid containers, controls block (vertical) axis alignment of children of this grid container within their grid areas. /// - /// - pub flex_basis: Val, + /// This value is overridden if [`AlignSelf`] on the child node is set. + /// + /// + pub align_items: AlignItems, - /// The size of the gutters between items in a vertical flexbox layout or between rows in a grid layout. + /// Used to control how each individual item is aligned by default within the space they're given. + /// - For Flexbox containers, this property has no effect. See `justify_content` for main axis alignment of flex items. + /// - For CSS Grid containers, sets default inline (horizontal) axis alignment of child items within their grid areas. /// - /// Note: Values of `Val::Auto` are not valid and are treated as zero. + /// This value is overridden if [`JustifySelf`] on the child node is set. /// - /// - pub row_gap: Val, + /// + pub justify_items: JustifyItems, - /// The size of the gutters between items in a horizontal flexbox layout or between column in a grid layout. + /// Used to control how items are distributed. + /// - For Flexbox containers, controls alignment of lines if `flex_wrap` is set to [`FlexWrap::Wrap`] and there are multiple lines of items. + /// - For CSS Grid containers, controls alignment of grid rows. /// - /// Note: Values of `Val::Auto` are not valid and are treated as zero. + /// + pub align_content: AlignContent, + + /// Used to control how items are distributed. + /// - For Flexbox containers, controls alignment of items in the main axis. + /// - For CSS Grid containers, controls alignment of grid columns. /// - /// - pub column_gap: Val, + /// + pub justify_content: JustifyContent, /// Controls whether automatically placed grid items are placed row-wise or column-wise as well as whether the sparse or dense packing algorithm is used. /// Only affects Grid layouts. @@ -670,69 +779,167 @@ pub struct Node { /// /// pub grid_auto_columns: Vec, - - /// The row in which a grid item starts and how many rows it spans. + /// The size of the gutters between items in a vertical flexbox layout or between rows in a grid layout. /// - /// - pub grid_row: GridPlacement, + /// Note: Values of `Val::Auto` are not valid and are treated as zero. + /// + /// + pub row_gap: Val, - /// The column in which a grid item starts and how many columns it spans. + /// The size of the gutters between items in a horizontal flexbox layout or between column in a grid layout. /// - /// - pub grid_column: GridPlacement, + /// Note: Values of `Val::Auto` are not valid and are treated as zero. + /// + /// + pub column_gap: Val, } - -impl Node { - pub const DEFAULT: Self = Self { - display: Display::DEFAULT, - box_sizing: BoxSizing::DEFAULT, - position_type: PositionType::DEFAULT, - left: Val::Auto, - right: Val::Auto, - top: Val::Auto, - bottom: Val::Auto, - flex_direction: FlexDirection::DEFAULT, - flex_wrap: FlexWrap::DEFAULT, +impl GridContainer { + const DEFAULT: GridContainer = Self { + display: true, align_items: AlignItems::DEFAULT, justify_items: JustifyItems::DEFAULT, - align_self: AlignSelf::DEFAULT, - justify_self: JustifySelf::DEFAULT, align_content: AlignContent::DEFAULT, justify_content: JustifyContent::DEFAULT, - margin: UiRect::DEFAULT, - padding: UiRect::DEFAULT, - border: UiRect::DEFAULT, - flex_grow: 0.0, - flex_shrink: 1.0, - flex_basis: Val::Auto, - width: Val::Auto, - height: Val::Auto, - min_width: Val::Auto, - min_height: Val::Auto, - max_width: Val::Auto, - max_height: Val::Auto, - aspect_ratio: None, - overflow: Overflow::DEFAULT, - overflow_clip_margin: OverflowClipMargin::DEFAULT, - scrollbar_width: 0., - row_gap: Val::ZERO, - column_gap: Val::ZERO, grid_auto_flow: GridAutoFlow::DEFAULT, grid_template_rows: Vec::new(), grid_template_columns: Vec::new(), grid_auto_rows: Vec::new(), grid_auto_columns: Vec::new(), - grid_column: GridPlacement::DEFAULT, - grid_row: GridPlacement::DEFAULT, + row_gap: Val::DEFAULT, + column_gap: Val::DEFAULT, }; } +impl Default for GridContainer { + fn default() -> Self { + Self::DEFAULT + } +} +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[require(Node)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct FlexBoxContainer { + // Setting this to false is equivlant to display: None + pub display: bool, + /// Used to control how items are distributed. + /// - For Flexbox containers, controls alignment of items in the main axis. + /// - For CSS Grid containers, controls alignment of grid columns. + /// + /// + pub justify_content: JustifyContent, -impl Default for Node { + /// Used to control how each individual item is aligned by default within the space they're given. + /// - For Flexbox containers, sets default cross axis alignment of the child items. + /// - For CSS Grid containers, controls block (vertical) axis alignment of children of this grid container within their grid areas. + /// + /// This value is overridden if [`AlignSelf`] on the child node is set. + /// + /// + pub align_items: AlignItems, + + /// Used to control how items are distributed. + /// - For Flexbox containers, controls alignment of lines if `flex_wrap` is set to [`FlexWrap::Wrap`] and there are multiple lines of items. + /// - For CSS Grid containers, controls alignment of grid rows. + /// + /// + pub align_content: AlignContent, + + /// Whether a Flexbox container should be a row or a column. This property has no effect on Grid nodes. + /// + /// + pub flex_direction: FlexDirection, + + /// Whether a Flexbox container should wrap its contents onto multiple lines if they overflow. This property has no effect on Grid nodes. + /// + /// + pub flex_wrap: FlexWrap, + /// The size of the gutters between items in a vertical flexbox layout or between rows in a grid layout. + /// + /// Note: Values of `Val::Auto` are not valid and are treated as zero. + /// + /// + pub row_gap: Val, + + /// The size of the gutters between items in a horizontal flexbox layout or between column in a grid layout. + /// + /// Note: Values of `Val::Auto` are not valid and are treated as zero. + /// + /// + pub column_gap: Val, +} +impl FlexBoxContainer { + const DEFAULT: Self = Self { + justify_content: JustifyContent::DEFAULT, + align_items: AlignItems::DEFAULT, + align_content: AlignContent::DEFAULT, + display: true, + flex_direction: FlexDirection::DEFAULT, + flex_wrap: FlexWrap::DEFAULT, + row_gap: Val::DEFAULT, + column_gap: Val::DEFAULT, + }; +} +impl Default for FlexBoxContainer { fn default() -> Self { Self::DEFAULT } } +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[require(Node)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct FlexBoxItem { + // Setting this to false is equivlant to display: None + pub display: bool, + /// Used to control how the specified item is aligned within the space it's given. + /// - For Flexbox items, controls cross axis alignment of the item. + /// - For CSS Grid items, controls block (vertical) axis alignment of a grid item within its grid area. + /// + /// If set to `Auto`, alignment is inherited from the value of [`AlignItems`] set on the parent node. + /// + /// + pub align_self: AlignSelf, + + /// Defines how much a flexbox item should grow if there's space available. Defaults to 0 (don't grow at all). + /// + /// + pub flex_grow: f32, + + /// Defines how much a flexbox item should shrink if there's not enough space available. Defaults to 1. + /// + /// + pub flex_shrink: f32, + + /// The initial length of a flexbox in the main axis, before flex growing/shrinking properties are applied. + /// + /// `flex_basis` overrides `width` (if the main axis is horizontal) or `height` (if the main axis is vertical) when both are set, but it obeys the constraints defined by `min_width`/`min_height` and `max_width`/`max_height`. + /// + /// + pub flex_basis: Val, +} +impl FlexBoxItem { + const DEFAULT: Self = Self { + display: true, + align_self: AlignSelf::DEFAULT, + flex_grow: 0.0f32, + flex_shrink: 1.0f32, + flex_basis: Val::DEFAULT, + }; +} +impl Default for FlexBoxItem { + fn default() -> Self { + Self::DEFAULT + } +} /// Used to control how each individual item is aligned by default within the space they're given. /// - For Flexbox containers, sets default cross axis alignment of the child items. /// - For CSS Grid containers, controls block (vertical) axis alignment of children of this grid container within their grid areas.