Upgrade to Taffy 0.3.3 (#7859)

# Objective

Upgrade to Taffy 0.3.3

Fixes: #7712

## Solution

Upgrade to Taffy 0.3.3 with the `grid` feature disabled.

---

## Changelog
* Changed Taffy version to 0.3.3 and disabled its `grid` feature. 
* Added the `Start` and `End` variants to `AlignItems`, `AlignSelf`, `AlignContent` and `JustifyContent`.
* Added the `SpaceEvenly` variant to `AlignContent`.
* Updated `from_style` for Taffy 0.3.3.
This commit is contained in:
ickshonpe 2023-03-04 14:09:47 +00:00
parent a213c8ac94
commit 76058bcf33
4 changed files with 201 additions and 98 deletions

View File

@ -31,7 +31,7 @@ bevy_window = { path = "../bevy_window", version = "0.9.0" }
bevy_utils = { path = "../bevy_utils", version = "0.9.0" }
# other
taffy = "0.2.2"
taffy = { version = "0.3.3", default-features = false, features = ["std"] }
serde = { version = "1", features = ["derive"] }
smallvec = { version = "1.6", features = ["union", "const_generics"] }
bytemuck = { version = "1.5", features = ["derive"] }

View File

@ -1,67 +1,136 @@
use taffy::style::LengthPercentageAuto;
use crate::{
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
PositionType, Size, Style, UiRect, Val,
};
pub fn from_rect(
scale_factor: f64,
rect: UiRect,
) -> taffy::geometry::Rect<taffy::style::Dimension> {
taffy::geometry::Rect {
left: from_val(scale_factor, rect.left),
right: from_val(scale_factor, rect.right),
top: from_val(scale_factor, rect.top),
bottom: from_val(scale_factor, rect.bottom),
impl Val {
fn scaled(self, scale_factor: f64) -> Self {
match self {
Val::Auto => Val::Auto,
Val::Percent(value) => Val::Percent(value),
Val::Px(value) => Val::Px((scale_factor * value as f64) as f32),
Val::Undefined => Val::Undefined,
}
}
fn to_inset(self) -> LengthPercentageAuto {
match self {
Val::Auto | Val::Undefined => taffy::style::LengthPercentageAuto::Auto,
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.0),
Val::Px(value) => taffy::style::LengthPercentageAuto::Points(value),
}
}
}
pub fn from_val_size(
scale_factor: f64,
size: Size,
) -> taffy::geometry::Size<taffy::style::Dimension> {
taffy::geometry::Size {
width: from_val(scale_factor, size.width),
height: from_val(scale_factor, size.height),
impl UiRect {
fn scaled(self, scale_factor: f64) -> Self {
Self {
left: self.left.scaled(scale_factor),
right: self.right.scaled(scale_factor),
top: self.top.scaled(scale_factor),
bottom: self.bottom.scaled(scale_factor),
}
}
}
pub fn from_style(scale_factor: f64, value: &Style) -> taffy::style::Style {
impl Size {
fn scaled(self, scale_factor: f64) -> Self {
Self {
width: self.width.scaled(scale_factor),
height: self.height.scaled(scale_factor),
}
}
}
impl<T: From<Val>> From<UiRect> for taffy::prelude::Rect<T> {
fn from(value: UiRect) -> Self {
Self {
left: value.left.into(),
right: value.right.into(),
top: value.top.into(),
bottom: value.bottom.into(),
}
}
}
impl<T: From<Val>> From<Size> for taffy::prelude::Size<T> {
fn from(value: Size) -> Self {
Self {
width: value.width.into(),
height: value.height.into(),
}
}
}
impl From<Val> for taffy::style::Dimension {
fn from(value: Val) -> Self {
match value {
Val::Auto | Val::Undefined => taffy::style::Dimension::Auto,
Val::Percent(value) => taffy::style::Dimension::Percent(value / 100.0),
Val::Px(value) => taffy::style::Dimension::Points(value),
}
}
}
impl From<Val> for taffy::style::LengthPercentage {
fn from(value: Val) -> Self {
match value {
Val::Auto | Val::Undefined => taffy::style::LengthPercentage::Points(0.0),
Val::Percent(value) => taffy::style::LengthPercentage::Percent(value / 100.0),
Val::Px(value) => taffy::style::LengthPercentage::Points(value),
}
}
}
impl From<Val> for taffy::style::LengthPercentageAuto {
fn from(value: Val) -> Self {
match value {
Val::Auto => taffy::style::LengthPercentageAuto::Auto,
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.0),
Val::Px(value) => taffy::style::LengthPercentageAuto::Points(value),
Val::Undefined => taffy::style::LengthPercentageAuto::Points(0.),
}
}
}
pub fn from_style(scale_factor: f64, style: &Style) -> taffy::style::Style {
taffy::style::Style {
display: value.display.into(),
position_type: value.position_type.into(),
flex_direction: value.flex_direction.into(),
flex_wrap: value.flex_wrap.into(),
align_items: value.align_items.into(),
align_self: value.align_self.into(),
align_content: value.align_content.into(),
justify_content: value.justify_content.into(),
position: from_rect(scale_factor, value.position),
margin: from_rect(scale_factor, value.margin),
padding: from_rect(scale_factor, value.padding),
border: from_rect(scale_factor, value.border),
flex_grow: value.flex_grow,
flex_shrink: value.flex_shrink,
flex_basis: from_val(scale_factor, value.flex_basis),
size: from_val_size(scale_factor, value.size),
min_size: from_val_size(scale_factor, value.min_size),
max_size: from_val_size(scale_factor, value.max_size),
aspect_ratio: value.aspect_ratio,
gap: from_val_size(scale_factor, value.gap),
}
}
pub fn from_val(scale_factor: f64, val: Val) -> taffy::style::Dimension {
match val {
Val::Auto => taffy::style::Dimension::Auto,
Val::Percent(value) => taffy::style::Dimension::Percent(value / 100.0),
Val::Px(value) => taffy::style::Dimension::Points((scale_factor * value as f64) as f32),
Val::Undefined => taffy::style::Dimension::Undefined,
display: style.display.into(),
position: style.position_type.into(),
flex_direction: style.flex_direction.into(),
flex_wrap: style.flex_wrap.into(),
align_items: Some(style.align_items.into()),
align_self: style.align_self.into(),
align_content: Some(style.align_content.into()),
justify_content: Some(style.justify_content.into()),
inset: taffy::prelude::Rect {
left: style.position.left.scaled(scale_factor).to_inset(),
right: style.position.right.scaled(scale_factor).to_inset(),
top: style.position.top.scaled(scale_factor).to_inset(),
bottom: style.position.bottom.scaled(scale_factor).to_inset(),
},
margin: style.margin.scaled(scale_factor).into(),
padding: style.padding.scaled(scale_factor).into(),
border: style.border.scaled(scale_factor).into(),
flex_grow: style.flex_grow,
flex_shrink: style.flex_shrink,
flex_basis: style.flex_basis.scaled(scale_factor).into(),
size: style.size.scaled(scale_factor).into(),
min_size: style.size.scaled(scale_factor).into(),
max_size: style.size.scaled(scale_factor).into(),
aspect_ratio: style.aspect_ratio,
gap: style.gap.scaled(scale_factor).into(),
justify_self: None,
}
}
impl From<AlignItems> for taffy::style::AlignItems {
fn from(value: AlignItems) -> Self {
match value {
AlignItems::Start => taffy::style::AlignItems::Start,
AlignItems::End => taffy::style::AlignItems::End,
AlignItems::FlexStart => taffy::style::AlignItems::FlexStart,
AlignItems::FlexEnd => taffy::style::AlignItems::FlexEnd,
AlignItems::Center => taffy::style::AlignItems::Center,
@ -71,15 +140,17 @@ impl From<AlignItems> for taffy::style::AlignItems {
}
}
impl From<AlignSelf> for taffy::style::AlignSelf {
impl From<AlignSelf> for Option<taffy::style::AlignSelf> {
fn from(value: AlignSelf) -> Self {
match value {
AlignSelf::Auto => taffy::style::AlignSelf::Auto,
AlignSelf::FlexStart => taffy::style::AlignSelf::FlexStart,
AlignSelf::FlexEnd => taffy::style::AlignSelf::FlexEnd,
AlignSelf::Center => taffy::style::AlignSelf::Center,
AlignSelf::Baseline => taffy::style::AlignSelf::Baseline,
AlignSelf::Stretch => taffy::style::AlignSelf::Stretch,
AlignSelf::Auto => None,
AlignSelf::Start => taffy::style::AlignSelf::Start.into(),
AlignSelf::End => taffy::style::AlignSelf::End.into(),
AlignSelf::FlexStart => taffy::style::AlignSelf::FlexStart.into(),
AlignSelf::FlexEnd => taffy::style::AlignSelf::FlexEnd.into(),
AlignSelf::Center => taffy::style::AlignSelf::Center.into(),
AlignSelf::Baseline => taffy::style::AlignSelf::Baseline.into(),
AlignSelf::Stretch => taffy::style::AlignSelf::Stretch.into(),
}
}
}
@ -87,12 +158,15 @@ impl From<AlignSelf> for taffy::style::AlignSelf {
impl From<AlignContent> for taffy::style::AlignContent {
fn from(value: AlignContent) -> Self {
match value {
AlignContent::Start => taffy::style::AlignContent::Start,
AlignContent::End => taffy::style::AlignContent::End,
AlignContent::FlexStart => taffy::style::AlignContent::FlexStart,
AlignContent::FlexEnd => taffy::style::AlignContent::FlexEnd,
AlignContent::Center => taffy::style::AlignContent::Center,
AlignContent::Stretch => taffy::style::AlignContent::Stretch,
AlignContent::SpaceBetween => taffy::style::AlignContent::SpaceBetween,
AlignContent::SpaceAround => taffy::style::AlignContent::SpaceAround,
AlignContent::SpaceEvenly => taffy::style::AlignContent::SpaceEvenly,
}
}
}
@ -120,6 +194,8 @@ impl From<FlexDirection> for taffy::style::FlexDirection {
impl From<JustifyContent> for taffy::style::JustifyContent {
fn from(value: JustifyContent) -> Self {
match value {
JustifyContent::Start => taffy::style::JustifyContent::Start,
JustifyContent::End => taffy::style::JustifyContent::End,
JustifyContent::FlexStart => taffy::style::JustifyContent::FlexStart,
JustifyContent::FlexEnd => taffy::style::JustifyContent::FlexEnd,
JustifyContent::Center => taffy::style::JustifyContent::Center,
@ -130,11 +206,11 @@ impl From<JustifyContent> for taffy::style::JustifyContent {
}
}
impl From<PositionType> for taffy::style::PositionType {
impl From<PositionType> for taffy::style::Position {
fn from(value: PositionType) -> Self {
match value {
PositionType::Relative => taffy::style::PositionType::Relative,
PositionType::Absolute => taffy::style::PositionType::Absolute,
PositionType::Relative => taffy::style::Position::Relative,
PositionType::Absolute => taffy::style::Position::Absolute,
}
}
}

View File

@ -18,6 +18,7 @@ use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChan
use std::fmt;
use taffy::{
prelude::{AvailableSpace, Size},
style_helpers::TaffyMaxContent,
Taffy,
};
@ -61,14 +62,17 @@ impl FlexSurface {
pub fn upsert_node(&mut self, entity: Entity, style: &Style, scale_factor: f64) {
let mut added = false;
let taffy = &mut self.taffy;
let taffy_style = convert::from_style(scale_factor, style);
let taffy_node = self.entity_to_taffy.entry(entity).or_insert_with(|| {
added = true;
taffy.new_leaf(taffy_style).unwrap()
taffy
.new_leaf(convert::from_style(scale_factor, style))
.unwrap()
});
if !added {
self.taffy.set_style(*taffy_node, taffy_style).unwrap();
self.taffy
.set_style(*taffy_node, convert::from_style(scale_factor, style))
.unwrap();
}
}

View File

@ -353,15 +353,21 @@ impl Default for Style {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum AlignItems {
/// Items are aligned at the start
/// Items are packed towards the start of the axis.
Start,
/// Items are packed towards the end of the axis.
End,
/// Items are packed towards the start of the axis, unless the flex direction is reversed;
/// then they are packed towards the end of the axis.
FlexStart,
/// Items are aligned at the end
/// Items are packed towards the end of the axis, unless the flex direction is reversed;
/// then they are packed towards the end of the axis.
FlexEnd,
/// Items are aligned at the center
/// Items are aligned at the center.
Center,
/// Items are aligned at the baseline
/// Items are aligned at the baseline.
Baseline,
/// Items are stretched across the whole cross axis
/// Items are stretched across the whole cross axis.
Stretch,
}
@ -380,17 +386,23 @@ impl Default for AlignItems {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum AlignSelf {
/// Use the parent node's [`AlignItems`] value to determine how this item should be aligned
/// Use the parent node's [`AlignItems`] value to determine how this item should be aligned.
Auto,
/// This item will be aligned at the start
/// This item will be aligned with the start of the axis.
Start,
/// This item will be aligned with the end of the axis.
End,
/// This item will be aligned with the start of the axis, unless the flex direction is reversed;
/// then it will be aligned with the end of the axis.
FlexStart,
/// This item will be aligned at the end
/// This item will be aligned with the start of the axis, unless the flex direction is reversed;
/// then it will be aligned with the end of the axis.
FlexEnd,
/// This item will be aligned at the center
/// This item will be aligned at the center.
Center,
/// This item will be aligned at the baseline
/// This item will be aligned at the baseline.
Baseline,
/// This item will be stretched across the whole cross axis
/// This item will be stretched across the whole cross axis.
Stretch,
}
@ -410,19 +422,26 @@ impl Default for AlignSelf {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum AlignContent {
/// Each line moves towards the start of the cross axis
/// Each line moves towards the start of the cross axis.
Start,
/// Each line moves towards the end of the cross axis.
End,
/// Each line moves towards the start of the cross axis, unless the flex direction is reversed; then the line moves towards the end of the cross axis.
FlexStart,
/// Each line moves towards the end of the cross axis
/// Each line moves towards the end of the cross axis, unless the flex direction is reversed; then the line moves towards the start of the cross axis.
FlexEnd,
/// Each line moves towards the center of the cross axis
/// Each line moves towards the center of the cross axis.
Center,
/// Each line will stretch to fill the remaining space
/// Each line will stretch to fill the remaining space.
Stretch,
/// Each line fills the space it needs, putting the remaining space, if any
/// inbetween the lines
/// inbetween the lines.
SpaceBetween,
/// The gap between the first and last items is exactly THE SAME as the gap between items.
/// The gaps are distributed evenly.
SpaceEvenly,
/// Each line fills the space it needs, putting the remaining space, if any
/// around the lines
/// around the lines.
SpaceAround,
}
@ -442,11 +461,11 @@ impl Default for AlignContent {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum Direction {
/// Inherit from parent node
/// Inherit from parent node.
Inherit,
/// Text is written left to right
/// Text is written left to right.
LeftToRight,
/// Text is written right to left
/// Text is written right to left.
RightToLeft,
}
@ -489,13 +508,13 @@ impl Default for Display {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum FlexDirection {
/// Same way as text direction along the main axis
/// Same way as text direction along the main axis.
Row,
/// Flex from top to bottom
/// Flex from top to bottom.
Column,
/// Opposite way as text direction along the main axis
/// Opposite way as text direction along the main axis.
RowReverse,
/// Flex from bottom to top
/// Flex from bottom to top.
ColumnReverse,
}
@ -513,17 +532,21 @@ impl Default for FlexDirection {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum JustifyContent {
/// Pushed towards the start
/// Items are packed toward the start of the axis.
Start,
/// Items are packed toward the end of the axis.
End,
/// Pushed towards the start, unless the flex direction is reversed; then pushed towards the end.
FlexStart,
/// Pushed towards the end
/// Pushed towards the end, unless the flex direction is reversed; then pushed towards the start.
FlexEnd,
/// Centered along the main axis
/// Centered along the main axis.
Center,
/// Remaining space is distributed between the items
/// Remaining space is distributed between the items.
SpaceBetween,
/// Remaining space is distributed around the items
/// Remaining space is distributed around the items.
SpaceAround,
/// Like [`JustifyContent::SpaceAround`] but with even spacing between items
/// Like [`JustifyContent::SpaceAround`] but with even spacing between items.
SpaceEvenly,
}
@ -541,9 +564,9 @@ impl Default for JustifyContent {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum Overflow {
/// Show overflowing items
/// Show overflowing items.
Visible,
/// Hide overflowing items
/// Hide overflowing items.
Hidden,
}
@ -561,11 +584,11 @@ impl Default for Overflow {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum PositionType {
/// Relative to all other nodes with the [`PositionType::Relative`] value
/// Relative to all other nodes with the [`PositionType::Relative`] value.
Relative,
/// Independent of all other nodes
/// Independent of all other nodes.
///
/// As usual, the `Style.position` field of this node is specified relative to its parent node
/// As usual, the `Style.position` field of this node is specified relative to its parent node.
Absolute,
}
@ -583,11 +606,11 @@ impl Default for PositionType {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum FlexWrap {
/// Single line, will overflow if needed
/// Single line, will overflow if needed.
NoWrap,
/// Multiple lines, if needed
/// Multiple lines, if needed.
Wrap,
/// Same as [`FlexWrap::Wrap`] but new lines will appear before the previous one
/// Same as [`FlexWrap::Wrap`] but new lines will appear before the previous one.
WrapReverse,
}