tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 231Rust 9TOML 3CSS 1345 Sutichaykuna

⎇ 724e286c826a377eef0214c0d2085c5d3f1a8b71 src/style.rs Rust · 339 siq'ikuna · 8.0 KB Ñawpa willay Pi imata llamkarqan ch'uya

Remove dead Direction type (#111) 724e286c8 · Alice Cecile ·

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