maycoon_core/
layout.rs

1use nalgebra::Vector2;
2pub use taffy::{
3    AlignContent, AlignItems, AlignSelf, Dimension, Display, FlexDirection, FlexWrap, GridAutoFlow,
4    GridPlacement, JustifyContent, JustifyItems, JustifySelf, Layout, LengthPercentage,
5    LengthPercentageAuto, Line, Overflow, Position, Rect,
6};
7
8/// Defines different aspects and properties of a widget layout.
9#[derive(Clone, PartialEq, Debug)]
10pub struct LayoutStyle {
11    /// What layout strategy should be used?
12    pub display: Display,
13
14    /// How children overflowing their container should affect layout.
15    pub overflow: (Overflow, Overflow),
16
17    /// How much space (in points) should be reserved for scrollbars.
18    pub scrollbar_width: f32,
19
20    /// What should the position value of this struct use as a base offset?
21    pub position: Position,
22
23    /// How should the position of this element be tweaked relative to the layout defined?
24    pub inset: Rect<LengthPercentageAuto>,
25
26    /// Sets the initial size of the item.
27    pub size: Vector2<Dimension>,
28
29    /// Controls the minimum size of the item.
30    pub min_size: Vector2<Dimension>,
31
32    /// Controls the maximum size of the item.
33    pub max_size: Vector2<Dimension>,
34
35    /// Sets the preferred aspect ratio for the item
36    ///
37    /// The ratio is calculated as width divided by height.
38    pub aspect_ratio: Option<f32>,
39
40    /// How large should the margin be on each side?
41    pub margin: Rect<LengthPercentageAuto>,
42
43    /// How large should the padding be on each side?
44    pub padding: Rect<LengthPercentage>,
45
46    /// How large should the border be on each side?
47    pub border: Rect<LengthPercentage>,
48
49    /// How this node's children aligned in the cross/block axis?
50    pub align_items: Option<AlignItems>,
51
52    /// How this node should be aligned in the cross/block axis
53    /// Falls back to the parents [`AlignItems`] if not set.
54    pub align_self: Option<AlignSelf>,
55
56    /// How this node's children should be aligned in the inline axis.
57    pub justify_items: Option<AlignItems>,
58
59    /// How this node should be aligned in the inline axis
60    /// Falls back to the parents [`JustifyItems`] if not set.
61    pub justify_self: Option<AlignSelf>,
62
63    /// How should content contained within this item be aligned in the cross/block axis?
64    pub align_content: Option<AlignContent>,
65
66    /// How should content contained within this item be aligned in the main/inline axis?
67    pub justify_content: Option<JustifyContent>,
68
69    /// How large should the gaps between items in a grid or flex container be?
70    pub gap: Vector2<LengthPercentage>,
71
72    /// Which direction does the main axis flow in?
73    pub flex_direction: FlexDirection,
74
75    /// Should elements wrap, or stay in a single line?
76    pub flex_wrap: FlexWrap,
77
78    /// Sets the initial main axis size of the item.
79    pub flex_basis: Dimension,
80
81    /// The relative rate at which this item grows when it is expanding to fill space.
82    ///
83    /// 0.0 is the default value, and this value must be positive.
84    pub flex_grow: f32,
85
86    /// The relative rate at which this item shrinks when it is contracting to fit into space.
87    ///
88    /// 1.0 is the default value, and this value must be positive.
89    pub flex_shrink: f32,
90
91    /// Controls how items get placed into the grid for auto-placed items.
92    pub grid_auto_flow: GridAutoFlow,
93
94    /// Defines which row in the grid the item should start and end at.
95    pub grid_row: Line<GridPlacement>,
96
97    /// Defines which column in the grid the item should start and end at.
98    pub grid_column: Line<GridPlacement>,
99}
100
101impl Default for LayoutStyle {
102    fn default() -> Self {
103        LayoutStyle {
104            display: Display::default(),
105            overflow: (Overflow::Visible, Overflow::Visible),
106            scrollbar_width: 0.0,
107            position: Position::Relative,
108            inset: Rect::auto(),
109            margin: Rect::zero(),
110            padding: Rect::zero(),
111            border: Rect::zero(),
112            size: Vector2::new(Dimension::Auto, Dimension::Auto),
113            min_size: Vector2::new(Dimension::Auto, Dimension::Auto),
114            max_size: Vector2::new(Dimension::Auto, Dimension::Auto),
115            aspect_ratio: None,
116            gap: Vector2::new(LengthPercentage::Length(0.0), LengthPercentage::Length(0.0)),
117            align_items: None,
118            align_self: None,
119            justify_items: None,
120            justify_self: None,
121            align_content: None,
122            justify_content: None,
123            flex_direction: FlexDirection::Row,
124            flex_wrap: FlexWrap::NoWrap,
125            flex_grow: 0.0,
126            flex_shrink: 1.0,
127            flex_basis: Dimension::Auto,
128            grid_auto_flow: GridAutoFlow::Row,
129            grid_row: Line {
130                start: GridPlacement::Auto,
131                end: GridPlacement::Auto,
132            },
133            grid_column: Line {
134                start: GridPlacement::Auto,
135                end: GridPlacement::Auto,
136            },
137        }
138    }
139}
140
141impl From<LayoutStyle> for taffy::Style {
142    fn from(value: LayoutStyle) -> Self {
143        taffy::Style {
144            display: value.display,
145            overflow: taffy::Point {
146                x: value.overflow.0,
147                y: value.overflow.1,
148            },
149            scrollbar_width: value.scrollbar_width,
150            position: value.position,
151            inset: value.inset,
152            margin: value.margin,
153            padding: value.padding,
154            border: value.border,
155            size: taffy::Size {
156                width: value.size.x,
157                height: value.size.y,
158            },
159            min_size: taffy::Size {
160                width: value.min_size.x,
161                height: value.min_size.y,
162            },
163            max_size: taffy::Size {
164                width: value.max_size.x,
165                height: value.max_size.y,
166            },
167            aspect_ratio: value.aspect_ratio,
168            gap: taffy::Size {
169                width: value.gap.x,
170                height: value.gap.y,
171            },
172            align_items: value.align_items,
173            align_self: value.align_self,
174            justify_items: value.justify_items,
175            justify_self: value.justify_self,
176            align_content: value.align_content,
177            justify_content: value.justify_content,
178            flex_direction: value.flex_direction,
179            flex_wrap: value.flex_wrap,
180            flex_grow: value.flex_grow,
181            flex_shrink: value.flex_shrink,
182            flex_basis: value.flex_basis,
183            grid_auto_flow: value.grid_auto_flow,
184            grid_row: value.grid_row,
185            grid_column: value.grid_column,
186            ..Default::default()
187        }
188    }
189}
190
191/// The computed layout with children nodes.
192#[derive(Debug)]
193pub struct LayoutNode {
194    /// The computed layout of this node.
195    pub layout: Layout,
196    /// The children of this node.
197    pub children: Vec<LayoutNode>,
198}
199
200/// The raw layout styles with children nodes.
201pub struct StyleNode {
202    /// The layout style of this node.
203    pub style: LayoutStyle,
204    /// The children of this node.
205    pub children: Vec<StyleNode>,
206}