gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 89Markdown 11TOML 91930 Definitions

Create style traits

439a292e9a6bff9c9a9736d37494354f852dbd05 · by Nico Burns · (3 years ago) · parent 385a9b803 · browse the tree at this commit

Semantic delta · 75

src/style/flex.rs

src/style/grid.rs

src/style/mod.rs

3 files · +390 −9

diff --git a/src/style/flex.rs b/src/style/flex.rs
index c24f488d8..f04f3a454 100644
--- a/src/style/flex.rs
+++ b/src/style/flex.rs
@@ -1,4 +1,70 @@
 //! Style types for Flexbox layout
+use super::{AlignContent, AlignItems, AlignSelf, CoreStyle, Dimension, JustifyContent, LengthPercentage, Style};
+use crate::geometry::Size;
+
+/// The set of styles required for a Flexbox container
+pub trait FlexboxContainerStyle: CoreStyle {
+    /// Which direction does the main axis flow in?
+    #[inline(always)]
+    fn flex_direction(&self) -> FlexDirection {
+        Style::DEFAULT.flex_direction
+    }
+    /// Should elements wrap, or stay in a single line?
+    #[inline(always)]
+    fn flex_wrap(&self) -> FlexWrap {
+        Style::DEFAULT.flex_wrap
+    }
+
+    /// How large should the gaps between items in a grid or flex container be?
+    #[inline(always)]
+    fn gap(&self) -> Size<LengthPercentage> {
+        Style::DEFAULT.gap
+    }
+
+    // Alignment properties
+
+    /// How should content contained within this item be aligned in the cross/block axis
+    #[inline(always)]
+    fn align_content(&self) -> Option<AlignContent> {
+        Style::DEFAULT.align_content
+    }
+    /// How this node's children aligned in the cross/block axis?
+    #[inline(always)]
+    fn align_items(&self) -> Option<AlignItems> {
+        Style::DEFAULT.align_items
+    }
+    /// How this node's children should be aligned in the inline axis
+    #[inline(always)]
+    fn justify_content(&self) -> Option<JustifyContent> {
+        Style::DEFAULT.justify_content
+    }
+}
+
+/// The set of styles required for a Flexbox item (child of a Flexbox container)
+pub trait FlexboxItemStyle: CoreStyle {
+    /// Sets the initial main axis size of the item
+    #[inline(always)]
+    fn flex_basis(&self) -> Dimension {
+        Style::DEFAULT.flex_basis
+    }
+    /// The relative rate at which this item grows when it is expanding to fill space
+    #[inline(always)]
+    fn flex_grow(&self) -> f32 {
+        Style::DEFAULT.flex_grow
+    }
+    /// The relative rate at which this item shrinks when it is contracting to fit into space
+    #[inline(always)]
+    fn flex_shrink(&self) -> f32 {
+        Style::DEFAULT.flex_shrink
+    }
+
+    /// How this node should be aligned in the cross/block axis
+    /// Falls back to the parents [`AlignItems`] if not set
+    #[inline(always)]
+    fn align_self(&self) -> Option<AlignSelf> {
+        Style::DEFAULT.align_self
+    }
+}
 
 use crate::geometry::AbsoluteAxis;
 
diff --git a/src/style/grid.rs b/src/style/grid.rs
index b2d2b04b4..0394b763d 100644
--- a/src/style/grid.rs
+++ b/src/style/grid.rs
@@ -1,13 +1,97 @@
 //! Style types for CSS Grid layout
-use super::{AlignContent, LengthPercentage, Style};
+use super::{AlignContent, AlignItems, AlignSelf, CoreStyle, JustifyContent, LengthPercentage, Style};
 use crate::compute::grid::{GridCoordinate, GridLine, OriginZeroLine};
-use crate::geometry::{AbsoluteAxis, AbstractAxis};
-use crate::geometry::{Line, MinMax};
+use crate::geometry::{AbsoluteAxis, AbstractAxis, Line, MinMax, Size};
 use crate::style_helpers::*;
 use crate::util::sys::GridTrackVec;
 use core::cmp::{max, min};
 use core::convert::Infallible;
 
+/// The set of styles required for a CSS Grid container
+pub trait GridContainerStyle: CoreStyle {
+    /// Defines the track sizing functions (heights) of the grid rows
+    #[inline(always)]
+    fn grid_template_rows(&self) -> &[TrackSizingFunction] {
+        &[]
+    }
+    /// Defines the track sizing functions (widths) of the grid columns
+    #[inline(always)]
+    fn grid_template_columns(&self) -> &[TrackSizingFunction] {
+        &[]
+    }
+    /// Defines the size of implicitly created rows
+    #[inline(always)]
+    fn grid_auto_rows(&self) -> &[NonRepeatedTrackSizingFunction] {
+        &[]
+    }
+    /// Defined the size of implicitly created columns
+    #[inline(always)]
+    fn grid_auto_columns(&self) -> &[NonRepeatedTrackSizingFunction] {
+        &[]
+    }
+    /// Controls how items get placed into the grid for auto-placed items
+    #[inline(always)]
+    fn grid_auto_flow(&self) -> GridAutoFlow {
+        Style::DEFAULT.grid_auto_flow
+    }
+
+    /// How large should the gaps between items in a grid or flex container be?
+    #[inline(always)]
+    fn gap(&self) -> Size<LengthPercentage> {
+        Style::DEFAULT.gap
+    }
+
+    // Alignment properties
+
+    /// How should content contained within this item be aligned in the cross/block axis
+    #[inline(always)]
+    fn align_content(&self) -> Option<AlignContent> {
+        Style::DEFAULT.align_content
+    }
+    /// How should contained within this item be aligned in the main/inline axis
+    #[inline(always)]
+    fn justify_content(&self) -> Option<JustifyContent> {
+        Style::DEFAULT.justify_content
+    }
+    /// How this node's children aligned in the cross/block axis?
+    #[inline(always)]
+    fn align_items(&self) -> Option<AlignItems> {
+        Style::DEFAULT.align_items
+    }
+    /// How this node's children should be aligned in the inline axis
+    #[inline(always)]
+    fn justify_items(&self) -> Option<AlignItems> {
+        Style::DEFAULT.justify_items
+    }
+}
+
+/// The set of styles required for a CSS Grid item (child of a CSS Grid container)
+pub trait GridItemStyle: CoreStyle {
+    /// Defines which row in the grid the item should start and end at
+    #[inline(always)]
+    fn grid_row(&self) -> Line<GridPlacement> {
+        Style::DEFAULT.grid_row
+    }
+    /// Defines which column in the grid the item should start and end at
+    #[inline(always)]
+    fn grid_column(&self) -> Line<GridPlacement> {
+        Style::DEFAULT.grid_column
+    }
+
+    /// How this node should be aligned in the cross/block axis
+    /// Falls back to the parents [`AlignItems`] if not set
+    #[inline(always)]
+    fn align_self(&self) -> Option<AlignSelf> {
+        Style::DEFAULT.align_self
+    }
+    /// How this node should be aligned in the inline axis
+    /// Falls back to the parents [`super::JustifyItems`] if not set
+    #[inline(always)]
+    fn justify_self(&self) -> Option<AlignSelf> {
+        Style::DEFAULT.justify_self
+    }
+}
+
 /// Controls whether grid items are placed row-wise or column-wise. And whether the sparse or dense packing algorithm is used.
 ///
 /// The "dense" packing algorithm attempts to fill in holes earlier in the grid, if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.
diff --git a/src/style/mod.rs b/src/style/mod.rs
index f77973156..fbaa7561b 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -9,7 +9,7 @@ pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, J
 pub use self::dimension::{AvailableSpace, Dimension, LengthPercentage, LengthPercentageAuto};
 
 #[cfg(feature = "flexbox")]
-pub use self::flex::{FlexDirection, FlexWrap};
+pub use self::flex::{FlexDirection, FlexWrap, FlexboxContainerStyle, FlexboxItemStyle};
 
 #[cfg(feature = "grid")]
 mod grid;
@@ -17,8 +17,8 @@ mod grid;
 pub(crate) use self::grid::{GenericGridPlacement, OriginZeroGridPlacement};
 #[cfg(feature = "grid")]
 pub use self::grid::{
-    GridAutoFlow, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction,
-    NonRepeatedTrackSizingFunction, TrackSizingFunction,
+    GridAutoFlow, GridContainerStyle, GridItemStyle, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction,
+    MinTrackSizingFunction, NonRepeatedTrackSizingFunction, TrackSizingFunction,
 };
 use crate::geometry::{Point, Rect, Size};
 
@@ -29,6 +29,80 @@ use crate::style_helpers;
 #[cfg(feature = "grid")]
 use crate::util::sys::GridTrackVec;
 
+/// The core set of styles that are shared between all CSS layout nodes
+///
+/// Note that all methods come with a default implementation which simply returns the default value for that style property
+/// but this is a just a convenience to save on boilerplate for styles that your implementation doesn't support. You will need
+/// to override the default implementation for each style property that your style type actually supports.
+pub trait CoreStyle {
+    /// What layout strategy should be used?
+    // fn display(&self);
+
+    // Overflow properties
+    /// How children overflowing their container should affect layout
+    #[inline(always)]
+    fn overflow(&self) -> Point<Overflow> {
+        Style::DEFAULT.overflow
+    }
+    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
+    #[inline(always)]
+    fn scrollbar_width(&self) -> f32 {
+        0.0
+    }
+
+    // Position properties
+    /// What should the `position` value of this struct use as a base offset?
+    #[inline(always)]
+    fn position(&self) -> Position {
+        Style::DEFAULT.position
+    }
+    /// How should the position of this element be tweaked relative to the layout defined?
+    #[inline(always)]
+    fn inset(&self) -> Rect<LengthPercentageAuto> {
+        Style::DEFAULT.inset
+    }
+
+    // Size properies
+    /// Sets the initial size of the item
+    #[inline(always)]
+    fn size(&self) -> Size<Dimension> {
+        Style::DEFAULT.size
+    }
+    /// Controls the minimum size of the item
+    #[inline(always)]
+    fn min_size(&self) -> Size<Dimension> {
+        Style::DEFAULT.min_size
+    }
+    /// Controls the maximum size of the item
+    #[inline(always)]
+    fn max_size(&self) -> Size<Dimension> {
+        Style::DEFAULT.max_size
+    }
+    /// Sets the preferred aspect ratio for the item
+    /// The ratio is calculated as width divided by height.
+    #[inline(always)]
+    fn aspect_ratio(&self) -> Option<f32> {
+        Style::DEFAULT.aspect_ratio
+    }
+
+    // Spacing Properties
+    /// How large should the margin be on each side?
+    #[inline(always)]
+    fn margin(&self) -> Rect<LengthPercentageAuto> {
+        Style::DEFAULT.margin
+    }
+    /// How large should the padding be on each side?
+    #[inline(always)]
+    fn padding(&self) -> Rect<LengthPercentage> {
+        Style::DEFAULT.padding
+    }
+    /// How large should the border be on each side?
+    #[inline(always)]
+    fn border(&self) -> Rect<LengthPercentage> {
+        Style::DEFAULT.border
+    }
+}
+
 /// Sets the layout used for the children of this node
 ///
 /// The default values depends on on which feature flags are enabled. The order of precedence is: Flex, Grid, Block, None.
@@ -276,11 +350,11 @@ pub struct Style {
     #[cfg(feature = "flexbox")]
     pub flex_shrink: f32,
 
-    // Grid container properties
-    /// Defines the track sizing functions (widths) of the grid rows
+    // Grid container properies
+    /// Defines the track sizing functions (heights) of the grid rows
     #[cfg(feature = "grid")]
     pub grid_template_rows: GridTrackVec<TrackSizingFunction>,
-    /// Defines the track sizing functions (heights) of the grid columns
+    /// Defines the track sizing functions (widths) of the grid columns
     #[cfg(feature = "grid")]
     pub grid_template_columns: GridTrackVec<TrackSizingFunction>,
     /// Defines the size of implicitly created rows
@@ -367,6 +441,163 @@ impl Default for Style {
     }
 }
 
+impl CoreStyle for Style {
+    #[inline(always)]
+    fn overflow(&self) -> Point<Overflow> {
+        self.overflow
+    }
+    #[inline(always)]
+    fn scrollbar_width(&self) -> f32 {
+        self.scrollbar_width
+    }
+    #[inline(always)]
+    fn position(&self) -> Position {
+        self.position
+    }
+    #[inline(always)]
+    fn inset(&self) -> Rect<LengthPercentageAuto> {
+        self.inset
+    }
+    #[inline(always)]
+    fn size(&self) -> Size<Dimension> {
+        self.size
+    }
+    #[inline(always)]
+    fn min_size(&self) -> Size<Dimension> {
+        self.min_size
+    }
+    #[inline(always)]
+    fn max_size(&self) -> Size<Dimension> {
+        self.max_size
+    }
+    #[inline(always)]
+    fn aspect_ratio(&self) -> Option<f32> {
+        self.aspect_ratio
+    }
+    #[inline(always)]
+    fn margin(&self) -> Rect<LengthPercentageAuto> {
+        self.margin
+    }
+    #[inline(always)]
+    fn padding(&self) -> Rect<LengthPercentage> {
+        self.padding
+    }
+    #[inline(always)]
+    fn border(&self) -> Rect<LengthPercentage> {
+        self.border
+    }
+}
+
+#[cfg(feature = "flexbox")]
+impl FlexboxContainerStyle for Style {
+    #[inline(always)]
+    fn flex_direction(&self) -> FlexDirection {
+        self.flex_direction
+    }
+    #[inline(always)]
+    fn flex_wrap(&self) -> FlexWrap {
+        self.flex_wrap
+    }
+    #[inline(always)]
+    fn gap(&self) -> Size<LengthPercentage> {
+        self.gap
+    }
+    #[inline(always)]
+    fn align_content(&self) -> Option<AlignContent> {
+        self.align_content
+    }
+    #[inline(always)]
+    fn align_items(&self) -> Option<AlignItems> {
+        self.align_items
+    }
+    #[inline(always)]
+    fn justify_content(&self) -> Option<JustifyContent> {
+        self.justify_content
+    }
+}
+#[cfg(feature = "flexbox")]
+impl FlexboxItemStyle for Style {
+    #[inline(always)]
+    fn flex_basis(&self) -> Dimension {
+        self.flex_basis
+    }
+    #[inline(always)]
+    fn flex_grow(&self) -> f32 {
+        self.flex_grow
+    }
+    #[inline(always)]
+    fn flex_shrink(&self) -> f32 {
+        self.flex_shrink
+    }
+    #[inline(always)]
+    fn align_self(&self) -> Option<AlignSelf> {
+        self.align_self
+    }
+}
+
+#[cfg(feature = "grid")]
+impl GridContainerStyle for Style {
+    #[inline(always)]
+    fn grid_template_rows(&self) -> &[TrackSizingFunction] {
+        &self.grid_template_rows
+    }
+    #[inline(always)]
+    fn grid_template_columns(&self) -> &[TrackSizingFunction] {
+        &self.grid_template_columns
+    }
+    #[inline(always)]
+    fn grid_auto_rows(&self) -> &[NonRepeatedTrackSizingFunction] {
+        &self.grid_auto_rows
+    }
+    #[inline(always)]
+    fn grid_auto_columns(&self) -> &[NonRepeatedTrackSizingFunction] {
+        &self.grid_auto_columns
+    }
+    #[inline(always)]
+    fn grid_auto_flow(&self) -> GridAutoFlow {
+        self.grid_auto_flow
+    }
+    #[inline(always)]
+    fn gap(&self) -> Size<LengthPercentage> {
+        self.gap
+    }
+    #[inline(always)]
+    fn align_content(&self) -> Option<AlignContent> {
+        self.align_content
+    }
+    #[inline(always)]
+    fn justify_content(&self) -> Option<JustifyContent> {
+        self.justify_content
+    }
+    #[inline(always)]
+    fn align_items(&self) -> Option<AlignItems> {
+        self.align_items
+    }
+    #[inline(always)]
+    fn justify_items(&self) -> Option<AlignItems> {
+        self.justify_items
+    }
+}
+#[cfg(feature = "grid")]
+impl GridItemStyle for Style {
+    #[inline(always)]
+    fn grid_row(&self) -> Line<GridPlacement> {
+        self.grid_row
+    }
+    #[inline(always)]
+    fn grid_column(&self) -> Line<GridPlacement> {
+        self.grid_column
+    }
+    #[inline(always)]
+    fn align_self(&self) -> Option<AlignSelf> {
+        self.align_self
+    }
+    #[inline(always)]
+    fn justify_self(&self) -> Option<AlignSelf> {
+        self.justify_self
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::Style;