tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 1111HTML 1039Markdown 12TOML 94541 Definitions

⎇ 5dde45d200e154a0f084780d575035dbb01599e4 src/style.rs Rust · 357 lines · 8.4 KB History Who touched what raw

Remove serde_camel_case and serde_kebab_case features (#84) 5dde45d20 · Alice Cecile ·

1use crate::geometry::{Rect, Size};
2use crate::number::Number;
3
4#[derive(Copy, Clone, PartialEq, Debug)]
5#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6pub enum AlignItems {
7    FlexStart,
8    FlexEnd,
9    Center,
10    Baseline,
11    Stretch,
12}
13
14impl Default for AlignItems {
15    fn default() -> Self {
16        Self::Stretch
17    }
18}
19
20#[derive(Copy, Clone, PartialEq, Debug)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22pub enum AlignSelf {
23    Auto,
24    FlexStart,
25    FlexEnd,
26    Center,
27    Baseline,
28    Stretch,
29}
30
31impl Default for AlignSelf {
32    fn default() -> Self {
33        Self::Auto
34    }
35}
36
37#[derive(Copy, Clone, PartialEq, Debug)]
38#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
39pub enum AlignContent {
40    FlexStart,
41    FlexEnd,
42    Center,
43    Stretch,
44    SpaceBetween,
45    SpaceAround,
46}
47
48impl Default for AlignContent {
49    fn default() -> Self {
50        Self::Stretch
51    }
52}
53
54#[derive(Copy, Clone, PartialEq, Debug)]
55#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
56pub enum Direction {
57    Inherit,
58    #[cfg_attr(feature = "serde", serde(rename = "ltr"))]
59    LTR,
60    #[cfg_attr(feature = "serde", serde(rename = "rtl"))]
61    RTL,
62}
63
64impl Default for Direction {
65    fn default() -> Self {
66        Self::Inherit
67    }
68}
69
70#[derive(Copy, Clone, PartialEq, Debug)]
71#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
72pub enum Display {
73    #[cfg_attr(feature = "serde", serde(rename = "flex"))]
74    Flex,
75    #[cfg_attr(feature = "serde", serde(rename = "none"))]
76    None,
77}
78
79impl Default for Display {
80    fn default() -> Self {
81        Self::Flex
82    }
83}
84
85#[derive(Copy, Clone, PartialEq, Debug)]
86#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
87pub enum FlexDirection {
88    Row,
89    Column,
90    RowReverse,
91    ColumnReverse,
92}
93
94impl Default for FlexDirection {
95    fn default() -> Self {
96        Self::Row
97    }
98}
99
100impl FlexDirection {
101    #[inline]
102    pub(crate) fn is_row(self) -> bool {
103        matches!(self, Self::Row | Self::RowReverse)
104    }
105
106    #[inline]
107    pub(crate) fn is_column(self) -> bool {
108        matches!(self, Self::Column | Self::ColumnReverse)
109    }
110
111    #[inline]
112    pub(crate) fn is_reverse(self) -> bool {
113        matches!(self, Self::RowReverse | Self::ColumnReverse)
114    }
115}
116
117#[derive(Copy, Clone, PartialEq, Debug)]
118#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
119pub enum JustifyContent {
120    FlexStart,
121    FlexEnd,
122    Center,
123    SpaceBetween,
124    SpaceAround,
125    SpaceEvenly,
126}
127
128impl Default for JustifyContent {
129    fn default() -> Self {
130        Self::FlexStart
131    }
132}
133
134#[derive(Copy, Clone, PartialEq, Debug)]
135#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
136pub enum Overflow {
137    Visible,
138    Hidden,
139    Scroll,
140}
141
142impl Default for Overflow {
143    fn default() -> Self {
144        Self::Visible
145    }
146}
147
148#[derive(Copy, Clone, PartialEq, Debug)]
149#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
150pub enum PositionType {
151    Relative,
152    Absolute,
153}
154
155impl Default for PositionType {
156    fn default() -> Self {
157        Self::Relative
158    }
159}
160
161#[derive(Copy, Clone, PartialEq, Debug)]
162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
163pub enum FlexWrap {
164    NoWrap,
165    Wrap,
166    WrapReverse,
167}
168
169impl Default for FlexWrap {
170    fn default() -> Self {
171        Self::NoWrap
172    }
173}
174
175#[derive(Copy, Clone, PartialEq, Debug)]
176#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
177pub enum Dimension {
178    Undefined,
179    Auto,
180    Points(f32),
181    Percent(f32),
182}
183
184impl Default for Dimension {
185    fn default() -> Self {
186        Self::Undefined
187    }
188}
189
190impl Dimension {
191    pub(crate) fn resolve(self, parent_dim: Number) -> Number {
192        match self {
193            Dimension::Points(points) => Number::Defined(points),
194            Dimension::Percent(percent) => parent_dim * percent,
195            _ => Number::Undefined,
196        }
197    }
198
199    pub(crate) fn is_defined(self) -> bool {
200        matches!(self, Dimension::Points(_) | Dimension::Percent(_))
201    }
202}
203
204impl Default for Rect<Dimension> {
205    fn default() -> Self {
206        Self { start: Default::default(), end: Default::default(), top: Default::default(), bottom: Default::default() }
207    }
208}
209
210impl Default for Size<Dimension> {
211    fn default() -> Self {
212        Self { width: Dimension::Auto, height: Dimension::Auto }
213    }
214}
215
216#[derive(Copy, Clone, PartialEq, Debug)]
217#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
218#[cfg_attr(feature = "serde", serde(default))]
219pub struct Style {
220    pub display: Display,
221    pub position_type: PositionType,
222    pub direction: Direction,
223    pub flex_direction: FlexDirection,
224    pub flex_wrap: FlexWrap,
225    pub overflow: Overflow,
226    pub align_items: AlignItems,
227    pub align_self: AlignSelf,
228    pub align_content: AlignContent,
229    pub justify_content: JustifyContent,
230    pub position: Rect<Dimension>,
231    pub margin: Rect<Dimension>,
232    pub padding: Rect<Dimension>,
233    pub border: Rect<Dimension>,
234    pub flex_grow: f32,
235    pub flex_shrink: f32,
236    pub flex_basis: Dimension,
237    pub size: Size<Dimension>,
238    pub min_size: Size<Dimension>,
239    pub max_size: Size<Dimension>,
240    pub aspect_ratio: Number,
241}
242
243impl Default for Style {
244    fn default() -> Self {
245        Self {
246            display: Default::default(),
247            position_type: Default::default(),
248            direction: Default::default(),
249            flex_direction: Default::default(),
250            flex_wrap: Default::default(),
251            overflow: Default::default(),
252            align_items: Default::default(),
253            align_self: Default::default(),
254            align_content: Default::default(),
255            justify_content: Default::default(),
256            position: Default::default(),
257            margin: Default::default(),
258            padding: Default::default(),
259            border: Default::default(),
260            flex_grow: 0.0,
261            flex_shrink: 1.0,
262            flex_basis: Dimension::Auto,
263            size: Default::default(),
264            min_size: Default::default(),
265            max_size: Default::default(),
266            aspect_ratio: Default::default(),
267        }
268    }
269}
270
271impl Style {
272    pub(crate) fn min_main_size(&self, direction: FlexDirection) -> Dimension {
273        if direction.is_row() {
274            self.min_size.width
275        } else {
276            self.min_size.height
277        }
278    }
279
280    pub(crate) fn max_main_size(&self, direction: FlexDirection) -> Dimension {
281        if direction.is_row() {
282            self.max_size.width
283        } else {
284            self.max_size.height
285        }
286    }
287
288    pub(crate) fn main_margin_start(&self, direction: FlexDirection) -> Dimension {
289        if direction.is_row() {
290            self.margin.start
291        } else {
292            self.margin.top
293        }
294    }
295
296    pub(crate) fn main_margin_end(&self, direction: FlexDirection) -> Dimension {
297        if direction.is_row() {
298            self.margin.end
299        } else {
300            self.margin.bottom
301        }
302    }
303
304    pub(crate) fn cross_size(&self, direction: FlexDirection) -> Dimension {
305        if direction.is_row() {
306            self.size.height
307        } else {
308            self.size.width
309        }
310    }
311
312    pub(crate) fn min_cross_size(&self, direction: FlexDirection) -> Dimension {
313        if direction.is_row() {
314            self.min_size.height
315        } else {
316            self.min_size.width
317        }
318    }
319
320    pub(crate) fn max_cross_size(&self, direction: FlexDirection) -> Dimension {
321        if direction.is_row() {
322            self.max_size.height
323        } else {
324            self.max_size.width
325        }
326    }
327
328    pub(crate) fn cross_margin_start(&self, direction: FlexDirection) -> Dimension {
329        if direction.is_row() {
330            self.margin.top
331        } else {
332            self.margin.start
333        }
334    }
335
336    pub(crate) fn cross_margin_end(&self, direction: FlexDirection) -> Dimension {
337        if direction.is_row() {
338            self.margin.bottom
339        } else {
340            self.margin.end
341        }
342    }
343
344    pub(crate) fn align_self(&self, parent: &Style) -> AlignSelf {
345        if self.align_self == AlignSelf::Auto {
346            match parent.align_items {
347                AlignItems::FlexStart => AlignSelf::FlexStart,
348                AlignItems::FlexEnd => AlignSelf::FlexEnd,
349                AlignItems::Center => AlignSelf::Center,
350                AlignItems::Baseline => AlignSelf::Baseline,
351                AlignItems::Stretch => AlignSelf::Stretch,
352            }
353        } else {
354            self.align_self
355        }
356    }
357}