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