clay_layout/layout/
sizing.rs

1use crate::bindings::*;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4#[repr(u8)]
5pub enum SizingType {
6    Fit = Clay__SizingType_CLAY__SIZING_TYPE_FIT,
7    Grow = Clay__SizingType_CLAY__SIZING_TYPE_GROW,
8    Percent = Clay__SizingType_CLAY__SIZING_TYPE_PERCENT,
9    Fixed = Clay__SizingType_CLAY__SIZING_TYPE_FIXED,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq)]
13pub enum Sizing {
14    /// Fit the layout [width](Layout::width)/[height](Layout::height) to a min and max constraint
15    Fit(f32, f32),
16    /// Grows to fill the parent, while keeping the layout [width](Layout::width)/[height](Layout::height)
17    /// between a min and max constraint
18    Grow(f32, f32),
19    /// Fix the layout [width](Layout::width)/[height](Layout::height) to a certain value
20    Fixed(f32),
21    /// Fix the layout [width](Layout::width)/[height](Layout::height) to a certain percentage of
22    /// it's parent
23    Percent(f32),
24}
25
26impl From<Clay_SizingAxis> for Sizing {
27    fn from(value: Clay_SizingAxis) -> Self {
28        match unsafe { core::mem::transmute::<u8, SizingType>(value.type_) } {
29            SizingType::Fit => {
30                let min_max = unsafe { value.size.minMax };
31                Self::Fit(min_max.min, min_max.max)
32            }
33            SizingType::Grow => {
34                let min_max = unsafe { value.size.minMax };
35                Self::Grow(min_max.min, min_max.max)
36            }
37            SizingType::Fixed => {
38                let min_max = unsafe { value.size.minMax };
39                Self::Fixed(min_max.min)
40            }
41            SizingType::Percent => {
42                let percent = unsafe { value.size.percent };
43                Self::Percent(percent)
44            }
45        }
46    }
47}
48
49impl From<Sizing> for Clay_SizingAxis {
50    fn from(value: Sizing) -> Self {
51        match value {
52            Sizing::Fit(min, max) => Self {
53                type_: SizingType::Fit as _,
54                size: Clay_SizingAxis__bindgen_ty_1 {
55                    minMax: Clay_SizingMinMax { min, max },
56                },
57            },
58            Sizing::Grow(min, max) => Self {
59                type_: SizingType::Grow as _,
60                size: Clay_SizingAxis__bindgen_ty_1 {
61                    minMax: Clay_SizingMinMax { min, max },
62                },
63            },
64            Sizing::Fixed(size) => Self {
65                type_: SizingType::Fixed as _,
66                size: Clay_SizingAxis__bindgen_ty_1 {
67                    minMax: Clay_SizingMinMax {
68                        min: size,
69                        max: size,
70                    },
71                },
72            },
73            Sizing::Percent(percent) => Self {
74                type_: SizingType::Percent as _,
75                size: Clay_SizingAxis__bindgen_ty_1 { percent },
76            },
77        }
78    }
79}
80
81/// Shorthand to create a [`Sizing::Fit`] value. Excluding the `$max` value sets it to `f32::MAX`.
82#[macro_export]
83macro_rules! fit {
84    ($min:expr, $max:expr) => {
85        $crate::layout::sizing::Sizing::Fit($min, $max)
86    };
87
88    ($min:expr) => {
89        fit!($min, f32::MAX)
90    };
91
92    () => {
93        fit!(0.0)
94    };
95}
96
97/// Shorthand to create a [`Sizing::Grow`] value. Excluding the `$max` value sets it to `f32::MAX`.
98#[macro_export]
99macro_rules! grow {
100    ($min:expr, $max:expr) => {
101        $crate::layout::sizing::Sizing::Grow($min, $max)
102    };
103
104    ($min:expr) => {
105        grow!($min, f32::MAX)
106    };
107
108    () => {
109        grow!(0.0)
110    };
111}
112
113/// Shorthand to create a [`Sizing::Fixed`] value.
114#[macro_export]
115macro_rules! fixed {
116    ($val:expr) => {
117        $crate::layout::sizing::Sizing::Fixed($val)
118    };
119}
120
121/// Shorthand to create a [`Sizing::Percent`] value.
122#[macro_export]
123macro_rules! percent {
124    ($percent:expr) => {
125        $crate::layout::sizing::Sizing::Percent($percent)
126    };
127}
128
129#[cfg(test)]
130mod test {
131    use super::*;
132    use crate::{fit, fixed, grow, percent};
133
134    #[test]
135    fn fit_macro() {
136        let both_args = fit!(12.0, 34.0);
137        assert!(matches!(both_args, Sizing::Fit(12.0, 34.0)));
138
139        let one_arg = fit!(12.0);
140        assert!(matches!(one_arg, Sizing::Fit(12.0, f32::MAX)));
141
142        let zero_args = fit!();
143        assert!(matches!(zero_args, Sizing::Fit(0.0, f32::MAX)));
144    }
145
146    #[test]
147    fn grow_macro() {
148        let both_args = grow!(12.0, 34.0);
149        assert!(matches!(both_args, Sizing::Grow(12.0, 34.0)));
150
151        let one_arg = grow!(12.0);
152        assert!(matches!(one_arg, Sizing::Grow(12.0, f32::MAX)));
153
154        let zero_args = grow!();
155        assert!(matches!(zero_args, Sizing::Grow(0.0, f32::MAX)));
156    }
157
158    #[test]
159    fn fixed_macro() {
160        let value = fixed!(123.0);
161        assert!(matches!(value, Sizing::Fixed(123.0)));
162    }
163
164    #[test]
165    fn percent_macro() {
166        let value = percent!(0.5);
167        assert!(matches!(value, Sizing::Percent(0.5)));
168    }
169}