torin/
node.rs

1pub use euclid::Rect;
2
3use crate::{
4    alignment::Alignment,
5    direction::Direction,
6    gaps::Gaps,
7    geometry::Length,
8    prelude::{
9        Content,
10        Position,
11        VisibleSize,
12    },
13    scaled::Scaled,
14    size::Size,
15};
16
17/// Node layout configuration
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[derive(PartialEq, Clone, Debug, Default)]
20pub struct Node {
21    /// Dimentions
22    pub width: Size,
23    pub height: Size,
24
25    // Minimum dimensions
26    pub minimum_width: Size,
27    pub minimum_height: Size,
28
29    // Maximum dimensions
30    pub maximum_width: Size,
31    pub maximum_height: Size,
32
33    // Visible dimensions
34    pub visible_width: VisibleSize,
35    pub visible_height: VisibleSize,
36
37    // Axis alignments for the children
38    pub main_alignment: Alignment,
39    pub cross_alignment: Alignment,
40
41    /// Inner padding
42    pub padding: Gaps,
43
44    /// Inner margin
45    pub margin: Gaps,
46
47    /// Inner position offsets
48    pub offset_x: Length,
49    pub offset_y: Length,
50
51    /// Direction in which it's inner Nodes will be stacked
52    pub direction: Direction,
53
54    /// Position config
55    pub position: Position,
56
57    pub content: Content,
58
59    /// A Node might depend on inner sizes but have a fixed position, like scroll views.
60    pub has_layout_references: bool,
61
62    pub spacing: Length,
63}
64
65impl Scaled for Node {
66    fn scale(&mut self, scale_factor: f32) {
67        self.width.scale(scale_factor);
68        self.height.scale(scale_factor);
69        self.minimum_width.scale(scale_factor);
70        self.minimum_height.scale(scale_factor);
71        self.maximum_width.scale(scale_factor);
72        self.maximum_height.scale(scale_factor);
73        self.margin.scale(scale_factor);
74        self.padding.scale(scale_factor);
75        self.offset_x *= scale_factor;
76        self.offset_y *= scale_factor;
77        self.position.scale(scale_factor);
78        self.spacing *= scale_factor;
79    }
80}
81
82impl Node {
83    /// Create a Node with the default values
84    pub fn new() -> Self {
85        Self::default()
86    }
87
88    pub fn self_layout_eq(&self, other: &Self) -> bool {
89        // Excludes offset_x and offset_y
90        self.width == other.width
91            && self.height == other.height
92            && self.minimum_width == other.minimum_width
93            && self.minimum_height == other.minimum_height
94            && self.maximum_width == other.maximum_width
95            && self.maximum_height == other.maximum_height
96            && self.visible_width == other.visible_width
97            && self.visible_height == other.visible_height
98            && self.main_alignment == other.main_alignment
99            && self.cross_alignment == other.cross_alignment
100            && self.padding == other.padding
101            && self.margin == other.margin
102            && self.direction == other.direction
103            && self.position == other.position
104            && self.content == other.content
105            && self.has_layout_references == other.has_layout_references
106            && self.spacing == other.spacing
107    }
108
109    pub fn inner_layout_eq(&self, other: &Self) -> bool {
110        // Excludes everything but offset_x and offset_y
111        self.offset_x == other.offset_x && self.offset_y == other.offset_y
112    }
113
114    /// Construct a new Node given a size and a direction
115    pub fn from_size_and_direction(width: Size, height: Size, direction: Direction) -> Self {
116        Self {
117            width,
118            height,
119            direction,
120            ..Default::default()
121        }
122    }
123
124    /// Construct a new Node given some sizes
125    pub fn from_sizes(
126        width: Size,
127        height: Size,
128        minimum_width: Size,
129        minimum_height: Size,
130        maximum_width: Size,
131        maximum_height: Size,
132    ) -> Self {
133        Self {
134            width,
135            height,
136            minimum_width,
137            minimum_height,
138            maximum_width,
139            maximum_height,
140            ..Default::default()
141        }
142    }
143
144    /// Construct a new Node given a size and a visible size
145    pub fn from_size_and_visible_size(
146        width: Size,
147        height: Size,
148        visible_width: VisibleSize,
149        visible_height: VisibleSize,
150    ) -> Self {
151        Self {
152            width,
153            height,
154            visible_width,
155            visible_height,
156            ..Default::default()
157        }
158    }
159
160    /// Construct a new Node given a size and some offsets
161    pub fn from_size_and_offset(
162        width: Size,
163        height: Size,
164        offset_x: Length,
165        offset_y: Length,
166    ) -> Self {
167        Self {
168            width,
169            height,
170            offset_x,
171            offset_y,
172            ..Default::default()
173        }
174    }
175
176    /// Construct a new Node given a size and padding
177    pub fn from_size_and_padding(width: Size, height: Size, padding: Gaps) -> Self {
178        Self {
179            width,
180            height,
181            padding,
182            ..Default::default()
183        }
184    }
185
186    /// Construct a new Node given a size, alignments and a direction
187    pub fn from_size_and_alignments_and_direction(
188        width: Size,
189        height: Size,
190        main_alignment: Alignment,
191        cross_alignment: Alignment,
192        direction: Direction,
193    ) -> Self {
194        Self {
195            width,
196            height,
197            main_alignment,
198            cross_alignment,
199            direction,
200            ..Default::default()
201        }
202    }
203
204    /// Construct a new Node given a size, alignments, direction and spacing
205    pub fn from_size_and_alignments_and_direction_and_spacing(
206        width: Size,
207        height: Size,
208        main_alignment: Alignment,
209        cross_alignment: Alignment,
210        direction: Direction,
211        spacing: Length,
212    ) -> Self {
213        Self {
214            width,
215            height,
216            main_alignment,
217            cross_alignment,
218            direction,
219            spacing,
220            ..Default::default()
221        }
222    }
223
224    /// Construct a new Node given a size and a direction
225    pub fn from_size_and_margin(width: Size, height: Size, margin: Gaps) -> Self {
226        Self {
227            width,
228            height,
229            margin,
230            ..Default::default()
231        }
232    }
233
234    /// Construct a new Node given a size and a direction and some margin,
235    pub fn from_size_and_direction_and_margin(
236        width: Size,
237        height: Size,
238        direction: Direction,
239        margin: Gaps,
240    ) -> Self {
241        Self {
242            width,
243            height,
244            margin,
245            direction,
246            ..Default::default()
247        }
248    }
249
250    /// Construct a new Node given a size, alignments and a direction
251    pub fn from_size_and_alignments_and_direction_and_padding(
252        width: Size,
253        height: Size,
254        main_alignment: Alignment,
255        cross_alignment: Alignment,
256        direction: Direction,
257        padding: Gaps,
258    ) -> Self {
259        Self {
260            width,
261            height,
262            main_alignment,
263            cross_alignment,
264            padding,
265            direction,
266            ..Default::default()
267        }
268    }
269
270    /// Construct a new Node given a size and a position
271    pub fn from_size_and_position(width: Size, height: Size, position: Position) -> Self {
272        Self {
273            width,
274            height,
275            position,
276            ..Default::default()
277        }
278    }
279
280    /// Construct a new Node given a size and content
281    pub fn from_size_and_content(width: Size, height: Size, content: Content) -> Self {
282        Self {
283            width,
284            height,
285            content,
286            ..Default::default()
287        }
288    }
289
290    /// Construct a new Node given a size and spacing
291    pub fn from_size_and_direction_and_spacing(
292        width: Size,
293        height: Size,
294        direction: Direction,
295        spacing: Length,
296    ) -> Self {
297        Self {
298            width,
299            height,
300            direction,
301            spacing,
302            ..Default::default()
303        }
304    }
305
306    /// Has properties that depend on the inner Nodes?
307    pub fn does_depend_on_inner(&self) -> bool {
308        self.width.inner_sized() || self.height.inner_sized() || self.do_inner_depend_on_parent()
309    }
310
311    /// Has properties that make its children dependant on it?
312    pub fn do_inner_depend_on_parent(&self) -> bool {
313        self.cross_alignment.is_not_start()
314            || self.main_alignment.is_not_start()
315            || self.has_layout_references
316    }
317}