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