Replace per-node measure functions with a single measure function + per-node context (#490)
1use taffy::prelude::*;
2
3#[test]
4fn relayout() {
5 let mut taffy: Taffy<()> = taffy::Taffy::new();
6 let node1 = taffy
7 .new_leaf(taffy::style::Style {
8 size: taffy::geometry::Size { width: length(8.0), height: length(80.0) },
9 ..Default::default()
10 })
11 .unwrap();
12 let node0 = taffy
13 .new_with_children(
14 taffy::style::Style {
15 align_self: Some(taffy::prelude::AlignSelf::Center),
16 size: taffy::geometry::Size { width: Dimension::Auto, height: Dimension::Auto },
17 // size: taffy::geometry::Size { width: Dimension::Percent(1.0), height: Dimension::Percent(1.0) },
18 ..Default::default()
19 },
20 &[node1],
21 )
22 .unwrap();
23 let node = taffy
24 .new_with_children(
25 taffy::style::Style {
26 size: taffy::geometry::Size { width: Dimension::Percent(1f32), height: Dimension::Percent(1f32) },
27 ..Default::default()
28 },
29 &[node0],
30 )
31 .unwrap();
32 taffy
33 .compute_layout(
34 node,
35 taffy::geometry::Size { width: AvailableSpace::Definite(100f32), height: AvailableSpace::Definite(100f32) },
36 )
37 .unwrap();
38 let initial = taffy.layout(node).unwrap().location;
39 let initial0 = taffy.layout(node0).unwrap().location;
40 let initial1 = taffy.layout(node1).unwrap().location;
41 for _ in 1..10 {
42 taffy
43 .compute_layout(
44 node,
45 taffy::geometry::Size {
46 width: AvailableSpace::Definite(100f32),
47 height: AvailableSpace::Definite(100f32),
48 },
49 )
50 .unwrap();
51 assert_eq!(taffy.layout(node).unwrap().location, initial);
52 assert_eq!(taffy.layout(node0).unwrap().location, initial0);
53 assert_eq!(taffy.layout(node1).unwrap().location, initial1);
54 }
55}
56
57#[test]
58fn toggle_root_display_none() {
59 let hidden_style = Style {
60 display: Display::None,
61 size: Size { width: length(100.0), height: length(100.0) },
62 ..Default::default()
63 };
64
65 let flex_style = Style {
66 display: Display::Flex,
67 size: Size { width: length(100.0), height: length(100.0) },
68 ..Default::default()
69 };
70
71 // Setup
72 let mut taffy: Taffy<()> = taffy::Taffy::new();
73 let node = taffy.new_leaf(hidden_style.clone()).unwrap();
74
75 // Layout 1 (None)
76 taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
77 let layout = taffy.layout(node).unwrap();
78 assert_eq!(layout.location.x, 0.0);
79 assert_eq!(layout.location.y, 0.0);
80 assert_eq!(layout.size.width, 0.0);
81 assert_eq!(layout.size.height, 0.0);
82
83 // Layout 2 (Flex)
84 taffy.set_style(node, flex_style).unwrap();
85 taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
86 let layout = taffy.layout(node).unwrap();
87 assert_eq!(layout.location.x, 0.0);
88 assert_eq!(layout.location.y, 0.0);
89 assert_eq!(layout.size.width, 100.0);
90 assert_eq!(layout.size.height, 100.0);
91
92 // Layout 3 (None)
93 taffy.set_style(node, hidden_style).unwrap();
94 taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
95 let layout = taffy.layout(node).unwrap();
96 assert_eq!(layout.location.x, 0.0);
97 assert_eq!(layout.location.y, 0.0);
98 assert_eq!(layout.size.width, 0.0);
99 assert_eq!(layout.size.height, 0.0);
100}
101
102#[test]
103fn toggle_root_display_none_with_children() {
104 use taffy::prelude::*;
105
106 let mut taffy: Taffy<()> = taffy::Taffy::new();
107
108 let child = taffy
109 .new_leaf(Style { size: Size { width: length(800.0), height: length(100.0) }, ..Default::default() })
110 .unwrap();
111
112 let parent = taffy
113 .new_with_children(
114 Style { size: Size { width: length(800.0), height: length(100.0) }, ..Default::default() },
115 &[child],
116 )
117 .unwrap();
118
119 let root = taffy.new_with_children(Style::default(), &[parent]).unwrap();
120 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
121 assert_eq!(taffy.layout(child).unwrap().size.width, 800.0);
122 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
123
124 taffy.set_style(root, Style { display: Display::None, ..Default::default() }).unwrap();
125 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
126 assert_eq!(taffy.layout(child).unwrap().size.width, 0.0);
127 assert_eq!(taffy.layout(child).unwrap().size.height, 0.0);
128
129 taffy.set_style(root, Style::default()).unwrap();
130 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
131 assert_eq!(taffy.layout(parent).unwrap().size.width, 800.0);
132 assert_eq!(taffy.layout(parent).unwrap().size.height, 100.0);
133 assert_eq!(taffy.layout(child).unwrap().size.width, 800.0);
134 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
135}
136
137#[test]
138fn toggle_flex_child_display_none() {
139 let hidden_style = Style {
140 display: Display::None,
141 size: Size { width: length(100.0), height: length(100.0) },
142 ..Default::default()
143 };
144
145 let flex_style = Style {
146 display: Display::Flex,
147 size: Size { width: length(100.0), height: length(100.0) },
148 ..Default::default()
149 };
150
151 // Setup
152 let mut taffy: Taffy<()> = taffy::Taffy::new();
153 let node = taffy.new_leaf(hidden_style.clone()).unwrap();
154 let root = taffy.new_with_children(flex_style.clone(), &[node]).unwrap();
155
156 // Layout 1 (None)
157 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
158 let layout = taffy.layout(node).unwrap();
159 assert_eq!(layout.location.x, 0.0);
160 assert_eq!(layout.location.y, 0.0);
161 assert_eq!(layout.size.width, 0.0);
162 assert_eq!(layout.size.height, 0.0);
163
164 // Layout 2 (Flex)
165 taffy.set_style(node, flex_style).unwrap();
166 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
167 let layout = taffy.layout(node).unwrap();
168 assert_eq!(layout.location.x, 0.0);
169 assert_eq!(layout.location.y, 0.0);
170 assert_eq!(layout.size.width, 100.0);
171 assert_eq!(layout.size.height, 100.0);
172
173 // Layout 3 (None)
174 taffy.set_style(node, hidden_style).unwrap();
175 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
176 let layout = taffy.layout(node).unwrap();
177 assert_eq!(layout.location.x, 0.0);
178 assert_eq!(layout.location.y, 0.0);
179 assert_eq!(layout.size.width, 0.0);
180 assert_eq!(layout.size.height, 0.0);
181}
182
183#[test]
184fn toggle_flex_container_display_none() {
185 let hidden_style = Style {
186 display: Display::None,
187 size: Size { width: length(100.0), height: length(100.0) },
188 ..Default::default()
189 };
190
191 let flex_style = Style {
192 display: Display::Flex,
193 size: Size { width: length(100.0), height: length(100.0) },
194 ..Default::default()
195 };
196
197 // Setup
198 let mut taffy: Taffy<()> = taffy::Taffy::new();
199 let node = taffy.new_leaf(hidden_style.clone()).unwrap();
200 let root = taffy.new_with_children(hidden_style.clone(), &[node]).unwrap();
201
202 // Layout 1 (None)
203 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
204 let layout = taffy.layout(root).unwrap();
205 assert_eq!(layout.location.x, 0.0);
206 assert_eq!(layout.location.y, 0.0);
207 assert_eq!(layout.size.width, 0.0);
208 assert_eq!(layout.size.height, 0.0);
209
210 // Layout 2 (Flex)
211 taffy.set_style(root, flex_style).unwrap();
212 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
213 let layout = taffy.layout(root).unwrap();
214 assert_eq!(layout.location.x, 0.0);
215 assert_eq!(layout.location.y, 0.0);
216 assert_eq!(layout.size.width, 100.0);
217 assert_eq!(layout.size.height, 100.0);
218
219 // Layout 3 (None)
220 taffy.set_style(root, hidden_style).unwrap();
221 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
222 let layout = taffy.layout(root).unwrap();
223 assert_eq!(layout.location.x, 0.0);
224 assert_eq!(layout.location.y, 0.0);
225 assert_eq!(layout.size.width, 0.0);
226 assert_eq!(layout.size.height, 0.0);
227}
228
229#[test]
230fn toggle_grid_child_display_none() {
231 let hidden_style = Style {
232 display: Display::None,
233 size: Size { width: length(100.0), height: length(100.0) },
234 ..Default::default()
235 };
236
237 let grid_style = Style {
238 display: Display::Grid,
239 size: Size { width: length(100.0), height: length(100.0) },
240 ..Default::default()
241 };
242
243 // Setup
244 let mut taffy: Taffy<()> = taffy::Taffy::new();
245 let node = taffy.new_leaf(hidden_style.clone()).unwrap();
246 let root = taffy.new_with_children(grid_style.clone(), &[node]).unwrap();
247
248 // Layout 1 (None)
249 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
250 let layout = taffy.layout(node).unwrap();
251 assert_eq!(layout.location.x, 0.0);
252 assert_eq!(layout.location.y, 0.0);
253 assert_eq!(layout.size.width, 0.0);
254 assert_eq!(layout.size.height, 0.0);
255
256 // Layout 2 (Flex)
257 taffy.set_style(node, grid_style).unwrap();
258 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
259 let layout = taffy.layout(node).unwrap();
260 assert_eq!(layout.location.x, 0.0);
261 assert_eq!(layout.location.y, 0.0);
262 assert_eq!(layout.size.width, 100.0);
263 assert_eq!(layout.size.height, 100.0);
264
265 // Layout 3 (None)
266 taffy.set_style(node, hidden_style).unwrap();
267 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
268 let layout = taffy.layout(node).unwrap();
269 assert_eq!(layout.location.x, 0.0);
270 assert_eq!(layout.location.y, 0.0);
271 assert_eq!(layout.size.width, 0.0);
272 assert_eq!(layout.size.height, 0.0);
273}
274
275#[test]
276fn toggle_grid_container_display_none() {
277 let hidden_style = Style {
278 display: Display::None,
279 size: Size { width: length(100.0), height: length(100.0) },
280 ..Default::default()
281 };
282
283 let grid_style = Style {
284 display: Display::Grid,
285 size: Size { width: length(100.0), height: length(100.0) },
286 ..Default::default()
287 };
288
289 // Setup
290 let mut taffy: Taffy<()> = taffy::Taffy::new();
291 let node = taffy.new_leaf(hidden_style.clone()).unwrap();
292 let root = taffy.new_with_children(hidden_style.clone(), &[node]).unwrap();
293
294 // Layout 1 (None)
295 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
296 let layout = taffy.layout(root).unwrap();
297 assert_eq!(layout.location.x, 0.0);
298 assert_eq!(layout.location.y, 0.0);
299 assert_eq!(layout.size.width, 0.0);
300 assert_eq!(layout.size.height, 0.0);
301
302 // Layout 2 (Flex)
303 taffy.set_style(root, grid_style).unwrap();
304 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
305 let layout = taffy.layout(root).unwrap();
306 assert_eq!(layout.location.x, 0.0);
307 assert_eq!(layout.location.y, 0.0);
308 assert_eq!(layout.size.width, 100.0);
309 assert_eq!(layout.size.height, 100.0);
310
311 // Layout 3 (None)
312 taffy.set_style(root, hidden_style).unwrap();
313 taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
314 let layout = taffy.layout(root).unwrap();
315 assert_eq!(layout.location.x, 0.0);
316 assert_eq!(layout.location.y, 0.0);
317 assert_eq!(layout.size.width, 0.0);
318 assert_eq!(layout.size.height, 0.0);
319}
320
321#[test]
322fn relayout_is_stable_with_rounding() {
323 let mut taffy: Taffy<()> = taffy::Taffy::new();
324 taffy.enable_rounding();
325
326 // <div style="width: 1920px; height: 1080px">
327 // <div style="width: 100%; left: 1.5px">
328 // <div style="width: 150px; justify-content: end">
329 // <div style="min-width: 300px" />
330 // </div>
331 // </div>
332 // </div>
333
334 let inner =
335 taffy.new_leaf(Style { min_size: Size { width: length(300.), height: auto() }, ..Default::default() }).unwrap();
336 let wrapper = taffy
337 .new_with_children(
338 Style {
339 size: Size { width: length(150.), height: auto() },
340 justify_content: Some(JustifyContent::End),
341 ..Default::default()
342 },
343 &[inner],
344 )
345 .unwrap();
346 let outer = taffy
347 .new_with_children(
348 Style {
349 size: Size { width: percent(1.), height: auto() },
350 inset: Rect { left: length(1.5), right: auto(), top: auto(), bottom: auto() },
351 ..Default::default()
352 },
353 &[wrapper],
354 )
355 .unwrap();
356 let root = taffy
357 .new_with_children(
358 Style { size: Size { width: length(1920.), height: length(1080.) }, ..Default::default() },
359 &[outer],
360 )
361 .unwrap();
362 for _ in 0..5 {
363 taffy.mark_dirty(root).ok();
364 taffy.compute_layout(root, Size::MAX_CONTENT).ok();
365 taffy.print_tree(root);
366
367 let root_layout = taffy.layout(root).unwrap();
368 assert_eq!(root_layout.location.x, 0.0);
369 assert_eq!(root_layout.location.y, 0.0);
370 assert_eq!(root_layout.size.width, 1920.0);
371 assert_eq!(root_layout.size.height, 1080.0);
372
373 let outer_layout = taffy.layout(outer).unwrap();
374 assert_eq!(outer_layout.location.x, 2.0);
375 assert_eq!(outer_layout.location.y, 0.0);
376 assert_eq!(outer_layout.size.width, 1920.0);
377 assert_eq!(outer_layout.size.height, 1080.0);
378
379 let wrapper_layout = taffy.layout(wrapper).unwrap();
380 assert_eq!(wrapper_layout.location.x, 0.0);
381 assert_eq!(wrapper_layout.location.y, 0.0);
382 assert_eq!(wrapper_layout.size.width, 150.0);
383 assert_eq!(wrapper_layout.size.height, 1080.0);
384
385 let inner_layout = taffy.layout(inner).unwrap();
386 assert_eq!(inner_layout.location.x, -150.0);
387 assert_eq!(inner_layout.location.y, 0.0);
388 assert_eq!(inner_layout.size.width, 301.0);
389 assert_eq!(inner_layout.size.height, 1080.0);
390 }
391}