1pub use euclid::Rect;
2
3use crate::{
4 alignment::Alignment,
5 direction::Direction,
6 gaps::Gaps,
7 geometry::Length,
8 order::Order,
9 prelude::{
10 Content,
11 Position,
12 VisibleSize,
13 },
14 scaled::Scaled,
15 size::Size,
16};
17
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[derive(PartialEq, Clone, Debug, Default)]
21pub struct Node {
22 pub width: Size,
24 pub height: Size,
25
26 pub minimum_width: Size,
28 pub minimum_height: Size,
29
30 pub maximum_width: Size,
32 pub maximum_height: Size,
33
34 pub visible_width: VisibleSize,
36 pub visible_height: VisibleSize,
37
38 pub main_alignment: Alignment,
40 pub cross_alignment: Alignment,
41
42 pub padding: Gaps,
44
45 pub margin: Gaps,
47
48 pub offset_x: Length,
50 pub offset_y: Length,
51
52 pub direction: Direction,
54
55 pub order: Order,
57
58 pub position: Position,
60
61 pub content: Content,
62
63 pub has_layout_references: bool,
65
66 pub spacing: Length,
67
68 pub depends_on_inner: bool,
71}
72
73impl Scaled for Node {
74 fn scale(&mut self, scale_factor: f32) {
75 self.width.scale(scale_factor);
76 self.height.scale(scale_factor);
77 self.minimum_width.scale(scale_factor);
78 self.minimum_height.scale(scale_factor);
79 self.maximum_width.scale(scale_factor);
80 self.maximum_height.scale(scale_factor);
81 self.margin.scale(scale_factor);
82 self.padding.scale(scale_factor);
83 self.offset_x *= scale_factor;
84 self.offset_y *= scale_factor;
85 self.position.scale(scale_factor);
86 self.spacing *= scale_factor;
87 }
88}
89
90impl Node {
91 pub fn new() -> Self {
93 Self::default()
94 }
95
96 pub fn self_layout_eq(&self, other: &Self) -> bool {
97 self.width == other.width
99 && self.height == other.height
100 && self.minimum_width == other.minimum_width
101 && self.minimum_height == other.minimum_height
102 && self.maximum_width == other.maximum_width
103 && self.maximum_height == other.maximum_height
104 && self.visible_width == other.visible_width
105 && self.visible_height == other.visible_height
106 && self.main_alignment == other.main_alignment
107 && self.cross_alignment == other.cross_alignment
108 && self.padding == other.padding
109 && self.margin == other.margin
110 && self.direction == other.direction
111 && self.order == other.order
112 && self.position == other.position
113 && self.content == other.content
114 && self.has_layout_references == other.has_layout_references
115 && self.spacing == other.spacing
116 && self.depends_on_inner == other.depends_on_inner
117 }
118
119 pub fn inner_layout_eq(&self, other: &Self) -> bool {
120 self.offset_x == other.offset_x && self.offset_y == other.offset_y
122 }
123
124 pub fn from_size_and_direction(width: Size, height: Size, direction: Direction) -> Self {
126 Self {
127 width,
128 height,
129 direction,
130 ..Default::default()
131 }
132 }
133
134 pub fn from_sizes(
136 width: Size,
137 height: Size,
138 minimum_width: Size,
139 minimum_height: Size,
140 maximum_width: Size,
141 maximum_height: Size,
142 ) -> Self {
143 Self {
144 width,
145 height,
146 minimum_width,
147 minimum_height,
148 maximum_width,
149 maximum_height,
150 ..Default::default()
151 }
152 }
153
154 pub fn from_size_and_visible_size(
156 width: Size,
157 height: Size,
158 visible_width: VisibleSize,
159 visible_height: VisibleSize,
160 ) -> Self {
161 Self {
162 width,
163 height,
164 visible_width,
165 visible_height,
166 ..Default::default()
167 }
168 }
169
170 pub fn from_size_and_offset(
172 width: Size,
173 height: Size,
174 offset_x: Length,
175 offset_y: Length,
176 ) -> Self {
177 Self {
178 width,
179 height,
180 offset_x,
181 offset_y,
182 ..Default::default()
183 }
184 }
185
186 pub fn from_size_and_padding(width: Size, height: Size, padding: Gaps) -> Self {
188 Self {
189 width,
190 height,
191 padding,
192 ..Default::default()
193 }
194 }
195
196 pub fn from_size_and_alignments_and_direction(
198 width: Size,
199 height: Size,
200 main_alignment: Alignment,
201 cross_alignment: Alignment,
202 direction: Direction,
203 ) -> Self {
204 Self {
205 width,
206 height,
207 main_alignment,
208 cross_alignment,
209 direction,
210 ..Default::default()
211 }
212 }
213
214 pub fn from_size_and_alignments_and_direction_and_spacing(
216 width: Size,
217 height: Size,
218 main_alignment: Alignment,
219 cross_alignment: Alignment,
220 direction: Direction,
221 spacing: Length,
222 ) -> Self {
223 Self {
224 width,
225 height,
226 main_alignment,
227 cross_alignment,
228 direction,
229 spacing,
230 ..Default::default()
231 }
232 }
233
234 pub fn from_size_and_margin(width: Size, height: Size, margin: Gaps) -> Self {
236 Self {
237 width,
238 height,
239 margin,
240 ..Default::default()
241 }
242 }
243
244 pub fn from_size_and_direction_and_margin(
246 width: Size,
247 height: Size,
248 direction: Direction,
249 margin: Gaps,
250 ) -> Self {
251 Self {
252 width,
253 height,
254 margin,
255 direction,
256 ..Default::default()
257 }
258 }
259
260 pub fn from_size_and_alignments_and_direction_and_padding(
262 width: Size,
263 height: Size,
264 main_alignment: Alignment,
265 cross_alignment: Alignment,
266 direction: Direction,
267 padding: Gaps,
268 ) -> Self {
269 Self {
270 width,
271 height,
272 main_alignment,
273 cross_alignment,
274 padding,
275 direction,
276 ..Default::default()
277 }
278 }
279
280 pub fn from_size_and_position(width: Size, height: Size, position: Position) -> Self {
282 Self {
283 width,
284 height,
285 position,
286 ..Default::default()
287 }
288 }
289
290 pub fn from_size_and_content(width: Size, height: Size, content: Content) -> Self {
292 Self {
293 width,
294 height,
295 content,
296 ..Default::default()
297 }
298 }
299
300 pub fn from_size_and_direction_and_spacing(
302 width: Size,
303 height: Size,
304 direction: Direction,
305 spacing: Length,
306 ) -> Self {
307 Self {
308 width,
309 height,
310 direction,
311 spacing,
312 ..Default::default()
313 }
314 }
315
316 pub fn does_depend_on_inner(&self) -> bool {
318 self.width.inner_sized()
319 || self.height.inner_sized()
320 || self.depends_on_inner
321 || self.do_inner_depend_on_parent()
322 }
323
324 pub fn do_inner_depend_on_parent(&self) -> bool {
326 self.cross_alignment.is_not_start()
327 || self.main_alignment.is_not_start()
328 || self.has_layout_references
329 || self.content == Content::Flex
330 }
331}