tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Definiciones

Moving flexbox behind a feature flag (#414)

* Moving flexbox behind a feature flag

* More stuff behind feature flag

* Enabling flexbox by default

* Fixing double definition of default

* Update workflow

* Adding default const to Display when no features are enabled

* Comment out more stuff from the prelude

* Ensure only one default

* Putting stuff behind feature flags

* formatting

* adding std to feature testing

* Uncomment temp commented code

* Fix missing comma

* Update Ci job keys

* Cleanup and documentatnion

* Gating alignement properties behind flexbox or grid

* Rename job key back to original value

* Gate justify_items and justify_self behind the grid feature

* Reinstate alloc job name

* Fix github actions job name

---------

Co-authored-by: Nico Burns <nico@nicoburns.com>

0bccf6cb6a3fc322e8e4fcc10ae38f8c42b26cf1 · por Andreas Weibye · (hace 3 años) · padre 83b9ac1f4 · ver el árbol en este commit

Delta semántico · 10

src/compute/mod.rs

src/debug.rs

src/style/mod.rs

8 archivos · +147 −25

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ebca2eebf..aa8e1c130 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,6 +9,7 @@ on:
 name: Continuous integration
 
 jobs:
+  # None
   test-features-none:
     name: "Test Suite [Features: None]"
     runs-on: ubuntu-latest
@@ -19,6 +20,7 @@ jobs:
       - run: cargo build --no-default-features
       - run: cargo test --no-default-features
 
+  # Default
   test-features-default:
     name: "Test Suite [Features: Default]"
     runs-on: ubuntu-latest
@@ -37,8 +39,37 @@ jobs:
       - run: cargo build --features serde
       - run: cargo test --features serde
 
-  test-features-alloc:
-    name: "Test Suite [Features: alloc]"
+  test-features-no-grid-nor-flexbox:
+    name: "Test Suite [Features: std (no grid or flexbox)]"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@stable
+      - run: cargo build --no-default-features --features std
+      - run: cargo test --no-default-features --features std
+
+  # Flexbox
+  test-features-flexbox:
+    name: "Test Suite [Features: flexbox + std]"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@stable
+      - run: cargo build --no-default-features --features flexbox,std
+      - run: cargo test --no-default-features --features flexbox,std
+
+  # Grid
+  test-features-grid:
+    name: "Test Suite [Features: grid + std]"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@stable
+      - run: cargo build --no-default-features --features grid,std
+      - run: cargo test --no-default-features --features grid,std
+
+  test-features-grid-with-alloc:
+    name: "Test Suite [Features: grid + alloc]"
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
@@ -46,8 +77,8 @@ jobs:
       - run: cargo build --no-default-features --features alloc,grid
       - run: cargo test --no-default-features --features alloc,grid
 
-  test-features-alloc-no-grid:
-    name: "Test Suite [Features: alloc (no grid)]"
+  test-features-alloc:
+    name: "Test Suite [Features: alloc]"
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
diff --git a/Cargo.toml b/Cargo.toml
index fc415b670..855eef245 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,8 @@ slotmap = "1.0.6"
 grid = { version = "0.9.0", optional = true }
 
 [features]
-default = ["std", "grid"]
+default = ["std", "flexbox", "grid" ]
+flexbox = []
 grid = ["alloc", "dep:grid"]
 alloc = []
 std = ["num-traits/std"]
diff --git a/RELEASES.md b/RELEASES.md
index 47ba3a2f3..97a7ab4c4 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,5 +1,12 @@
 # Release Notes
 
+## Unreleased
+
+### Changes
+
+- The Flexbox algorithm has now been moved behind the `flexbox` feature. The `flexbox` feature is enabled by default.
+- The `justify_self` property has been moved behind the `grid` feature.
+
 ## 0.3.11
 
 ### Fixes
diff --git a/src/compute/mod.rs b/src/compute/mod.rs
index 35fc1b9b0..0fa23fae8 100644
--- a/src/compute/mod.rs
+++ b/src/compute/mod.rs
@@ -1,9 +1,11 @@
 //! The layout algorithms themselves
 
 pub(crate) mod common;
-pub(crate) mod flexbox;
 pub(crate) mod leaf;
 
+#[cfg(feature = "flexbox")]
+pub(crate) mod flexbox;
+
 #[cfg(feature = "grid")]
 pub(crate) mod grid;
 
@@ -16,7 +18,9 @@ use crate::style::{AvailableSpace, Display};
 use crate::sys::round;
 use crate::tree::LayoutTree;
 
+#[cfg(feature = "flexbox")]
 use self::flexbox::FlexboxAlgorithm;
+
 #[cfg(feature = "grid")]
 use self::grid::CssGridAlgorithm;
 use self::leaf::LeafAlgorithm;
@@ -189,6 +193,7 @@ fn compute_node_layout(
             run_mode,
             sizing_mode,
         ),
+        #[cfg(feature = "flexbox")]
         (Display::Flex, true) => perform_computations::<FlexboxAlgorithm>(
             tree,
             node,
diff --git a/src/debug.rs b/src/debug.rs
index 991cbc4a2..b95fa4703 100644
--- a/src/debug.rs
+++ b/src/debug.rs
@@ -21,6 +21,7 @@ fn print_node(tree: &impl LayoutTree, node: Node, has_sibling: bool, lines_strin
     let display = match (num_children, style.display) {
         (_, style::Display::None) => "NONE",
         (0, _) => "LEAF",
+        #[cfg(feature = "flexbox")]
         (_, style::Display::Flex) => "FLEX",
         #[cfg(feature = "grid")]
         (_, style::Display::Grid) => "GRID",
diff --git a/src/geometry.rs b/src/geometry.rs
index 3f96d3d85..65dce8e3e 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -1,9 +1,12 @@
 //! Geometric primitives useful for layout
 
-use crate::style::{Dimension, FlexDirection};
+use crate::style::Dimension;
 use crate::sys::f32_max;
 use core::ops::Add;
 
+#[cfg(feature = "flexbox")]
+use crate::style::FlexDirection;
+
 #[cfg(feature = "grid")]
 use crate::axis::AbstractAxis;
 
@@ -61,6 +64,7 @@ impl<T> Rect<T> {
     /// When applied to the left and right sides, the width is used
     /// as the second parameter of `f`.
     /// When applied to the top or bottom sides, the height is used instead.
+    #[cfg(feature = "flexbox")]
     pub(crate) fn zip_size<R, F, U>(self, size: Size<U>, f: F) -> Rect<R>
     where
         F: Fn(T, U) -> R,
@@ -134,6 +138,7 @@ where
     ///
     /// If the [`FlexDirection`] is [`FlexDirection::Row`] or [`FlexDirection::RowReverse`], this is [`Rect::horizontal`].
     /// Otherwise, this is [`Rect::vertical`].
+    #[cfg(feature = "flexbox")]
     pub(crate) fn main_axis_sum(&self, direction: FlexDirection) -> U {
         if direction.is_row() {
             self.horizontal_axis_sum()
@@ -146,6 +151,7 @@ where
     ///
     /// If the [`FlexDirection`] is [`FlexDirection::Row`] or [`FlexDirection::RowReverse`], this is [`Rect::vertical`].
     /// Otherwise, this is [`Rect::horizontal`].
+    #[cfg(feature = "flexbox")]
     pub(crate) fn cross_axis_sum(&self, direction: FlexDirection) -> U {
         if direction.is_row() {
             self.vertical_axis_sum()
@@ -160,6 +166,7 @@ where
     T: Copy + Clone,
 {
     /// The `start` or `top` value of the [`Rect`], from the perspective of the main layout axis
+    #[cfg(feature = "flexbox")]
     pub(crate) fn main_start(&self, direction: FlexDirection) -> T {
         if direction.is_row() {
             self.left
@@ -169,6 +176,7 @@ where
     }
 
     /// The `end` or `bottom` value of the [`Rect`], from the perspective of the main layout axis
+    #[cfg(feature = "flexbox")]
     pub(crate) fn main_end(&self, direction: FlexDirection) -> T {
         if direction.is_row() {
             self.right
@@ -178,6 +186,7 @@ where
     }
 
     /// The `start` or `top` value of the [`Rect`], from the perspective of the cross layout axis
+    #[cfg(feature = "flexbox")]
     pub(crate) fn cross_start(&self, direction: FlexDirection) -> T {
         if direction.is_row() {
             self.top
@@ -187,6 +196,7 @@ where
     }
 
     /// The `end` or `bottom` value of the [`Rect`], from the perspective of the main layout axis
+    #[cfg(feature = "flexbox")]
     pub(crate) fn cross_end(&self, direction: FlexDirection) -> T {
         if direction.is_row() {
             self.bottom
@@ -301,6 +311,7 @@ impl<T> Size<T> {
     /// Sets the extent of the main layout axis
     ///
     /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
     pub(crate) fn set_main(&mut self, direction: FlexDirection, value: T) {
         if direction.is_row() {
             self.width = value
@@ -312,6 +323,7 @@ impl<T> Size<T> {
     /// Sets the extent of the cross layout axis
     ///
     /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
     pub(crate) fn set_cross(&mut self, direction: FlexDirection, value: T) {
         if direction.is_row() {
             self.height = value
@@ -324,6 +336,7 @@ impl<T> Size<T> {
     ///
     /// Whether this is the width or height depends on the `direction` provided
     #[allow(dead_code)]
+    #[cfg(feature = "flexbox")]
     pub(crate) fn with_main(self, direction: FlexDirection, value: T) -> Self {
         let mut new = self;
         if direction.is_row() {
@@ -337,6 +350,7 @@ impl<T> Size<T> {
     /// Creates a new value of type Self with the cross axis set to value provided
     ///
     /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
     pub(crate) fn with_cross(self, direction: FlexDirection, value: T) -> Self {
         let mut new = self;
         if direction.is_row() {
@@ -350,6 +364,7 @@ impl<T> Size<T> {
     /// Gets the extent of the main layout axis
     ///
     /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
     pub(crate) fn main(self, direction: FlexDirection) -> T {
         if direction.is_row() {
             self.width
@@ -361,6 +376,7 @@ impl<T> Size<T> {
     /// Gets the extent of the cross layout axis
     ///
     /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
     pub(crate) fn cross(self, direction: FlexDirection) -> T {
         if direction.is_row() {
             self.height
diff --git a/src/prelude.rs b/src/prelude.rs
index db21a6df2..22a89a119 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -1,9 +1,13 @@
 //! Commonly used types
 
-use crate::compute::LayoutAlgorithm;
-use crate::layout::{SizeAndBaselines, SizingMode};
+#[cfg(feature = "flexbox")]
+use crate::{
+    compute::LayoutAlgorithm,
+    layout::{SizeAndBaselines, SizingMode},
+};
 
 /// Apply the flexbox algorithm and recursively layout the specified node
+#[cfg(feature = "flexbox")]
 #[inline(always)]
 pub fn layout_flexbox(
     tree: &mut impl LayoutTree,
@@ -28,8 +32,8 @@ pub use crate::{
     layout::Layout,
     node::{Node, Taffy},
     style::{
-        AlignContent, AlignItems, AlignSelf, AvailableSpace, Dimension, Display, FlexDirection, FlexWrap,
-        JustifyContent, JustifyItems, JustifySelf, LengthPercentage, LengthPercentageAuto, Position, Style,
+        AlignContent, AlignItems, AlignSelf, AvailableSpace, Dimension, Display, JustifyContent, JustifyItems,
+        JustifySelf, LengthPercentage, LengthPercentageAuto, Position, Style,
     },
     style_helpers::{
         auto, fit_content, max_content, min_content, percent, points, zero, FromFlex, FromPercent, FromPoints,
@@ -38,6 +42,9 @@ pub use crate::{
     tree::LayoutTree,
 };
 
+#[cfg(feature = "flexbox")]
+pub use crate::style::{FlexDirection, FlexWrap};
+
 #[cfg(feature = "grid")]
 pub use crate::style::{
     GridAutoFlow, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction,
diff --git a/src/style/mod.rs b/src/style/mod.rs
index ee4fa9d21..a784bd6e8 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -1,10 +1,14 @@
 //! A representation of [CSS layout properties](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) in Rust, used for flexbox layout
 mod alignment;
 mod dimension;
+
+#[cfg(feature = "flexbox")]
 mod flex;
 
 pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, JustifyItems, JustifySelf};
 pub use self::dimension::{AvailableSpace, Dimension, LengthPercentage, LengthPercentageAuto};
+
+#[cfg(feature = "flexbox")]
 pub use self::flex::{FlexDirection, FlexWrap};
 
 #[cfg(feature = "grid")]
@@ -27,11 +31,12 @@ use crate::sys::GridTrackVec;
 
 /// Sets the layout used for the children of this node
 ///
-/// [`Display::Flex`] is the default value.
+/// The default values depends on on which feature flags are enabled. The order of precedence is: Flex, Grid, None.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 pub enum Display {
     /// The children will follow the flexbox layout algorithm
+    #[cfg(feature = "flexbox")]
     Flex,
     /// The children will follow the CSS Grid layout algorithm
     #[cfg(feature = "grid")]
@@ -40,9 +45,23 @@ pub enum Display {
     None,
 }
 
+impl Display {
+    /// The default of Display.
+    #[cfg(feature = "flexbox")]
+    pub const DEFAULT: Display = Display::Flex;
+
+    /// The default of Display.
+    #[cfg(all(feature = "grid", not(feature = "flexbox")))]
+    pub const DEFAULT: Display = Display::Grid;
+
+    /// The default of Display.
+    #[cfg(all(not(feature = "flexbox"), not(feature = "grid")))]
+    pub const DEFAULT: Display = Display::None;
+}
+
 impl Default for Display {
     fn default() -> Self {
-        Self::Flex
+        Self::DEFAULT
     }
 }
 
@@ -131,38 +150,49 @@ pub struct Style {
 
     // Alignment properties
     /// How this node's children aligned in the cross/block axis?
+    #[cfg(any(feature = "flexbox", feature = "grid"))]
     pub align_items: Option<AlignItems>,
     /// How this node should be aligned in the cross/block axis
     /// Falls back to the parents [`AlignItems`] if not set
+    #[cfg(any(feature = "flexbox", feature = "grid"))]
     pub align_self: Option<AlignSelf>,
     /// How this node's children should be aligned in the inline axis
     #[cfg(feature = "grid")]
     pub justify_items: Option<AlignItems>,
     /// How this node should be aligned in the inline axis
     /// Falls back to the parents [`JustifyItems`] if not set
+    #[cfg(feature = "grid")]
     pub justify_self: Option<AlignSelf>,
     /// How should content contained within this item be aligned in the cross/block axis
+    #[cfg(any(feature = "flexbox", feature = "grid"))]
     pub align_content: Option<AlignContent>,
     /// How should contained within this item be aligned in the main/inline axis
+    #[cfg(any(feature = "flexbox", feature = "grid"))]
     pub justify_content: Option<JustifyContent>,
     /// How large should the gaps between items in a grid or flex container be?
+    #[cfg(any(feature = "flexbox", feature = "grid"))]
     #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
     pub gap: Size<LengthPercentage>,
 
     // Flexbox properies
     /// Which direction does the main axis flow in?
+    #[cfg(feature = "flexbox")]
     pub flex_direction: FlexDirection,
     /// Should elements wrap, or stay in a single line?
+    #[cfg(feature = "flexbox")]
     pub flex_wrap: FlexWrap,
     /// Sets the initial main axis size of the item
+    #[cfg(feature = "flexbox")]
     pub flex_basis: Dimension,
     /// The relative rate at which this item grows when it is expanding to fill space
     ///
     /// 0.0 is the default value, and this value must be positive.
+    #[cfg(feature = "flexbox")]
     pub flex_grow: f32,
     /// The relative rate at which this item shrinks when it is contracting to fit into space
     ///
     /// 1.0 is the default value, and this value must be positive.
+    #[cfg(feature = "flexbox")]
     pub flex_shrink: f32,
 
     // Grid container properies
@@ -194,29 +224,43 @@ pub struct Style {
 impl Style {
     /// The [`Default`] layout, in a form that can be used in const functions
     pub const DEFAULT: Style = Style {
-        display: Display::Flex,
+        display: Display::DEFAULT,
         position: Position::Relative,
-        flex_direction: FlexDirection::Row,
-        flex_wrap: FlexWrap::NoWrap,
+        inset: Rect::auto(),
+        margin: Rect::zero(),
+        padding: Rect::zero(),
+        border: Rect::zero(),
+        size: Size::auto(),
+        min_size: Size::auto(),
+        max_size: Size::auto(),
+        aspect_ratio: None,
+        #[cfg(any(feature = "flexbox", feature = "grid"))]
+        gap: Size::zero(),
+        // Aligment
+        #[cfg(any(feature = "flexbox", feature = "grid"))]
         align_items: None,
+        #[cfg(any(feature = "flexbox", feature = "grid"))]
         align_self: None,
         #[cfg(feature = "grid")]
         justify_items: None,
+        #[cfg(feature = "grid")]
         justify_self: None,
+        #[cfg(any(feature = "flexbox", feature = "grid"))]
         align_content: None,
+        #[cfg(any(feature = "flexbox", feature = "grid"))]
         justify_content: None,
-        inset: Rect::auto(),
-        margin: Rect::zero(),
-        padding: Rect::zero(),
-        border: Rect::zero(),
-        gap: Size::zero(),
+        // Flexbox
+        #[cfg(feature = "flexbox")]
+        flex_direction: FlexDirection::Row,
+        #[cfg(feature = "flexbox")]
+        flex_wrap: FlexWrap::NoWrap,
+        #[cfg(feature = "flexbox")]
         flex_grow: 0.0,
+        #[cfg(feature = "flexbox")]
         flex_shrink: 1.0,
+        #[cfg(feature = "flexbox")]
         flex_basis: Dimension::Auto,
-        size: Size::auto(),
-        min_size: Size::auto(),
-        max_size: Size::auto(),
-        aspect_ratio: None,
+        // Grid
         #[cfg(feature = "grid")]
         grid_template_rows: GridTrackVec::new(),
         #[cfg(feature = "grid")]
@@ -253,22 +297,32 @@ mod tests {
         let old_defaults = Style {
             display: Default::default(),
             position: Default::default(),
+            #[cfg(feature = "flexbox")]
             flex_direction: Default::default(),
+            #[cfg(feature = "flexbox")]
             flex_wrap: Default::default(),
+            #[cfg(any(feature = "flexbox", feature = "grid"))]
             align_items: Default::default(),
+            #[cfg(any(feature = "flexbox", feature = "grid"))]
             align_self: Default::default(),
             #[cfg(feature = "grid")]
             justify_items: Default::default(),
+            #[cfg(feature = "grid")]
             justify_self: Default::default(),
+            #[cfg(any(feature = "flexbox", feature = "grid"))]
             align_content: Default::default(),
+            #[cfg(any(feature = "flexbox", feature = "grid"))]
             justify_content: Default::default(),
             inset: Rect::auto(),
             margin: Rect::zero(),
             padding: Rect::zero(),
             border: Rect::zero(),
             gap: Size::zero(),
+            #[cfg(feature = "flexbox")]
             flex_grow: 0.0,
+            #[cfg(feature = "flexbox")]
             flex_shrink: 1.0,
+            #[cfg(feature = "flexbox")]
             flex_basis: super::Dimension::Auto,
             size: Size::auto(),
             min_size: Size::auto(),