tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5334Rust 85Markdown 12TOML 91813 Definitions

⎇ 8951e8bf14ffe31d4039beeee80842bee3f1e6a3 src/style.rs Rust · 450 lines · 12.1 KB History Who touched what raw

Add support for column/row reverse 8951e8bf1 · Emil Sjölander ·

1#[derive(Copy, Clone, PartialEq, Debug)]
2pub enum AlignItems {
3    FlexStart,
4    FlexEnd,
5    Center,
6    Baseline,
7    Stretch,
8}
9
10impl Default for AlignItems {
11    fn default() -> AlignItems {
12        AlignItems::Stretch
13    }
14}
15
16#[derive(Copy, Clone, PartialEq, Debug)]
17pub enum AlignSelf {
18    Auto,
19    FlexStart,
20    FlexEnd,
21    Center,
22    Baseline,
23    Stretch,
24}
25
26impl Default for AlignSelf {
27    fn default() -> AlignSelf {
28        AlignSelf::Auto
29    }
30}
31
32#[derive(Copy, Clone, PartialEq, Debug)]
33pub enum AlignContent {
34    FlexStart,
35    FlexEnd,
36    Center,
37    Stretch,
38    SpaceBetween,
39    SpaceAround,
40}
41
42impl Default for AlignContent {
43    fn default() -> AlignContent {
44        AlignContent::Stretch
45    }
46}
47
48#[derive(Copy, Clone, PartialEq, Debug)]
49pub enum Direction {
50    Inherit,
51    LTR,
52    RTL,
53}
54
55impl Default for Direction {
56    fn default() -> Direction {
57        Direction::Inherit
58    }
59}
60
61#[derive(Copy, Clone, PartialEq, Debug)]
62pub enum Display {
63    Flex,
64    None,
65}
66
67impl Default for Display {
68    fn default() -> Display {
69        Display::Flex
70    }
71}
72
73#[derive(Copy, Clone, PartialEq, Debug)]
74pub enum FlexDirection {
75    Row,
76    Column,
77    RowReverse,
78    ColumnReverse,
79}
80
81impl Default for FlexDirection {
82    fn default() -> FlexDirection {
83        FlexDirection::Row
84    }
85}
86
87impl FlexDirection {
88    pub(crate) fn is_row(self) -> bool {
89        self == FlexDirection::Row || self == FlexDirection::RowReverse
90    }
91
92    pub(crate) fn is_column(self) -> bool {
93        self == FlexDirection::Column || self == FlexDirection::ColumnReverse
94    }
95
96    pub(crate) fn is_reverse(self) -> bool {
97        self == FlexDirection::RowReverse || self == FlexDirection::ColumnReverse
98    }
99}
100
101#[derive(Copy, Clone, PartialEq, Debug)]
102pub enum JustifyContent {
103    FlexStart,
104    FlexEnd,
105    Center,
106    SpaceBetween,
107    SpaceAround,
108    SpaceEvenly,
109}
110
111impl Default for JustifyContent {
112    fn default() -> JustifyContent {
113        JustifyContent::FlexStart
114    }
115}
116
117#[derive(Copy, Clone, PartialEq, Debug)]
118pub enum Overflow {
119    Visible,
120    Hidden,
121    Scroll,
122}
123
124impl Default for Overflow {
125    fn default() -> Overflow {
126        Overflow::Visible
127    }
128}
129
130#[derive(Copy, Clone, PartialEq, Debug)]
131pub enum Position {
132    Relative,
133    Absolute,
134}
135
136impl Default for Position {
137    fn default() -> Position {
138        Position::Relative
139    }
140}
141
142#[derive(Copy, Clone, PartialEq, Debug)]
143pub enum FlexWrap {
144    NoWrap,
145    Wrap,
146    WrapReverse,
147}
148
149impl Default for FlexWrap {
150    fn default() -> FlexWrap {
151        FlexWrap::NoWrap
152    }
153}
154
155#[derive(Copy, Clone, PartialEq, Debug)]
156pub enum Dimension {
157    Auto,
158    Points(f32),
159    Percent(f32),
160}
161
162impl Default for Dimension {
163    fn default() -> Dimension {
164        Dimension::Auto
165    }
166}
167
168impl Dimension {
169    pub(crate) fn resolve(&self, parent_width: f32, auto_size: f32) -> f32 {
170        match self {
171            Dimension::Points(points) => *points,
172            Dimension::Percent(percent) if parent_width.is_finite() => percent * parent_width,
173            _ => auto_size,
174        }
175    }
176}
177
178#[derive(Debug)]
179pub struct Edges {
180    pub start: Dimension,
181    pub end: Dimension,
182    pub top: Dimension,
183    pub bottom: Dimension,
184}
185
186impl Default for Edges {
187    fn default() -> Edges {
188        Edges {
189            start: Dimension::Points(0.0),
190            end: Dimension::Points(0.0),
191            top: Dimension::Points(0.0),
192            bottom: Dimension::Points(0.0),
193        }
194    }
195}
196
197#[derive(Debug)]
198pub struct Node {
199    pub position: Position,
200    pub direction: Direction,
201    pub flex_direction: FlexDirection,
202
203    pub flex_wrap: FlexWrap,
204    pub overflow: Overflow,
205
206    pub align_items: AlignItems,
207    pub align_self: AlignSelf,
208    pub align_content: AlignContent,
209
210    pub justify_content: JustifyContent,
211
212    pub margin: Edges,
213    pub padding: Edges,
214    pub border: Edges,
215
216    pub flex_grow: f32,
217    pub flex_shrink: f32,
218    pub flex_basis: Dimension,
219
220    pub start: Dimension,
221    pub end: Dimension,
222    pub top: Dimension,
223    pub bottom: Dimension,
224
225    pub width: Dimension,
226    pub min_width: Dimension,
227    pub max_width: Dimension,
228
229    pub height: Dimension,
230    pub min_height: Dimension,
231    pub max_height: Dimension,
232
233    pub aspect_ratio: Option<f32>,
234
235    pub children: Vec<Node>,
236}
237
238impl Default for Node {
239    fn default() -> Node {
240        Node {
241            position: Default::default(),
242            direction: Default::default(),
243            flex_direction: Default::default(),
244
245            flex_wrap: Default::default(),
246            overflow: Default::default(),
247
248            align_items: Default::default(),
249            align_self: Default::default(),
250            align_content: Default::default(),
251
252            justify_content: Default::default(),
253
254            margin: Default::default(),
255            padding: Default::default(),
256            border: Default::default(),
257
258            flex_grow: 0.0,
259            flex_shrink: 1.0,
260            flex_basis: Default::default(),
261
262            start: Default::default(),
263            end: Default::default(),
264            top: Default::default(),
265            bottom: Default::default(),
266
267            width: Default::default(),
268            min_width: Default::default(),
269            max_width: Default::default(),
270
271            height: Default::default(),
272            min_height: Default::default(),
273            max_height: Default::default(),
274
275            aspect_ratio: Default::default(),
276
277            children: vec![],
278        }
279    }
280}
281
282impl Node {
283    pub(crate) fn main_size(&self, direction: FlexDirection) -> Dimension {
284        match direction {
285            FlexDirection::Row | FlexDirection::RowReverse => self.width,
286            FlexDirection::Column | FlexDirection::ColumnReverse => self.height,
287        }
288    }
289
290    pub(crate) fn min_main_size(&self, direction: FlexDirection) -> Dimension {
291        match direction {
292            FlexDirection::Row | FlexDirection::RowReverse => self.min_width,
293            FlexDirection::Column | FlexDirection::ColumnReverse => self.min_height,
294        }
295    }
296
297    pub(crate) fn max_main_size(&self, direction: FlexDirection) -> Dimension {
298        match direction {
299            FlexDirection::Row | FlexDirection::RowReverse => self.max_width,
300            FlexDirection::Column | FlexDirection::ColumnReverse => self.max_height,
301        }
302    }
303
304    pub(crate) fn main_margin_start(&self, direction: FlexDirection) -> Dimension {
305        match direction {
306            FlexDirection::Row | FlexDirection::RowReverse => self.margin.start,
307            FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.top,
308        }
309    }
310
311    pub(crate) fn main_margin_end(&self, direction: FlexDirection) -> Dimension {
312        match direction {
313            FlexDirection::Row | FlexDirection::RowReverse => self.margin.end,
314            FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.bottom,
315        }
316    }
317
318    pub(crate) fn main_padding_start(&self, direction: FlexDirection) -> Dimension {
319        match direction {
320            FlexDirection::Row | FlexDirection::RowReverse => self.padding.start,
321            FlexDirection::Column | FlexDirection::ColumnReverse => self.padding.top,
322        }
323    }
324
325    pub(crate) fn main_padding_end(&self, direction: FlexDirection) -> Dimension {
326        match direction {
327            FlexDirection::Row | FlexDirection::RowReverse => self.padding.end,
328            FlexDirection::Column | FlexDirection::ColumnReverse => self.padding.bottom,
329        }
330    }
331
332    pub(crate) fn main_border_start(&self, direction: FlexDirection) -> Dimension {
333        match direction {
334            FlexDirection::Row | FlexDirection::RowReverse => self.border.start,
335            FlexDirection::Column | FlexDirection::ColumnReverse => self.border.top,
336        }
337    }
338
339    pub(crate) fn main_border_end(&self, direction: FlexDirection) -> Dimension {
340        match direction {
341            FlexDirection::Row | FlexDirection::RowReverse => self.border.end,
342            FlexDirection::Column | FlexDirection::ColumnReverse => self.border.bottom,
343        }
344    }
345
346    pub(crate) fn cross_size(&self, direction: FlexDirection) -> Dimension {
347        match direction {
348            FlexDirection::Row | FlexDirection::RowReverse => self.height,
349            FlexDirection::Column | FlexDirection::ColumnReverse => self.width,
350        }
351    }
352
353    pub(crate) fn min_cross_size(&self, direction: FlexDirection) -> Dimension {
354        match direction {
355            FlexDirection::Row | FlexDirection::RowReverse => self.min_height,
356            FlexDirection::Column | FlexDirection::ColumnReverse => self.min_width,
357        }
358    }
359
360    pub(crate) fn max_cross_size(&self, direction: FlexDirection) -> Dimension {
361        match direction {
362            FlexDirection::Row | FlexDirection::RowReverse => self.max_height,
363            FlexDirection::Column | FlexDirection::ColumnReverse => self.max_width,
364        }
365    }
366
367    pub(crate) fn cross_margin_start(&self, direction: FlexDirection) -> Dimension {
368        match direction {
369            FlexDirection::Row | FlexDirection::RowReverse => self.margin.top,
370            FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.start,
371        }
372    }
373
374    pub(crate) fn cross_margin_end(&self, direction: FlexDirection) -> Dimension {
375        match direction {
376            FlexDirection::Row | FlexDirection::RowReverse => self.margin.bottom,
377            FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.end,
378        }
379    }
380
381    pub(crate) fn cross_padding_start(&self, direction: FlexDirection) -> Dimension {
382        match direction {
383            FlexDirection::Row | FlexDirection::RowReverse => self.padding.top,
384            FlexDirection::Column | FlexDirection::ColumnReverse => self.padding.start,
385        }
386    }
387
388    pub(crate) fn cross_padding_end(&self, direction: FlexDirection) -> Dimension {
389        match direction {
390            FlexDirection::Row | FlexDirection::RowReverse => self.padding.bottom,
391            FlexDirection::Column | FlexDirection::ColumnReverse => self.padding.end,
392        }
393    }
394
395    pub(crate) fn cross_border_start(&self, direction: FlexDirection) -> Dimension {
396        match direction {
397            FlexDirection::Row | FlexDirection::RowReverse => self.border.top,
398            FlexDirection::Column | FlexDirection::ColumnReverse => self.border.start,
399        }
400    }
401
402    pub(crate) fn cross_border_end(&self, direction: FlexDirection) -> Dimension {
403        match direction {
404            FlexDirection::Row | FlexDirection::RowReverse => self.border.bottom,
405            FlexDirection::Column | FlexDirection::ColumnReverse => self.border.end,
406        }
407    }
408
409    pub(crate) fn main_start(&self, direction: FlexDirection) -> Dimension {
410        match direction {
411            FlexDirection::Row | FlexDirection::RowReverse => self.start,
412            FlexDirection::Column | FlexDirection::ColumnReverse => self.top,
413        }
414    }
415
416    pub(crate) fn main_end(&self, direction: FlexDirection) -> Dimension {
417        match direction {
418            FlexDirection::Row | FlexDirection::RowReverse => self.end,
419            FlexDirection::Column | FlexDirection::ColumnReverse => self.bottom,
420        }
421    }
422
423    pub(crate) fn cross_start(&self, direction: FlexDirection) -> Dimension {
424        match direction {
425            FlexDirection::Row | FlexDirection::RowReverse => self.top,
426            FlexDirection::Column | FlexDirection::ColumnReverse => self.start,
427        }
428    }
429
430    pub(crate) fn cross_end(&self, direction: FlexDirection) -> Dimension {
431        match direction {
432            FlexDirection::Row | FlexDirection::RowReverse => self.bottom,
433            FlexDirection::Column | FlexDirection::ColumnReverse => self.end,
434        }
435    }
436
437    pub(crate) fn align_self(&self, parent: &Node) -> AlignSelf {
438        if self.align_self == AlignSelf::Auto {
439            match parent.align_items {
440                AlignItems::FlexStart => AlignSelf::FlexStart,
441                AlignItems::FlexEnd => AlignSelf::FlexEnd,
442                AlignItems::Center => AlignSelf::Center,
443                AlignItems::Baseline => AlignSelf::Baseline,
444                AlignItems::Stretch => AlignSelf::Stretch,
445            }
446        } else {
447            self.align_self
448        }
449    }
450}