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