Add support for column/row reverse
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}