1use cranpose_ui_layout::{
2 Axis, Constraints, MeasurePolicy, MeasureResult, MeasureScope, ParentData, Placement,
3};
4use smallvec::SmallVec;
5
6use crate::layout::core::{
7 Alignment, Arrangement, HorizontalAlignment, LinearArrangement, Measurable, VerticalAlignment,
8};
9
10#[derive(Clone, Debug, PartialEq)]
12pub struct BoxMeasurePolicy {
13 pub content_alignment: Alignment,
14 pub propagate_min_constraints: bool,
15}
16
17impl BoxMeasurePolicy {
18 pub fn new(content_alignment: Alignment, propagate_min_constraints: bool) -> Self {
19 Self {
20 content_alignment,
21 propagate_min_constraints,
22 }
23 }
24}
25
26impl MeasurePolicy for BoxMeasurePolicy {
27 fn measure(
28 &self,
29 scope: &dyn MeasureScope,
30 measurables: &[Box<dyn Measurable>],
31 constraints: Constraints,
32 ) -> MeasureResult {
33 let mut placements = Vec::new();
34 let size = self.measure_into(scope, measurables, constraints, &mut placements);
35 MeasureResult::new(size, placements)
36 }
37
38 fn measure_into(
39 &self,
40 _scope: &dyn MeasureScope,
41 measurables: &[Box<dyn Measurable>],
42 constraints: Constraints,
43 placements: &mut Vec<Placement>,
44 ) -> crate::modifier::Size {
45 placements.clear();
46 let child_constraints = if self.propagate_min_constraints {
47 constraints
48 } else {
49 Constraints {
50 min_width: 0.0,
51 max_width: constraints.max_width,
52 min_height: 0.0,
53 max_height: constraints.max_height,
54 }
55 };
56
57 let mut max_width = 0.0_f32;
58 let mut max_height = 0.0_f32;
59 let mut placeables: SmallVec<[(cranpose_ui_layout::Placeable, Alignment); 8]> =
60 SmallVec::new();
61
62 for measurable in measurables {
63 let placeable = measurable.measure(child_constraints);
64 max_width = max_width.max(placeable.width());
65 max_height = max_height.max(placeable.height());
66 let alignment = measurable
67 .parent_data()
68 .box_alignment
69 .unwrap_or(self.content_alignment);
70 placeables.push((placeable, alignment));
71 }
72
73 let width = max_width.clamp(constraints.min_width, constraints.max_width);
74 let height = max_height.clamp(constraints.min_height, constraints.max_height);
75
76 placements.reserve(placeables.len());
77 for (placeable, alignment) in placeables {
78 let child_width = placeable.width();
79 let child_height = placeable.height();
80
81 let x = match alignment.horizontal {
82 HorizontalAlignment::Start => 0.0,
83 HorizontalAlignment::CenterHorizontally => ((width - child_width) / 2.0).max(0.0),
84 HorizontalAlignment::End => (width - child_width).max(0.0),
85 };
86
87 let y = match alignment.vertical {
88 VerticalAlignment::Top => 0.0,
89 VerticalAlignment::CenterVertically => ((height - child_height) / 2.0).max(0.0),
90 VerticalAlignment::Bottom => (height - child_height).max(0.0),
91 };
92
93 placeable.place(x, y);
94 placements.push(Placement::new(placeable.node_id(), x, y, 0));
95 }
96
97 crate::modifier::Size { width, height }
98 }
99
100 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
101 measurables
102 .iter()
103 .map(|m| m.min_intrinsic_width(height))
104 .fold(0.0, f32::max)
105 }
106
107 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
108 measurables
109 .iter()
110 .map(|m| m.max_intrinsic_width(height))
111 .fold(0.0, f32::max)
112 }
113
114 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
115 measurables
116 .iter()
117 .map(|m| m.min_intrinsic_height(width))
118 .fold(0.0, f32::max)
119 }
120
121 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
122 measurables
123 .iter()
124 .map(|m| m.max_intrinsic_height(width))
125 .fold(0.0, f32::max)
126 }
127}
128
129#[derive(Clone, Debug, PartialEq)]
167pub struct FlexMeasurePolicy {
168 pub axis: Axis,
170 pub main_axis_arrangement: LinearArrangement,
172 pub cross_axis_alignment: CrossAxisAlignment,
174}
175
176#[derive(Clone, Copy, Debug, PartialEq)]
179pub enum CrossAxisAlignment {
180 Start,
182 Center,
184 End,
186}
187
188impl CrossAxisAlignment {
189 fn align(&self, available: f32, child: f32) -> f32 {
190 match self {
191 CrossAxisAlignment::Start => 0.0,
192 CrossAxisAlignment::Center => ((available - child) / 2.0).max(0.0),
193 CrossAxisAlignment::End => (available - child).max(0.0),
194 }
195 }
196}
197
198impl From<HorizontalAlignment> for CrossAxisAlignment {
199 fn from(alignment: HorizontalAlignment) -> Self {
200 match alignment {
201 HorizontalAlignment::Start => CrossAxisAlignment::Start,
202 HorizontalAlignment::CenterHorizontally => CrossAxisAlignment::Center,
203 HorizontalAlignment::End => CrossAxisAlignment::End,
204 }
205 }
206}
207
208impl From<VerticalAlignment> for CrossAxisAlignment {
209 fn from(alignment: VerticalAlignment) -> Self {
210 match alignment {
211 VerticalAlignment::Top => CrossAxisAlignment::Start,
212 VerticalAlignment::CenterVertically => CrossAxisAlignment::Center,
213 VerticalAlignment::Bottom => CrossAxisAlignment::End,
214 }
215 }
216}
217
218impl FlexMeasurePolicy {
219 pub fn new(
220 axis: Axis,
221 main_axis_arrangement: LinearArrangement,
222 cross_axis_alignment: CrossAxisAlignment,
223 ) -> Self {
224 Self {
225 axis,
226 main_axis_arrangement,
227 cross_axis_alignment,
228 }
229 }
230
231 pub fn row(
233 horizontal_arrangement: LinearArrangement,
234 vertical_alignment: VerticalAlignment,
235 ) -> Self {
236 Self::new(
237 Axis::Horizontal,
238 horizontal_arrangement,
239 vertical_alignment.into(),
240 )
241 }
242
243 pub fn column(
245 vertical_arrangement: LinearArrangement,
246 horizontal_alignment: HorizontalAlignment,
247 ) -> Self {
248 Self::new(
249 Axis::Vertical,
250 vertical_arrangement,
251 horizontal_alignment.into(),
252 )
253 }
254
255 fn get_axis_constraints(&self, constraints: Constraints) -> (f32, f32, f32, f32) {
256 match self.axis {
257 Axis::Horizontal => (
258 constraints.min_width,
259 constraints.max_width,
260 constraints.min_height,
261 constraints.max_height,
262 ),
263 Axis::Vertical => (
264 constraints.min_height,
265 constraints.max_height,
266 constraints.min_width,
267 constraints.max_width,
268 ),
269 }
270 }
271
272 fn make_constraints(
273 &self,
274 min_main: f32,
275 max_main: f32,
276 min_cross: f32,
277 max_cross: f32,
278 ) -> Constraints {
279 match self.axis {
280 Axis::Horizontal => Constraints {
281 min_width: min_main,
282 max_width: max_main,
283 min_height: min_cross,
284 max_height: max_cross,
285 },
286 Axis::Vertical => Constraints {
287 min_width: min_cross,
288 max_width: max_cross,
289 min_height: min_main,
290 max_height: max_main,
291 },
292 }
293 }
294
295 fn get_main_axis_size(&self, width: f32, height: f32) -> f32 {
296 match self.axis {
297 Axis::Horizontal => width,
298 Axis::Vertical => height,
299 }
300 }
301
302 fn get_cross_axis_size(&self, width: f32, height: f32) -> f32 {
303 match self.axis {
304 Axis::Horizontal => height,
305 Axis::Vertical => width,
306 }
307 }
308
309 fn get_spacing(&self) -> f32 {
310 match self.main_axis_arrangement {
311 LinearArrangement::SpacedBy(value) => value.max(0.0),
312 _ => 0.0,
313 }
314 }
315}
316
317impl MeasurePolicy for FlexMeasurePolicy {
318 fn measure(
319 &self,
320 scope: &dyn MeasureScope,
321 measurables: &[Box<dyn Measurable>],
322 constraints: Constraints,
323 ) -> MeasureResult {
324 let mut placements = Vec::new();
325 let size = self.measure_into(scope, measurables, constraints, &mut placements);
326 MeasureResult::new(size, placements)
327 }
328
329 fn measure_into(
330 &self,
331 _scope: &dyn MeasureScope,
332 measurables: &[Box<dyn Measurable>],
333 constraints: Constraints,
334 placements: &mut Vec<Placement>,
335 ) -> crate::modifier::Size {
336 placements.clear();
337 if measurables.is_empty() {
338 let (width, height) = constraints.constrain(0.0, 0.0);
339 return crate::modifier::Size { width, height };
340 }
341
342 let (min_main, max_main, min_cross, max_cross) = self.get_axis_constraints(constraints);
343 let main_axis_bounded = max_main.is_finite();
344 let spacing = self.get_spacing();
345
346 let mut fixed_children: SmallVec<[usize; 8]> = SmallVec::new();
347 let parent_data: SmallVec<[ParentData; 8]> = measurables
348 .iter()
349 .map(|child| child.parent_data())
350 .collect();
351 let mut weighted_children: SmallVec<[(usize, ParentData); 8]> = SmallVec::new();
352
353 for (idx, data) in parent_data.iter().copied().enumerate() {
354 if data.has_weight() {
355 weighted_children.push((idx, data));
356 } else {
357 fixed_children.push(idx);
358 }
359 }
360
361 let child_constraints = self.make_constraints(0.0, max_main, 0.0, max_cross);
362
363 let mut placeables: SmallVec<[Option<cranpose_ui_layout::Placeable>; 8]> = SmallVec::new();
364 placeables.resize_with(measurables.len(), || None);
365 let mut fixed_main_size = 0.0_f32;
366 let mut max_cross_size = 0.0_f32;
367
368 for &idx in &fixed_children {
369 let measurable = &measurables[idx];
370 let placeable = measurable.measure(child_constraints);
371 let main_size = self.get_main_axis_size(placeable.width(), placeable.height());
372 let cross_size = self.get_cross_axis_size(placeable.width(), placeable.height());
373
374 fixed_main_size += main_size;
375 max_cross_size = max_cross_size.max(cross_size);
376 placeables[idx] = Some(placeable);
377 }
378
379 let num_children = measurables.len();
380 let total_spacing = if num_children > 1 {
381 spacing * (num_children - 1) as f32
382 } else {
383 0.0
384 };
385
386 if !weighted_children.is_empty() {
387 if main_axis_bounded {
388 let used_main = fixed_main_size + total_spacing;
389 let remaining_main = (max_main - used_main).max(0.0);
390
391 let total_weight: f32 = weighted_children.iter().map(|(_, data)| data.weight).sum();
392
393 for &(idx, parent_data) in &weighted_children {
394 let measurable = &measurables[idx];
395 let allocated = if total_weight > 0.0 {
396 remaining_main * (parent_data.weight / total_weight)
397 } else {
398 0.0
399 };
400
401 let weighted_constraints = if parent_data.fill {
402 self.make_constraints(allocated, allocated, 0.0, max_cross)
403 } else {
404 self.make_constraints(0.0, allocated, 0.0, max_cross)
405 };
406
407 let placeable = measurable.measure(weighted_constraints);
408 let cross_size =
409 self.get_cross_axis_size(placeable.width(), placeable.height());
410 max_cross_size = max_cross_size.max(cross_size);
411 placeables[idx] = Some(placeable);
412 }
413 } else {
414 for &(idx, _) in &weighted_children {
415 let measurable = &measurables[idx];
416 let placeable = measurable.measure(child_constraints);
417 let cross_size =
418 self.get_cross_axis_size(placeable.width(), placeable.height());
419 max_cross_size = max_cross_size.max(cross_size);
420 placeables[idx] = Some(placeable);
421 }
422 }
423 }
424
425 let placeables: SmallVec<[cranpose_ui_layout::Placeable; 8]> = placeables
426 .into_iter()
427 .enumerate()
428 .map(|(idx, placeable)| {
429 placeable.unwrap_or_else(|| measurables[idx].measure(child_constraints))
430 })
431 .collect();
432
433 let total_main: f32 = placeables
434 .iter()
435 .map(|p| self.get_main_axis_size(p.width(), p.height()))
436 .sum::<f32>()
437 + total_spacing;
438
439 let container_main = total_main.clamp(min_main, max_main);
440 let container_cross = max_cross_size.clamp(min_cross, max_cross);
441
442 let child_main_sizes: SmallVec<[f32; 8]> = placeables
443 .iter()
444 .map(|p| self.get_main_axis_size(p.width(), p.height()))
445 .collect();
446
447 let mut main_positions: SmallVec<[f32; 8]> =
448 SmallVec::with_capacity(child_main_sizes.len());
449 main_positions.resize(child_main_sizes.len(), 0.0);
450
451 let arrangement = if total_main > container_main
452 && !matches!(self.main_axis_arrangement, LinearArrangement::SpacedBy(_))
453 {
454 LinearArrangement::Start
455 } else {
456 self.main_axis_arrangement
457 };
458 arrangement.arrange(container_main, &child_main_sizes, &mut main_positions);
459
460 placements.reserve(placeables.len());
461 for (idx, (placeable, main_pos)) in placeables.into_iter().zip(main_positions).enumerate() {
462 let child_cross = self.get_cross_axis_size(placeable.width(), placeable.height());
463 let cross_axis_alignment = match self.axis {
464 Axis::Horizontal => parent_data[idx]
465 .row_alignment
466 .map(Into::into)
467 .unwrap_or(self.cross_axis_alignment),
468 Axis::Vertical => parent_data[idx]
469 .column_alignment
470 .map(Into::into)
471 .unwrap_or(self.cross_axis_alignment),
472 };
473 let cross_pos = cross_axis_alignment.align(container_cross, child_cross);
474
475 let (x, y) = match self.axis {
476 Axis::Horizontal => (main_pos, cross_pos),
477 Axis::Vertical => (cross_pos, main_pos),
478 };
479
480 placeable.place(x, y);
481 placements.push(Placement::new(placeable.node_id(), x, y, 0));
482 }
483
484 let (width, height) = match self.axis {
485 Axis::Horizontal => (container_main, container_cross),
486 Axis::Vertical => (container_cross, container_main),
487 };
488
489 crate::modifier::Size { width, height }
490 }
491
492 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
493 let spacing = self.get_spacing();
494 let total_spacing = if measurables.len() > 1 {
495 spacing * (measurables.len() - 1) as f32
496 } else {
497 0.0
498 };
499
500 match self.axis {
501 Axis::Horizontal => {
502 measurables
503 .iter()
504 .map(|m| m.min_intrinsic_width(height))
505 .sum::<f32>()
506 + total_spacing
507 }
508 Axis::Vertical => measurables
509 .iter()
510 .map(|m| m.min_intrinsic_width(height))
511 .fold(0.0, f32::max),
512 }
513 }
514
515 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
516 let spacing = self.get_spacing();
517 let total_spacing = if measurables.len() > 1 {
518 spacing * (measurables.len() - 1) as f32
519 } else {
520 0.0
521 };
522
523 match self.axis {
524 Axis::Horizontal => {
525 measurables
526 .iter()
527 .map(|m| m.max_intrinsic_width(height))
528 .sum::<f32>()
529 + total_spacing
530 }
531 Axis::Vertical => measurables
532 .iter()
533 .map(|m| m.max_intrinsic_width(height))
534 .fold(0.0, f32::max),
535 }
536 }
537
538 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
539 let spacing = self.get_spacing();
540 let total_spacing = if measurables.len() > 1 {
541 spacing * (measurables.len() - 1) as f32
542 } else {
543 0.0
544 };
545
546 match self.axis {
547 Axis::Horizontal => measurables
548 .iter()
549 .map(|m| m.min_intrinsic_height(width))
550 .fold(0.0, f32::max),
551 Axis::Vertical => {
552 measurables
553 .iter()
554 .map(|m| m.min_intrinsic_height(width))
555 .sum::<f32>()
556 + total_spacing
557 }
558 }
559 }
560
561 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
562 let spacing = self.get_spacing();
563 let total_spacing = if measurables.len() > 1 {
564 spacing * (measurables.len() - 1) as f32
565 } else {
566 0.0
567 };
568
569 match self.axis {
570 Axis::Horizontal => measurables
571 .iter()
572 .map(|m| m.max_intrinsic_height(width))
573 .fold(0.0, f32::max),
574 Axis::Vertical => {
575 measurables
576 .iter()
577 .map(|m| m.max_intrinsic_height(width))
578 .sum::<f32>()
579 + total_spacing
580 }
581 }
582 }
583}
584
585#[derive(Clone, Debug, PartialEq)]
598pub struct FlowRowMeasurePolicy {
599 pub main_axis_spacing: f32,
601 pub cross_axis_spacing: f32,
603}
604
605impl FlowRowMeasurePolicy {
606 pub fn new(main_axis_spacing: f32, cross_axis_spacing: f32) -> Self {
607 Self {
608 main_axis_spacing: main_axis_spacing.max(0.0),
609 cross_axis_spacing: cross_axis_spacing.max(0.0),
610 }
611 }
612
613 fn wrapped_intrinsic_height(
614 &self,
615 measurables: &[Box<dyn Measurable>],
616 available_width: f32,
617 use_min_height: bool,
618 ) -> f32 {
619 let mut cursor_x = 0.0_f32;
620 let mut line_top = 0.0_f32;
621 let mut line_height = 0.0_f32;
622
623 for measurable in measurables {
624 let child_width = measurable.max_intrinsic_width(f32::INFINITY);
625 let child_height = if use_min_height {
626 measurable.min_intrinsic_height(child_width)
627 } else {
628 measurable.max_intrinsic_height(child_width)
629 };
630
631 if cursor_x > 0.0 && cursor_x + self.main_axis_spacing + child_width > available_width {
632 line_top += line_height + self.cross_axis_spacing;
633 cursor_x = 0.0;
634 line_height = 0.0;
635 }
636 cursor_x += if cursor_x > 0.0 {
637 self.main_axis_spacing + child_width
638 } else {
639 child_width
640 };
641 line_height = line_height.max(child_height);
642 }
643
644 line_top + line_height
645 }
646}
647
648impl MeasurePolicy for FlowRowMeasurePolicy {
649 fn measure(
650 &self,
651 scope: &dyn MeasureScope,
652 measurables: &[Box<dyn Measurable>],
653 constraints: Constraints,
654 ) -> MeasureResult {
655 let mut placements = Vec::new();
656 let size = self.measure_into(scope, measurables, constraints, &mut placements);
657 MeasureResult::new(size, placements)
658 }
659
660 fn measure_into(
661 &self,
662 _scope: &dyn MeasureScope,
663 measurables: &[Box<dyn Measurable>],
664 constraints: Constraints,
665 placements: &mut Vec<Placement>,
666 ) -> crate::modifier::Size {
667 placements.clear();
668 if measurables.is_empty() {
669 let (width, height) = constraints.constrain(0.0, 0.0);
670 return crate::modifier::Size { width, height };
671 }
672
673 let child_constraints = Constraints {
674 min_width: 0.0,
675 max_width: constraints.max_width,
676 min_height: 0.0,
677 max_height: constraints.max_height,
678 };
679
680 let placeables: SmallVec<[cranpose_ui_layout::Placeable; 8]> = measurables
681 .iter()
682 .map(|measurable| measurable.measure(child_constraints))
683 .collect();
684
685 let mut cursor_x = 0.0_f32;
686 let mut line_top = 0.0_f32;
687 let mut line_height = 0.0_f32;
688 let mut max_line_width = 0.0_f32;
689
690 placements.reserve(placeables.len());
691 for placeable in placeables {
692 let child_width = placeable.width();
693 let child_height = placeable.height();
694
695 if cursor_x > 0.0
696 && cursor_x + self.main_axis_spacing + child_width > constraints.max_width
697 {
698 max_line_width = max_line_width.max(cursor_x);
699 line_top += line_height + self.cross_axis_spacing;
700 cursor_x = 0.0;
701 line_height = 0.0;
702 }
703
704 let x = if cursor_x > 0.0 {
705 cursor_x + self.main_axis_spacing
706 } else {
707 0.0
708 };
709 placeable.place(x, line_top);
710 placements.push(Placement::new(placeable.node_id(), x, line_top, 0));
711
712 cursor_x = x + child_width;
713 line_height = line_height.max(child_height);
714 }
715 max_line_width = max_line_width.max(cursor_x);
716
717 let width = max_line_width.clamp(constraints.min_width, constraints.max_width);
718 let height = (line_top + line_height).clamp(constraints.min_height, constraints.max_height);
719 crate::modifier::Size { width, height }
720 }
721
722 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
723 measurables
724 .iter()
725 .map(|m| m.min_intrinsic_width(height))
726 .fold(0.0, f32::max)
727 }
728
729 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
730 let total_spacing = if measurables.len() > 1 {
731 self.main_axis_spacing * (measurables.len() - 1) as f32
732 } else {
733 0.0
734 };
735 measurables
736 .iter()
737 .map(|m| m.max_intrinsic_width(height))
738 .sum::<f32>()
739 + total_spacing
740 }
741
742 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
743 self.wrapped_intrinsic_height(measurables, width, true)
744 }
745
746 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
747 self.wrapped_intrinsic_height(measurables, width, false)
748 }
749}
750
751#[derive(Clone, Debug, PartialEq)]
754pub struct LeafMeasurePolicy {
755 pub intrinsic_size: crate::modifier::Size,
756}
757
758impl LeafMeasurePolicy {
759 pub fn new(intrinsic_size: crate::modifier::Size) -> Self {
760 Self { intrinsic_size }
761 }
762}
763
764impl MeasurePolicy for LeafMeasurePolicy {
765 fn measure(
766 &self,
767 scope: &dyn MeasureScope,
768 _measurables: &[Box<dyn Measurable>],
769 constraints: Constraints,
770 ) -> MeasureResult {
771 let mut placements = Vec::new();
772 let size = self.measure_into(scope, &[], constraints, &mut placements);
773 MeasureResult::new(size, placements)
774 }
775
776 fn measure_into(
777 &self,
778 _scope: &dyn MeasureScope,
779 _measurables: &[Box<dyn Measurable>],
780 constraints: Constraints,
781 placements: &mut Vec<Placement>,
782 ) -> crate::modifier::Size {
783 placements.clear();
784 let (width, height) =
785 constraints.constrain(self.intrinsic_size.width, self.intrinsic_size.height);
786
787 crate::modifier::Size { width, height }
788 }
789
790 fn min_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
791 self.intrinsic_size.width
792 }
793
794 fn max_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
795 self.intrinsic_size.width
796 }
797
798 fn min_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
799 self.intrinsic_size.height
800 }
801
802 fn max_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
803 self.intrinsic_size.height
804 }
805}
806
807#[derive(Clone, Debug, PartialEq)]
813pub struct EmptyMeasurePolicy;
814
815impl EmptyMeasurePolicy {
816 pub fn new() -> Self {
817 Self
818 }
819}
820
821impl Default for EmptyMeasurePolicy {
822 fn default() -> Self {
823 Self::new()
824 }
825}
826
827impl MeasurePolicy for EmptyMeasurePolicy {
828 fn measure(
829 &self,
830 scope: &dyn MeasureScope,
831 _measurables: &[Box<dyn Measurable>],
832 constraints: Constraints,
833 ) -> MeasureResult {
834 let mut placements = Vec::new();
835 let size = self.measure_into(scope, &[], constraints, &mut placements);
836 MeasureResult::new(size, placements)
837 }
838
839 fn measure_into(
840 &self,
841 _scope: &dyn MeasureScope,
842 _measurables: &[Box<dyn Measurable>],
843 constraints: Constraints,
844 placements: &mut Vec<Placement>,
845 ) -> crate::modifier::Size {
846 placements.clear();
847 let (width, height) = constraints.constrain(0.0, 0.0);
848
849 crate::modifier::Size { width, height }
850 }
851
852 fn min_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
853 0.0
854 }
855
856 fn max_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
857 0.0
858 }
859
860 fn min_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
861 0.0
862 }
863
864 fn max_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
865 0.0
866 }
867}
868
869#[cfg(test)]
870#[path = "tests/policies_tests.rs"]
871mod tests;