Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion crates/bevy_ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,14 @@ bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-fea
] }

# other
taffy = { version = "0.7" }
taffy = { version = "0.9", default-features = false, features = [
"std",
"block_layout",
"flexbox",
"grid",
"content_size",
"taffy_tree",
] }
serde = { version = "1", features = ["derive"], optional = true }
uuid = { version = "1.1", features = ["v4"], optional = true }
thiserror = { version = "2", default-features = false }
Expand Down
203 changes: 100 additions & 103 deletions crates/bevy_ui/src/layout/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,33 @@ impl Val {
context: &LayoutContext,
) -> taffy::style::LengthPercentageAuto {
match self {
Val::Auto => taffy::style::LengthPercentageAuto::Auto,
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.),
Val::Px(value) => {
taffy::style::LengthPercentageAuto::Length(context.scale_factor * value)
Val::Auto => style_helpers::auto(),
Val::Percent(value) => style_helpers::percent(value / 100.),
Val::Px(value) => style_helpers::length(context.scale_factor * value),
Val::VMin(value) => {
style_helpers::length(context.physical_size.min_element() * value / 100.)
}
Val::VMin(value) => taffy::style::LengthPercentageAuto::Length(
context.physical_size.min_element() * value / 100.,
),
Val::VMax(value) => taffy::style::LengthPercentageAuto::Length(
context.physical_size.max_element() * value / 100.,
),
Val::Vw(value) => {
taffy::style::LengthPercentageAuto::Length(context.physical_size.x * value / 100.)
}
Val::Vh(value) => {
taffy::style::LengthPercentageAuto::Length(context.physical_size.y * value / 100.)
Val::VMax(value) => {
style_helpers::length(context.physical_size.max_element() * value / 100.)
}
Val::Vw(value) => style_helpers::length(context.physical_size.x * value / 100.),
Val::Vh(value) => style_helpers::length(context.physical_size.y * value / 100.),
}
}

fn into_length_percentage(self, context: &LayoutContext) -> taffy::style::LengthPercentage {
match self.into_length_percentage_auto(context) {
taffy::style::LengthPercentageAuto::Auto => taffy::style::LengthPercentage::Length(0.0),
taffy::style::LengthPercentageAuto::Percent(value) => {
taffy::style::LengthPercentage::Percent(value)
match self {
Val::Auto => style_helpers::length(0.),
Val::Percent(value) => style_helpers::percent(value / 100.),
Val::Px(value) => style_helpers::length(context.scale_factor * value),
Val::VMin(value) => {
style_helpers::length(context.physical_size.min_element() * value / 100.)
}
taffy::style::LengthPercentageAuto::Length(value) => {
taffy::style::LengthPercentage::Length(value)
Val::VMax(value) => {
style_helpers::length(context.physical_size.max_element() * value / 100.)
}
Val::Vw(value) => style_helpers::length(context.physical_size.x * value / 100.),
Val::Vh(value) => style_helpers::length(context.physical_size.y * value / 100.),
}
}

Expand Down Expand Up @@ -146,6 +144,7 @@ pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> t
.collect::<Vec<_>>(),
grid_row: node.grid_row.into(),
grid_column: node.grid_column.into(),
..Default::default()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fields added are dummy, item_is_replaced, grid_template_areas, grid_template_column_names, grid_template_row_names. Not sure if this should be using their default or we should add these fields and have our own default.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dummy is just phantomdata. grid_template_areas, grid_template_column_names, and grid_template_row_names should all be left at their default values for now.

I'm confused about is_replaced. The CoreStyle trait seems to map it to is_compressible_replaced which isn't quite same thing as a replaced element, like a form field isn't compressible normally?

}
}

Expand Down Expand Up @@ -311,7 +310,7 @@ impl From<GridAutoFlow> for taffy::style::GridAutoFlow {
}
}

impl From<GridPlacement> for taffy::geometry::Line<taffy::style::GridPlacement> {
impl From<GridPlacement> for taffy::geometry::Line<taffy::style::GridPlacement<String>> {
fn from(value: GridPlacement) -> Self {
let span = value.get_span().unwrap_or(1);
match (value.get_start(), value.get_end()) {
Expand All @@ -335,77 +334,76 @@ impl From<GridPlacement> for taffy::geometry::Line<taffy::style::GridPlacement>
impl MinTrackSizingFunction {
fn into_taffy(self, context: &LayoutContext) -> taffy::style::MinTrackSizingFunction {
match self {
MinTrackSizingFunction::Px(val) => taffy::style::MinTrackSizingFunction::Fixed(
Val::Px(val).into_length_percentage(context),
),
MinTrackSizingFunction::Percent(val) => taffy::style::MinTrackSizingFunction::Fixed(
Val::Percent(val).into_length_percentage(context),
),
MinTrackSizingFunction::Auto => taffy::style::MinTrackSizingFunction::Auto,
MinTrackSizingFunction::MinContent => taffy::style::MinTrackSizingFunction::MinContent,
MinTrackSizingFunction::MaxContent => taffy::style::MinTrackSizingFunction::MaxContent,
MinTrackSizingFunction::VMin(val) => taffy::style::MinTrackSizingFunction::Fixed(
Val::VMin(val).into_length_percentage(context),
),
MinTrackSizingFunction::VMax(val) => taffy::style::MinTrackSizingFunction::Fixed(
Val::VMax(val).into_length_percentage(context),
),
MinTrackSizingFunction::Vh(val) => taffy::style::MinTrackSizingFunction::Fixed(
Val::Vh(val).into_length_percentage(context),
),
MinTrackSizingFunction::Vw(val) => taffy::style::MinTrackSizingFunction::Fixed(
Val::Vw(val).into_length_percentage(context),
),
MinTrackSizingFunction::Px(val) => Val::Px(val).into_length_percentage(context).into(),
MinTrackSizingFunction::Percent(val) => {
Val::Percent(val).into_length_percentage(context).into()
}
MinTrackSizingFunction::Auto => taffy::style::MinTrackSizingFunction::auto(),
MinTrackSizingFunction::MinContent => {
taffy::style::MinTrackSizingFunction::min_content()
}
MinTrackSizingFunction::MaxContent => {
taffy::style::MinTrackSizingFunction::max_content()
}
MinTrackSizingFunction::VMin(val) => {
Val::VMin(val).into_length_percentage(context).into()
}
MinTrackSizingFunction::VMax(val) => {
Val::VMax(val).into_length_percentage(context).into()
}
MinTrackSizingFunction::Vh(val) => Val::Vh(val).into_length_percentage(context).into(),
MinTrackSizingFunction::Vw(val) => Val::Vw(val).into_length_percentage(context).into(),
}
}
}

impl MaxTrackSizingFunction {
fn into_taffy(self, context: &LayoutContext) -> taffy::style::MaxTrackSizingFunction {
match self {
MaxTrackSizingFunction::Px(val) => taffy::style::MaxTrackSizingFunction::Fixed(
Val::Px(val).into_length_percentage(context),
),
MaxTrackSizingFunction::Percent(val) => taffy::style::MaxTrackSizingFunction::Fixed(
Val::Percent(val).into_length_percentage(context),
),
MaxTrackSizingFunction::Auto => taffy::style::MaxTrackSizingFunction::Auto,
MaxTrackSizingFunction::MinContent => taffy::style::MaxTrackSizingFunction::MinContent,
MaxTrackSizingFunction::MaxContent => taffy::style::MaxTrackSizingFunction::MaxContent,
MaxTrackSizingFunction::Px(val) => Val::Px(val).into_length_percentage(context).into(),
MaxTrackSizingFunction::Percent(val) => {
Val::Percent(val).into_length_percentage(context).into()
}
MaxTrackSizingFunction::Auto => taffy::style::MaxTrackSizingFunction::auto(),
MaxTrackSizingFunction::MinContent => {
taffy::style::MaxTrackSizingFunction::min_content()
}
MaxTrackSizingFunction::MaxContent => {
taffy::style::MaxTrackSizingFunction::max_content()
}
MaxTrackSizingFunction::FitContentPx(val) => {
taffy::style::MaxTrackSizingFunction::FitContent(
Val::Px(val).into_length_percentage(context),
taffy::style::MaxTrackSizingFunction::fit_content_px(
Val::Px(val)
.into_length_percentage(context)
.into_raw()
.value(),
)
}
MaxTrackSizingFunction::FitContentPercent(val) => {
taffy::style::MaxTrackSizingFunction::FitContent(
Val::Percent(val).into_length_percentage(context),
taffy::style::MaxTrackSizingFunction::fit_content_percent(
Val::Percent(val)
.into_length_percentage(context)
.into_raw()
.value(),
)
}
MaxTrackSizingFunction::Fraction(fraction) => {
taffy::style::MaxTrackSizingFunction::Fraction(fraction)
taffy::style::MaxTrackSizingFunction::fr(fraction)
}
MaxTrackSizingFunction::VMin(val) => {
Val::VMin(val).into_length_percentage(context).into()
}
MaxTrackSizingFunction::VMin(val) => taffy::style::MaxTrackSizingFunction::Fixed(
Val::VMin(val).into_length_percentage(context),
),
MaxTrackSizingFunction::VMax(val) => taffy::style::MaxTrackSizingFunction::Fixed(
Val::VMax(val).into_length_percentage(context),
),
MaxTrackSizingFunction::Vh(val) => taffy::style::MaxTrackSizingFunction::Fixed(
Val::Vh(val).into_length_percentage(context),
),
MaxTrackSizingFunction::Vw(val) => taffy::style::MaxTrackSizingFunction::Fixed(
Val::Vw(val).into_length_percentage(context),
),
MaxTrackSizingFunction::VMax(val) => {
Val::VMax(val).into_length_percentage(context).into()
}
MaxTrackSizingFunction::Vh(val) => Val::Vh(val).into_length_percentage(context).into(),
MaxTrackSizingFunction::Vw(val) => Val::Vw(val).into_length_percentage(context).into(),
}
}
}

impl GridTrack {
fn into_taffy_track(
self,
context: &LayoutContext,
) -> taffy::style::NonRepeatedTrackSizingFunction {
fn into_taffy_track(self, context: &LayoutContext) -> taffy::style::TrackSizingFunction {
let min = self.min_sizing_function.into_taffy(context);
let max = self.max_sizing_function.into_taffy(context);
style_helpers::minmax(min, max)
Expand All @@ -416,12 +414,12 @@ impl RepeatedGridTrack {
fn clone_into_repeated_taffy_track(
&self,
context: &LayoutContext,
) -> taffy::style::TrackSizingFunction {
) -> taffy::style::GridTemplateComponent<String> {
if self.tracks.len() == 1 && self.repetition == GridTrackRepetition::Count(1) {
let min = self.tracks[0].min_sizing_function.into_taffy(context);
let max = self.tracks[0].max_sizing_function.into_taffy(context);
let taffy_track = style_helpers::minmax(min, max);
taffy::style::TrackSizingFunction::Single(taffy_track)
taffy::GridTemplateComponent::Single(taffy_track)
} else {
let taffy_tracks: Vec<_> = self
.tracks
Expand All @@ -436,10 +434,10 @@ impl RepeatedGridTrack {
match self.repetition {
GridTrackRepetition::Count(count) => style_helpers::repeat(count, taffy_tracks),
GridTrackRepetition::AutoFit => {
style_helpers::repeat(taffy::style::GridTrackRepetition::AutoFit, taffy_tracks)
style_helpers::repeat(taffy::style::RepetitionCount::AutoFit, taffy_tracks)
}
GridTrackRepetition::AutoFill => {
style_helpers::repeat(taffy::style::GridTrackRepetition::AutoFill, taffy_tracks)
style_helpers::repeat(taffy::style::RepetitionCount::AutoFill, taffy_tracks)
}
}
}
Expand Down Expand Up @@ -537,15 +535,15 @@ mod tests {
);
assert_eq!(
taffy_style.inset.right,
taffy::style::LengthPercentageAuto::Percent(0.5)
taffy::style::LengthPercentageAuto::percent(0.5)
);
assert_eq!(
taffy_style.inset.top,
taffy::style::LengthPercentageAuto::Length(12.)
taffy::style::LengthPercentageAuto::length(12.)
);
assert_eq!(
taffy_style.inset.bottom,
taffy::style::LengthPercentageAuto::Auto
taffy::style::LengthPercentageAuto::auto()
);
assert_eq!(
taffy_style.flex_direction,
Expand Down Expand Up @@ -576,23 +574,23 @@ mod tests {
);
assert_eq!(
taffy_style.margin.right,
taffy::style::LengthPercentageAuto::Length(10.)
taffy::style::LengthPercentageAuto::length(10.)
);
assert_eq!(
taffy_style.margin.top,
taffy::style::LengthPercentageAuto::Percent(0.15)
taffy::style::LengthPercentageAuto::percent(0.15)
);
assert_eq!(
taffy_style.margin.bottom,
taffy::style::LengthPercentageAuto::Auto
taffy::style::LengthPercentageAuto::auto()
);
assert_eq!(
taffy_style.padding.left,
taffy::style::LengthPercentage::Percent(0.13)
taffy::style::LengthPercentage::percent(0.13)
);
assert_eq!(
taffy_style.padding.right,
taffy::style::LengthPercentage::Length(21.)
taffy::style::LengthPercentage::length(21.)
);
assert_eq!(
taffy_style.padding.top,
Expand All @@ -604,7 +602,7 @@ mod tests {
);
assert_eq!(
taffy_style.border.left,
taffy::style::LengthPercentage::Length(14.)
taffy::style::LengthPercentage::length(14.)
);
assert_eq!(
taffy_style.border.right,
Expand All @@ -613,16 +611,16 @@ mod tests {
assert_eq!(taffy_style.border.top, taffy::style::LengthPercentage::ZERO);
assert_eq!(
taffy_style.border.bottom,
taffy::style::LengthPercentage::Percent(0.31)
taffy::style::LengthPercentage::percent(0.31)
);
assert_eq!(taffy_style.flex_grow, 1.);
assert_eq!(taffy_style.flex_shrink, 0.);
assert_eq!(taffy_style.flex_basis, taffy::style::Dimension::ZERO);
assert_eq!(taffy_style.size.width, taffy::style::Dimension::ZERO);
assert_eq!(taffy_style.size.height, taffy::style::Dimension::Auto);
assert_eq!(taffy_style.size.height, taffy::style::Dimension::auto());
assert_eq!(taffy_style.min_size.width, taffy::style::Dimension::ZERO);
assert_eq!(taffy_style.min_size.height, taffy::style::Dimension::ZERO);
assert_eq!(taffy_style.max_size.width, taffy::style::Dimension::Auto);
assert_eq!(taffy_style.max_size.width, taffy::style::Dimension::auto());
assert_eq!(taffy_style.max_size.height, taffy::style::Dimension::ZERO);
assert_eq!(taffy_style.aspect_ratio, None);
assert_eq!(taffy_style.scrollbar_width, 7.);
Expand All @@ -643,8 +641,8 @@ mod tests {
assert_eq!(
taffy_style.grid_auto_rows,
vec![
sh::fit_content(taffy::style::LengthPercentage::Length(10.0)),
sh::fit_content(taffy::style::LengthPercentage::Percent(0.25)),
sh::fit_content(taffy::style::LengthPercentage::length(10.0)),
sh::fit_content(taffy::style::LengthPercentage::percent(0.25)),
sh::minmax(sh::length(0.0), sh::fr(2.0)),
]
);
Expand All @@ -667,20 +665,19 @@ mod tests {
use taffy::style::LengthPercentage;
let context = LayoutContext::new(2.0, Vec2::new(800., 600.));
let cases = [
(Val::Auto, LengthPercentage::Length(0.)),
(Val::Percent(1.), LengthPercentage::Percent(0.01)),
(Val::Px(1.), LengthPercentage::Length(2.)),
(Val::Vw(1.), LengthPercentage::Length(8.)),
(Val::Vh(1.), LengthPercentage::Length(6.)),
(Val::VMin(2.), LengthPercentage::Length(12.)),
(Val::VMax(2.), LengthPercentage::Length(16.)),
(Val::Auto, LengthPercentage::length(0.)),
(Val::Percent(1.), LengthPercentage::percent(0.01)),
(Val::Px(1.), LengthPercentage::length(2.)),
(Val::Vw(1.), LengthPercentage::length(8.)),
(Val::Vh(1.), LengthPercentage::length(6.)),
(Val::VMin(2.), LengthPercentage::length(12.)),
(Val::VMax(2.), LengthPercentage::length(16.)),
];
for (val, length) in cases {
assert!(match (val.into_length_percentage(&context), length) {
(LengthPercentage::Length(a), LengthPercentage::Length(b))
| (LengthPercentage::Percent(a), LengthPercentage::Percent(b)) =>
(a - b).abs() < 0.0001,
_ => false,
assert!({
let lhs = val.into_length_percentage(&context).into_raw().value();
let rhs = length.into_raw().value();
(lhs - rhs).abs() < 0.0001
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub enum LayoutError {
#[error("Invalid hierarchy")]
InvalidHierarchy,
#[error("Taffy error: {0}")]
TaffyError(taffy::TaffyError),
TaffyError(taffy::tree::TaffyError),
}

/// Updates the UI's layout tree, computes the new layout geometry and then updates the sizes and transforms of all the UI nodes.
Expand Down
Loading