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_or(self.cross_axis_alignment, Into::into),
467 Axis::Vertical => parent_data[idx]
468 .column_alignment
469 .map_or(self.cross_axis_alignment, Into::into),
470 };
471 let cross_pos = cross_axis_alignment.align(container_cross, child_cross);
472
473 let (x, y) = match self.axis {
474 Axis::Horizontal => (main_pos, cross_pos),
475 Axis::Vertical => (cross_pos, main_pos),
476 };
477
478 placeable.place(x, y);
479 placements.push(Placement::new(placeable.node_id(), x, y, 0));
480 }
481
482 let (width, height) = match self.axis {
483 Axis::Horizontal => (container_main, container_cross),
484 Axis::Vertical => (container_cross, container_main),
485 };
486
487 crate::modifier::Size { width, height }
488 }
489
490 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
491 let spacing = self.get_spacing();
492 let total_spacing = if measurables.len() > 1 {
493 spacing * (measurables.len() - 1) as f32
494 } else {
495 0.0
496 };
497
498 match self.axis {
499 Axis::Horizontal => {
500 measurables
501 .iter()
502 .map(|m| m.min_intrinsic_width(height))
503 .sum::<f32>()
504 + total_spacing
505 }
506 Axis::Vertical => measurables
507 .iter()
508 .map(|m| m.min_intrinsic_width(height))
509 .fold(0.0, f32::max),
510 }
511 }
512
513 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
514 let spacing = self.get_spacing();
515 let total_spacing = if measurables.len() > 1 {
516 spacing * (measurables.len() - 1) as f32
517 } else {
518 0.0
519 };
520
521 match self.axis {
522 Axis::Horizontal => {
523 measurables
524 .iter()
525 .map(|m| m.max_intrinsic_width(height))
526 .sum::<f32>()
527 + total_spacing
528 }
529 Axis::Vertical => measurables
530 .iter()
531 .map(|m| m.max_intrinsic_width(height))
532 .fold(0.0, f32::max),
533 }
534 }
535
536 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
537 let spacing = self.get_spacing();
538 let total_spacing = if measurables.len() > 1 {
539 spacing * (measurables.len() - 1) as f32
540 } else {
541 0.0
542 };
543
544 match self.axis {
545 Axis::Horizontal => measurables
546 .iter()
547 .map(|m| m.min_intrinsic_height(width))
548 .fold(0.0, f32::max),
549 Axis::Vertical => {
550 measurables
551 .iter()
552 .map(|m| m.min_intrinsic_height(width))
553 .sum::<f32>()
554 + total_spacing
555 }
556 }
557 }
558
559 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
560 let spacing = self.get_spacing();
561 let total_spacing = if measurables.len() > 1 {
562 spacing * (measurables.len() - 1) as f32
563 } else {
564 0.0
565 };
566
567 match self.axis {
568 Axis::Horizontal => measurables
569 .iter()
570 .map(|m| m.max_intrinsic_height(width))
571 .fold(0.0, f32::max),
572 Axis::Vertical => {
573 measurables
574 .iter()
575 .map(|m| m.max_intrinsic_height(width))
576 .sum::<f32>()
577 + total_spacing
578 }
579 }
580 }
581}
582
583#[derive(Clone, Debug, PartialEq)]
596pub struct FlowRowMeasurePolicy {
597 pub main_axis_spacing: f32,
599 pub cross_axis_spacing: f32,
601}
602
603impl FlowRowMeasurePolicy {
604 pub fn new(main_axis_spacing: f32, cross_axis_spacing: f32) -> Self {
605 Self {
606 main_axis_spacing: main_axis_spacing.max(0.0),
607 cross_axis_spacing: cross_axis_spacing.max(0.0),
608 }
609 }
610
611 fn wrapped_intrinsic_height(
612 &self,
613 measurables: &[Box<dyn Measurable>],
614 available_width: f32,
615 use_min_height: bool,
616 ) -> f32 {
617 let mut cursor_x = 0.0_f32;
618 let mut line_top = 0.0_f32;
619 let mut line_height = 0.0_f32;
620
621 for measurable in measurables {
622 let child_width = measurable.max_intrinsic_width(f32::INFINITY);
623 let child_height = if use_min_height {
624 measurable.min_intrinsic_height(child_width)
625 } else {
626 measurable.max_intrinsic_height(child_width)
627 };
628
629 if cursor_x > 0.0 && cursor_x + self.main_axis_spacing + child_width > available_width {
630 line_top += line_height + self.cross_axis_spacing;
631 cursor_x = 0.0;
632 line_height = 0.0;
633 }
634 cursor_x += if cursor_x > 0.0 {
635 self.main_axis_spacing + child_width
636 } else {
637 child_width
638 };
639 line_height = line_height.max(child_height);
640 }
641
642 line_top + line_height
643 }
644}
645
646impl MeasurePolicy for FlowRowMeasurePolicy {
647 fn measure(
648 &self,
649 scope: &dyn MeasureScope,
650 measurables: &[Box<dyn Measurable>],
651 constraints: Constraints,
652 ) -> MeasureResult {
653 let mut placements = Vec::new();
654 let size = self.measure_into(scope, measurables, constraints, &mut placements);
655 MeasureResult::new(size, placements)
656 }
657
658 fn measure_into(
659 &self,
660 _scope: &dyn MeasureScope,
661 measurables: &[Box<dyn Measurable>],
662 constraints: Constraints,
663 placements: &mut Vec<Placement>,
664 ) -> crate::modifier::Size {
665 placements.clear();
666 if measurables.is_empty() {
667 let (width, height) = constraints.constrain(0.0, 0.0);
668 return crate::modifier::Size { width, height };
669 }
670
671 let child_constraints = Constraints {
672 min_width: 0.0,
673 max_width: constraints.max_width,
674 min_height: 0.0,
675 max_height: constraints.max_height,
676 };
677
678 let placeables: SmallVec<[cranpose_ui_layout::Placeable; 8]> = measurables
679 .iter()
680 .map(|measurable| measurable.measure(child_constraints))
681 .collect();
682
683 let mut cursor_x = 0.0_f32;
684 let mut line_top = 0.0_f32;
685 let mut line_height = 0.0_f32;
686 let mut max_line_width = 0.0_f32;
687
688 placements.reserve(placeables.len());
689 for placeable in placeables {
690 let child_width = placeable.width();
691 let child_height = placeable.height();
692
693 if cursor_x > 0.0
694 && cursor_x + self.main_axis_spacing + child_width > constraints.max_width
695 {
696 max_line_width = max_line_width.max(cursor_x);
697 line_top += line_height + self.cross_axis_spacing;
698 cursor_x = 0.0;
699 line_height = 0.0;
700 }
701
702 let x = if cursor_x > 0.0 {
703 cursor_x + self.main_axis_spacing
704 } else {
705 0.0
706 };
707 placeable.place(x, line_top);
708 placements.push(Placement::new(placeable.node_id(), x, line_top, 0));
709
710 cursor_x = x + child_width;
711 line_height = line_height.max(child_height);
712 }
713 max_line_width = max_line_width.max(cursor_x);
714
715 let width = max_line_width.clamp(constraints.min_width, constraints.max_width);
716 let height = (line_top + line_height).clamp(constraints.min_height, constraints.max_height);
717 crate::modifier::Size { width, height }
718 }
719
720 fn min_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
721 measurables
722 .iter()
723 .map(|m| m.min_intrinsic_width(height))
724 .fold(0.0, f32::max)
725 }
726
727 fn max_intrinsic_width(&self, measurables: &[Box<dyn Measurable>], height: f32) -> f32 {
728 let total_spacing = if measurables.len() > 1 {
729 self.main_axis_spacing * (measurables.len() - 1) as f32
730 } else {
731 0.0
732 };
733 measurables
734 .iter()
735 .map(|m| m.max_intrinsic_width(height))
736 .sum::<f32>()
737 + total_spacing
738 }
739
740 fn min_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
741 self.wrapped_intrinsic_height(measurables, width, true)
742 }
743
744 fn max_intrinsic_height(&self, measurables: &[Box<dyn Measurable>], width: f32) -> f32 {
745 self.wrapped_intrinsic_height(measurables, width, false)
746 }
747}
748
749#[derive(Clone, Debug, PartialEq)]
752pub struct LeafMeasurePolicy {
753 pub intrinsic_size: crate::modifier::Size,
754}
755
756impl LeafMeasurePolicy {
757 pub fn new(intrinsic_size: crate::modifier::Size) -> Self {
758 Self { intrinsic_size }
759 }
760}
761
762impl MeasurePolicy for LeafMeasurePolicy {
763 fn measure(
764 &self,
765 scope: &dyn MeasureScope,
766 _measurables: &[Box<dyn Measurable>],
767 constraints: Constraints,
768 ) -> MeasureResult {
769 let mut placements = Vec::new();
770 let size = self.measure_into(scope, &[], constraints, &mut placements);
771 MeasureResult::new(size, placements)
772 }
773
774 fn measure_into(
775 &self,
776 _scope: &dyn MeasureScope,
777 _measurables: &[Box<dyn Measurable>],
778 constraints: Constraints,
779 placements: &mut Vec<Placement>,
780 ) -> crate::modifier::Size {
781 placements.clear();
782 let (width, height) =
783 constraints.constrain(self.intrinsic_size.width, self.intrinsic_size.height);
784
785 crate::modifier::Size { width, height }
786 }
787
788 fn min_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
789 self.intrinsic_size.width
790 }
791
792 fn max_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
793 self.intrinsic_size.width
794 }
795
796 fn min_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
797 self.intrinsic_size.height
798 }
799
800 fn max_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
801 self.intrinsic_size.height
802 }
803}
804
805#[derive(Clone, Debug, PartialEq)]
811pub struct EmptyMeasurePolicy;
812
813impl EmptyMeasurePolicy {
814 pub fn new() -> Self {
815 Self
816 }
817}
818
819impl Default for EmptyMeasurePolicy {
820 fn default() -> Self {
821 Self::new()
822 }
823}
824
825impl MeasurePolicy for EmptyMeasurePolicy {
826 fn measure(
827 &self,
828 scope: &dyn MeasureScope,
829 _measurables: &[Box<dyn Measurable>],
830 constraints: Constraints,
831 ) -> MeasureResult {
832 let mut placements = Vec::new();
833 let size = self.measure_into(scope, &[], constraints, &mut placements);
834 MeasureResult::new(size, placements)
835 }
836
837 fn measure_into(
838 &self,
839 _scope: &dyn MeasureScope,
840 _measurables: &[Box<dyn Measurable>],
841 constraints: Constraints,
842 placements: &mut Vec<Placement>,
843 ) -> crate::modifier::Size {
844 placements.clear();
845 let (width, height) = constraints.constrain(0.0, 0.0);
846
847 crate::modifier::Size { width, height }
848 }
849
850 fn min_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
851 0.0
852 }
853
854 fn max_intrinsic_width(&self, _measurables: &[Box<dyn Measurable>], _height: f32) -> f32 {
855 0.0
856 }
857
858 fn min_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
859 0.0
860 }
861
862 fn max_intrinsic_height(&self, _measurables: &[Box<dyn Measurable>], _width: f32) -> f32 {
863 0.0
864 }
865}
866
867#[cfg(test)]
868#[path = "tests/policies_tests.rs"]
869mod tests;