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};
67/// 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
11Track,
12/// Track is a gutter (aka grid line) (aka gap)
13Gutter, // { name: Option<u16> },
14}
1516/// 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
23pub kind: GridTrackKind,
2425/// 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.
27pub is_collapsed: bool,
2829/// The minimum track sizing function of the track
30pub min_track_sizing_function: MinTrackSizingFunction,
3132/// The maximum track sizing function of the track
33pub max_track_sizing_function: MaxTrackSizingFunction,
3435/// The distance of the start of the track from the start of the grid container
36pub offset: f32,
3738/// The size (width/height as applicable) of the track
39pub base_size: f32,
4041/// A temporary scratch value when sizing tracks
42 /// Note: can be infinity
43pub growth_limit: f32,
4445/// 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
47pub content_alignment_adjustment: f32,
4849/// A temporary scratch value when "distributing space" to avoid clobbering planned increase variable
50pub item_incurred_increase: f32,
51/// A temporary scratch value when "distributing space" to avoid clobbering the main variable
52pub base_size_planned_increase: f32,
53/// A temporary scratch value when "distributing space" to avoid clobbering the main variable
54pub 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
57pub infinitely_growable: bool,
58}
5960impl GridTrack {
61/// GridTrack constructor with all configuration parameters for the other constructors exposed
62fn 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 }
8283/// Create new GridTrack representing an actual track (not a gutter)
84pub fn new(
85 min_track_sizing_function: MinTrackSizingFunction,
86 max_track_sizing_function: MaxTrackSizingFunction,
87 ) -> GridTrack {
88Self::new_with_kind(GridTrackKind::Track, min_track_sizing_function, max_track_sizing_function)
89 }
9091/// Create a new GridTrack representing a gutter
92pub fn gutter(size: LengthPercentage) -> GridTrack {
93Self::new_with_kind(
94 GridTrackKind::Gutter,
95 MinTrackSizingFunction::Fixed(size),
96 MaxTrackSizingFunction::Fixed(size),
97 )
98 }
99100/// Mark a GridTrack as collapsed. Also sets both of the track's sizing functions
101 /// to fixed zero-sized sizing functions.
102pub fn collapse(&mut self) {
103self.is_collapsed = true;
104self.min_track_sizing_function = MinTrackSizingFunction::Fixed(LengthPercentage::Length(0.0));
105self.max_track_sizing_function = MaxTrackSizingFunction::Fixed(LengthPercentage::Length(0.0));
106 }
107108#[inline(always)]
109/// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
110pub fn is_flexible(&self) -> bool {
111matches!(self.max_track_sizing_function, MaxTrackSizingFunction::Fraction(_))
112 }
113114#[inline(always)]
115/// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
116pub fn uses_percentage(&self) -> bool {
117self.min_track_sizing_function.uses_percentage() || self.max_track_sizing_function.uses_percentage()
118 }
119120#[inline(always)]
121/// Returns true if the track has an intrinsic min and or max sizing function
122pub fn has_intrinsic_sizing_function(&self) -> bool {
123self.min_track_sizing_function.is_intrinsic() || self.max_track_sizing_function.is_intrinsic()
124 }
125126#[inline]
127/// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
128pub fn fit_content_limit(&self, axis_available_grid_space: Option<f32>) -> f32 {
129match self.max_track_sizing_function {
130 MaxTrackSizingFunction::FitContent(LengthPercentage::Length(limit)) => limit,
131 MaxTrackSizingFunction::FitContent(LengthPercentage::Percent(fraction)) => {
132match axis_available_grid_space {
133Some(space) => space * fraction,
134None => f32::INFINITY,
135 }
136 }
137_ => f32::INFINITY,
138 }
139 }
140141#[inline]
142/// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
143pub 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 }
146147#[inline]
148/// Returns the track's flex factor if it is a flex track, else 0.
149pub fn flex_factor(&self) -> f32 {
150match self.max_track_sizing_function {
151 MaxTrackSizingFunction::Fraction(flex_factor) => flex_factor,
152_ => 0.0,
153 }
154 }
155}