• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Contains GridTrack used to represent a single grid track (row/column) during layout
2 use 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)]
9 pub(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)]
20 pub(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 
60 impl GridTrack {
61     /// GridTrack constructor with all configuration parameters for the other constructors exposed
new_with_kind( kind: GridTrackKind, min_track_sizing_function: MinTrackSizingFunction, max_track_sizing_function: MaxTrackSizingFunction, ) -> GridTrack62     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)
new( min_track_sizing_function: MinTrackSizingFunction, max_track_sizing_function: MaxTrackSizingFunction, ) -> GridTrack84     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
gutter(size: LengthPercentage) -> GridTrack92     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.
collapse(&mut self)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.
is_flexible(&self) -> bool110     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.
uses_percentage(&self) -> bool116     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
has_intrinsic_sizing_function(&self) -> bool122     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.
fit_content_limit(&self, axis_available_grid_space: Option<f32>) -> f32128     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.
fit_content_limited_growth_limit(&self, axis_available_grid_space: Option<f32>) -> f32143     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.
flex_factor(&self) -> f32149     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 }
156