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#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[derive(PartialEq, Clone, Debug, Default)]
20pub struct Node {
21 pub width: Size,
23 pub height: Size,
24
25 pub minimum_width: Size,
27 pub minimum_height: Size,
28
29 pub maximum_width: Size,
31 pub maximum_height: Size,
32
33 pub visible_width: VisibleSize,
35 pub visible_height: VisibleSize,
36
37 pub main_alignment: Alignment,
39 pub cross_alignment: Alignment,
40
41 pub padding: Gaps,
43
44 pub margin: Gaps,
46
47 pub offset_x: Length,
49 pub offset_y: Length,
50
51 pub direction: Direction,
53
54 pub position: Position,
56
57 pub content: Content,
58
59 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 pub fn new() -> Self {
85 Self::default()
86 }
87
88 pub fn self_layout_eq(&self, other: &Self) -> bool {
89 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 self.offset_x == other.offset_x && self.offset_y == other.offset_y
112 }
113
114 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}