From 1234acc44a4d04b01a8e31208b57432614345266 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 2 Mar 2023 21:21:05 +0000 Subject: [PATCH 1/6] Add style builder methods to bevy_ui Style struct --- crates/bevy_ui/src/ui_node.rs | 302 ++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 46beae57f8247..fd3264aecb311 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -341,6 +341,308 @@ 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: Val) -> Self { + self.position.left = val; + self + } + /// Set the `position.left` property + pub fn right(mut self, val: Val) -> Self { + self.position.right = val; + self + } + /// Set the `position.top` property + pub fn top(mut self, val: Val) -> Self { + self.position.top = val; + self + } + /// Set the `position.bottom` property + pub fn bottom(mut self, val: Val) -> Self { + self.position.bottom = val; + self + } + /// Set the `position.left` and `position.right` properties + pub fn position_horizontal(mut self, val: Val) -> Self { + self.position.right = val; + self.position.left = val; + self + } + /// Set the `position.top` and `position.bottom` properties + pub fn position_vertical(mut self, val: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + self.margin.left = val; + self + } + /// Set the `margin.left` property + pub fn margin_right(mut self, val: Val) -> Self { + self.margin.right = val; + self + } + /// Set the `margin.top` property + pub fn margin_top(mut self, val: Val) -> Self { + self.margin.top = val; + self + } + /// Set the `margin.bottom` property + pub fn margin_bottom(mut self, val: Val) -> Self { + self.margin.bottom = val; + self + } + /// Set the `margin.left` and `margin.right` properties + pub fn margin_horizontal(mut self, val: Val) -> Self { + self.margin.right = val; + self.margin.left = val; + self + } + /// Set the `margin.top` and `margin.bottom` properties + pub fn margin_vertical(mut self, val: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + self.padding.left = val; + self + } + /// Set the `padding.left` property + pub fn padding_right(mut self, val: Val) -> Self { + self.padding.right = val; + self + } + /// Set the `padding.top` property + pub fn padding_top(mut self, val: Val) -> Self { + self.padding.top = val; + self + } + /// Set the `padding.bottom` property + pub fn padding_bottom(mut self, val: Val) -> Self { + self.padding.bottom = val; + self + } + /// Set the `padding.left` and `padding.right` properties + pub fn padding_horizontal(mut self, val: Val) -> Self { + self.padding.right = val; + self.padding.left = val; + self + } + /// Set the `padding.top` and `padding.bottom` properties + pub fn padding_vertical(mut self, val: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + self.border.left = val; + self + } + /// Set the `border.left` property + pub fn border_right(mut self, val: Val) -> Self { + self.border.right = val; + self + } + /// Set the `border.top` property + pub fn border_top(mut self, val: Val) -> Self { + self.border.top = val; + self + } + /// Set the `border.bottom` property + pub fn border_bottom(mut self, val: Val) -> Self { + self.border.bottom = val; + self + } + /// Set the `border.left` and `border.right` properties + pub fn border_horizontal(mut self, val: Val) -> Self { + self.border.right = val; + self.border.left = val; + self + } + /// Set the `border.top` and `border.bottom` properties + pub fn border_vertical(mut self, val: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + self.flex_basis = val; + self + } + /// Set the `size.width` property + pub fn width(mut self, val: Val) -> Self { + self.size.width = val; + self + } + /// Set the `size.height` property + pub fn height(mut self, val: Val) -> Self { + self.size.height = val; + self + } + /// Set the `min_size.width` property + pub fn min_width(mut self, val: Val) -> Self { + self.min_size.width = val; + self + } + /// Set the `min_size.height` property + pub fn min_height(mut self, val: Val) -> Self { + self.min_size.height = val; + self + } + /// Set the `max_size.width` property + pub fn max_width(mut self, val: Val) -> Self { + self.max_size.width = val; + self + } + /// Set the `max_size.height` property + pub fn max_height(mut self, val: Val) -> Self { + self.max_size.height = val; + 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: Val) -> Self { + self.gap.height = val; + self + } + /// Set the spacing between columns + pub fn column_gap(mut self, val: Val) -> Self { + self.gap.width = val; + self + } + /// Set the spacing between both rows and columns + pub fn gap(mut self, val: Val) -> Self { + self.gap.width = val; + self.gap.height = val; + self + } } impl Default for Style { From 94f1cbf3680b6e2fa5165fc915e63535ad857aae Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 2 Mar 2023 21:26:04 +0000 Subject: [PATCH 2/6] Add with_style method to NodeBundle --- crates/bevy_ui/src/node_bundles.rs | 9 +++++++++ 1 file changed, 9 insertions(+) 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 { From 84d17faab2aa835e68291642588c77fea4ac8fd8 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 3 Mar 2023 00:06:37 +0000 Subject: [PATCH 3/6] Add From and From impls for Val --- crates/bevy_ui/src/ui_node.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index fd3264aecb311..42575185d6685 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; From 9252aa327cc8578c05813277ed6abb0443ee56c0 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 3 Mar 2023 00:11:25 +0000 Subject: [PATCH 4/6] Add methods to center node content --- crates/bevy_ui/src/ui_node.rs | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 42575185d6685..46d5dc5fddd03 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -655,6 +655,46 @@ impl Style { 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 { From 6960be35eb277362db8c46979f0973319f653ed3 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 3 Mar 2023 00:23:27 +0000 Subject: [PATCH 5/6] Convert builder methods to take impl Into instead of Val --- crates/bevy_ui/src/ui_node.rs | 139 +++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 63 deletions(-) diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 46d5dc5fddd03..9e5024c178bf1 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -421,39 +421,42 @@ impl Style { } /// Set the `position.left` property - pub fn left(mut self, val: Val) -> Self { - self.position.left = val; + 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: Val) -> Self { - self.position.right = val; + 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: Val) -> Self { - self.position.top = val; + 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: Val) -> Self { - self.position.bottom = val; + 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: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + 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; @@ -462,39 +465,42 @@ impl Style { } /// Set the `margin.left` property - pub fn margin_left(mut self, val: Val) -> Self { - self.margin.left = val; + 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: Val) -> Self { - self.margin.right = val; + 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: Val) -> Self { - self.margin.top = val; + 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: Val) -> Self { - self.margin.bottom = val; + 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: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + 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; @@ -503,39 +509,42 @@ impl Style { } /// Set the `padding.left` property - pub fn padding_left(mut self, val: Val) -> Self { - self.padding.left = val; + 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: Val) -> Self { - self.padding.right = val; + 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: Val) -> Self { - self.padding.top = val; + 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: Val) -> Self { - self.padding.bottom = val; + 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: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + 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; @@ -544,39 +553,42 @@ impl Style { } /// Set the `border.left` property - pub fn border_left(mut self, val: Val) -> Self { - self.border.left = val; + 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: Val) -> Self { - self.border.right = val; + 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: Val) -> Self { - self.border.top = val; + 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: Val) -> Self { - self.border.bottom = val; + 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: Val) -> Self { + 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: Val) -> Self { + 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: Val) -> Self { + 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; @@ -595,38 +607,38 @@ impl Style { self } /// Set the `flex_basis` property - pub fn flex_basis(mut self, val: Val) -> Self { - self.flex_basis = val; + 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: Val) -> Self { - self.size.width = val; + 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: Val) -> Self { - self.size.height = val; + 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: Val) -> Self { - self.min_size.width = val; + 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: Val) -> Self { - self.min_size.height = val; + 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: Val) -> Self { - self.max_size.width = val; + 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: Val) -> Self { - self.max_size.height = val; + pub fn max_height(mut self, val: impl Into) -> Self { + self.max_size.height = val.into(); self } /// Set the `aspect_ratio` property @@ -640,17 +652,18 @@ impl Style { self } /// Set the spacing between rows - pub fn row_gap(mut self, val: Val) -> Self { - self.gap.height = val; + 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: Val) -> Self { - self.gap.width = val; + 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: Val) -> Self { + pub fn gap(mut self, val: impl Into) -> Self { + let val = val.into(); self.gap.width = val; self.gap.height = val; self From dd799a51703024a3407305c3f5b1bd125493be6e Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 3 Mar 2023 00:25:56 +0000 Subject: [PATCH 6/6] Update button example --- examples/ui/button.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) 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() })