1use typed_floats::tf64::{Positive, PositiveFinite};
2
3use crate::style::layout::Direction;
4
5#[derive(Clone, Copy, Debug)]
7pub enum PreferredSize {
8 Fixed(PositiveFinite),
10 Grow(PositiveFinite),
12}
13
14impl Default for PreferredSize {
15 fn default() -> Self {
16 PreferredSize::Fixed(PositiveFinite::new(0.0).unwrap()) }
18}
19
20#[derive(Clone, Copy, Debug)]
22pub struct SizingDimensions {
23 pub min: PositiveFinite, pub preferred: PreferredSize, pub max: Positive, }
27
28impl Default for SizingDimensions {
29 fn default() -> Self {
30 SizingDimensions {
31 min: PositiveFinite::new(0.0).unwrap(),
32 preferred: PreferredSize::default(),
33 max: Positive::new(f64::INFINITY).unwrap(), }
35 }
36}
37
38impl SizingDimensions {
39 pub fn is_fixed(&self) -> bool {
41 matches!(self.preferred, PreferredSize::Fixed(_))
42 }
43
44 pub fn is_growable(&self) -> bool {
46 matches!(self.preferred, PreferredSize::Grow(_))
47 }
48
49 pub fn is_shrinkable(&self) -> bool {
52 self.max > self.min }
54
55 pub fn get_grow_factor(&self) -> f64 {
57 match self.preferred {
58 PreferredSize::Grow(factor) => factor.into(),
59 _ => 0.0, }
61 }
62
63 pub fn clamped(&self, value: f64) -> f64 {
82 if value.is_nan() {
83 return self.min.into(); }
85 value.clamp(self.min.into(), self.max.into())
86 }
87
88 pub fn max(&self) -> f64 {
89 self.max.into()
90 }
91
92 pub fn min(&self) -> f64 {
93 self.min.into()
94 }
95}
96
97#[derive(Default, Clone, Copy)]
99pub struct BoxSizing {
100 pub width: Sizing,
101 pub height: Sizing,
102}
103
104impl BoxSizing {
105 pub fn main(&mut self, dir: Direction) -> &mut Sizing {
106 match dir {
107 Direction::LeftToRight | Direction::RightToLeft => &mut self.width,
108 Direction::TopToBottom | Direction::BottomToTop => &mut self.height,
109 }
110 }
111
112 pub fn cross(&mut self, dir: Direction) -> &mut Sizing {
113 match dir {
114 Direction::LeftToRight | Direction::RightToLeft => &mut self.height,
115 Direction::TopToBottom | Direction::BottomToTop => &mut self.width,
116 }
117 }
118}
119
120#[macro_export]
139macro_rules! sizing {
140 ($width:expr, $height:expr) => {
141 $crate::style::sizing::BoxSizing {
142 width: $width,
143 height: $height,
144 }
145 };
146
147 ($size:expr) => {
148 $crate::style::sizing::BoxSizing {
149 width: $size,
150 height: $size,
151 }
152 };
153 (width: $width:expr, height: $height:expr) => {
154 $crate::style::sizing::BoxSizing {
155 width: $width,
156 height: $height,
157 }
158 };
159 ($key:ident : $value:expr$(,)?) => {
160 $crate::style::sizing::BoxSizing {
161 $key: $value,
162 ..$crate::style::sizing::BoxSizing::default()
163 }
164 };
165 ($($key:ident : $value:expr),* $(,)?) => {
166 $crate::style::sizing::BoxSizing {
167 $($key: $value,)*
168 }
169 };
170 () => {
171 $crate::style::sizing::BoxSizing::default()
172 };
173}
174
175#[derive(Default, Clone, Copy)]
177pub enum Sizing {
178 #[default]
179 Default,
180 Fit {
181 min: Option<PositiveFinite>,
182 max: Option<Positive>,
183 },
184 Fixed(PositiveFinite),
185 Grow {
186 factor: Option<PositiveFinite>, min: Option<PositiveFinite>,
188 max: Option<Positive>,
189 },
190}
191
192impl From<Sizing> for SizingDimensions {
193 fn from(sizing: Sizing) -> Self {
194 match sizing {
195 Sizing::Default => SizingDimensions::default(), Sizing::Fit { min, max } => SizingDimensions {
197 min: min.unwrap_or_default(),
198 preferred: PreferredSize::Fixed(min.unwrap_or_default()), max: max.unwrap_or(Positive::new(f64::INFINITY).unwrap()),
200 },
201 Sizing::Fixed(size) => SizingDimensions {
202 min: size,
203 preferred: PreferredSize::Fixed(size),
204 max: size.into(),
205 },
206 Sizing::Grow { factor, min, max } => SizingDimensions {
207 min: min.unwrap_or_default(),
208 preferred: PreferredSize::Grow(factor.unwrap_or(PositiveFinite::new(1.0).unwrap())),
209 max: max.unwrap_or(Positive::new(f64::INFINITY).unwrap()),
210 },
211 }
212 }
213}
214
215#[macro_export]
221macro_rules! fit {
222 ($min:expr, $max:expr) => {
223 $crate::style::sizing::Sizing::Fit {
224 min: Some(typed_floats::tf64::PositiveFinite::new($min).unwrap()),
225 max: Some(typed_floats::tf64::Positive::new($max).unwrap()),
226 }
227 };
228
229 ($max:expr) => {
230 $crate::style::sizing::Sizing::Fit {
231 min: None,
232 max: Some(typed_floats::tf64::Positive::new($max).unwrap()),
233 }
234 };
235
236 () => {
237 $crate::style::sizing::Sizing::Fit {
238 min: None,
239 max: None,
240 }
241 };
242}
243
244#[macro_export]
248macro_rules! fixed {
249 ($size:expr) => {
250 $crate::style::sizing::Sizing::Fixed(
251 typed_floats::tf64::PositiveFinite::new($size).unwrap(),
252 )
253 };
254}
255
256#[macro_export]
264macro_rules! grow {
265 ($factor:expr, $min:expr, $max:expr) => {
266 $crate::style::sizing::Sizing::Grow {
267 factor: Some(typed_floats::tf64::PositiveFinite::new($factor).unwrap()),
268 min: Some(typed_floats::tf64::PositiveFinite::new($min).unwrap()),
269 max: Some(typed_floats::tf64::Positive::new($max).unwrap()),
270 }
271 };
272
273 ($factor:expr) => {
274 $crate::style::sizing::Sizing::Grow {
275 factor: Some(typed_floats::tf64::PositiveFinite::new($factor).unwrap()),
276 min: None,
277 max: None,
278 }
279 };
280
281 () => {
282 $crate::style::sizing::Sizing::Grow {
283 factor: None,
284 min: None,
285 max: None,
286 }
287 };
288}