diff --git a/crates/bevy_ui/Cargo.toml b/crates/bevy_ui/Cargo.toml index 1517543e16..321388d63b 100644 --- a/crates/bevy_ui/Cargo.toml +++ b/crates/bevy_ui/Cargo.toml @@ -33,7 +33,7 @@ bevy_window = { path = "../bevy_window", version = "0.15.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" } # other -taffy = { version = "0.5" } +taffy = { version = "0.6" } serde = { version = "1", features = ["derive"], optional = true } bytemuck = { version = "1.5", features = ["derive"] } derive_more = { version = "1", default-features = false, features = [ diff --git a/crates/bevy_ui/src/layout/convert.rs b/crates/bevy_ui/src/layout/convert.rs index cbe790f3f5..42aaa77f73 100644 --- a/crates/bevy_ui/src/layout/convert.rs +++ b/crates/bevy_ui/src/layout/convert.rs @@ -1,7 +1,7 @@ use taffy::style_helpers; use crate::{ - AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, GridAutoFlow, + AlignContent, AlignItems, AlignSelf, BoxSizing, Display, FlexDirection, FlexWrap, GridAutoFlow, GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf, MaxTrackSizingFunction, MinTrackSizingFunction, Node, OverflowAxis, PositionType, RepeatedGridTrack, UiRect, Val, @@ -66,6 +66,9 @@ impl UiRect { pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> taffy::style::Style { taffy::style::Style { display: node.display.into(), + box_sizing: node.box_sizing.into(), + item_is_table: false, + text_align: taffy::TextAlign::Auto, overflow: taffy::Point { x: node.overflow.x.into(), y: node.overflow.y.into(), @@ -247,6 +250,15 @@ impl From for taffy::style::Display { } } +impl From for taffy::style::BoxSizing { + fn from(value: BoxSizing) -> Self { + match value { + BoxSizing::BorderBox => taffy::style::BoxSizing::BorderBox, + BoxSizing::ContentBox => taffy::style::BoxSizing::ContentBox, + } + } +} + impl From for taffy::style::Overflow { fn from(value: OverflowAxis) -> Self { match value { @@ -445,6 +457,7 @@ mod tests { let node = Node { display: Display::Flex, + box_sizing: BoxSizing::ContentBox, position_type: PositionType::Absolute, left: Val::ZERO, right: Val::Percent(50.), @@ -513,6 +526,7 @@ mod tests { let viewport_values = LayoutContext::new(1.0, bevy_math::Vec2::new(800., 600.)); let taffy_style = from_node(&node, &viewport_values, false); assert_eq!(taffy_style.display, taffy::style::Display::Flex); + assert_eq!(taffy_style.box_sizing, taffy::style::BoxSizing::ContentBox); assert_eq!(taffy_style.position, taffy::style::Position::Absolute); assert_eq!( taffy_style.inset.left, diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index b35bf42dfa..b9658f794d 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -324,6 +324,15 @@ pub struct Node { /// pub display: Display, + /// Which part of a Node's box length styles like width and height control + /// - [`BoxSizing::BorderBox`]: They refer to the "border box" size (size including padding and border) + /// - [`BoxSizing::ContentBox`]: They refer to the "content box" size (size excluding padding and border) + /// + /// `BoxSizing::BorderBox` is generally considered more intuitive and is the default in Bevy even though it is not on the web. + /// + /// See: + pub box_sizing: BoxSizing, + /// Whether a node should be laid out in-flow with, or independently of its siblings: /// - [`PositionType::Relative`]: Layout this node in-flow with other nodes using the usual (flexbox/grid) layout algorithm. /// - [`PositionType::Absolute`]: Layout this node on top and independently of other nodes. @@ -591,6 +600,7 @@ pub struct Node { impl Node { pub const DEFAULT: Self = Self { display: Display::DEFAULT, + box_sizing: BoxSizing::DEFAULT, position_type: PositionType::DEFAULT, left: Val::Auto, right: Val::Auto, @@ -925,6 +935,31 @@ impl Default for Display { } } +/// Which part of a Node's box length styles like width and height control +/// +/// See: +#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)] +#[reflect(Default, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub enum BoxSizing { + /// Length styles like width and height refer to the "border box" size (size including padding and border) + BorderBox, + /// Length styles like width and height refer to the "content box" size (size excluding padding and border) + ContentBox, +} +impl BoxSizing { + pub const DEFAULT: Self = Self::BorderBox; +} +impl Default for BoxSizing { + fn default() -> Self { + Self::DEFAULT + } +} + /// Defines how flexbox items are ordered within a flexbox #[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)] #[reflect(Default, PartialEq)]