gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5364Rust 86Markdown 12TOML 91841 Sutichaykuna

⎇ 32973e7ca8635aa870a77f52d0d0070381ae5f8c src/style.rs Rust · 354 siq'ikuna · 8.4 KB Ñawpa willay Pi imata llamkarqan ch'uya

Factor out some logic into geometry module 32973e7ca · Emil Sjölander ·

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