gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 709HTML 662Markdown 12TOML 62348 Definitions

⎇ b2526d2c42d548be6f1e8d249db180aefb67216a src/style.rs Rust · 373 lines · 11.8 KB History Who touched what raw

Make Style derive PartialEq b2526d2c4 · David Flemström ·

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