taffy/compute/grid/types/
grid_track.rs

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