diff --git a/crates/bevy_ui/src/node_bundles.rs b/crates/bevy_ui/src/node_bundles.rs index c5c3e3171fc42..ced5d54c5bd39 100644 --- a/crates/bevy_ui/src/node_bundles.rs +++ b/crates/bevy_ui/src/node_bundles.rs @@ -44,6 +44,15 @@ pub struct NodeBundle { pub z_index: ZIndex, } +impl NodeBundle { + pub fn with_style(style: Style) -> Self { + Self { + style, + ..Default::default() + } + } +} + impl Default for NodeBundle { fn default() -> Self { NodeBundle { diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 46beae57f8247..9e5024c178bf1 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -64,6 +64,18 @@ impl Default for Val { } } +impl From for Val { + fn from(value: f32) -> Self { + Self::Px(value) + } +} + +impl From for Val { + fn from(value: i32) -> Self { + Self::Px(value as f32) + } +} + impl Mul for Val { type Output = Val; @@ -341,6 +353,361 @@ impl Style { overflow: Overflow::DEFAULT, gap: Size::UNDEFINED, }; + + /// Construct a style instance with `flex_direction` set to `FlexDirection::Row` + pub fn row() -> Self { + Self { + display: Display::Flex, + flex_direction: FlexDirection::Row, + ..Self::DEFAULT + } + } + + /// Construct a style instance with `flex_direction` set to `FlexDirection::Column` + pub fn column() -> Self { + Self { + display: Display::Flex, + flex_direction: FlexDirection::Row, + ..Self::DEFAULT + } + } + + /// Set the `display` property + pub fn display(mut self, val: Display) -> Self { + self.display = val; + self + } + + /// Set the `position_type` property + pub fn position_type(mut self, val: PositionType) -> Self { + self.position_type = val; + self + } + + /// Set the `direction` property + pub fn direction(mut self, val: Direction) -> Self { + self.direction = val; + self + } + /// Set the `flex_direction` property + pub fn flex_direction(mut self, val: FlexDirection) -> Self { + self.flex_direction = val; + self + } + /// Set the `flex_wrap` property + pub fn flex_wrap(mut self, val: FlexWrap) -> Self { + self.flex_wrap = val; + self + } + /// Set the `align_items` property + pub fn align_items(mut self, val: AlignItems) -> Self { + self.align_items = val; + self + } + /// Set the `align_self` property + pub fn align_self(mut self, val: AlignSelf) -> Self { + self.align_self = val; + self + } + /// Set the `align_content` property + pub fn align_content(mut self, val: AlignContent) -> Self { + self.align_content = val; + self + } + /// Set the `justify_content` property + pub fn justify_content(mut self, val: JustifyContent) -> Self { + self.justify_content = val; + self + } + + /// Set the `position.left` property + pub fn left(mut self, val: impl Into) -> Self { + self.position.left = val.into(); + self + } + /// Set the `position.left` property + pub fn right(mut self, val: impl Into) -> Self { + self.position.right = val.into(); + self + } + /// Set the `position.top` property + pub fn top(mut self, val: impl Into) -> Self { + self.position.top = val.into(); + self + } + /// Set the `position.bottom` property + pub fn bottom(mut self, val: impl Into) -> Self { + self.position.bottom = val.into(); + self + } + /// Set the `position.left` and `position.right` properties + pub fn position_horizontal(mut self, val: impl Into) -> Self { + let val = val.into(); + self.position.right = val; + self.position.left = val; + self + } + /// Set the `position.top` and `position.bottom` properties + pub fn position_vertical(mut self, val: impl Into) -> Self { + let val = val.into(); + self.position.top = val; + self.position.bottom = val; + self + } + /// Set the `position.top`,`position.bottom`,`position.left`, and `position.right` properties + pub fn position(mut self, val: impl Into) -> Self { + let val = val.into(); + self.position.top = val; + self.position.bottom = val; + self.position.left = val; + self.position.right = val; + self + } + + /// Set the `margin.left` property + pub fn margin_left(mut self, val: impl Into) -> Self { + self.margin.left = val.into(); + self + } + /// Set the `margin.left` property + pub fn margin_right(mut self, val: impl Into) -> Self { + self.margin.right = val.into(); + self + } + /// Set the `margin.top` property + pub fn margin_top(mut self, val: impl Into) -> Self { + self.margin.top = val.into(); + self + } + /// Set the `margin.bottom` property + pub fn margin_bottom(mut self, val: impl Into) -> Self { + self.margin.bottom = val.into(); + self + } + /// Set the `margin.left` and `margin.right` properties + pub fn margin_horizontal(mut self, val: impl Into) -> Self { + let val = val.into(); + self.margin.right = val; + self.margin.left = val; + self + } + /// Set the `margin.top` and `margin.bottom` properties + pub fn margin_vertical(mut self, val: impl Into) -> Self { + let val = val.into(); + self.margin.top = val; + self.margin.bottom = val; + self + } + /// Set the `margin.top`,`margin.bottom`,`margin.left`, and `margin.right` properties + pub fn margin(mut self, val: impl Into) -> Self { + let val = val.into(); + self.margin.top = val; + self.margin.bottom = val; + self.margin.left = val; + self.margin.right = val; + self + } + + /// Set the `padding.left` property + pub fn padding_left(mut self, val: impl Into) -> Self { + self.padding.left = val.into(); + self + } + /// Set the `padding.left` property + pub fn padding_right(mut self, val: impl Into) -> Self { + self.padding.right = val.into(); + self + } + /// Set the `padding.top` property + pub fn padding_top(mut self, val: impl Into) -> Self { + self.padding.top = val.into(); + self + } + /// Set the `padding.bottom` property + pub fn padding_bottom(mut self, val: impl Into) -> Self { + self.padding.bottom = val.into(); + self + } + /// Set the `padding.left` and `padding.right` properties + pub fn padding_horizontal(mut self, val: impl Into) -> Self { + let val = val.into(); + self.padding.right = val; + self.padding.left = val; + self + } + /// Set the `padding.top` and `padding.bottom` properties + pub fn padding_vertical(mut self, val: impl Into) -> Self { + let val = val.into(); + self.padding.top = val; + self.padding.bottom = val; + self + } + /// Set the `padding.top`,`padding.bottom`,`padding.left`, and `padding.right` properties + pub fn padding(mut self, val: impl Into) -> Self { + let val = val.into(); + self.padding.top = val; + self.padding.bottom = val; + self.padding.left = val; + self.padding.right = val; + self + } + + /// Set the `border.left` property + pub fn border_left(mut self, val: impl Into) -> Self { + self.border.left = val.into(); + self + } + /// Set the `border.left` property + pub fn border_right(mut self, val: impl Into) -> Self { + self.border.right = val.into(); + self + } + /// Set the `border.top` property + pub fn border_top(mut self, val: impl Into) -> Self { + self.border.top = val.into(); + self + } + /// Set the `border.bottom` property + pub fn border_bottom(mut self, val: impl Into) -> Self { + self.border.bottom = val.into(); + self + } + /// Set the `border.left` and `border.right` properties + pub fn border_horizontal(mut self, val: impl Into) -> Self { + let val = val.into(); + self.border.right = val; + self.border.left = val; + self + } + /// Set the `border.top` and `border.bottom` properties + pub fn border_vertical(mut self, val: impl Into) -> Self { + let val = val.into(); + self.border.top = val; + self.border.bottom = val; + self + } + /// Set the `border.top`,`border.bottom`,`border.left`, and `border.right` properties + pub fn border(mut self, val: impl Into) -> Self { + let val = val.into(); + self.border.top = val; + self.border.bottom = val; + self.border.left = val; + self.border.right = val; + self + } + + /// Set the `flex_grow` property + pub fn flex_grow(mut self, val: f32) -> Self { + self.flex_grow = val; + self + } + /// Set the `flex_shrink` property + pub fn flex_shrink(mut self, val: f32) -> Self { + self.flex_shrink = val; + self + } + /// Set the `flex_basis` property + pub fn flex_basis(mut self, val: impl Into) -> Self { + self.flex_basis = val.into(); + self + } + /// Set the `size.width` property + pub fn width(mut self, val: impl Into) -> Self { + self.size.width = val.into(); + self + } + /// Set the `size.height` property + pub fn height(mut self, val: impl Into) -> Self { + self.size.height = val.into(); + self + } + /// Set the `min_size.width` property + pub fn min_width(mut self, val: impl Into) -> Self { + self.min_size.width = val.into(); + self + } + /// Set the `min_size.height` property + pub fn min_height(mut self, val: impl Into) -> Self { + self.min_size.height = val.into(); + self + } + /// Set the `max_size.width` property + pub fn max_width(mut self, val: impl Into) -> Self { + self.max_size.width = val.into(); + self + } + /// Set the `max_size.height` property + pub fn max_height(mut self, val: impl Into) -> Self { + self.max_size.height = val.into(); + self + } + /// Set the `aspect_ratio` property + pub fn aspect_ratio(mut self, val: f32) -> Self { + self.aspect_ratio = Some(val); + self + } + /// Set the `overflow` property + pub fn overflow(mut self, val: Overflow) -> Self { + self.overflow = val; + self + } + /// Set the spacing between rows + pub fn row_gap(mut self, val: impl Into) -> Self { + self.gap.height = val.into(); + self + } + /// Set the spacing between columns + pub fn column_gap(mut self, val: impl Into) -> Self { + self.gap.width = val.into(); + self + } + /// Set the spacing between both rows and columns + pub fn gap(mut self, val: impl Into) -> Self { + let val = val.into(); + self.gap.width = val; + self.gap.height = val; + self + } + + /// Center content in the vertical axis using the `align_items` `align_content` and `justify_content` properties + pub fn center_content_vertically(mut self) -> Self { + match (self.display, self.flex_direction) { + (Display::Flex, FlexDirection::Row | FlexDirection::RowReverse) => { + self.align_items = AlignItems::Center; + self.align_content = AlignContent::Center; + } + (Display::Flex, FlexDirection::Column | FlexDirection::ColumnReverse) => { + self.justify_content = JustifyContent::Center; + } + _ => {} + } + + self + } + + /// Center content in the vertical axis using the `align_items` and `justify_content` properties + pub fn center_content_horizontally(mut self) -> Self { + match (self.display, self.flex_direction) { + (Display::Flex, FlexDirection::Row | FlexDirection::RowReverse) => { + self.justify_content = JustifyContent::Center; + } + (Display::Flex, FlexDirection::Column | FlexDirection::ColumnReverse) => { + self.align_content = AlignContent::Center; + self.align_items = AlignItems::Center; + } + _ => {} + } + + self + } + + /// Center content in both axes using the `align_items` and `justify_content` properties + pub fn center_content(mut self) -> Self { + self.align_items = AlignItems::Center; + self.justify_content = JustifyContent::Center; + self.align_content = AlignContent::Center; + self + } } impl Default for Style { diff --git a/examples/ui/button.rs b/examples/ui/button.rs index aa364baf8bc55..b14bbcbda45aa 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -47,26 +47,18 @@ fn setup(mut commands: Commands, asset_server: Res) { // ui camera commands.spawn(Camera2dBundle::default()); commands - .spawn(NodeBundle { - style: Style { - size: Size::width(Val::Percent(100.0)), - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, - ..default() - }) + .spawn(NodeBundle::with_style( + Style::row() + .width(Val::Percent(100.0)) + .center_content() + )) .with_children(|parent| { parent .spawn(ButtonBundle { - style: Style { - size: Size::new(Val::Px(150.0), Val::Px(65.0)), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - ..default() - }, + style: Style::row() + .width(150) + .height(65) + .center_content(), background_color: NORMAL_BUTTON.into(), ..default() })