Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Taffy 0.4 #10690

Merged
merged 9 commits into from
Apr 30, 2024
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
2 changes: 1 addition & 1 deletion crates/bevy_ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ bevy_window = { path = "../bevy_window", version = "0.14.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" }

# other
taffy = { version = "0.3.10" }
taffy = { version = "0.4" }
serde = { version = "1", features = ["derive"], optional = true }
bytemuck = { version = "1.5", features = ["derive"] }
thiserror = "1.0.0"
Expand Down
108 changes: 70 additions & 38 deletions crates/bevy_ui/src/layout/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use taffy::style_helpers;
use crate::{
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, GridAutoFlow,
GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf,
MaxTrackSizingFunction, MinTrackSizingFunction, PositionType, RepeatedGridTrack, Style, UiRect,
Val,
MaxTrackSizingFunction, MinTrackSizingFunction, OverflowAxis, PositionType, RepeatedGridTrack,
Style, UiRect, Val,
};

use super::LayoutContext;
Expand All @@ -18,31 +18,31 @@ impl Val {
Val::Auto => taffy::style::LengthPercentageAuto::Auto,
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.),
Val::Px(value) => {
taffy::style::LengthPercentageAuto::Points(context.scale_factor * value)
taffy::style::LengthPercentageAuto::Length(context.scale_factor * value)
}
Val::VMin(value) => {
taffy::style::LengthPercentageAuto::Points(context.min_size * value / 100.)
taffy::style::LengthPercentageAuto::Length(context.min_size * value / 100.)
}
Val::VMax(value) => {
taffy::style::LengthPercentageAuto::Points(context.max_size * value / 100.)
taffy::style::LengthPercentageAuto::Length(context.max_size * value / 100.)
}
Val::Vw(value) => {
taffy::style::LengthPercentageAuto::Points(context.physical_size.x * value / 100.)
taffy::style::LengthPercentageAuto::Length(context.physical_size.x * value / 100.)
}
Val::Vh(value) => {
taffy::style::LengthPercentageAuto::Points(context.physical_size.y * value / 100.)
taffy::style::LengthPercentageAuto::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::Points(0.0),
taffy::style::LengthPercentageAuto::Auto => taffy::style::LengthPercentage::Length(0.0),
taffy::style::LengthPercentageAuto::Percent(value) => {
taffy::style::LengthPercentage::Percent(value)
}
taffy::style::LengthPercentageAuto::Points(value) => {
taffy::style::LengthPercentage::Points(value)
taffy::style::LengthPercentageAuto::Length(value) => {
taffy::style::LengthPercentage::Length(value)
}
}
}
Expand All @@ -63,9 +63,18 @@ impl UiRect {
}
}

pub fn from_style(context: &LayoutContext, style: &Style) -> taffy::style::Style {
pub fn from_style(
context: &LayoutContext,
style: &Style,
ignore_padding_and_border: bool,
) -> taffy::style::Style {
taffy::style::Style {
display: style.display.into(),
overflow: taffy::Point {
x: style.overflow.x.into(),
y: style.overflow.y.into(),
},
scrollbar_width: 0.0,
position: style.position_type.into(),
flex_direction: style.flex_direction.into(),
flex_wrap: style.flex_wrap.into(),
Expand All @@ -75,7 +84,7 @@ pub fn from_style(context: &LayoutContext, style: &Style) -> taffy::style::Style
justify_self: style.justify_self.into(),
align_content: style.align_content.into(),
justify_content: style.justify_content.into(),
inset: taffy::prelude::Rect {
inset: taffy::Rect {
left: style.left.into_length_percentage_auto(context),
right: style.right.into_length_percentage_auto(context),
top: style.top.into_length_percentage_auto(context),
Expand All @@ -84,29 +93,41 @@ pub fn from_style(context: &LayoutContext, style: &Style) -> taffy::style::Style
margin: style
.margin
.map_to_taffy_rect(|m| m.into_length_percentage_auto(context)),
padding: style
.padding
.map_to_taffy_rect(|m| m.into_length_percentage(context)),
border: style
.border
.map_to_taffy_rect(|m| m.into_length_percentage(context)),
// Ignore padding for leaf nodes as it isn't implemented in the rendering engine.
// TODO: Implement rendering of padding for leaf nodes
padding: if ignore_padding_and_border {
taffy::Rect::zero()
} else {
style
.padding
.map_to_taffy_rect(|m| m.into_length_percentage(context))
},
// Ignore border for leaf nodes as it isn't implemented in the rendering engine.
// TODO: Implement rendering of border for leaf nodes
border: if ignore_padding_and_border {
taffy::Rect::zero()
} else {
style
.border
.map_to_taffy_rect(|m| m.into_length_percentage(context))
},
flex_grow: style.flex_grow,
flex_shrink: style.flex_shrink,
flex_basis: style.flex_basis.into_dimension(context),
size: taffy::prelude::Size {
size: taffy::Size {
width: style.width.into_dimension(context),
height: style.height.into_dimension(context),
},
min_size: taffy::prelude::Size {
min_size: taffy::Size {
width: style.min_width.into_dimension(context),
height: style.min_height.into_dimension(context),
},
max_size: taffy::prelude::Size {
max_size: taffy::Size {
width: style.max_width.into_dimension(context),
height: style.max_height.into_dimension(context),
},
aspect_ratio: style.aspect_ratio,
gap: taffy::prelude::Size {
gap: taffy::Size {
width: style.column_gap.into_length_percentage(context),
height: style.row_gap.into_length_percentage(context),
},
Expand Down Expand Up @@ -231,11 +252,22 @@ impl From<Display> for taffy::style::Display {
match value {
Display::Flex => taffy::style::Display::Flex,
Display::Grid => taffy::style::Display::Grid,
Display::Block => taffy::style::Display::Block,
Display::None => taffy::style::Display::None,
}
}
}

impl From<OverflowAxis> for taffy::style::Overflow {
fn from(value: OverflowAxis) -> Self {
match value {
OverflowAxis::Visible => taffy::style::Overflow::Visible,
OverflowAxis::Clip => taffy::style::Overflow::Clip,
OverflowAxis::Hidden => taffy::style::Overflow::Hidden,
}
}
}

impl From<FlexDirection> for taffy::style::FlexDirection {
fn from(value: FlexDirection) -> Self {
match value {
Expand Down Expand Up @@ -489,7 +521,7 @@ mod tests {
grid_row: GridPlacement::span(3),
};
let viewport_values = LayoutContext::new(1.0, bevy_math::Vec2::new(800., 600.));
let taffy_style = from_style(&viewport_values, &bevy_style);
let taffy_style = from_style(&viewport_values, &bevy_style, false);
assert_eq!(taffy_style.display, taffy::style::Display::Flex);
assert_eq!(taffy_style.position, taffy::style::Position::Absolute);
assert_eq!(
Expand All @@ -502,7 +534,7 @@ mod tests {
);
assert_eq!(
taffy_style.inset.top,
taffy::style::LengthPercentageAuto::Points(12.)
taffy::style::LengthPercentageAuto::Length(12.)
);
assert_eq!(
taffy_style.inset.bottom,
Expand Down Expand Up @@ -537,7 +569,7 @@ mod tests {
);
assert_eq!(
taffy_style.margin.right,
taffy::style::LengthPercentageAuto::Points(10.)
taffy::style::LengthPercentageAuto::Length(10.)
);
assert_eq!(
taffy_style.margin.top,
Expand All @@ -553,7 +585,7 @@ mod tests {
);
assert_eq!(
taffy_style.padding.right,
taffy::style::LengthPercentage::Points(21.)
taffy::style::LengthPercentage::Length(21.)
);
assert_eq!(
taffy_style.padding.top,
Expand All @@ -565,7 +597,7 @@ mod tests {
);
assert_eq!(
taffy_style.border.left,
taffy::style::LengthPercentage::Points(14.)
taffy::style::LengthPercentage::Length(14.)
);
assert_eq!(
taffy_style.border.right,
Expand Down Expand Up @@ -594,18 +626,18 @@ mod tests {
);
assert_eq!(
taffy_style.grid_template_rows,
vec![sh::points(10.0), sh::percent(0.5), sh::fr(1.0)]
vec![sh::length(10.0), sh::percent(0.5), sh::fr(1.0)]
);
assert_eq!(
taffy_style.grid_template_columns,
vec![sh::repeat(5, vec![sh::points(10.0)])]
vec![sh::repeat(5, vec![sh::length(10.0)])]
);
assert_eq!(
taffy_style.grid_auto_rows,
vec![
sh::fit_content(taffy::style::LengthPercentage::Points(10.0)),
sh::fit_content(taffy::style::LengthPercentage::Length(10.0)),
sh::fit_content(taffy::style::LengthPercentage::Percent(0.25)),
sh::minmax(sh::points(0.0), sh::fr(2.0)),
sh::minmax(sh::length(0.0), sh::fr(2.0)),
]
);
assert_eq!(
Expand All @@ -627,17 +659,17 @@ mod tests {
use taffy::style::LengthPercentage;
let context = LayoutContext::new(2.0, bevy_math::Vec2::new(800., 600.));
let cases = [
(Val::Auto, LengthPercentage::Points(0.)),
(Val::Auto, LengthPercentage::Length(0.)),
(Val::Percent(1.), LengthPercentage::Percent(0.01)),
(Val::Px(1.), LengthPercentage::Points(2.)),
(Val::Vw(1.), LengthPercentage::Points(8.)),
(Val::Vh(1.), LengthPercentage::Points(6.)),
(Val::VMin(2.), LengthPercentage::Points(12.)),
(Val::VMax(2.), LengthPercentage::Points(16.)),
(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::Points(a), LengthPercentage::Points(b))
(LengthPercentage::Length(a), LengthPercentage::Length(b))
| (LengthPercentage::Percent(a), LengthPercentage::Percent(b)) =>
(a - b).abs() < 0.0001,
_ => false,
Expand Down
14 changes: 7 additions & 7 deletions crates/bevy_ui/src/layout/debug.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::fmt::Write;

use taffy::prelude::Node;
use taffy::tree::LayoutTree;
use taffy::{NodeId, TraversePartialTree};

use bevy_ecs::prelude::Entity;
use bevy_utils::HashMap;
Expand All @@ -10,7 +9,7 @@ use crate::layout::ui_surface::UiSurface;

/// Prints a debug representation of the computed layout of the UI layout tree for each window.
pub fn print_ui_layout_tree(ui_surface: &UiSurface) {
let taffy_to_entity: HashMap<Node, Entity> = ui_surface
let taffy_to_entity: HashMap<NodeId, Entity> = ui_surface
.entity_to_taffy
.iter()
.map(|(entity, node)| (*node, *entity))
Expand All @@ -35,9 +34,9 @@ pub fn print_ui_layout_tree(ui_surface: &UiSurface) {
/// Recursively navigates the layout tree printing each node's information.
fn print_node(
ui_surface: &UiSurface,
taffy_to_entity: &HashMap<Node, Entity>,
taffy_to_entity: &HashMap<NodeId, Entity>,
entity: Entity,
node: Node,
node: NodeId,
has_sibling: bool,
lines_string: String,
acc: &mut String,
Expand All @@ -46,13 +45,14 @@ fn print_node(
let layout = tree.layout(node).unwrap();
let style = tree.style(node).unwrap();

let num_children = tree.child_count(node).unwrap();
let num_children = tree.child_count(node);

let display_variant = match (num_children, style.display) {
(_, taffy::style::Display::None) => "NONE",
(0, _) => "LEAF",
(_, taffy::style::Display::Flex) => "FLEX",
(_, taffy::style::Display::Grid) => "GRID",
(_, taffy::style::Display::Block) => "BLOCK",
};

let fork_string = if has_sibling {
Expand All @@ -70,7 +70,7 @@ fn print_node(
y = layout.location.y,
width = layout.size.width,
height = layout.size.height,
measured = if tree.needs_measure(node) { "measured" } else { "" }
measured = if tree.get_node_context(node).is_some() { "measured" } else { "" }
).ok();
let bar = if has_sibling { "│ " } else { " " };
let new_string = lines_string + bar;
Expand Down
Loading