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)]
169pub struct FlexMeasurePolicy {
170 pub axis: Axis,
172 pub main_axis_arrangement: LinearArrangement,
174 pub cross_axis_alignment: CrossAxisAlignment,
176}
177
178#[derive(Clone, Copy, Debug, PartialEq)]
181pub enum CrossAxisAlignment {
182 Start,
184 Center,
186 End,
188}
189
190impl CrossAxisAlignment {
191 fn align(&self, available: f32, child: f32) -> f32 {
193 match self {
194 CrossAxisAlignment::Start => 0.0,
195 CrossAxisAlignment::Center => ((available - child) / 2.0).max(0.0),
196 CrossAxisAlignment::End => (available - child).max(0.0),
197 }
198 }
199}
200
201impl From<HorizontalAlignment> for CrossAxisAlignment {
202 fn from(alignment: HorizontalAlignment) -> Self {
203 match alignment {
204 HorizontalAlignment::Start => CrossAxisAlignment::Start,
205 HorizontalAlignment::CenterHorizontally => CrossAxisAlignment::Center,
206 HorizontalAlignment::End => CrossAxisAlignment::End,
207 }
208 }
209}
210
211impl From<VerticalAlignment> for CrossAxisAlignment {
212 fn from(alignment: VerticalAlignment) -> Self {
213 match alignment {
214 VerticalAlignment::Top => CrossAxisAlignment::Start,
215 VerticalAlignment::CenterVertically => CrossAxisAlignment::Center,
216 VerticalAlignment::Bottom => CrossAxisAlignment::End,
217 }
218 }
219}
220
221impl FlexMeasurePolicy {
222 pub fn new(
223 axis: Axis,
224 main_axis_arrangement: LinearArrangement,
225 cross_axis_alignment: CrossAxisAlignment,
226 ) -> Self {
227 Self {
228 axis,
229 main_axis_arrangement,
230 cross_axis_alignment,
231 }
232 }
233
234 pub fn row(
236 horizontal_arrangement: LinearArrangement,
237 vertical_alignment: VerticalAlignment,
238 ) -> Self {
239 Self::new(
240 Axis::Horizontal,
241 horizontal_arrangement,
242 vertical_alignment.into(),
243 )
244 }
245
246 pub fn column(
248 vertical_arrangement: LinearArrangement,
249 horizontal_alignment: HorizontalAlignment,
250 ) -> Self {
251 Self::new(
252 Axis::Vertical,
253 vertical_arrangement,
254 horizontal_alignment.into(),
255 )
256 }
257
258 fn get_axis_constraints(&self, constraints: Constraints) -> (f32, f32, f32, f32) {
260 match self.axis {
261 Axis::Horizontal => (
262 constraints.min_width,
263 constraints.max_width,
264 constraints.min_height,
265 constraints.max_height,
266 ),
267 Axis::Vertical => (
268 constraints.min_height,
269 constraints.max_height,
270 constraints.min_width,
271 constraints.max_width,
272 ),
273 }
274 }
275
276 fn make_constraints(
278 &self,
279 min_main: f32,
280 max_main: f32,
281 min_cross: f32,
282 max_cross: f32,
283 ) -> Constraints {
284 match self.axis {
285 Axis::Horizontal => Constraints {
286 min_width: min_main,
287 max_width: max_main,
288 min_height: min_cross,
289 max_height: max_cross,
290 },
291 Axis::Vertical => Constraints {
292 min_width: min_cross,
293 max_width: max_cross,
294 min_height: min_main,
295 max_height: max_main,
296 },
297 }
298 }
299
300 fn get_main_axis_size(&self, width: f32, height: f32) -> f32 {
302 match self.axis {
303 Axis::Horizontal => width,
304 Axis::Vertical => height,
305 }
306 }
307
308 fn get_cross_axis_size(&self, width: f32, height: f32) -> f32 {
310 match self.axis {
311 Axis::Horizontal => height,
312 Axis::Vertical => width,
313 }
314 }
315
316 fn get_spacing(&self) -> f32 {
318 match self.main_axis_arrangement {
319 LinearArrangement::SpacedBy(value) => value.max(0.0),
320 _ => 0.0,
321 }
322 }
323}
324
325impl MeasurePolicy for FlexMeasurePolicy {
326 fn measure(
327 &self,
328 scope: &dyn MeasureScope,
329 measurables: &[Box<dyn Measurable>],
330 constraints: Constraints,
331 ) -> MeasureResult {
332 let mut placements = Vec::new();
333 let size = self.measure_into(scope, measurables, constraints, &mut placements);
334 MeasureResult::new(size, placements)
335 }
336
337 fn measure_into(
338 &self,
339 _scope: &dyn MeasureScope,
340 measurables: &[Box<dyn Measurable>],
341 constraints: Constraints,
342 placements: &mut Vec<Placement>,
343 ) -> crate::modifier::Size {
344 placements.clear();
345 if measurables.is_empty() {
346 let (width, height) = constraints.constrain(0.0, 0.0);
347 return crate::modifier::Size { width, height };
348 }
349
350 let (min_main, max_main, min_cross, max_cross) = self.get_axis_constraints(constraints);
351 let main_axis_bounded = max_main.is_finite();
352 let spacing = self.get_spacing();
353
354 let mut fixed_children: SmallVec<[usize; 8]> = SmallVec::new();
356 let parent_data: SmallVec<[ParentData; 8]> = measurables
357 .iter()
358 .map(|child| child.parent_data())
359 .collect();
360 let mut weighted_children: SmallVec<[(usize, ParentData); 8]> = SmallVec::new();
361
362 for (idx, data) in parent_data.iter().copied().enumerate() {
363 if data.has_weight() {
364 weighted_children.push((idx, data));
365 } else {
366 fixed_children.push(idx);
367 }
368 }
369
370 let child_constraints = self.make_constraints(0.0, max_main, 0.0, max_cross);
373
374 let mut placeables: SmallVec<[Option<cranpose_ui_layout::Placeable>; 8]> = SmallVec::new();
375 placeables.resize_with(measurables.len(), || None);
376 let mut fixed_main_size = 0.0_f32;
377 let mut max_cross_size = 0.0_f32;
378
379 for &idx in &fixed_children {
380 let measurable = &measurables[idx];
381 let placeable = measurable.measure(child_constraints);
382 let main_size = self.get_main_axis_size(placeable.width(), placeable.height());
383 let cross_size = self.get_cross_axis_size(placeable.width(), placeable.height());
384
385 fixed_main_size += main_size;
386 max_cross_size = max_cross_size.max(cross_size);
387 placeables[idx] = Some(placeable);
388 }
389
390 let num_children = measurables.len();
392 let total_spacing = if num_children > 1 {
393 spacing * (num_children - 1) as f32
394 } else {
395 0.0
396 };
397
398 if !weighted_children.is_empty() {
400 if main_axis_bounded {
401 let used_main = fixed_main_size + total_spacing;
403 let remaining_main = (max_main - used_main).max(0.0);
404
405 let total_weight: f32 = weighted_children.iter().map(|(_, data)| data.weight).sum();
407
408 for &(idx, parent_data) in &weighted_children {
410 let measurable = &measurables[idx];
411 let allocated = if total_weight > 0.0 {
412 remaining_main * (parent_data.weight / total_weight)
413 } else {
414 0.0
415 };
416
417 let weighted_constraints = if parent_data.fill {
418 self.make_constraints(allocated, allocated, 0.0, max_cross)
420 } else {
421 self.make_constraints(0.0, allocated, 0.0, max_cross)
423 };
424
425 let placeable = measurable.measure(weighted_constraints);
426 let cross_size =
427 self.get_cross_axis_size(placeable.width(), placeable.height());
428 max_cross_size = max_cross_size.max(cross_size);
429 placeables[idx] = Some(placeable);
430 }
431 } else {
432 for &(idx, _) in &weighted_children {
434 let measurable = &measurables[idx];
435 let placeable = measurable.measure(child_constraints);
436 let cross_size =
437 self.get_cross_axis_size(placeable.width(), placeable.height());
438 max_cross_size = max_cross_size.max(cross_size);
439 placeables[idx] = Some(placeable);
440 }
441 }
442 }
443
444 let placeables: SmallVec<[cranpose_ui_layout::Placeable; 8]> = placeables
445 .into_iter()
446 .enumerate()
447 .map(|(idx, placeable)| {
448 placeable.unwrap_or_else(|| measurables[idx].measure(child_constraints))
449 })
450 .collect();
451
452 let total_main: f32 = placeables
454 .iter()
455 .map(|p| self.get_main_axis_size(p.width(), p.height()))
456 .sum::<f32>()
457 + total_spacing;
458
459 let container_main = total_main.clamp(min_main, max_main);
461 let container_cross = max_cross_size.clamp(min_cross, max_cross);
462
463 let child_main_sizes: SmallVec<[f32; 8]> = placeables
465 .iter()
466 .map(|p| self.get_main_axis_size(p.width(), p.height()))
467 .collect();
468
469 let mut main_positions: SmallVec<[f32; 8]> =
470 SmallVec::with_capacity(child_main_sizes.len());
471 main_positions.resize(child_main_sizes.len(), 0.0);
472
473 let arrangement = if total_main > container_main
476 && !matches!(self.main_axis_arrangement, LinearArrangement::SpacedBy(_))
477 {
478 LinearArrangement::Start
479 } else {
480 self.main_axis_arrangement
481 };
482 arrangement.arrange(container_main, &child_main_sizes, &mut main_positions);
483
484 placements.reserve(placeables.len());
486 for (idx, (placeable, main_pos)) in placeables.into_iter().zip(main_positions).enumerate() {
487 let child_cross = self.get_cross_axis_size(placeable.width(), placeable.height());
488 let cross_axis_alignment = match self.axis {
489 Axis::Horizontal => parent_data[idx]
490 .row_alignment
491 .map(Into::into)
492 .unwrap_or(self.cross_axis_alignment),
493 Axis::Vertical => parent_data[idx]
494 .column_alignment
495 .map(Into::into)
496 .unwrap_or(self.cross_axis_alignment),
497 };
498 let cross_pos = cross_axis_alignment.align(container_cross, child_cross);
499
500 let (x, y) = match self.axis {
501 Axis::Horizontal => (main_pos, cross_pos),
502 Axis::Vertical => (cross_pos, main_pos),
503 };
504
505 placeable.place(x, y);
506 placements.push(Placement::new(placeable.node_id(), x, y, 0));
507 }
508
509 let (width, height) = match self.axis {
511 Axis::Horizontal => (container_main, container_cross),
512 Axis::Vertical => (container_cross, container_main),
513 };
514
515 crate::modifier::Size { width, height }
516 }
517
518 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
519 let spacing = self.get_spacing();
520 let total_spacing = if measurables.len() > 1 {
521 spacing * (measurables.len() - 1) as f32
522 } else {
523 0.0
524 };
525
526 match self.axis {
527 Axis::Horizontal => {
528 measurables
530 .iter()
531 .map(|m| m.min_intrinsic_width(height))
532 .sum::<f32>()
533 + total_spacing
534 }
535 Axis::Vertical => {
536 measurables
538 .iter()
539 .map(|m| m.min_intrinsic_width(height))
540 .fold(0.0, f32::max)
541 }
542 }
543 }
544
545 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
546 let spacing = self.get_spacing();
547 let total_spacing = if measurables.len() > 1 {
548 spacing * (measurables.len() - 1) as f32
549 } else {
550 0.0
551 };
552
553 match self.axis {
554 Axis::Horizontal => {
555 measurables
557 .iter()
558 .map(|m| m.max_intrinsic_width(height))
559 .sum::<f32>()
560 + total_spacing
561 }
562 Axis::Vertical => {
563 measurables
565 .iter()
566 .map(|m| m.max_intrinsic_width(height))
567 .fold(0.0, f32::max)
568 }
569 }
570 }
571
572 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
573 let spacing = self.get_spacing();
574 let total_spacing = if measurables.len() > 1 {
575 spacing * (measurables.len() - 1) as f32
576 } else {
577 0.0
578 };
579
580 match self.axis {
581 Axis::Horizontal => {
582 measurables
584 .iter()
585 .map(|m| m.min_intrinsic_height(width))
586 .fold(0.0, f32::max)
587 }
588 Axis::Vertical => {
589 measurables
591 .iter()
592 .map(|m| m.min_intrinsic_height(width))
593 .sum::<f32>()
594 + total_spacing
595 }
596 }
597 }
598
599 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
600 let spacing = self.get_spacing();
601 let total_spacing = if measurables.len() > 1 {
602 spacing * (measurables.len() - 1) as f32
603 } else {
604 0.0
605 };
606
607 match self.axis {
608 Axis::Horizontal => {
609 measurables
611 .iter()
612 .map(|m| m.max_intrinsic_height(width))
613 .fold(0.0, f32::max)
614 }
615 Axis::Vertical => {
616 measurables
618 .iter()
619 .map(|m| m.max_intrinsic_height(width))
620 .sum::<f32>()
621 + total_spacing
622 }
623 }
624 }
625}
626
627#[derive(Clone, Debug, PartialEq)]
640pub struct FlowRowMeasurePolicy {
641 pub main_axis_spacing: f32,
643 pub cross_axis_spacing: f32,
645}
646
647impl FlowRowMeasurePolicy {
648 pub fn new(main_axis_spacing: f32, cross_axis_spacing: f32) -> Self {
649 Self {
650 main_axis_spacing: main_axis_spacing.max(0.0),
651 cross_axis_spacing: cross_axis_spacing.max(0.0),
652 }
653 }
654
655 fn wrapped_intrinsic_height(
657 &self,
658 measurables: &[Box<dyn Measurable>],
659 available_width: f32,
660 use_min_height: bool,
661 ) -> f32 {
662 let mut cursor_x = 0.0_f32;
663 let mut line_top = 0.0_f32;
664 let mut line_height = 0.0_f32;
665
666 for measurable in measurables {
667 let child_width = measurable.max_intrinsic_width(f32::INFINITY);
668 let child_height = if use_min_height {
669 measurable.min_intrinsic_height(child_width)
670 } else {
671 measurable.max_intrinsic_height(child_width)
672 };
673
674 if cursor_x > 0.0 && cursor_x + self.main_axis_spacing + child_width > available_width {
675 line_top += line_height + self.cross_axis_spacing;
676 cursor_x = 0.0;
677 line_height = 0.0;
678 }
679 cursor_x += if cursor_x > 0.0 {
680 self.main_axis_spacing + child_width
681 } else {
682 child_width
683 };
684 line_height = line_height.max(child_height);
685 }
686
687 line_top + line_height
688 }
689}
690
691impl MeasurePolicy for FlowRowMeasurePolicy {
692 fn measure(
693 &self,
694 scope: &dyn MeasureScope,
695 measurables: &[Box<dyn Measurable>],
696 constraints: Constraints,
697 ) -> MeasureResult {
698 let mut placements = Vec::new();
699 let size = self.measure_into(scope, measurables, constraints, &mut placements);
700 MeasureResult::new(size, placements)
701 }
702
703 fn measure_into(
704 &self,
705 _scope: &dyn MeasureScope,
706 measurables: &[Box<dyn Measurable>],
707 constraints: Constraints,
708 placements: &mut Vec<Placement>,
709 ) -> crate::modifier::Size {
710 placements.clear();
711 if measurables.is_empty() {
712 let (width, height) = constraints.constrain(0.0, 0.0);
713 return crate::modifier::Size { width, height };
714 }
715
716 let child_constraints = Constraints {
719 min_width: 0.0,
720 max_width: constraints.max_width,
721 min_height: 0.0,
722 max_height: constraints.max_height,
723 };
724
725 let placeables: SmallVec<[cranpose_ui_layout::Placeable; 8]> = measurables
726 .iter()
727 .map(|measurable| measurable.measure(child_constraints))
728 .collect();
729
730 let mut cursor_x = 0.0_f32; let mut line_top = 0.0_f32; let mut line_height = 0.0_f32;
733 let mut max_line_width = 0.0_f32;
734
735 placements.reserve(placeables.len());
736 for placeable in placeables {
737 let child_width = placeable.width();
738 let child_height = placeable.height();
739
740 if cursor_x > 0.0
745 && cursor_x + self.main_axis_spacing + child_width > constraints.max_width
746 {
747 max_line_width = max_line_width.max(cursor_x);
748 line_top += line_height + self.cross_axis_spacing;
749 cursor_x = 0.0;
750 line_height = 0.0;
751 }
752
753 let x = if cursor_x > 0.0 {
754 cursor_x + self.main_axis_spacing
755 } else {
756 0.0
757 };
758 placeable.place(x, line_top);
759 placements.push(Placement::new(placeable.node_id(), x, line_top, 0));
760
761 cursor_x = x + child_width;
762 line_height = line_height.max(child_height);
763 }
764 max_line_width = max_line_width.max(cursor_x);
765
766 let width = max_line_width.clamp(constraints.min_width, constraints.max_width);
767 let height = (line_top + line_height).clamp(constraints.min_height, constraints.max_height);
768 crate::modifier::Size { width, height }
769 }
770
771 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
772 measurables
774 .iter()
775 .map(|m| m.min_intrinsic_width(height))
776 .fold(0.0, f32::max)
777 }
778
779 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
780 let total_spacing = if measurables.len() > 1 {
782 self.main_axis_spacing * (measurables.len() - 1) as f32
783 } else {
784 0.0
785 };
786 measurables
787 .iter()
788 .map(|m| m.max_intrinsic_width(height))
789 .sum::<f32>()
790 + total_spacing
791 }
792
793 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
794 self.wrapped_intrinsic_height(measurables, width, true)
795 }
796
797 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
798 self.wrapped_intrinsic_height(measurables, width, false)
799 }
800}
801
802#[derive(Clone, Debug, PartialEq)]
805pub struct LeafMeasurePolicy {
806 pub intrinsic_size: crate::modifier::Size,
807}
808
809impl LeafMeasurePolicy {
810 pub fn new(intrinsic_size: crate::modifier::Size) -> Self {
811 Self { intrinsic_size }
812 }
813}
814
815impl MeasurePolicy for LeafMeasurePolicy {
816 fn measure(
817 &self,
818 scope: &dyn MeasureScope,
819 _measurables: &[Box<dyn Measurable>],
820 constraints: Constraints,
821 ) -> MeasureResult {
822 let mut placements = Vec::new();
823 let size = self.measure_into(scope, &[], constraints, &mut placements);
824 MeasureResult::new(size, placements)
825 }
826
827 fn measure_into(
828 &self,
829 _scope: &dyn MeasureScope,
830 _measurables: &[Box<dyn Measurable>],
831 constraints: Constraints,
832 placements: &mut Vec<Placement>,
833 ) -> crate::modifier::Size {
834 placements.clear();
835 let (width, height) =
837 constraints.constrain(self.intrinsic_size.width, self.intrinsic_size.height);
838
839 crate::modifier::Size { width, height }
840 }
841
842 fn min_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
843 self.intrinsic_size.width
844 }
845
846 fn max_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
847 self.intrinsic_size.width
848 }
849
850 fn min_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
851 self.intrinsic_size.height
852 }
853
854 fn max_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
855 self.intrinsic_size.height
856 }
857}
858
859#[derive(Clone, Debug, PartialEq)]
865pub struct EmptyMeasurePolicy;
866
867impl EmptyMeasurePolicy {
868 pub fn new() -> Self {
869 Self
870 }
871}
872
873impl Default for EmptyMeasurePolicy {
874 fn default() -> Self {
875 Self::new()
876 }
877}
878
879impl MeasurePolicy for EmptyMeasurePolicy {
880 fn measure(
881 &self,
882 scope: &dyn MeasureScope,
883 _measurables: &[Box<dyn Measurable>],
884 constraints: Constraints,
885 ) -> MeasureResult {
886 let mut placements = Vec::new();
887 let size = self.measure_into(scope, &[], constraints, &mut placements);
888 MeasureResult::new(size, placements)
889 }
890
891 fn measure_into(
892 &self,
893 _scope: &dyn MeasureScope,
894 _measurables: &[Box<dyn Measurable>],
895 constraints: Constraints,
896 placements: &mut Vec<Placement>,
897 ) -> crate::modifier::Size {
898 placements.clear();
899 let (width, height) = constraints.constrain(0.0, 0.0);
902
903 crate::modifier::Size { width, height }
904 }
905
906 fn min_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
907 0.0
908 }
909
910 fn max_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
911 0.0
912 }
913
914 fn min_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
915 0.0
916 }
917
918 fn max_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
919 0.0
920 }
921}
922
923#[cfg(test)]
924#[path = "tests/policies_tests.rs"]
925mod tests;