Factor out some logic into geometry module
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}