Pass axis information when measuring a child's size (#575)
1//! Style types for Flexbox layout
2
3use crate::geometry::AbsoluteAxis;
4
5/// Controls whether flex items are forced onto one line or can wrap onto multiple lines.
6///
7/// Defaults to [`FlexWrap::NoWrap`]
8///
9/// [Specification](https://www.w3.org/TR/css-flexbox-1/#flex-wrap-property)
10#[derive(Copy, Clone, PartialEq, Eq, Debug)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum FlexWrap {
13 /// Items will not wrap and stay on a single line
14 NoWrap,
15 /// Items will wrap according to this item's [`FlexDirection`]
16 Wrap,
17 /// Items will wrap in the opposite direction to this item's [`FlexDirection`]
18 WrapReverse,
19}
20
21impl Default for FlexWrap {
22 fn default() -> Self {
23 Self::NoWrap
24 }
25}
26
27/// The direction of the flexbox layout main axis.
28///
29/// There are always two perpendicular layout axes: main (or primary) and cross (or secondary).
30/// Adding items will cause them to be positioned adjacent to each other along the main axis.
31/// By varying this value throughout your tree, you can create complex axis-aligned layouts.
32///
33/// Items are always aligned relative to the cross axis, and justified relative to the main axis.
34///
35/// The default behavior is [`FlexDirection::Row`].
36///
37/// [Specification](https://www.w3.org/TR/css-flexbox-1/#flex-direction-property)
38#[derive(Copy, Clone, PartialEq, Eq, Debug)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub enum FlexDirection {
41 /// Defines +x as the main axis
42 ///
43 /// Items will be added from left to right in a row.
44 Row,
45 /// Defines +y as the main axis
46 ///
47 /// Items will be added from top to bottom in a column.
48 Column,
49 /// Defines -x as the main axis
50 ///
51 /// Items will be added from right to left in a row.
52 RowReverse,
53 /// Defines -y as the main axis
54 ///
55 /// Items will be added from bottom to top in a column.
56 ColumnReverse,
57}
58
59impl Default for FlexDirection {
60 fn default() -> Self {
61 Self::Row
62 }
63}
64
65impl FlexDirection {
66 #[inline]
67 /// Is the direction [`FlexDirection::Row`] or [`FlexDirection::RowReverse`]?
68 pub(crate) fn is_row(self) -> bool {
69 matches!(self, Self::Row | Self::RowReverse)
70 }
71
72 #[inline]
73 /// Is the direction [`FlexDirection::Column`] or [`FlexDirection::ColumnReverse`]?
74 pub(crate) fn is_column(self) -> bool {
75 matches!(self, Self::Column | Self::ColumnReverse)
76 }
77
78 #[inline]
79 /// Is the direction [`FlexDirection::RowReverse`] or [`FlexDirection::ColumnReverse`]?
80 pub(crate) fn is_reverse(self) -> bool {
81 matches!(self, Self::RowReverse | Self::ColumnReverse)
82 }
83
84 #[inline]
85 /// The `AbsoluteAxis` that corresponds to the main axis
86 pub(crate) fn main_axis(self) -> AbsoluteAxis {
87 match self {
88 Self::Row | Self::RowReverse => AbsoluteAxis::Horizontal,
89 Self::Column | Self::ColumnReverse => AbsoluteAxis::Vertical,
90 }
91 }
92
93 #[inline]
94 /// The `AbsoluteAxis` that corresponds to the cross axis
95 pub(crate) fn cross_axis(self) -> AbsoluteAxis {
96 match self {
97 Self::Row | Self::RowReverse => AbsoluteAxis::Vertical,
98 Self::Column | Self::ColumnReverse => AbsoluteAxis::Horizontal,
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 mod test_flex_direction {
106 use crate::style::*;
107
108 #[test]
109 fn flex_direction_is_row() {
110 assert_eq!(FlexDirection::Row.is_row(), true);
111 assert_eq!(FlexDirection::RowReverse.is_row(), true);
112 assert_eq!(FlexDirection::Column.is_row(), false);
113 assert_eq!(FlexDirection::ColumnReverse.is_row(), false);
114 }
115
116 #[test]
117 fn flex_direction_is_column() {
118 assert_eq!(FlexDirection::Row.is_column(), false);
119 assert_eq!(FlexDirection::RowReverse.is_column(), false);
120 assert_eq!(FlexDirection::Column.is_column(), true);
121 assert_eq!(FlexDirection::ColumnReverse.is_column(), true);
122 }
123
124 #[test]
125 fn flex_direction_is_reverse() {
126 assert_eq!(FlexDirection::Row.is_reverse(), false);
127 assert_eq!(FlexDirection::RowReverse.is_reverse(), true);
128 assert_eq!(FlexDirection::Column.is_reverse(), false);
129 assert_eq!(FlexDirection::ColumnReverse.is_reverse(), true);
130 }
131 }
132}