taffy/compute/grid/types/
grid_track.rs

1//! Contains GridTrack used to represent a single grid track (row/column) during layout
2use crate::{
3    style::{LengthPercentage, MaxTrackSizingFunction, MinTrackSizingFunction},
4    util::sys::f32_min,
5};
6
7/// Whether a GridTrack represents an actual track or a gutter.
8#[derive(Copy, Clone, Debug, PartialEq)]
9pub(in super::super) enum GridTrackKind {
10    /// Track is an actual track
11    Track,
12    /// Track is a gutter (aka grid line) (aka gap)
13    Gutter, // { name: Option<u16> },
14}
15
16/// Internal sizing information for a single grid track (row/column)
17/// Gutters between tracks are sized similarly to actual tracks, so they
18/// are also represented by this struct
19#[derive(Debug, Clone)]
20pub(in super::super) struct GridTrack {
21    #[allow(dead_code)] // Used in tests + may be useful in future
22    /// Whether the track is a full track, a gutter, or a placeholder that has not yet been initialised
23    pub kind: GridTrackKind,
24
25    /// Whether the track is a collapsed track/gutter. Collapsed tracks are effectively treated as if
26    /// they don't exist for the purposes of grid sizing. Gutters between collapsed tracks are also collapsed.
27    pub is_collapsed: bool,
28
29    /// The minimum track sizing function of the track
30    pub min_track_sizing_function: MinTrackSizingFunction,
31
32    /// The maximum track sizing function of the track
33    pub max_track_sizing_function: MaxTrackSizingFunction,
34
35    /// The distance of the start of the track from the start of the grid container
36    pub offset: f32,
37
38    /// The size (width/height as applicable) of the track
39    pub base_size: f32,
40
41    /// A temporary scratch value when sizing tracks
42    /// Note: can be infinity
43    pub growth_limit: f32,
44
45    /// A temporary scratch value when sizing tracks. Is used as an additional amount to add to the
46    /// estimate for the available space in the opposite axis when content sizing items
47    pub content_alignment_adjustment: f32,
48
49    /// A temporary scratch value when "distributing space" to avoid clobbering planned increase variable
50    pub item_incurred_increase: f32,
51    /// A temporary scratch value when "distributing space" to avoid clobbering the main variable
52    pub base_size_planned_increase: f32,
53    /// A temporary scratch value when "distributing space" to avoid clobbering the main variable
54    pub growth_limit_planned_increase: f32,
55    /// A temporary scratch value when "distributing space"
56    /// See: https://www.w3.org/TR/css3-grid-layout/#infinitely-growable
57    pub infinitely_growable: bool,
58}
59
60impl GridTrack {
61    /// GridTrack constructor with all configuration parameters for the other constructors exposed
62    fn new_with_kind(
63        kind: GridTrackKind,
64        min_track_sizing_function: MinTrackSizingFunction,
65        max_track_sizing_function: MaxTrackSizingFunction,
66    ) -> GridTrack {
67        GridTrack {
68            kind,
69            is_collapsed: false,
70            min_track_sizing_function,
71            max_track_sizing_function,
72            offset: 0.0,
73            base_size: 0.0,
74            growth_limit: 0.0,
75            content_alignment_adjustment: 0.0,
76            item_incurred_increase: 0.0,
77            base_size_planned_increase: 0.0,
78            growth_limit_planned_increase: 0.0,
79            infinitely_growable: false,
80        }
81    }
82
83    /// Create new GridTrack representing an actual track (not a gutter)
84    pub fn new(
85        min_track_sizing_function: MinTrackSizingFunction,
86        max_track_sizing_function: MaxTrackSizingFunction,
87    ) -> GridTrack {
88        Self::new_with_kind(GridTrackKind::Track, min_track_sizing_function, max_track_sizing_function)
89    }
90
91    /// Create a new GridTrack representing a gutter
92    pub fn gutter(size: LengthPercentage) -> GridTrack {
93        Self::new_with_kind(
94            GridTrackKind::Gutter,
95            MinTrackSizingFunction::Fixed(size),
96            MaxTrackSizingFunction::Fixed(size),
97        )
98    }
99
100    /// Mark a GridTrack as collapsed. Also sets both of the track's sizing functions
101    /// to fixed zero-sized sizing functions.
102    pub fn collapse(&mut self) {
103        self.is_collapsed = true;
104        self.min_track_sizing_function = MinTrackSizingFunction::Fixed(LengthPercentage::Length(0.0));
105        self.max_track_sizing_function = MaxTrackSizingFunction::Fixed(LengthPercentage::Length(0.0));
106    }
107
108    #[inline(always)]
109    /// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
110    pub fn is_flexible(&self) -> bool {
111        matches!(self.max_track_sizing_function, MaxTrackSizingFunction::Fraction(_))
112    }
113
114    #[inline(always)]
115    /// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
116    pub fn uses_percentage(&self) -> bool {
117        self.min_track_sizing_function.uses_percentage() || self.max_track_sizing_function.uses_percentage()
118    }
119
120    #[inline(always)]
121    /// Returns true if the track has an intrinsic min and or max sizing function
122    pub fn has_intrinsic_sizing_function(&self) -> bool {
123        self.min_track_sizing_function.is_intrinsic() || self.max_track_sizing_function.is_intrinsic()
124    }
125
126    #[inline]
127    /// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
128    pub fn fit_content_limit(&self, axis_available_grid_space: Option<f32>) -> f32 {
129        match self.max_track_sizing_function {
130            MaxTrackSizingFunction::FitContent(LengthPercentage::Length(limit)) => limit,
131            MaxTrackSizingFunction::FitContent(LengthPercentage::Percent(fraction)) => {
132                match axis_available_grid_space {
133                    Some(space) => space * fraction,
134                    None => f32::INFINITY,
135                }
136            }
137            _ => f32::INFINITY,
138        }
139    }
140
141    #[inline]
142    /// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
143    pub fn fit_content_limited_growth_limit(&self, axis_available_grid_space: Option<f32>) -> f32 {
144        f32_min(self.growth_limit, self.fit_content_limit(axis_available_grid_space))
145    }
146
147    #[inline]
148    /// Returns the track's flex factor if it is a flex track, else 0.
149    pub fn flex_factor(&self) -> f32 {
150        match self.max_track_sizing_function {
151            MaxTrackSizingFunction::Fraction(flex_factor) => flex_factor,
152            _ => 0.0,
153        }
154    }
155}