Skip to main content

sequoia_view/
views.rs

1use sequoia_core::{Color, Constraints, Edges, Length, Rect, Size};
2use sequoia_layout::{
3    Align, Axis, ContainerStyle, GridFlow, GridPlacement, GridStyle, Indents, Inset, Justify,
4    LayoutCtx, LayoutStyle, Overflow, Position, Track, WrapStyle,
5};
6use sequoia_style::BoxStyle;
7use sequoia_text::{ElideMode, FontStyle, FontWeight, LetterSpacing, WrapMode};
8
9use crate::any::AnyView;
10use crate::runtime::{ElementId, Runtime};
11use crate::view::{PaintCtx, View};
12
13macro_rules! impl_style_extras {
14    ($name:ident) => {
15        impl $name {
16            pub fn margin(mut self, margin: impl Into<Edges>) -> Self {
17                self.style = self.style.margin(margin);
18                self
19            }
20
21            pub fn margin_xy(mut self, x: f32, y: f32) -> Self {
22                self.style = self.style.margin_xy(x, y);
23                self
24            }
25
26            pub fn margin_x(mut self, x: f32) -> Self {
27                self.style = self.style.margin_x(x);
28                self
29            }
30
31            pub fn margin_y(mut self, y: f32) -> Self {
32                self.style = self.style.margin_y(y);
33                self
34            }
35
36            pub fn margin_left(mut self, v: f32) -> Self {
37                self.style = self.style.margin_left(v);
38                self
39            }
40
41            pub fn margin_right(mut self, v: f32) -> Self {
42                self.style = self.style.margin_right(v);
43                self
44            }
45
46            pub fn margin_top(mut self, v: f32) -> Self {
47                self.style = self.style.margin_top(v);
48                self
49            }
50
51            pub fn margin_bottom(mut self, v: f32) -> Self {
52                self.style = self.style.margin_bottom(v);
53                self
54            }
55
56            pub fn indent_top(mut self, v: f32) -> Self {
57                self.style = self.style.indent_top(v);
58                self
59            }
60
61            pub fn indent_bottom(mut self, v: f32) -> Self {
62                self.style = self.style.indent_bottom(v);
63                self
64            }
65
66            pub fn indent_left(mut self, v: f32) -> Self {
67                self.style = self.style.indent_left(v);
68                self
69            }
70
71            pub fn indent_right(mut self, v: f32) -> Self {
72                self.style = self.style.indent_right(v);
73                self
74            }
75
76            pub fn clear_indents(mut self) -> Self {
77                self.style = self.style.clear_indents();
78                self
79            }
80
81            pub fn indent(mut self, indents: Indents) -> Self {
82                self.style = self.style.indent(indents);
83                self
84            }
85
86            pub fn indent_all(mut self, v: f32) -> Self {
87                self.style = self.style.indent_all(v);
88                self
89            }
90
91            pub fn indent_xy(mut self, x: f32, y: f32) -> Self {
92                self.style = self.style.indent_xy(x, y);
93                self
94            }
95
96            pub fn indent_axes(mut self, horizontal: f32, vertical: f32) -> Self {
97                self.style = self.style.indent_axes(horizontal, vertical);
98                self
99            }
100
101            pub fn flex_grow(mut self, weight: f32) -> Self {
102                self.style = self.style.flex_grow(weight);
103                self
104            }
105
106            pub fn flex_shrink(mut self, shrink: f32) -> Self {
107                self.style = self.style.flex_shrink(shrink);
108                self
109            }
110
111            pub fn flex_basis(mut self, basis: Option<Length>) -> Self {
112                self.style = self.style.flex_basis(basis);
113                self
114            }
115
116            pub fn align_self(mut self, align: Option<Align>) -> Self {
117                self.style = self.style.align_self(align);
118                self
119            }
120
121            pub fn align_self_value(mut self, align: Align) -> Self {
122                self.style = self.style.align_self_value(align);
123                self
124            }
125
126            pub fn aspect_ratio(mut self, ratio: Option<f32>) -> Self {
127                self.style = self.style.aspect_ratio(ratio);
128                self
129            }
130
131            pub fn aspect(mut self, ratio: f32) -> Self {
132                self.style = self.style.aspect(ratio);
133                self
134            }
135
136            pub fn position(mut self, position: Position) -> Self {
137                self.style = self.style.position(position);
138                self
139            }
140
141            pub fn absolute(mut self) -> Self {
142                self.style = self.style.absolute();
143                self
144            }
145
146            pub fn absolute_at(mut self, left: f32, top: f32) -> Self {
147                self.style = self.style.absolute_at(left, top);
148                self
149            }
150
151            pub fn absolute_inset(mut self, inset: Inset) -> Self {
152                self.style = self.style.absolute_inset(inset);
153                self
154            }
155
156            pub fn fit(mut self) -> Self {
157                self.style = self.style.fit();
158                self
159            }
160
161            pub fn hit_testable(mut self, on: bool) -> Self {
162                self.style = self.style.hit_testable(on);
163                self
164            }
165        }
166    };
167}
168
169pub trait IntoChildren {
170    fn into_children(self) -> Vec<AnyView>;
171}
172
173impl<V: View + 'static, const N: usize> IntoChildren for [V; N] {
174    fn into_children(self) -> Vec<AnyView> {
175        self.into_iter().map(AnyView::new).collect()
176    }
177}
178
179impl<V: View + 'static> IntoChildren for Vec<V> {
180    fn into_children(self) -> Vec<AnyView> {
181        self.into_iter().map(AnyView::new).collect()
182    }
183}
184
185impl<V: View + 'static> IntoChildren for Option<V> {
186    fn into_children(self) -> Vec<AnyView> {
187        self.into_iter().map(AnyView::new).collect()
188    }
189}
190
191macro_rules! impl_into_children_tuple {
192    ($($T:ident),*) => {
193        #[allow(non_snake_case)]
194        impl<$($T: View + 'static),*> IntoChildren for ($($T,)*) {
195            fn into_children(self) -> Vec<AnyView> {
196                let ($($T,)*) = self;
197                vec![$(AnyView::new($T)),*]
198            }
199        }
200    };
201}
202
203impl_into_children_tuple!(A);
204impl_into_children_tuple!(A, B);
205impl_into_children_tuple!(A, B, C);
206impl_into_children_tuple!(A, B, C, D);
207impl_into_children_tuple!(A, B, C, D, E);
208impl_into_children_tuple!(A, B, C, D, E, F);
209impl_into_children_tuple!(A, B, C, D, E, F, G);
210impl_into_children_tuple!(A, B, C, D, E, F, G, H);
211impl_into_children_tuple!(A, B, C, D, E, F, G, H, I);
212impl_into_children_tuple!(A, B, C, D, E, F, G, H, I, J);
213impl_into_children_tuple!(A, B, C, D, E, F, G, H, I, J, K);
214impl_into_children_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
215
216macro_rules! impl_child_helpers {
217    ($name:ident) => {
218        impl $name {
219            pub fn child_if<V: View + 'static>(self, cond: bool, make: impl FnOnce() -> V) -> Self {
220                if cond { self.child(make()) } else { self }
221            }
222
223            pub fn child_opt<V: View + 'static>(self, child: Option<V>) -> Self {
224                match child {
225                    Some(v) => self.child(v),
226                    None => self,
227                }
228            }
229        }
230    };
231}
232
233#[derive(Clone, Copy, Default, Debug)]
234pub struct Unit;
235
236impl View for Unit {
237    fn body(&self) -> impl View + 'static {
238        Unit
239    }
240    fn is_leaf(&self) -> bool {
241        true
242    }
243    fn layout_style(&self) -> LayoutStyle {
244        LayoutStyle::default()
245    }
246}
247
248pub struct Text {
249    content: Box<dyn Fn() -> String>,
250    font_size: Option<f32>,
251    color: Option<Color>,
252    weight: Option<FontWeight>,
253    family: Option<String>,
254    font_style: FontStyle,
255    letter_spacing: f32,
256    wrap_width: Option<f32>,
257    wrap_mode: WrapMode,
258    truncate_width: Option<f32>,
259
260    truncate_fill: bool,
261    elide_mode: ElideMode,
262    underline: bool,
263    strikethrough: bool,
264    style: LayoutStyle,
265}
266
267impl Text {
268    pub fn new(content: impl Into<String>) -> Self {
269        let s = content.into();
270        Self {
271            content: Box::new(move || s.clone()),
272            font_size: None,
273            color: None,
274            weight: None,
275            family: None,
276            font_style: FontStyle::Normal,
277            letter_spacing: 0.0,
278            wrap_width: None,
279            wrap_mode: WrapMode::default(),
280            truncate_width: None,
281            truncate_fill: false,
282            elide_mode: ElideMode::default(),
283            underline: false,
284            strikethrough: false,
285            style: LayoutStyle {
286                width: Length::Fit,
287                height: Length::Fit,
288                ..LayoutStyle::default()
289            },
290        }
291    }
292
293    pub fn with(content: impl Fn() -> String + 'static) -> Self {
294        Self {
295            content: Box::new(content),
296            font_size: None,
297            color: None,
298            weight: None,
299            family: None,
300            font_style: FontStyle::Normal,
301            letter_spacing: 0.0,
302            wrap_width: None,
303            wrap_mode: WrapMode::default(),
304            truncate_width: None,
305            truncate_fill: false,
306            elide_mode: ElideMode::default(),
307            underline: false,
308            strikethrough: false,
309            style: LayoutStyle {
310                width: Length::Fit,
311                height: Length::Fit,
312                ..LayoutStyle::default()
313            },
314        }
315    }
316
317    pub fn underline(mut self, on: bool) -> Self {
318        self.underline = on;
319        self
320    }
321
322    pub fn strikethrough(mut self, on: bool) -> Self {
323        self.strikethrough = on;
324        self
325    }
326
327    pub fn size(mut self, size: f32) -> Self {
328        self.font_size = Some(size);
329        self
330    }
331
332    pub fn color(mut self, color: Color) -> Self {
333        self.color = Some(color);
334        self
335    }
336
337    pub fn weight(mut self, weight: FontWeight) -> Self {
338        self.weight = Some(weight);
339        self
340    }
341
342    pub fn bold(mut self) -> Self {
343        self.weight = Some(FontWeight::BOLD);
344        self
345    }
346
347    pub fn bold_if(mut self, bold: bool) -> Self {
348        self.weight = Some(if bold {
349            FontWeight::BOLD
350        } else {
351            FontWeight::NORMAL
352        });
353        self
354    }
355
356    pub fn semibold(mut self) -> Self {
357        self.weight = Some(FontWeight::SEMIBOLD);
358        self
359    }
360
361    pub fn medium(mut self) -> Self {
362        self.weight = Some(FontWeight::MEDIUM);
363        self
364    }
365
366    pub fn normal(mut self) -> Self {
367        self.weight = Some(FontWeight::NORMAL);
368        self
369    }
370
371    pub fn light(mut self) -> Self {
372        self.weight = Some(FontWeight::LIGHT);
373        self
374    }
375
376    pub fn black(mut self) -> Self {
377        self.weight = Some(FontWeight::BLACK);
378        self
379    }
380
381    pub fn font(mut self, family: impl Into<String>) -> Self {
382        let family = family.into();
383        self.family = if family.is_empty() {
384            None
385        } else {
386            Some(family)
387        };
388        self
389    }
390
391    pub fn family(self, family: impl Into<String>) -> Self {
392        self.font(family)
393    }
394
395    pub fn font_style(mut self, style: FontStyle) -> Self {
396        self.font_style = style;
397        self
398    }
399
400    pub fn italic(mut self) -> Self {
401        self.font_style = FontStyle::Italic;
402        self
403    }
404
405    pub fn oblique(mut self) -> Self {
406        self.font_style = FontStyle::Oblique;
407        self
408    }
409
410    pub fn upright(mut self) -> Self {
411        self.font_style = FontStyle::Normal;
412        self
413    }
414
415    pub fn italic_if(mut self, on: bool) -> Self {
416        self.font_style = if on {
417            FontStyle::Italic
418        } else {
419            FontStyle::Normal
420        };
421        self
422    }
423
424    pub fn letter_spacing(mut self, spacing: LetterSpacing) -> Self {
425        self.letter_spacing = if spacing.is_finite() { spacing } else { 0.0 };
426        self
427    }
428
429    pub fn wrap_width(mut self, width: f32) -> Self {
430        self.wrap_width = if width > 0.0 { Some(width) } else { None };
431        self
432    }
433
434    pub fn wrap_mode(mut self, mode: WrapMode) -> Self {
435        self.wrap_mode = mode;
436        self
437    }
438
439    pub fn truncate(mut self, max_width: f32) -> Self {
440        self.truncate_width = if max_width > 0.0 {
441            Some(max_width)
442        } else {
443            None
444        };
445        self
446    }
447
448    pub fn truncate_fill(mut self) -> Self {
449        self.truncate_fill = true;
450        self
451    }
452
453    pub fn elide(mut self, mode: ElideMode) -> Self {
454        self.elide_mode = mode;
455        self
456    }
457
458    pub fn width(mut self, width: impl Into<Length>) -> Self {
459        self.style = self.style.width(width.into());
460        self
461    }
462
463    pub fn height(mut self, height: impl Into<Length>) -> Self {
464        self.style = self.style.height(height.into());
465        self
466    }
467
468    pub fn min_width(mut self, v: f32) -> Self {
469        self.style = self.style.min_width(v);
470        self
471    }
472
473    pub fn max_width(mut self, v: f32) -> Self {
474        self.style = self.style.max_width(v);
475        self
476    }
477
478    pub fn min_height(mut self, v: f32) -> Self {
479        self.style = self.style.min_height(v);
480        self
481    }
482
483    pub fn max_height(mut self, v: f32) -> Self {
484        self.style = self.style.max_height(v);
485        self
486    }
487
488    pub fn flex(mut self, weight: f32) -> Self {
489        self.style = self.style.flex(weight);
490        self
491    }
492
493    pub fn expand(self) -> Self {
494        self.flex(1.0)
495    }
496
497    pub fn fill_width(mut self) -> Self {
498        self.style = self.style.width(Length::Fill(1.0));
499        self
500    }
501
502    pub fn fill_height(mut self) -> Self {
503        self.style = self.style.height(Length::Fill(1.0));
504        self
505    }
506
507    pub fn fill_size(self) -> Self {
508        self.fill_width().fill_height()
509    }
510
511    pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
512        self.style = self.style.padding(padding);
513        self
514    }
515
516    pub fn pad(self, padding: impl Into<Edges>) -> Self {
517        self.padding(padding)
518    }
519
520    pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
521        self.style = self.style.padding_xy(x, y);
522        self
523    }
524
525    pub fn padding_x(mut self, x: f32) -> Self {
526        self.style = self.style.padding_x(x);
527        self
528    }
529
530    pub fn padding_y(mut self, y: f32) -> Self {
531        self.style = self.style.padding_y(y);
532        self
533    }
534
535    pub fn padding_left(mut self, v: f32) -> Self {
536        self.style = self.style.padding_left(v);
537        self
538    }
539
540    pub fn padding_right(mut self, v: f32) -> Self {
541        self.style = self.style.padding_right(v);
542        self
543    }
544
545    pub fn padding_top(mut self, v: f32) -> Self {
546        self.style = self.style.padding_top(v);
547        self
548    }
549
550    pub fn padding_bottom(mut self, v: f32) -> Self {
551        self.style = self.style.padding_bottom(v);
552        self
553    }
554
555    pub fn margin(mut self, margin: impl Into<Edges>) -> Self {
556        self.style = self.style.margin(margin);
557        self
558    }
559
560    pub fn margin_xy(mut self, x: f32, y: f32) -> Self {
561        self.style = self.style.margin_xy(x, y);
562        self
563    }
564
565    pub fn margin_x(mut self, x: f32) -> Self {
566        self.style = self.style.margin_x(x);
567        self
568    }
569
570    pub fn margin_y(mut self, y: f32) -> Self {
571        self.style = self.style.margin_y(y);
572        self
573    }
574
575    pub fn margin_left(mut self, v: f32) -> Self {
576        self.style = self.style.margin_left(v);
577        self
578    }
579
580    pub fn margin_right(mut self, v: f32) -> Self {
581        self.style = self.style.margin_right(v);
582        self
583    }
584
585    pub fn margin_top(mut self, v: f32) -> Self {
586        self.style = self.style.margin_top(v);
587        self
588    }
589
590    pub fn margin_bottom(mut self, v: f32) -> Self {
591        self.style = self.style.margin_bottom(v);
592        self
593    }
594
595    pub fn indent_top(mut self, v: f32) -> Self {
596        self.style = self.style.indent_top(v);
597        self
598    }
599
600    pub fn indent_bottom(mut self, v: f32) -> Self {
601        self.style = self.style.indent_bottom(v);
602        self
603    }
604
605    pub fn indent_left(mut self, v: f32) -> Self {
606        self.style = self.style.indent_left(v);
607        self
608    }
609
610    pub fn indent_right(mut self, v: f32) -> Self {
611        self.style = self.style.indent_right(v);
612        self
613    }
614
615    pub fn clear_indents(mut self) -> Self {
616        self.style = self.style.clear_indents();
617        self
618    }
619
620    pub fn indent(mut self, indents: Indents) -> Self {
621        self.style = self.style.indent(indents);
622        self
623    }
624
625    pub fn indent_all(mut self, v: f32) -> Self {
626        self.style = self.style.indent_all(v);
627        self
628    }
629
630    pub fn indent_xy(mut self, x: f32, y: f32) -> Self {
631        self.style = self.style.indent_xy(x, y);
632        self
633    }
634
635    pub fn indent_axes(mut self, horizontal: f32, vertical: f32) -> Self {
636        self.style = self.style.indent_axes(horizontal, vertical);
637        self
638    }
639
640    pub fn hit_testable(mut self, on: bool) -> Self {
641        self.style = self.style.hit_testable(on);
642        self
643    }
644
645    pub fn content(&self) -> String {
646        (self.content)()
647    }
648
649    fn paint_decoration(
650        &self,
651        ctx: &mut PaintCtx,
652        shown: &str,
653        x: f32,
654        baseline: f32,
655        size: f32,
656        weight: FontWeight,
657        color: Color,
658    ) {
659        if !self.underline && !self.strikethrough {
660            return;
661        }
662        let width = ctx.text_width_styled_spaced(
663            shown,
664            size,
665            weight,
666            self.letter_spacing,
667            self.family.as_deref(),
668            self.font_style,
669        );
670        if width <= 0.0 {
671            return;
672        }
673        let thickness = (size * 0.07).max(1.0);
674        if self.underline {
675            let y = (baseline + size * 0.12).round();
676            ctx.quad(Rect::from_xywh(x, y, width, thickness), color, 0.0);
677        }
678        if self.strikethrough {
679            let y = (baseline - size * 0.30).round();
680            ctx.quad(Rect::from_xywh(x, y, width, thickness), color, 0.0);
681        }
682    }
683}
684
685impl View for Text {
686    fn body(&self) -> impl View + 'static {
687        let _ = (self.content)();
688        Unit
689    }
690    fn is_leaf(&self) -> bool {
691        true
692    }
693
694    fn accessibility(&self) -> Option<crate::a11y::Accessible> {
695        Some(crate::a11y::Accessible::new(
696            crate::a11y::AccessibleRole::Text,
697            (self.content)(),
698        ))
699    }
700
701    fn clip_self(&self) -> bool {
702        true
703    }
704    fn layout_style(&self) -> LayoutStyle {
705        self.style
706    }
707    fn intrinsic_size(&self, ctx: &mut LayoutCtx) -> Option<Size> {
708        let size = self.font_size.unwrap_or(14.0);
709        let weight = self.weight.unwrap_or_default();
710        let family = self.family.as_deref();
711        let fstyle = self.font_style;
712        let content = (self.content)();
713        let pad = self.style.padding;
714        let text_size = if let Some(w) = self.truncate_width {
715            ctx.text_elided_size_styled_spaced(
716                &content,
717                size,
718                weight,
719                w,
720                self.elide_mode,
721                self.letter_spacing,
722                family,
723                fstyle,
724            )
725        } else {
726            match self.wrap_width {
727                Some(w) => ctx.text_wrapped_size_styled_spaced(
728                    &content,
729                    size,
730                    weight,
731                    w,
732                    self.wrap_mode,
733                    self.letter_spacing,
734                    family,
735                    fstyle,
736                ),
737                None => {
738                    let w = ctx.text_width_styled_spaced(
739                        &content,
740                        size,
741                        weight,
742                        self.letter_spacing,
743                        family,
744                        fstyle,
745                    );
746                    Size::new(w, LayoutCtx::text_line_height(size))
747                }
748            }
749        };
750        Some(Size::new(
751            text_size.width + pad.horizontal_sum(),
752            text_size.height + pad.vertical_sum(),
753        ))
754    }
755    fn paint_self(&self, ctx: &mut PaintCtx) {
756        let theme = ctx.theme();
757        let size = self.font_size.unwrap_or(theme.font_size);
758        let weight = self.weight.unwrap_or_default();
759        let color = self.color.unwrap_or(theme.text);
760        let content = (self.content)();
761        let pad = self.style.padding;
762
763        let content_rect = Rect::from_xywh(
764            ctx.rect.left() + pad.left,
765            ctx.rect.top() + pad.top,
766            (ctx.rect.size.width - pad.horizontal_sum()).max(0.0),
767            (ctx.rect.size.height - pad.vertical_sum()).max(0.0),
768        );
769        let x = content_rect.left();
770
771        let family = self.family.as_deref();
772        let fstyle = self.font_style;
773        let (shown, y, wrapped) = if let Some(w) = self.truncate_width.or(if self.truncate_fill {
774            Some(content_rect.size.width.max(0.0))
775        } else {
776            None
777        }) {
778            let shown = ctx.elide_styled_spaced(
779                &content,
780                size,
781                weight,
782                w,
783                self.elide_mode,
784                self.letter_spacing,
785                family,
786                fstyle,
787            );
788            let y = content_rect.top() + content_rect.size.height * 0.5 + size * 0.35;
789            (shown, y, None)
790        } else {
791            let y = match self.wrap_width {
792                Some(_) => {
793                    content_rect.top() + LayoutCtx::text_line_height(size) * 0.5 + size * 0.35
794                }
795                None => content_rect.top() + content_rect.size.height * 0.5 + size * 0.35,
796            };
797
798            #[cfg(debug_assertions)]
799            {
800                if self.wrap_width.is_none() && !content.is_empty() {
801                    let full_w = ctx.text_width_styled_spaced(
802                        &content,
803                        size,
804                        weight,
805                        self.letter_spacing,
806                        family,
807                        fstyle,
808                    );
809                    if full_w > content_rect.size.width + 1.0 && content_rect.size.width > 0.0 {
810                        use std::sync::Once;
811                        static WARN_ONCE: Once = Once::new();
812                        WARN_ONCE.call_once(|| {
813                            log::warn!(
814                                "sequoia-view: Text `{}` overflows box ({full_w:.1}px > {:.1}px) without truncate — add `.truncate_fill()` or `.truncate(w)`. \
815                                 (This warning once per process; subsequent overflows are silent.)",
816                                content.chars().take(24).collect::<String>(),
817                                content_rect.size.width,
818                            );
819                        });
820                    }
821                }
822            }
823            (content.clone(), y, self.wrap_width)
824        };
825        match wrapped {
826            Some(w) => ctx.draw_text_wrapped_styled_spaced(
827                &shown,
828                (x, y),
829                size,
830                weight,
831                w,
832                self.wrap_mode,
833                self.letter_spacing,
834                family,
835                fstyle,
836                color,
837            ),
838            None => ctx.draw_text_styled_spaced(
839                &shown,
840                (x, y),
841                size,
842                weight,
843                self.letter_spacing,
844                family,
845                fstyle,
846                color,
847            ),
848        }
849        self.paint_decoration(ctx, &shown, x, y, size, weight, color);
850    }
851}
852
853#[derive(Clone, Default)]
854pub struct Fragment {
855    children: Vec<AnyView>,
856}
857
858impl Fragment {
859    pub fn new() -> Self {
860        Self::default()
861    }
862
863    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
864        self.children.push(AnyView::new(child));
865        self
866    }
867
868    pub fn children(mut self, children: impl IntoChildren) -> Self {
869        self.children.extend(children.into_children());
870        self
871    }
872}
873
874impl View for Fragment {
875    fn body(&self) -> impl View + 'static {
876        Unit
877    }
878    fn children_override(&self) -> Option<Vec<AnyView>> {
879        Some(self.children.clone())
880    }
881    fn layout_style(&self) -> LayoutStyle {
882        LayoutStyle::default().hit_testable(false)
883    }
884    fn hit_testable(&self) -> bool {
885        false
886    }
887}
888
889#[derive(Clone)]
890pub struct Margined {
891    child: AnyView,
892    margin: Edges,
893    indents: Indents,
894}
895
896impl Margined {
897    pub fn new<V: View + 'static>(child: V, margin: impl Into<Edges>) -> Self {
898        Self {
899            child: AnyView::new(child),
900            margin: margin.into(),
901            indents: Indents::NONE,
902        }
903    }
904
905    pub fn with_indents<V: View + 'static>(child: V, indents: Indents) -> Self {
906        Self {
907            child: AnyView::new(child),
908            margin: Edges::ZERO,
909            indents,
910        }
911    }
912
913    pub fn margin(mut self, margin: impl Into<Edges>) -> Self {
914        let m = margin.into();
915        self.margin = Edges::only(
916            sanitize_margin_edge(m.left),
917            sanitize_margin_edge(m.top),
918            sanitize_margin_edge(m.right),
919            sanitize_margin_edge(m.bottom),
920        );
921        self
922    }
923
924    pub fn margin_xy(self, x: f32, y: f32) -> Self {
925        self.margin(Edges::xy(x, y))
926    }
927
928    pub fn margin_x(mut self, x: f32) -> Self {
929        let x = sanitize_margin_edge(x);
930        self.margin.left = x;
931        self.margin.right = x;
932        self
933    }
934
935    pub fn margin_y(mut self, y: f32) -> Self {
936        let y = sanitize_margin_edge(y);
937        self.margin.top = y;
938        self.margin.bottom = y;
939        self
940    }
941
942    pub fn margin_left(mut self, v: f32) -> Self {
943        self.margin.left = sanitize_margin_edge(v);
944        self
945    }
946
947    pub fn margin_right(mut self, v: f32) -> Self {
948        self.margin.right = sanitize_margin_edge(v);
949        self
950    }
951
952    pub fn margin_top(mut self, v: f32) -> Self {
953        self.margin.top = sanitize_margin_edge(v);
954        self
955    }
956
957    pub fn margin_bottom(mut self, v: f32) -> Self {
958        self.margin.bottom = sanitize_margin_edge(v);
959        self
960    }
961
962    pub fn indent_top(mut self, v: f32) -> Self {
963        self.indents.top = Some(sequoia_layout::sanitize_indent(v));
964        self
965    }
966
967    pub fn indent_bottom(mut self, v: f32) -> Self {
968        self.indents.bottom = Some(sequoia_layout::sanitize_indent(v));
969        self
970    }
971
972    pub fn indent_left(mut self, v: f32) -> Self {
973        self.indents.left = Some(sequoia_layout::sanitize_indent(v));
974        self
975    }
976
977    pub fn indent_right(mut self, v: f32) -> Self {
978        self.indents.right = Some(sequoia_layout::sanitize_indent(v));
979        self
980    }
981
982    pub fn clear_indents(mut self) -> Self {
983        self.indents = Indents::NONE;
984        self
985    }
986
987    pub fn indent(mut self, indents: Indents) -> Self {
988        if let Some(v) = indents.top {
989            self.indents.top = Some(sequoia_layout::sanitize_indent(v));
990        }
991        if let Some(v) = indents.bottom {
992            self.indents.bottom = Some(sequoia_layout::sanitize_indent(v));
993        }
994        if let Some(v) = indents.left {
995            self.indents.left = Some(sequoia_layout::sanitize_indent(v));
996        }
997        if let Some(v) = indents.right {
998            self.indents.right = Some(sequoia_layout::sanitize_indent(v));
999        }
1000        self
1001    }
1002
1003    pub fn indent_all(self, v: f32) -> Self {
1004        self.indent(Indents::all(v))
1005    }
1006
1007    pub fn indent_xy(self, x: f32, y: f32) -> Self {
1008        self.indent(Indents::xy(x, y))
1009    }
1010
1011    pub fn indent_axes(self, horizontal: f32, vertical: f32) -> Self {
1012        self.indent(Indents::axes(horizontal, vertical))
1013    }
1014}
1015
1016fn sanitize_margin_edge(v: f32) -> f32 {
1017    if v.is_finite() { v.max(0.0) } else { 0.0 }
1018}
1019
1020impl View for Margined {
1021    fn body(&self) -> impl View + 'static {
1022        Unit
1023    }
1024    fn children_override(&self) -> Option<Vec<AnyView>> {
1025        Some(vec![self.child.clone()])
1026    }
1027    fn layout_style(&self) -> LayoutStyle {
1028        LayoutStyle {
1029            width: Length::Fit,
1030            height: Length::Fit,
1031            margin: self.margin,
1032            indent_top: self.indents.top,
1033            indent_bottom: self.indents.bottom,
1034            indent_left: self.indents.left,
1035            indent_right: self.indents.right,
1036            ..LayoutStyle::default().hit_testable(false)
1037        }
1038    }
1039    fn hit_testable(&self) -> bool {
1040        false
1041    }
1042}
1043
1044#[derive(Clone, Default)]
1045pub struct FocusScope {
1046    children: Vec<AnyView>,
1047    trap: bool,
1048}
1049
1050impl FocusScope {
1051    pub fn new() -> Self {
1052        Self::default()
1053    }
1054
1055    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
1056        self.children.push(AnyView::new(child));
1057        self
1058    }
1059
1060    pub fn children(mut self, children: impl IntoChildren) -> Self {
1061        self.children.extend(children.into_children());
1062        self
1063    }
1064
1065    pub fn trap(mut self, trap: bool) -> Self {
1066        self.trap = trap;
1067        self
1068    }
1069}
1070
1071impl View for FocusScope {
1072    fn body(&self) -> impl View + 'static {
1073        Unit
1074    }
1075    fn children_override(&self) -> Option<Vec<AnyView>> {
1076        Some(self.children.clone())
1077    }
1078    fn focus_trap(&self) -> bool {
1079        self.trap
1080    }
1081    fn layout_style(&self) -> LayoutStyle {
1082        LayoutStyle::default()
1083    }
1084}
1085
1086struct Flex {
1087    children: Vec<AnyView>,
1088
1089    flex: Vec<f32>,
1090    gap: f32,
1091    cross_gap: f32,
1092    wrap: bool,
1093    align_content: Align,
1094    style: LayoutStyle,
1095    axis: Axis,
1096    align: Align,
1097    justify: Justify,
1098    deco: BoxStyle,
1099}
1100
1101impl Flex {
1102    fn new(axis: Axis) -> Self {
1103        Self {
1104            children: Vec::new(),
1105            flex: Vec::new(),
1106            gap: 0.0,
1107            cross_gap: 0.0,
1108            wrap: false,
1109            align_content: Align::Start,
1110            style: LayoutStyle {
1111                width: Length::Fit,
1112                height: Length::Fit,
1113                ..LayoutStyle::default()
1114            },
1115            axis,
1116            align: Align::Start,
1117            justify: Justify::Start,
1118            deco: BoxStyle::new(),
1119        }
1120    }
1121
1122    fn sanitize_flex(flex: f32) -> f32 {
1123        if flex.is_finite() && flex > 0.0 {
1124            flex
1125        } else {
1126            0.0
1127        }
1128    }
1129}
1130
1131impl View for Flex {
1132    fn body(&self) -> impl View + 'static {
1133        Unit
1134    }
1135    fn children_override(&self) -> Option<Vec<AnyView>> {
1136        Some(self.children.clone())
1137    }
1138    fn layout_style(&self) -> LayoutStyle {
1139        let mut style = self.style;
1140        let edges = self.deco.border_edges();
1141        style.padding.left += edges.left;
1142        style.padding.top += edges.top;
1143        style.padding.right += edges.right;
1144        style.padding.bottom += edges.bottom;
1145        style
1146    }
1147    fn container(&self) -> Option<ContainerStyle> {
1148        Some(ContainerStyle {
1149            axis: self.axis,
1150            gap: self.gap,
1151            cross_gap: self.cross_gap,
1152            align: self.align,
1153            justify: self.justify,
1154            wrap: self.wrap,
1155            align_content: self.align_content,
1156        })
1157    }
1158}
1159
1160macro_rules! impl_flex_container {
1161    ($name:ident, $axis:expr) => {
1162        impl $name {
1163            pub fn gap(mut self, gap: f32) -> Self {
1164                let gap = if gap.is_finite() { gap.max(0.0) } else { 0.0 };
1165                self.0.gap = gap;
1166                self.0.cross_gap = gap;
1167                self
1168            }
1169
1170            pub fn main_gap(mut self, gap: f32) -> Self {
1171                self.0.gap = if gap.is_finite() { gap.max(0.0) } else { 0.0 };
1172                self
1173            }
1174
1175            pub fn cross_gap(mut self, gap: f32) -> Self {
1176                self.0.cross_gap = if gap.is_finite() { gap.max(0.0) } else { 0.0 };
1177                self
1178            }
1179
1180            pub fn gaps(mut self, main: f32, cross: f32) -> Self {
1181                self.0.gap = if main.is_finite() { main.max(0.0) } else { 0.0 };
1182                self.0.cross_gap = if cross.is_finite() {
1183                    cross.max(0.0)
1184                } else {
1185                    0.0
1186                };
1187                self
1188            }
1189
1190            pub fn wrap(mut self, wrap: bool) -> Self {
1191                self.0.wrap = wrap;
1192                self
1193            }
1194
1195            pub fn wrapped(mut self) -> Self {
1196                self.0.wrap = true;
1197                self
1198            }
1199
1200            pub fn align_content(mut self, align: Align) -> Self {
1201                self.0.align_content = align;
1202                self
1203            }
1204
1205            pub fn margin(mut self, margin: impl Into<Edges>) -> Self {
1206                self.0.style = self.0.style.margin(margin);
1207                self
1208            }
1209
1210            pub fn margin_xy(mut self, x: f32, y: f32) -> Self {
1211                self.0.style = self.0.style.margin_xy(x, y);
1212                self
1213            }
1214
1215            pub fn margin_x(mut self, x: f32) -> Self {
1216                self.0.style = self.0.style.margin_x(x);
1217                self
1218            }
1219
1220            pub fn margin_y(mut self, y: f32) -> Self {
1221                self.0.style = self.0.style.margin_y(y);
1222                self
1223            }
1224
1225            pub fn margin_left(mut self, v: f32) -> Self {
1226                self.0.style = self.0.style.margin_left(v);
1227                self
1228            }
1229
1230            pub fn margin_right(mut self, v: f32) -> Self {
1231                self.0.style = self.0.style.margin_right(v);
1232                self
1233            }
1234
1235            pub fn margin_top(mut self, v: f32) -> Self {
1236                self.0.style = self.0.style.margin_top(v);
1237                self
1238            }
1239
1240            pub fn margin_bottom(mut self, v: f32) -> Self {
1241                self.0.style = self.0.style.margin_bottom(v);
1242                self
1243            }
1244
1245            pub fn indent_top(mut self, v: f32) -> Self {
1246                self.0.style = self.0.style.indent_top(v);
1247                self
1248            }
1249
1250            pub fn indent_bottom(mut self, v: f32) -> Self {
1251                self.0.style = self.0.style.indent_bottom(v);
1252                self
1253            }
1254
1255            pub fn indent_left(mut self, v: f32) -> Self {
1256                self.0.style = self.0.style.indent_left(v);
1257                self
1258            }
1259
1260            pub fn indent_right(mut self, v: f32) -> Self {
1261                self.0.style = self.0.style.indent_right(v);
1262                self
1263            }
1264
1265            pub fn clear_indents(mut self) -> Self {
1266                self.0.style = self.0.style.clear_indents();
1267                self
1268            }
1269
1270            pub fn indent(mut self, indents: Indents) -> Self {
1271                self.0.style = self.0.style.indent(indents);
1272                self
1273            }
1274
1275            pub fn indent_all(mut self, v: f32) -> Self {
1276                self.0.style = self.0.style.indent_all(v);
1277                self
1278            }
1279
1280            pub fn indent_xy(mut self, x: f32, y: f32) -> Self {
1281                self.0.style = self.0.style.indent_xy(x, y);
1282                self
1283            }
1284
1285            pub fn indent_axes(mut self, horizontal: f32, vertical: f32) -> Self {
1286                self.0.style = self.0.style.indent_axes(horizontal, vertical);
1287                self
1288            }
1289
1290            pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
1291                self.0.style = self.0.style.padding(padding);
1292                self
1293            }
1294
1295            pub fn pad(self, padding: impl Into<Edges>) -> Self {
1296                self.padding(padding)
1297            }
1298
1299            pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
1300                self.0.style = self.0.style.padding_xy(x, y);
1301                self
1302            }
1303
1304            pub fn padding_x(mut self, x: f32) -> Self {
1305                self.0.style = self.0.style.padding_x(x);
1306                self
1307            }
1308
1309            pub fn padding_y(mut self, y: f32) -> Self {
1310                self.0.style = self.0.style.padding_y(y);
1311                self
1312            }
1313
1314            pub fn padding_left(mut self, v: f32) -> Self {
1315                self.0.style = self.0.style.padding_left(v);
1316                self
1317            }
1318
1319            pub fn padding_right(mut self, v: f32) -> Self {
1320                self.0.style = self.0.style.padding_right(v);
1321                self
1322            }
1323
1324            pub fn padding_top(mut self, v: f32) -> Self {
1325                self.0.style = self.0.style.padding_top(v);
1326                self
1327            }
1328
1329            pub fn padding_bottom(mut self, v: f32) -> Self {
1330                self.0.style = self.0.style.padding_bottom(v);
1331                self
1332            }
1333
1334            pub fn width(mut self, width: impl Into<Length>) -> Self {
1335                self.0.style = self.0.style.width(width.into());
1336                self
1337            }
1338
1339            pub fn height(mut self, height: impl Into<Length>) -> Self {
1340                self.0.style = self.0.style.height(height.into());
1341                self
1342            }
1343
1344            pub fn size(mut self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
1345                self.0.style = self.0.style.width(width.into()).height(height.into());
1346                self
1347            }
1348
1349            pub fn square(mut self, side: impl Into<Length>) -> Self {
1350                let side = side.into();
1351                self.0.style = self.0.style.width(side).height(side);
1352                self
1353            }
1354
1355            pub fn min_width(mut self, v: f32) -> Self {
1356                self.0.style = self.0.style.min_width(v);
1357                self
1358            }
1359
1360            pub fn max_width(mut self, v: f32) -> Self {
1361                self.0.style = self.0.style.max_width(v);
1362                self
1363            }
1364
1365            pub fn min_height(mut self, v: f32) -> Self {
1366                self.0.style = self.0.style.min_height(v);
1367                self
1368            }
1369
1370            pub fn max_height(mut self, v: f32) -> Self {
1371                self.0.style = self.0.style.max_height(v);
1372                self
1373            }
1374
1375            pub fn overflow(mut self, overflow: Overflow) -> Self {
1376                self.0.style = self.0.style.overflow(overflow);
1377                self
1378            }
1379
1380            pub fn flex(mut self, weight: f32) -> Self {
1381                self.0.style = self.0.style.flex(weight);
1382                self
1383            }
1384
1385            pub fn flex_grow(mut self, weight: f32) -> Self {
1386                self.0.style = self.0.style.flex_grow(weight);
1387                self
1388            }
1389
1390            pub fn flex_shrink(mut self, shrink: f32) -> Self {
1391                self.0.style = self.0.style.flex_shrink(shrink);
1392                self
1393            }
1394
1395            pub fn flex_basis(mut self, basis: Option<Length>) -> Self {
1396                self.0.style = self.0.style.flex_basis(basis);
1397                self
1398            }
1399
1400            pub fn align_self(mut self, align: Option<Align>) -> Self {
1401                self.0.style = self.0.style.align_self(align);
1402                self
1403            }
1404
1405            pub fn align_self_value(mut self, align: Align) -> Self {
1406                self.0.style = self.0.style.align_self_value(align);
1407                self
1408            }
1409
1410            pub fn aspect_ratio(mut self, ratio: Option<f32>) -> Self {
1411                self.0.style = self.0.style.aspect_ratio(ratio);
1412                self
1413            }
1414
1415            pub fn aspect(mut self, ratio: f32) -> Self {
1416                self.0.style = self.0.style.aspect(ratio);
1417                self
1418            }
1419
1420            pub fn position(mut self, position: Position) -> Self {
1421                self.0.style = self.0.style.position(position);
1422                self
1423            }
1424
1425            pub fn absolute(mut self) -> Self {
1426                self.0.style = self.0.style.absolute();
1427                self
1428            }
1429
1430            pub fn absolute_at(mut self, left: f32, top: f32) -> Self {
1431                self.0.style = self.0.style.absolute_at(left, top);
1432                self
1433            }
1434
1435            pub fn absolute_inset(mut self, inset: Inset) -> Self {
1436                self.0.style = self.0.style.absolute_inset(inset);
1437                self
1438            }
1439
1440            pub fn expand(self) -> Self {
1441                self.flex(1.0)
1442            }
1443
1444            pub fn fill_width(mut self) -> Self {
1445                self.0.style = self.0.style.width(Length::Fill(1.0));
1446                self
1447            }
1448
1449            pub fn fill_height(mut self) -> Self {
1450                self.0.style = self.0.style.height(Length::Fill(1.0));
1451                self
1452            }
1453
1454            pub fn fill_size(self) -> Self {
1455                self.fill_width().fill_height()
1456            }
1457
1458            pub fn fit(mut self) -> Self {
1459                self.0.style = self.0.style.fit();
1460                self
1461            }
1462
1463            pub fn hit_testable(mut self, on: bool) -> Self {
1464                self.0.style = self.0.style.hit_testable(on);
1465                self
1466            }
1467
1468            pub fn align_items(mut self, align: Align) -> Self {
1469                self.0.align = align;
1470                self
1471            }
1472
1473            pub fn justify_content(mut self, justify: Justify) -> Self {
1474                self.0.justify = justify;
1475                self
1476            }
1477
1478            pub fn center(mut self) -> Self {
1479                self.0.align = Align::Center;
1480                self.0.justify = Justify::Center;
1481                self
1482            }
1483
1484            pub fn background(mut self, color: Color) -> Self {
1485                self.0.deco = self.0.deco.background(color);
1486                self
1487            }
1488
1489            pub fn border(mut self, width: f32, color: Color) -> Self {
1490                self.0.deco = self.0.deco.border(width, color);
1491                self
1492            }
1493
1494            pub fn border_left(mut self, width: f32, color: Color) -> Self {
1495                self.0.deco = self.0.deco.border_left(width, color);
1496                self
1497            }
1498
1499            pub fn border_right(mut self, width: f32, color: Color) -> Self {
1500                self.0.deco = self.0.deco.border_right(width, color);
1501                self
1502            }
1503
1504            pub fn border_top(mut self, width: f32, color: Color) -> Self {
1505                self.0.deco = self.0.deco.border_top(width, color);
1506                self
1507            }
1508
1509            pub fn border_bottom(mut self, width: f32, color: Color) -> Self {
1510                self.0.deco = self.0.deco.border_bottom(width, color);
1511                self
1512            }
1513
1514            pub fn border_x(mut self, width: f32, color: Color) -> Self {
1515                self.0.deco = self.0.deco.border_x(width, color);
1516                self
1517            }
1518
1519            pub fn border_y(mut self, width: f32, color: Color) -> Self {
1520                self.0.deco = self.0.deco.border_y(width, color);
1521                self
1522            }
1523
1524            pub fn radius(mut self, radius: f32) -> Self {
1525                self.0.deco = self.0.deco.radius(radius);
1526                self
1527            }
1528
1529            pub fn box_style(mut self, style: BoxStyle) -> Self {
1530                self.0.deco = style;
1531                self
1532            }
1533
1534            pub fn style(self, style: BoxStyle) -> Self {
1535                self.box_style(style)
1536            }
1537        }
1538    };
1539}
1540
1541pub struct Row(Flex);
1542
1543impl Row {
1544    pub fn new() -> Self {
1545        Self(Flex::new(Axis::Horizontal))
1546    }
1547
1548    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
1549        self.0.children.push(AnyView::new(child));
1550        self.0.flex.push(0.0);
1551        self
1552    }
1553
1554    pub fn child_flex<V: View + 'static>(mut self, child: V, flex: f32) -> Self {
1555        self.0.children.push(AnyView::new(child));
1556        self.0.flex.push(Flex::sanitize_flex(flex));
1557        self
1558    }
1559
1560    pub fn children(mut self, children: impl IntoChildren) -> Self {
1561        let mut children = children.into_children();
1562        self.0.flex.extend(std::iter::repeat_n(0.0, children.len()));
1563        self.0.children.append(&mut children);
1564        self
1565    }
1566}
1567
1568impl Default for Row {
1569    fn default() -> Self {
1570        Self::new()
1571    }
1572}
1573
1574impl View for Row {
1575    fn body(&self) -> impl View + 'static {
1576        Unit
1577    }
1578    fn children_override(&self) -> Option<Vec<AnyView>> {
1579        self.0.children_override()
1580    }
1581    fn layout_style(&self) -> LayoutStyle {
1582        self.0.layout_style()
1583    }
1584    fn container(&self) -> Option<ContainerStyle> {
1585        self.0.container()
1586    }
1587    fn flex_weights(&self) -> Option<&[f32]> {
1588        Some(&self.0.flex)
1589    }
1590    fn paint_self(&self, ctx: &mut PaintCtx) {
1591        ctx.paint_box(self.0.deco);
1592    }
1593}
1594
1595impl_flex_container!(Row, Axis::Horizontal);
1596
1597pub struct Column(Flex);
1598
1599impl Column {
1600    pub fn new() -> Self {
1601        Self(Flex::new(Axis::Vertical))
1602    }
1603
1604    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
1605        self.0.children.push(AnyView::new(child));
1606        self.0.flex.push(0.0);
1607        self
1608    }
1609
1610    pub fn child_flex<V: View + 'static>(mut self, child: V, flex: f32) -> Self {
1611        self.0.children.push(AnyView::new(child));
1612        self.0.flex.push(Flex::sanitize_flex(flex));
1613        self
1614    }
1615
1616    pub fn children(mut self, children: impl IntoChildren) -> Self {
1617        let mut children = children.into_children();
1618        self.0.flex.extend(std::iter::repeat_n(0.0, children.len()));
1619        self.0.children.append(&mut children);
1620        self
1621    }
1622}
1623
1624impl Default for Column {
1625    fn default() -> Self {
1626        Self::new()
1627    }
1628}
1629
1630impl View for Column {
1631    fn body(&self) -> impl View + 'static {
1632        Unit
1633    }
1634    fn children_override(&self) -> Option<Vec<AnyView>> {
1635        self.0.children_override()
1636    }
1637    fn layout_style(&self) -> LayoutStyle {
1638        self.0.layout_style()
1639    }
1640    fn container(&self) -> Option<ContainerStyle> {
1641        self.0.container()
1642    }
1643    fn flex_weights(&self) -> Option<&[f32]> {
1644        Some(&self.0.flex)
1645    }
1646    fn paint_self(&self, ctx: &mut PaintCtx) {
1647        ctx.paint_box(self.0.deco);
1648    }
1649}
1650
1651impl_flex_container!(Column, Axis::Vertical);
1652
1653#[derive(Clone)]
1654pub struct Stack {
1655    children: Vec<AnyView>,
1656    positions: Vec<StackPos>,
1657    style: LayoutStyle,
1658    deco: BoxStyle,
1659}
1660
1661impl Default for Stack {
1662    fn default() -> Self {
1663        Self {
1664            children: Vec::new(),
1665            positions: Vec::new(),
1666            style: LayoutStyle::default(),
1667            deco: BoxStyle::new(),
1668        }
1669    }
1670}
1671
1672#[derive(Clone, Copy, Debug, Default, PartialEq)]
1673pub struct StackPos {
1674    pub top: Option<f32>,
1675
1676    pub left: Option<f32>,
1677
1678    pub bottom: Option<f32>,
1679
1680    pub right: Option<f32>,
1681
1682    pub dx: f32,
1683
1684    pub dy: f32,
1685
1686    pub z: i32,
1687}
1688
1689impl StackPos {
1690    pub const fn top() -> Self {
1691        Self {
1692            top: Some(0.0),
1693            left: None,
1694            bottom: None,
1695            right: None,
1696            dx: 0.0,
1697            dy: 0.0,
1698            z: 0,
1699        }
1700    }
1701
1702    pub const fn bottom() -> Self {
1703        Self {
1704            top: None,
1705            left: None,
1706            bottom: Some(0.0),
1707            right: None,
1708            dx: 0.0,
1709            dy: 0.0,
1710            z: 0,
1711        }
1712    }
1713
1714    pub const fn left() -> Self {
1715        Self {
1716            top: None,
1717            left: Some(0.0),
1718            bottom: None,
1719            right: None,
1720            dx: 0.0,
1721            dy: 0.0,
1722            z: 0,
1723        }
1724    }
1725
1726    pub const fn right() -> Self {
1727        Self {
1728            top: None,
1729            left: None,
1730            bottom: None,
1731            right: Some(0.0),
1732            dx: 0.0,
1733            dy: 0.0,
1734            z: 0,
1735        }
1736    }
1737
1738    pub const fn top_left() -> Self {
1739        Self {
1740            top: Some(0.0),
1741            left: Some(0.0),
1742            bottom: None,
1743            right: None,
1744            dx: 0.0,
1745            dy: 0.0,
1746            z: 0,
1747        }
1748    }
1749
1750    pub const fn top_right() -> Self {
1751        Self {
1752            top: Some(0.0),
1753            left: None,
1754            bottom: None,
1755            right: Some(0.0),
1756            dx: 0.0,
1757            dy: 0.0,
1758            z: 0,
1759        }
1760    }
1761
1762    pub const fn bottom_left() -> Self {
1763        Self {
1764            top: None,
1765            left: Some(0.0),
1766            bottom: Some(0.0),
1767            right: None,
1768            dx: 0.0,
1769            dy: 0.0,
1770            z: 0,
1771        }
1772    }
1773
1774    pub const fn bottom_right() -> Self {
1775        Self {
1776            top: None,
1777            left: None,
1778            bottom: Some(0.0),
1779            right: Some(0.0),
1780            dx: 0.0,
1781            dy: 0.0,
1782            z: 0,
1783        }
1784    }
1785
1786    pub const fn fill() -> Self {
1787        Self {
1788            top: Some(0.0),
1789            left: Some(0.0),
1790            bottom: Some(0.0),
1791            right: Some(0.0),
1792            dx: 0.0,
1793            dy: 0.0,
1794            z: 0,
1795        }
1796    }
1797
1798    pub const fn offset(mut self, dx: f32, dy: f32) -> Self {
1799        self.dx = dx;
1800        self.dy = dy;
1801        self
1802    }
1803
1804    pub const fn z(mut self, z: i32) -> Self {
1805        self.z = z;
1806        self
1807    }
1808
1809    pub const fn is_pinned(self) -> bool {
1810        self.top.is_some() || self.left.is_some() || self.bottom.is_some() || self.right.is_some()
1811    }
1812}
1813
1814impl Stack {
1815    pub fn new() -> Self {
1816        Self::default()
1817    }
1818
1819    fn stack_axis(len: Length, measured: f32, start: f32, extent: f32) -> (f32, f32) {
1820        if len.is_fill() && extent.is_finite() {
1821            return (extent.max(0.0), start);
1822        }
1823
1824        let size = measured.max(0.0);
1825        let off = if extent.is_finite() {
1826            ((extent - size) * 0.5).max(0.0)
1827        } else {
1828            0.0
1829        };
1830        (size, start + off)
1831    }
1832
1833    fn pinned_axis(
1834        pin_start: Option<f32>,
1835        pin_end: Option<f32>,
1836        delta: f32,
1837        len: Length,
1838        measured: f32,
1839        start: f32,
1840        extent: f32,
1841    ) -> (f32, f32) {
1842        let delta = if delta.is_finite() { delta } else { 0.0 };
1843        if !extent.is_finite() {
1844            return (measured.max(0.0), start + delta);
1845        }
1846        let extent = extent.max(0.0);
1847        match (pin_start, pin_end) {
1848            (Some(a), Some(b)) => {
1849                let x = a.max(0.0);
1850                let w = (extent - a.max(0.0) - b.max(0.0)).max(0.0);
1851                (w, start + x + delta)
1852            }
1853            (Some(a), None) => {
1854                let size = if len.is_fill() {
1855                    (extent - a.max(0.0)).max(0.0)
1856                } else {
1857                    measured.max(0.0)
1858                };
1859                (size, start + a + delta)
1860            }
1861            (None, Some(b)) => {
1862                let size = if len.is_fill() {
1863                    (extent - b.max(0.0)).max(0.0)
1864                } else {
1865                    measured.max(0.0)
1866                };
1867                (size, start + extent - b - size + delta)
1868            }
1869            (None, None) => {
1870                let (size, off) = Self::stack_axis(len, measured, start, extent);
1871                (size, off + delta)
1872            }
1873        }
1874    }
1875
1876    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
1877        self.children.push(AnyView::new(child));
1878        self.positions.push(StackPos::default());
1879        self
1880    }
1881
1882    pub fn child_at<V: View + 'static>(mut self, child: V, pos: StackPos) -> Self {
1883        self.children.push(AnyView::new(child));
1884        self.positions.push(pos);
1885        self
1886    }
1887
1888    pub fn child_z<V: View + 'static>(mut self, child: V, z: i32) -> Self {
1889        self.children.push(AnyView::new(child));
1890        self.positions.push(StackPos::default().z(z));
1891        self
1892    }
1893
1894    pub fn fill<V: View + 'static>(mut self, child: V) -> Self {
1895        self.children.push(AnyView::new(child));
1896        self.positions.push(StackPos::fill());
1897        self
1898    }
1899
1900    pub fn overlay<V: View + 'static>(mut self, child: V, dx: f32, dy: f32) -> Self {
1901        self.children.push(AnyView::new(child));
1902        self.positions.push(StackPos::top_left().offset(dx, dy));
1903        self
1904    }
1905
1906    pub fn hud<V: View + 'static>(mut self, child: V, dy: f32) -> Self {
1907        self.children.push(AnyView::new(child));
1908        self.positions.push(StackPos::bottom().offset(0.0, dy));
1909        self
1910    }
1911
1912    fn paint_order(&self) -> Option<Vec<usize>> {
1913        if self.positions.windows(2).all(|w| w[0].z <= w[1].z) {
1914            return None;
1915        }
1916        let mut order: Vec<usize> = (0..self.children.len()).collect();
1917        order.sort_by_key(|&i| self.positions.get(i).map_or(0, |p| p.z));
1918        Some(order)
1919    }
1920
1921    fn pos_at(&self, i: usize, order: Option<&[usize]>) -> StackPos {
1922        match order {
1923            None => self.positions.get(i).copied().unwrap_or_default(),
1924            Some(order) => order
1925                .get(i)
1926                .and_then(|&k| self.positions.get(k))
1927                .copied()
1928                .unwrap_or_default(),
1929        }
1930    }
1931
1932    pub fn children(mut self, children: impl IntoChildren) -> Self {
1933        for c in children.into_children() {
1934            self.children.push(c);
1935            self.positions.push(StackPos::default());
1936        }
1937        self
1938    }
1939
1940    pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
1941        self.style = self.style.padding(padding);
1942        self
1943    }
1944
1945    pub fn pad(self, padding: impl Into<Edges>) -> Self {
1946        self.padding(padding)
1947    }
1948
1949    pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
1950        self.style = self.style.padding_xy(x, y);
1951        self
1952    }
1953
1954    pub fn padding_x(mut self, x: f32) -> Self {
1955        self.style = self.style.padding_x(x);
1956        self
1957    }
1958
1959    pub fn padding_y(mut self, y: f32) -> Self {
1960        self.style = self.style.padding_y(y);
1961        self
1962    }
1963
1964    pub fn padding_left(mut self, v: f32) -> Self {
1965        self.style = self.style.padding_left(v);
1966        self
1967    }
1968
1969    pub fn padding_right(mut self, v: f32) -> Self {
1970        self.style = self.style.padding_right(v);
1971        self
1972    }
1973
1974    pub fn padding_top(mut self, v: f32) -> Self {
1975        self.style = self.style.padding_top(v);
1976        self
1977    }
1978
1979    pub fn padding_bottom(mut self, v: f32) -> Self {
1980        self.style = self.style.padding_bottom(v);
1981        self
1982    }
1983
1984    pub fn width(mut self, width: impl Into<Length>) -> Self {
1985        self.style = self.style.width(width.into());
1986        self
1987    }
1988
1989    pub fn height(mut self, height: impl Into<Length>) -> Self {
1990        self.style = self.style.height(height.into());
1991        self
1992    }
1993
1994    pub fn size(mut self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
1995        self.style = self.style.width(width.into()).height(height.into());
1996        self
1997    }
1998
1999    pub fn square(mut self, side: impl Into<Length>) -> Self {
2000        let side = side.into();
2001        self.style = self.style.width(side).height(side);
2002        self
2003    }
2004
2005    pub fn min_width(mut self, v: f32) -> Self {
2006        self.style = self.style.min_width(v);
2007        self
2008    }
2009
2010    pub fn max_width(mut self, v: f32) -> Self {
2011        self.style = self.style.max_width(v);
2012        self
2013    }
2014
2015    pub fn min_height(mut self, v: f32) -> Self {
2016        self.style = self.style.min_height(v);
2017        self
2018    }
2019
2020    pub fn max_height(mut self, v: f32) -> Self {
2021        self.style = self.style.max_height(v);
2022        self
2023    }
2024
2025    pub fn overflow(mut self, overflow: Overflow) -> Self {
2026        self.style = self.style.overflow(overflow);
2027        self
2028    }
2029
2030    pub fn flex(mut self, weight: f32) -> Self {
2031        self.style = self.style.flex(weight);
2032        self
2033    }
2034
2035    pub fn expand(self) -> Self {
2036        self.flex(1.0)
2037    }
2038
2039    pub fn fill_width(mut self) -> Self {
2040        self.style = self.style.width(Length::Fill(1.0));
2041        self
2042    }
2043
2044    pub fn fill_height(mut self) -> Self {
2045        self.style = self.style.height(Length::Fill(1.0));
2046        self
2047    }
2048
2049    pub fn fill_size(self) -> Self {
2050        self.fill_width().fill_height()
2051    }
2052
2053    pub fn background(mut self, color: Color) -> Self {
2054        self.deco = self.deco.background(color);
2055        self
2056    }
2057
2058    pub fn border(mut self, width: f32, color: Color) -> Self {
2059        self.deco = self.deco.border(width, color);
2060        self
2061    }
2062
2063    pub fn border_left(mut self, width: f32, color: Color) -> Self {
2064        self.deco = self.deco.border_left(width, color);
2065        self
2066    }
2067
2068    pub fn border_right(mut self, width: f32, color: Color) -> Self {
2069        self.deco = self.deco.border_right(width, color);
2070        self
2071    }
2072
2073    pub fn border_top(mut self, width: f32, color: Color) -> Self {
2074        self.deco = self.deco.border_top(width, color);
2075        self
2076    }
2077
2078    pub fn border_bottom(mut self, width: f32, color: Color) -> Self {
2079        self.deco = self.deco.border_bottom(width, color);
2080        self
2081    }
2082
2083    pub fn border_x(mut self, width: f32, color: Color) -> Self {
2084        self.deco = self.deco.border_x(width, color);
2085        self
2086    }
2087
2088    pub fn border_y(mut self, width: f32, color: Color) -> Self {
2089        self.deco = self.deco.border_y(width, color);
2090        self
2091    }
2092
2093    pub fn radius(mut self, radius: f32) -> Self {
2094        self.deco = self.deco.radius(radius);
2095        self
2096    }
2097
2098    pub fn box_style(mut self, style: BoxStyle) -> Self {
2099        self.deco = style;
2100        self
2101    }
2102
2103    pub fn style(self, style: BoxStyle) -> Self {
2104        self.box_style(style)
2105    }
2106}
2107
2108impl_style_extras!(Stack);
2109
2110impl View for Stack {
2111    fn body(&self) -> impl View + 'static {
2112        Unit
2113    }
2114    fn children_override(&self) -> Option<Vec<AnyView>> {
2115        Some(match self.paint_order() {
2116            None => self.children.clone(),
2117            Some(order) => order
2118                .iter()
2119                .filter_map(|&i| self.children.get(i).cloned())
2120                .collect(),
2121        })
2122    }
2123    fn layout_style(&self) -> LayoutStyle {
2124        let mut style = self.style;
2125        let edges = self.deco.border_edges();
2126        style.padding.left += edges.left;
2127        style.padding.top += edges.top;
2128        style.padding.right += edges.right;
2129        style.padding.bottom += edges.bottom;
2130        style
2131    }
2132    fn paint_self(&self, ctx: &mut PaintCtx) {
2133        ctx.paint_box(self.deco);
2134    }
2135    fn arrange_override(
2136        &self,
2137        rt: &Runtime,
2138        el: ElementId,
2139        rect: Rect,
2140        ctx: &mut LayoutCtx,
2141    ) -> bool {
2142        let mut pad = self.style.padding;
2143        let edges = self.deco.border_edges();
2144        pad.left += edges.left;
2145        pad.top += edges.top;
2146        pad.right += edges.right;
2147        pad.bottom += edges.bottom;
2148        let content = Rect::from_xywh(
2149            rect.left() + pad.left,
2150            rect.top() + pad.top,
2151            (rect.size.width - pad.horizontal_sum()).max(0.0),
2152            (rect.size.height - pad.vertical_sum()).max(0.0),
2153        );
2154        let max = Size::new(content.size.width, content.size.height);
2155        let order = self.paint_order();
2156        let kids = rt.children(el);
2157        for (i, child) in kids.iter().enumerate() {
2158            let style = rt.child_layout_style(*child);
2159
2160            if style.is_absolute() {
2161                rt.arrange_absolute(*child, content, ctx);
2162                continue;
2163            }
2164            let pos = self.pos_at(i, order.as_deref());
2165
2166            let m = rt.measure_node(
2167                *child,
2168                Constraints {
2169                    min: Size::ZERO,
2170                    max,
2171                },
2172                ctx,
2173            );
2174            let (w0, x) = Self::pinned_axis(
2175                pos.left,
2176                pos.right,
2177                pos.dx,
2178                style.width,
2179                m.width,
2180                content.left(),
2181                content.size.width,
2182            );
2183            let (h0, y) = Self::pinned_axis(
2184                pos.top,
2185                pos.bottom,
2186                pos.dy,
2187                style.height,
2188                m.height,
2189                content.top(),
2190                content.size.height,
2191            );
2192
2193            let w = style.clamp_width(w0).max(0.0);
2194            let h = style.clamp_height(h0).max(0.0);
2195            rt.arrange_node(*child, Rect::from_xywh(x, y, w, h), ctx);
2196        }
2197        true
2198    }
2199}
2200
2201pub struct Grid {
2202    children: Vec<AnyView>,
2203    placements: Vec<GridPlacement>,
2204    style: LayoutStyle,
2205    grid: GridStyle,
2206    deco: BoxStyle,
2207}
2208
2209impl Grid {
2210    pub fn new(columns: impl IntoIterator<Item = Track>) -> Self {
2211        Self {
2212            children: Vec::new(),
2213            placements: Vec::new(),
2214            style: LayoutStyle {
2215                width: Length::Fit,
2216                height: Length::Fit,
2217                ..LayoutStyle::default()
2218            },
2219            grid: GridStyle::new(columns),
2220            deco: BoxStyle::new(),
2221        }
2222    }
2223
2224    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
2225        self.children.push(AnyView::new(child));
2226        self.placements.push(GridPlacement::AUTO);
2227        self
2228    }
2229
2230    pub fn child_at<V: View + 'static>(mut self, child: V, placement: GridPlacement) -> Self {
2231        self.children.push(AnyView::new(child));
2232        self.placements.push(placement);
2233        self
2234    }
2235
2236    pub fn child_span<V: View + 'static>(
2237        mut self,
2238        child: V,
2239        column: usize,
2240        row: usize,
2241        col_span: usize,
2242        row_span: usize,
2243    ) -> Self {
2244        self.children.push(AnyView::new(child));
2245        self.placements.push(
2246            GridPlacement::new()
2247                .at(column, row)
2248                .span(col_span, row_span),
2249        );
2250        self
2251    }
2252
2253    pub fn children(mut self, children: impl IntoChildren) -> Self {
2254        let mut children = children.into_children();
2255        self.placements
2256            .extend(std::iter::repeat_n(GridPlacement::AUTO, children.len()));
2257        self.children.append(&mut children);
2258        self
2259    }
2260
2261    pub fn rows(mut self, rows: impl IntoIterator<Item = Track>) -> Self {
2262        self.grid = self.grid.rows(rows);
2263        self
2264    }
2265
2266    pub fn gap(mut self, gap: f32) -> Self {
2267        self.grid = self.grid.gap(gap);
2268        self
2269    }
2270
2271    pub fn column_gap(mut self, gap: f32) -> Self {
2272        self.grid = self.grid.column_gap(gap);
2273        self
2274    }
2275
2276    pub fn row_gap(mut self, gap: f32) -> Self {
2277        self.grid = self.grid.row_gap(gap);
2278        self
2279    }
2280
2281    pub fn auto_flow(mut self, flow: GridFlow) -> Self {
2282        self.grid = self.grid.auto_flow(flow);
2283        self
2284    }
2285
2286    pub fn column_flow(mut self) -> Self {
2287        self.grid = self.grid.column_flow();
2288        self
2289    }
2290
2291    pub fn align_items(mut self, align: Align) -> Self {
2292        self.grid = self.grid.align_items(align);
2293        self
2294    }
2295
2296    pub fn justify_items(mut self, align: Align) -> Self {
2297        self.grid = self.grid.justify_items(align);
2298        self
2299    }
2300
2301    pub fn place_items(mut self, align: Align) -> Self {
2302        self.grid = self.grid.place_items(align);
2303        self
2304    }
2305
2306    pub fn margin(mut self, margin: impl Into<Edges>) -> Self {
2307        self.style = self.style.margin(margin);
2308        self
2309    }
2310
2311    pub fn margin_xy(mut self, x: f32, y: f32) -> Self {
2312        self.style = self.style.margin_xy(x, y);
2313        self
2314    }
2315
2316    pub fn margin_x(mut self, x: f32) -> Self {
2317        self.style = self.style.margin_x(x);
2318        self
2319    }
2320
2321    pub fn margin_y(mut self, y: f32) -> Self {
2322        self.style = self.style.margin_y(y);
2323        self
2324    }
2325
2326    pub fn margin_left(mut self, v: f32) -> Self {
2327        self.style = self.style.margin_left(v);
2328        self
2329    }
2330
2331    pub fn margin_right(mut self, v: f32) -> Self {
2332        self.style = self.style.margin_right(v);
2333        self
2334    }
2335
2336    pub fn margin_top(mut self, v: f32) -> Self {
2337        self.style = self.style.margin_top(v);
2338        self
2339    }
2340
2341    pub fn margin_bottom(mut self, v: f32) -> Self {
2342        self.style = self.style.margin_bottom(v);
2343        self
2344    }
2345
2346    pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
2347        self.style = self.style.padding(padding);
2348        self
2349    }
2350
2351    pub fn pad(self, padding: impl Into<Edges>) -> Self {
2352        self.padding(padding)
2353    }
2354
2355    pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
2356        self.style = self.style.padding_xy(x, y);
2357        self
2358    }
2359
2360    pub fn padding_x(mut self, x: f32) -> Self {
2361        self.style = self.style.padding_x(x);
2362        self
2363    }
2364
2365    pub fn padding_y(mut self, y: f32) -> Self {
2366        self.style = self.style.padding_y(y);
2367        self
2368    }
2369
2370    pub fn padding_left(mut self, v: f32) -> Self {
2371        self.style = self.style.padding_left(v);
2372        self
2373    }
2374
2375    pub fn padding_right(mut self, v: f32) -> Self {
2376        self.style = self.style.padding_right(v);
2377        self
2378    }
2379
2380    pub fn padding_top(mut self, v: f32) -> Self {
2381        self.style = self.style.padding_top(v);
2382        self
2383    }
2384
2385    pub fn padding_bottom(mut self, v: f32) -> Self {
2386        self.style = self.style.padding_bottom(v);
2387        self
2388    }
2389
2390    pub fn width(mut self, width: impl Into<Length>) -> Self {
2391        self.style = self.style.width(width.into());
2392        self
2393    }
2394
2395    pub fn height(mut self, height: impl Into<Length>) -> Self {
2396        self.style = self.style.height(height.into());
2397        self
2398    }
2399
2400    pub fn size(mut self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
2401        self.style = self.style.width(width.into()).height(height.into());
2402        self
2403    }
2404
2405    pub fn square(mut self, side: impl Into<Length>) -> Self {
2406        let side = side.into();
2407        self.style = self.style.width(side).height(side);
2408        self
2409    }
2410
2411    pub fn min_width(mut self, v: f32) -> Self {
2412        self.style = self.style.min_width(v);
2413        self
2414    }
2415
2416    pub fn max_width(mut self, v: f32) -> Self {
2417        self.style = self.style.max_width(v);
2418        self
2419    }
2420
2421    pub fn min_height(mut self, v: f32) -> Self {
2422        self.style = self.style.min_height(v);
2423        self
2424    }
2425
2426    pub fn max_height(mut self, v: f32) -> Self {
2427        self.style = self.style.max_height(v);
2428        self
2429    }
2430
2431    pub fn overflow(mut self, overflow: Overflow) -> Self {
2432        self.style = self.style.overflow(overflow);
2433        self
2434    }
2435
2436    pub fn flex(mut self, weight: f32) -> Self {
2437        self.style = self.style.flex(weight);
2438        self
2439    }
2440
2441    pub fn flex_shrink(mut self, shrink: f32) -> Self {
2442        self.style = self.style.flex_shrink(shrink);
2443        self
2444    }
2445
2446    pub fn flex_basis(mut self, basis: Option<Length>) -> Self {
2447        self.style = self.style.flex_basis(basis);
2448        self
2449    }
2450
2451    pub fn align_self(mut self, align: Option<Align>) -> Self {
2452        self.style = self.style.align_self(align);
2453        self
2454    }
2455
2456    pub fn aspect_ratio(mut self, ratio: Option<f32>) -> Self {
2457        self.style = self.style.aspect_ratio(ratio);
2458        self
2459    }
2460
2461    pub fn aspect(mut self, ratio: f32) -> Self {
2462        self.style = self.style.aspect(ratio);
2463        self
2464    }
2465
2466    pub fn position(mut self, position: Position) -> Self {
2467        self.style = self.style.position(position);
2468        self
2469    }
2470
2471    pub fn absolute(mut self) -> Self {
2472        self.style = self.style.absolute();
2473        self
2474    }
2475
2476    pub fn absolute_at(mut self, left: f32, top: f32) -> Self {
2477        self.style = self.style.absolute_at(left, top);
2478        self
2479    }
2480
2481    pub fn absolute_inset(mut self, inset: Inset) -> Self {
2482        self.style = self.style.absolute_inset(inset);
2483        self
2484    }
2485
2486    pub fn expand(self) -> Self {
2487        self.flex(1.0)
2488    }
2489
2490    pub fn fill_width(mut self) -> Self {
2491        self.style = self.style.width(Length::Fill(1.0));
2492        self
2493    }
2494
2495    pub fn fill_height(mut self) -> Self {
2496        self.style = self.style.height(Length::Fill(1.0));
2497        self
2498    }
2499
2500    pub fn fill_size(self) -> Self {
2501        self.fill_width().fill_height()
2502    }
2503
2504    pub fn background(mut self, color: Color) -> Self {
2505        self.deco = self.deco.background(color);
2506        self
2507    }
2508
2509    pub fn border(mut self, width: f32, color: Color) -> Self {
2510        self.deco = self.deco.border(width, color);
2511        self
2512    }
2513
2514    pub fn border_left(mut self, width: f32, color: Color) -> Self {
2515        self.deco = self.deco.border_left(width, color);
2516        self
2517    }
2518
2519    pub fn border_right(mut self, width: f32, color: Color) -> Self {
2520        self.deco = self.deco.border_right(width, color);
2521        self
2522    }
2523
2524    pub fn border_top(mut self, width: f32, color: Color) -> Self {
2525        self.deco = self.deco.border_top(width, color);
2526        self
2527    }
2528
2529    pub fn border_bottom(mut self, width: f32, color: Color) -> Self {
2530        self.deco = self.deco.border_bottom(width, color);
2531        self
2532    }
2533
2534    pub fn border_x(mut self, width: f32, color: Color) -> Self {
2535        self.deco = self.deco.border_x(width, color);
2536        self
2537    }
2538
2539    pub fn border_y(mut self, width: f32, color: Color) -> Self {
2540        self.deco = self.deco.border_y(width, color);
2541        self
2542    }
2543
2544    pub fn radius(mut self, radius: f32) -> Self {
2545        self.deco = self.deco.radius(radius);
2546        self
2547    }
2548
2549    pub fn box_style(mut self, style: BoxStyle) -> Self {
2550        self.deco = style;
2551        self
2552    }
2553
2554    pub fn style(self, style: BoxStyle) -> Self {
2555        self.box_style(style)
2556    }
2557}
2558
2559impl View for Grid {
2560    fn body(&self) -> impl View + 'static {
2561        Unit
2562    }
2563    fn children_override(&self) -> Option<Vec<AnyView>> {
2564        Some(self.children.clone())
2565    }
2566    fn layout_style(&self) -> LayoutStyle {
2567        self.style
2568    }
2569    fn grid(&self) -> Option<GridStyle> {
2570        Some(self.grid.clone())
2571    }
2572    fn grid_placements(&self) -> Option<Vec<GridPlacement>> {
2573        Some(self.placements.clone())
2574    }
2575    fn paint_self(&self, ctx: &mut PaintCtx) {
2576        ctx.paint_box(self.deco);
2577    }
2578}
2579
2580pub struct Wrap {
2581    children: Vec<AnyView>,
2582    style: LayoutStyle,
2583    wrap: WrapStyle,
2584    deco: BoxStyle,
2585}
2586
2587impl Wrap {
2588    pub fn new() -> Self {
2589        Self {
2590            children: Vec::new(),
2591            style: LayoutStyle {
2592                width: Length::Fill(1.0),
2593                height: Length::Fit,
2594                ..LayoutStyle::default()
2595            },
2596            wrap: WrapStyle::new(Axis::Horizontal),
2597            deco: BoxStyle::new(),
2598        }
2599    }
2600
2601    pub fn vertical() -> Self {
2602        Self {
2603            wrap: WrapStyle::new(Axis::Vertical),
2604            ..Self::new()
2605        }
2606    }
2607
2608    pub fn axis(mut self, axis: Axis) -> Self {
2609        self.wrap = self.wrap.axis(axis);
2610        self
2611    }
2612
2613    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
2614        self.children.push(AnyView::new(child));
2615        self
2616    }
2617
2618    pub fn children(mut self, children: impl IntoChildren) -> Self {
2619        self.children.extend(children.into_children());
2620        self
2621    }
2622
2623    pub fn gap(mut self, gap: f32) -> Self {
2624        self.wrap = self.wrap.gap(gap);
2625        self
2626    }
2627
2628    pub fn column_gap(mut self, gap: f32) -> Self {
2629        self.wrap = self.wrap.column_gap(gap);
2630        self
2631    }
2632
2633    pub fn row_gap(mut self, gap: f32) -> Self {
2634        self.wrap = self.wrap.row_gap(gap);
2635        self
2636    }
2637
2638    pub fn align_items(mut self, align: Align) -> Self {
2639        self.wrap = self.wrap.align(align);
2640        self
2641    }
2642
2643    pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
2644        self.style = self.style.padding(padding);
2645        self
2646    }
2647
2648    pub fn pad(self, padding: impl Into<Edges>) -> Self {
2649        self.padding(padding)
2650    }
2651
2652    pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
2653        self.style = self.style.padding_xy(x, y);
2654        self
2655    }
2656
2657    pub fn padding_x(mut self, x: f32) -> Self {
2658        self.style = self.style.padding_x(x);
2659        self
2660    }
2661
2662    pub fn padding_y(mut self, y: f32) -> Self {
2663        self.style = self.style.padding_y(y);
2664        self
2665    }
2666
2667    pub fn padding_left(mut self, v: f32) -> Self {
2668        self.style = self.style.padding_left(v);
2669        self
2670    }
2671
2672    pub fn padding_right(mut self, v: f32) -> Self {
2673        self.style = self.style.padding_right(v);
2674        self
2675    }
2676
2677    pub fn padding_top(mut self, v: f32) -> Self {
2678        self.style = self.style.padding_top(v);
2679        self
2680    }
2681
2682    pub fn padding_bottom(mut self, v: f32) -> Self {
2683        self.style = self.style.padding_bottom(v);
2684        self
2685    }
2686
2687    pub fn width(mut self, width: impl Into<Length>) -> Self {
2688        self.style = self.style.width(width.into());
2689        self
2690    }
2691
2692    pub fn height(mut self, height: impl Into<Length>) -> Self {
2693        self.style = self.style.height(height.into());
2694        self
2695    }
2696
2697    pub fn size(mut self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
2698        self.style = self.style.width(width.into()).height(height.into());
2699        self
2700    }
2701
2702    pub fn square(mut self, side: impl Into<Length>) -> Self {
2703        let side = side.into();
2704        self.style = self.style.width(side).height(side);
2705        self
2706    }
2707
2708    pub fn min_width(mut self, v: f32) -> Self {
2709        self.style = self.style.min_width(v);
2710        self
2711    }
2712
2713    pub fn max_width(mut self, v: f32) -> Self {
2714        self.style = self.style.max_width(v);
2715        self
2716    }
2717
2718    pub fn min_height(mut self, v: f32) -> Self {
2719        self.style = self.style.min_height(v);
2720        self
2721    }
2722
2723    pub fn max_height(mut self, v: f32) -> Self {
2724        self.style = self.style.max_height(v);
2725        self
2726    }
2727
2728    pub fn overflow(mut self, overflow: Overflow) -> Self {
2729        self.style = self.style.overflow(overflow);
2730        self
2731    }
2732
2733    pub fn flex(mut self, weight: f32) -> Self {
2734        self.style = self.style.flex(weight);
2735        self
2736    }
2737
2738    pub fn expand(self) -> Self {
2739        self.flex(1.0)
2740    }
2741
2742    pub fn fill_width(mut self) -> Self {
2743        self.style = self.style.width(Length::Fill(1.0));
2744        self
2745    }
2746
2747    pub fn fill_height(mut self) -> Self {
2748        self.style = self.style.height(Length::Fill(1.0));
2749        self
2750    }
2751
2752    pub fn fill_size(self) -> Self {
2753        self.fill_width().fill_height()
2754    }
2755
2756    pub fn background(mut self, color: Color) -> Self {
2757        self.deco = self.deco.background(color);
2758        self
2759    }
2760
2761    pub fn border(mut self, width: f32, color: Color) -> Self {
2762        self.deco = self.deco.border(width, color);
2763        self
2764    }
2765
2766    pub fn border_left(mut self, width: f32, color: Color) -> Self {
2767        self.deco = self.deco.border_left(width, color);
2768        self
2769    }
2770
2771    pub fn border_right(mut self, width: f32, color: Color) -> Self {
2772        self.deco = self.deco.border_right(width, color);
2773        self
2774    }
2775
2776    pub fn border_top(mut self, width: f32, color: Color) -> Self {
2777        self.deco = self.deco.border_top(width, color);
2778        self
2779    }
2780
2781    pub fn border_bottom(mut self, width: f32, color: Color) -> Self {
2782        self.deco = self.deco.border_bottom(width, color);
2783        self
2784    }
2785
2786    pub fn border_x(mut self, width: f32, color: Color) -> Self {
2787        self.deco = self.deco.border_x(width, color);
2788        self
2789    }
2790
2791    pub fn border_y(mut self, width: f32, color: Color) -> Self {
2792        self.deco = self.deco.border_y(width, color);
2793        self
2794    }
2795
2796    pub fn radius(mut self, radius: f32) -> Self {
2797        self.deco = self.deco.radius(radius);
2798        self
2799    }
2800
2801    pub fn box_style(mut self, style: BoxStyle) -> Self {
2802        self.deco = style;
2803        self
2804    }
2805
2806    pub fn style(self, style: BoxStyle) -> Self {
2807        self.box_style(style)
2808    }
2809}
2810
2811impl Default for Wrap {
2812    fn default() -> Self {
2813        Self::new()
2814    }
2815}
2816
2817impl_style_extras!(Wrap);
2818
2819impl View for Wrap {
2820    fn body(&self) -> impl View + 'static {
2821        Unit
2822    }
2823    fn children_override(&self) -> Option<Vec<AnyView>> {
2824        Some(self.children.clone())
2825    }
2826    fn layout_style(&self) -> LayoutStyle {
2827        self.style
2828    }
2829    fn wrap(&self) -> Option<WrapStyle> {
2830        Some(self.wrap)
2831    }
2832    fn paint_self(&self, ctx: &mut PaintCtx) {
2833        ctx.paint_box(self.deco);
2834    }
2835}
2836
2837#[derive(Clone, Copy, Debug)]
2838pub struct Panel {
2839    color: Option<Color>,
2840    radius: f32,
2841    style: LayoutStyle,
2842    borders: BoxStyle,
2843}
2844
2845impl Default for Panel {
2846    fn default() -> Self {
2847        Self {
2848            color: None,
2849            radius: 0.0,
2850            style: LayoutStyle::default(),
2851            borders: BoxStyle::new(),
2852        }
2853    }
2854}
2855
2856impl Panel {
2857    pub fn new() -> Self {
2858        Self::default()
2859    }
2860
2861    pub fn background(mut self, color: Color) -> Self {
2862        self.color = Some(color);
2863        self
2864    }
2865
2866    pub fn radius(mut self, radius: f32) -> Self {
2867        self.radius = radius.max(0.0);
2868        self
2869    }
2870
2871    pub fn border(mut self, width: f32, color: Color) -> Self {
2872        self.borders = self.borders.border(width, color);
2873        self
2874    }
2875
2876    pub fn border_left(mut self, width: f32, color: Color) -> Self {
2877        self.borders = self.borders.border_left(width, color);
2878        self
2879    }
2880
2881    pub fn border_right(mut self, width: f32, color: Color) -> Self {
2882        self.borders = self.borders.border_right(width, color);
2883        self
2884    }
2885
2886    pub fn border_top(mut self, width: f32, color: Color) -> Self {
2887        self.borders = self.borders.border_top(width, color);
2888        self
2889    }
2890
2891    pub fn border_bottom(mut self, width: f32, color: Color) -> Self {
2892        self.borders = self.borders.border_bottom(width, color);
2893        self
2894    }
2895
2896    pub fn border_x(mut self, width: f32, color: Color) -> Self {
2897        self.borders = self.borders.border_x(width, color);
2898        self
2899    }
2900
2901    pub fn border_y(mut self, width: f32, color: Color) -> Self {
2902        self.borders = self.borders.border_y(width, color);
2903        self
2904    }
2905
2906    pub fn box_style(mut self, style: BoxStyle) -> Self {
2907        if style.background.a > 0.0 {
2908            self.color = Some(style.background);
2909        } else {
2910            self.color = None;
2911        }
2912        self.radius = style.radius;
2913        let mut borders = style;
2914        borders.background = Color::TRANSPARENT;
2915        borders.radius = 0.0;
2916        self.borders = borders;
2917        self
2918    }
2919
2920    pub fn style(self, style: BoxStyle) -> Self {
2921        self.box_style(style)
2922    }
2923
2924    pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
2925        self.style = self.style.padding(padding);
2926        self
2927    }
2928
2929    pub fn pad(self, padding: impl Into<Edges>) -> Self {
2930        self.padding(padding)
2931    }
2932
2933    pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
2934        self.style = self.style.padding_xy(x, y);
2935        self
2936    }
2937
2938    pub fn padding_x(mut self, x: f32) -> Self {
2939        self.style = self.style.padding_x(x);
2940        self
2941    }
2942
2943    pub fn padding_y(mut self, y: f32) -> Self {
2944        self.style = self.style.padding_y(y);
2945        self
2946    }
2947
2948    pub fn padding_left(mut self, v: f32) -> Self {
2949        self.style = self.style.padding_left(v);
2950        self
2951    }
2952
2953    pub fn padding_right(mut self, v: f32) -> Self {
2954        self.style = self.style.padding_right(v);
2955        self
2956    }
2957
2958    pub fn padding_top(mut self, v: f32) -> Self {
2959        self.style = self.style.padding_top(v);
2960        self
2961    }
2962
2963    pub fn padding_bottom(mut self, v: f32) -> Self {
2964        self.style = self.style.padding_bottom(v);
2965        self
2966    }
2967
2968    pub fn width(mut self, width: impl Into<Length>) -> Self {
2969        self.style = self.style.width(width.into());
2970        self
2971    }
2972
2973    pub fn height(mut self, height: impl Into<Length>) -> Self {
2974        self.style = self.style.height(height.into());
2975        self
2976    }
2977
2978    pub fn size(mut self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
2979        self.style = self.style.width(width.into()).height(height.into());
2980        self
2981    }
2982
2983    pub fn square(mut self, side: impl Into<Length>) -> Self {
2984        let side = side.into();
2985        self.style = self.style.width(side).height(side);
2986        self
2987    }
2988
2989    pub fn min_width(mut self, v: f32) -> Self {
2990        self.style = self.style.min_width(v);
2991        self
2992    }
2993
2994    pub fn max_width(mut self, v: f32) -> Self {
2995        self.style = self.style.max_width(v);
2996        self
2997    }
2998
2999    pub fn min_height(mut self, v: f32) -> Self {
3000        self.style = self.style.min_height(v);
3001        self
3002    }
3003
3004    pub fn max_height(mut self, v: f32) -> Self {
3005        self.style = self.style.max_height(v);
3006        self
3007    }
3008
3009    pub fn overflow(mut self, overflow: Overflow) -> Self {
3010        self.style = self.style.overflow(overflow);
3011        self
3012    }
3013
3014    pub fn flex(mut self, weight: f32) -> Self {
3015        self.style = self.style.flex(weight);
3016        self
3017    }
3018
3019    pub fn expand(self) -> Self {
3020        self.flex(1.0)
3021    }
3022
3023    pub fn fill_width(mut self) -> Self {
3024        self.style = self.style.width(Length::Fill(1.0));
3025        self
3026    }
3027
3028    pub fn fill_height(mut self) -> Self {
3029        self.style = self.style.height(Length::Fill(1.0));
3030        self
3031    }
3032
3033    pub fn fill_size(self) -> Self {
3034        self.fill_width().fill_height()
3035    }
3036}
3037
3038impl_style_extras!(Panel);
3039
3040impl View for Panel {
3041    fn body(&self) -> impl View + 'static {
3042        Unit
3043    }
3044    fn is_leaf(&self) -> bool {
3045        true
3046    }
3047    fn layout_style(&self) -> LayoutStyle {
3048        self.style
3049    }
3050    fn paint_self(&self, ctx: &mut PaintCtx) {
3051        let theme = ctx.theme();
3052        let color = self.color.unwrap_or(theme.surface);
3053        let radius = if self.radius > 0.0 {
3054            self.radius
3055        } else {
3056            theme.radius
3057        };
3058        let p = self.style.padding;
3059        let rect = ctx.rect;
3060        let quad = Rect::from_xywh(
3061            rect.left() + p.left,
3062            rect.top() + p.top,
3063            (rect.size.width - p.horizontal_sum()).max(0.0),
3064            (rect.size.height - p.vertical_sum()).max(0.0),
3065        );
3066
3067        let mut deco = self.borders;
3068        deco.background = color;
3069        deco.radius = radius;
3070        ctx.paint_box_in(deco, quad);
3071    }
3072}
3073
3074#[derive(Clone, Copy, Debug)]
3075pub struct Spacer {
3076    style: LayoutStyle,
3077}
3078
3079impl Spacer {
3080    pub fn flex(weight: f32) -> Self {
3081        let w = if weight.is_finite() {
3082            weight.max(0.0)
3083        } else {
3084            0.0
3085        };
3086        Self {
3087            style: LayoutStyle {
3088                width: Length::Fill(w),
3089                height: Length::Fit,
3090                ..LayoutStyle::default()
3091            },
3092        }
3093    }
3094
3095    pub fn vertical(weight: f32) -> Self {
3096        let w = if weight.is_finite() {
3097            weight.max(0.0)
3098        } else {
3099            0.0
3100        };
3101        Self {
3102            style: LayoutStyle {
3103                width: Length::Fit,
3104                height: Length::Fill(w),
3105                ..LayoutStyle::default()
3106            },
3107        }
3108    }
3109
3110    pub fn fixed(size: f32) -> Self {
3111        let s = if size.is_finite() { size.max(0.0) } else { 0.0 };
3112        Self {
3113            style: LayoutStyle {
3114                width: Length::Px(s),
3115                height: Length::Px(s),
3116                ..LayoutStyle::default()
3117            },
3118        }
3119    }
3120
3121    pub fn fixed_width(w: f32) -> Self {
3122        let w = if w.is_finite() { w.max(0.0) } else { 0.0 };
3123        Self {
3124            style: LayoutStyle {
3125                width: Length::Px(w),
3126                height: Length::Px(0.0),
3127                ..LayoutStyle::default()
3128            },
3129        }
3130    }
3131
3132    pub fn fixed_height(h: f32) -> Self {
3133        let h = if h.is_finite() { h.max(0.0) } else { 0.0 };
3134        Self {
3135            style: LayoutStyle {
3136                width: Length::Px(0.0),
3137                height: Length::Px(h),
3138                ..LayoutStyle::default()
3139            },
3140        }
3141    }
3142
3143    pub fn width(mut self, width: impl Into<Length>) -> Self {
3144        self.style = self.style.width(width.into());
3145        self
3146    }
3147
3148    pub fn height(mut self, height: impl Into<Length>) -> Self {
3149        self.style = self.style.height(height.into());
3150        self
3151    }
3152
3153    pub fn min_width(mut self, v: f32) -> Self {
3154        self.style = self.style.min_width(v);
3155        self
3156    }
3157
3158    pub fn max_width(mut self, v: f32) -> Self {
3159        self.style = self.style.max_width(v);
3160        self
3161    }
3162
3163    pub fn min_height(mut self, v: f32) -> Self {
3164        self.style = self.style.min_height(v);
3165        self
3166    }
3167
3168    pub fn max_height(mut self, v: f32) -> Self {
3169        self.style = self.style.max_height(v);
3170        self
3171    }
3172
3173    pub fn expand(mut self) -> Self {
3174        self.style = self.style.flex(1.0);
3175        self
3176    }
3177}
3178
3179impl Default for Spacer {
3180    fn default() -> Self {
3181        Self::flex(1.0)
3182    }
3183}
3184
3185impl_style_extras!(Spacer);
3186
3187impl_child_helpers!(Fragment);
3188impl_child_helpers!(FocusScope);
3189impl_child_helpers!(Row);
3190impl_child_helpers!(Column);
3191impl_child_helpers!(Stack);
3192impl_child_helpers!(Grid);
3193impl_child_helpers!(Wrap);
3194
3195impl View for Spacer {
3196    fn body(&self) -> impl View + 'static {
3197        Unit
3198    }
3199    fn is_leaf(&self) -> bool {
3200        true
3201    }
3202    fn layout_style(&self) -> LayoutStyle {
3203        self.style
3204    }
3205}
3206
3207fn aspect_contain(content: Size, ratio: f32) -> (Size, f32, f32) {
3208    let (w, h) = (content.width.max(0.0), content.height.max(0.0));
3209    if !(ratio.is_finite() && ratio > 0.0) || w <= 0.0 || h <= 0.0 {
3210        return (Size::new(w, h), 0.0, 0.0);
3211    }
3212    if !w.is_finite() || !h.is_finite() {
3213        return (Size::new(w, h), 0.0, 0.0);
3214    }
3215    let box_w = (h * ratio).min(w);
3216    let box_h = box_w / ratio;
3217    (
3218        Size::new(box_w, box_h),
3219        (w - box_w) * 0.5,
3220        (h - box_h) * 0.5,
3221    )
3222}
3223
3224fn sanitize_aspect_ratio(ratio: f32) -> f32 {
3225    if ratio.is_finite() && ratio > 0.0 {
3226        ratio
3227    } else {
3228        1.0
3229    }
3230}
3231
3232#[derive(Clone)]
3233pub struct AspectRatio {
3234    ratio: f32,
3235    child: Option<AnyView>,
3236    style: LayoutStyle,
3237    deco: BoxStyle,
3238    clip: bool,
3239}
3240
3241impl AspectRatio {
3242    pub fn new(ratio: f32) -> Self {
3243        Self {
3244            ratio: sanitize_aspect_ratio(ratio),
3245            child: None,
3246            style: LayoutStyle {
3247                width: Length::Fit,
3248                height: Length::Fit,
3249                ..LayoutStyle::default()
3250            },
3251            deco: BoxStyle::new(),
3252            clip: false,
3253        }
3254    }
3255
3256    pub fn ratio(mut self, ratio: f32) -> Self {
3257        self.ratio = sanitize_aspect_ratio(ratio);
3258        self
3259    }
3260
3261    pub fn aspect(self, ratio: f32) -> Self {
3262        self.ratio(ratio)
3263    }
3264
3265    pub fn child<V: View + 'static>(mut self, child: V) -> Self {
3266        debug_assert!(
3267            self.child.is_none(),
3268            "AspectRatio takes a single child - a second `.child()` would overwrite the first. Use Row/Column for many."
3269        );
3270        self.child = Some(AnyView::new(child));
3271        self
3272    }
3273
3274    pub fn child_if<V: View + 'static>(mut self, cond: bool, make: impl FnOnce() -> V) -> Self {
3275        if cond {
3276            self.child = Some(AnyView::new(make()));
3277        }
3278        self
3279    }
3280
3281    pub fn child_opt<V: View + 'static>(mut self, child: Option<V>) -> Self {
3282        if let Some(v) = child {
3283            self.child = Some(AnyView::new(v));
3284        }
3285        self
3286    }
3287
3288    pub fn background(mut self, color: Color) -> Self {
3289        self.deco = self.deco.background(color);
3290        self
3291    }
3292
3293    pub fn border(mut self, width: f32, color: Color) -> Self {
3294        self.deco = self.deco.border(width, color);
3295        self
3296    }
3297
3298    pub fn border_left(mut self, width: f32, color: Color) -> Self {
3299        self.deco = self.deco.border_left(width, color);
3300        self
3301    }
3302
3303    pub fn border_right(mut self, width: f32, color: Color) -> Self {
3304        self.deco = self.deco.border_right(width, color);
3305        self
3306    }
3307
3308    pub fn border_top(mut self, width: f32, color: Color) -> Self {
3309        self.deco = self.deco.border_top(width, color);
3310        self
3311    }
3312
3313    pub fn border_bottom(mut self, width: f32, color: Color) -> Self {
3314        self.deco = self.deco.border_bottom(width, color);
3315        self
3316    }
3317
3318    pub fn border_x(mut self, width: f32, color: Color) -> Self {
3319        self.deco = self.deco.border_x(width, color);
3320        self
3321    }
3322
3323    pub fn border_y(mut self, width: f32, color: Color) -> Self {
3324        self.deco = self.deco.border_y(width, color);
3325        self
3326    }
3327
3328    pub fn box_style(mut self, style: BoxStyle) -> Self {
3329        self.deco = style;
3330        self
3331    }
3332
3333    pub fn style(self, style: BoxStyle) -> Self {
3334        self.box_style(style)
3335    }
3336
3337    pub fn radius(mut self, radius: f32) -> Self {
3338        self.deco = self.deco.radius(radius);
3339        self
3340    }
3341
3342    pub fn padding(mut self, padding: impl Into<Edges>) -> Self {
3343        self.style = self.style.padding(padding);
3344        self
3345    }
3346
3347    pub fn pad(self, padding: impl Into<Edges>) -> Self {
3348        self.padding(padding)
3349    }
3350
3351    pub fn padding_xy(mut self, x: f32, y: f32) -> Self {
3352        self.style = self.style.padding_xy(x, y);
3353        self
3354    }
3355
3356    pub fn padding_x(mut self, x: f32) -> Self {
3357        self.style = self.style.padding_x(x);
3358        self
3359    }
3360
3361    pub fn padding_y(mut self, y: f32) -> Self {
3362        self.style = self.style.padding_y(y);
3363        self
3364    }
3365
3366    pub fn padding_left(mut self, v: f32) -> Self {
3367        self.style = self.style.padding_left(v);
3368        self
3369    }
3370
3371    pub fn padding_right(mut self, v: f32) -> Self {
3372        self.style = self.style.padding_right(v);
3373        self
3374    }
3375
3376    pub fn padding_top(mut self, v: f32) -> Self {
3377        self.style = self.style.padding_top(v);
3378        self
3379    }
3380
3381    pub fn padding_bottom(mut self, v: f32) -> Self {
3382        self.style = self.style.padding_bottom(v);
3383        self
3384    }
3385
3386    pub fn width(mut self, width: impl Into<Length>) -> Self {
3387        self.style = self.style.width(width.into());
3388        self
3389    }
3390
3391    pub fn height(mut self, height: impl Into<Length>) -> Self {
3392        self.style = self.style.height(height.into());
3393        self
3394    }
3395
3396    pub fn size(mut self, width: impl Into<Length>, height: impl Into<Length>) -> Self {
3397        self.style = self.style.width(width.into()).height(height.into());
3398        self
3399    }
3400
3401    pub fn square(mut self, side: impl Into<Length>) -> Self {
3402        let side = side.into();
3403        self.style = self.style.width(side).height(side);
3404        self
3405    }
3406
3407    pub fn min_width(mut self, v: f32) -> Self {
3408        self.style = self.style.min_width(v);
3409        self
3410    }
3411
3412    pub fn max_width(mut self, v: f32) -> Self {
3413        self.style = self.style.max_width(v);
3414        self
3415    }
3416
3417    pub fn min_height(mut self, v: f32) -> Self {
3418        self.style = self.style.min_height(v);
3419        self
3420    }
3421
3422    pub fn max_height(mut self, v: f32) -> Self {
3423        self.style = self.style.max_height(v);
3424        self
3425    }
3426
3427    pub fn overflow(mut self, overflow: Overflow) -> Self {
3428        self.style = self.style.overflow(overflow);
3429        self
3430    }
3431
3432    pub fn margin(mut self, margin: impl Into<Edges>) -> Self {
3433        self.style = self.style.margin(margin);
3434        self
3435    }
3436
3437    pub fn margin_xy(mut self, x: f32, y: f32) -> Self {
3438        self.style = self.style.margin_xy(x, y);
3439        self
3440    }
3441
3442    pub fn margin_x(mut self, x: f32) -> Self {
3443        self.style = self.style.margin_x(x);
3444        self
3445    }
3446
3447    pub fn margin_y(mut self, y: f32) -> Self {
3448        self.style = self.style.margin_y(y);
3449        self
3450    }
3451
3452    pub fn margin_left(mut self, v: f32) -> Self {
3453        self.style = self.style.margin_left(v);
3454        self
3455    }
3456
3457    pub fn margin_right(mut self, v: f32) -> Self {
3458        self.style = self.style.margin_right(v);
3459        self
3460    }
3461
3462    pub fn margin_top(mut self, v: f32) -> Self {
3463        self.style = self.style.margin_top(v);
3464        self
3465    }
3466
3467    pub fn margin_bottom(mut self, v: f32) -> Self {
3468        self.style = self.style.margin_bottom(v);
3469        self
3470    }
3471
3472    pub fn flex(mut self, weight: f32) -> Self {
3473        self.style = self.style.flex(weight);
3474        self
3475    }
3476
3477    pub fn flex_shrink(mut self, shrink: f32) -> Self {
3478        self.style = self.style.flex_shrink(shrink);
3479        self
3480    }
3481
3482    pub fn flex_basis(mut self, basis: Option<Length>) -> Self {
3483        self.style = self.style.flex_basis(basis);
3484        self
3485    }
3486
3487    pub fn align_self(mut self, align: Option<Align>) -> Self {
3488        self.style = self.style.align_self(align);
3489        self
3490    }
3491
3492    pub fn position(mut self, position: Position) -> Self {
3493        self.style = self.style.position(position);
3494        self
3495    }
3496
3497    pub fn absolute(mut self) -> Self {
3498        self.style = self.style.absolute();
3499        self
3500    }
3501
3502    pub fn absolute_at(mut self, left: f32, top: f32) -> Self {
3503        self.style = self.style.absolute_at(left, top);
3504        self
3505    }
3506
3507    pub fn absolute_inset(mut self, inset: Inset) -> Self {
3508        self.style = self.style.absolute_inset(inset);
3509        self
3510    }
3511
3512    pub fn expand(self) -> Self {
3513        self.flex(1.0)
3514    }
3515
3516    pub fn fill_width(mut self) -> Self {
3517        self.style = self.style.width(Length::Fill(1.0));
3518        self
3519    }
3520
3521    pub fn fill_height(mut self) -> Self {
3522        self.style = self.style.height(Length::Fill(1.0));
3523        self
3524    }
3525
3526    pub fn fill_size(self) -> Self {
3527        self.fill_width().fill_height()
3528    }
3529
3530    pub fn fit(mut self) -> Self {
3531        self.style = self.style.fit();
3532        self
3533    }
3534
3535    pub fn hit_testable(mut self, on: bool) -> Self {
3536        self.style = self.style.hit_testable(on);
3537        self
3538    }
3539
3540    pub fn clip(mut self, clip: bool) -> Self {
3541        self.clip = clip;
3542        self
3543    }
3544
3545    pub fn clip_children(self) -> Self {
3546        self.clip(true)
3547    }
3548}
3549
3550impl View for AspectRatio {
3551    fn body(&self) -> impl View + 'static {
3552        Unit
3553    }
3554    fn children_override(&self) -> Option<Vec<AnyView>> {
3555        self.child.clone().map(|c| vec![c])
3556    }
3557    fn clip_self(&self) -> bool {
3558        self.clip
3559    }
3560    fn clip_radius(&self) -> f32 {
3561        if self.clip { self.deco.radius } else { 0.0 }
3562    }
3563    fn layout_style(&self) -> LayoutStyle {
3564        let mut style = self.style;
3565        style.aspect_ratio = Some(self.ratio);
3566        style
3567    }
3568    fn arrange_override(
3569        &self,
3570        rt: &Runtime,
3571        el: ElementId,
3572        rect: Rect,
3573        ctx: &mut LayoutCtx,
3574    ) -> bool {
3575        let children = rt.children(el);
3576        let Some(&child) = children.first() else {
3577            return true;
3578        };
3579
3580        if matches!(self.style.width, Length::Fit) || matches!(self.style.height, Length::Fit) {
3581            return false;
3582        }
3583        let pad = self.style.padding;
3584        let content = Rect::from_xywh(
3585            rect.left() + pad.left,
3586            rect.top() + pad.top,
3587            (rect.size.width - pad.horizontal_sum()).max(0.0),
3588            (rect.size.height - pad.vertical_sum()).max(0.0),
3589        );
3590        if !content.size.width.is_finite() || !content.size.height.is_finite() {
3591            return false;
3592        }
3593        let (boxed, dx, dy) = aspect_contain(content.size, self.ratio);
3594        let cs = rt.child_layout_style(child);
3595        rt.arrange_node(
3596            child,
3597            Rect::from_xywh(
3598                content.left() + dx + cs.margin.left,
3599                content.top() + dy + cs.margin.top,
3600                (boxed.width - cs.margin.horizontal_sum()).max(0.0),
3601                (boxed.height - cs.margin.vertical_sum()).max(0.0),
3602            ),
3603            ctx,
3604        );
3605        true
3606    }
3607    fn paint_self(&self, ctx: &mut PaintCtx) {
3608        ctx.paint_box(self.deco);
3609    }
3610}
3611
3612impl crate::styleable::Styleable for AspectRatio {
3613    fn fill_width(mut self) -> Self {
3614        self.style = self.style.width(Length::Fill(1.0));
3615        self
3616    }
3617    fn fill_height(mut self) -> Self {
3618        self.style = self.style.height(Length::Fill(1.0));
3619        self
3620    }
3621    fn fit(mut self) -> Self {
3622        self.style = self.style.fit();
3623        self
3624    }
3625    fn hit_testable(mut self, on: bool) -> Self {
3626        self.style = self.style.hit_testable(on);
3627        self
3628    }
3629    fn padding(mut self, padding: impl Into<Edges>) -> Self {
3630        self.style = self.style.padding(padding);
3631        self
3632    }
3633}
3634
3635impl crate::styleable::Decoratable for AspectRatio {
3636    fn background(mut self, color: Color) -> Self {
3637        self.deco = self.deco.background(color);
3638        self
3639    }
3640    fn border(mut self, width: f32, color: Color) -> Self {
3641        self.deco = self.deco.border(width, color);
3642        self
3643    }
3644    fn radius(mut self, radius: f32) -> Self {
3645        self.deco = self.deco.radius(radius);
3646        self
3647    }
3648    fn box_style(mut self, style: BoxStyle) -> Self {
3649        self.deco = style;
3650        self
3651    }
3652}
3653
3654impl crate::styleable::Styleable for Row {
3655    fn fill_width(mut self) -> Self {
3656        self.0.style = self.0.style.width(Length::Fill(1.0));
3657        self
3658    }
3659    fn fill_height(mut self) -> Self {
3660        self.0.style = self.0.style.height(Length::Fill(1.0));
3661        self
3662    }
3663    fn fit(mut self) -> Self {
3664        self.0.style = self.0.style.fit();
3665        self
3666    }
3667    fn hit_testable(mut self, on: bool) -> Self {
3668        self.0.style = self.0.style.hit_testable(on);
3669        self
3670    }
3671    fn padding(mut self, padding: impl Into<Edges>) -> Self {
3672        self.0.style = self.0.style.padding(padding);
3673        self
3674    }
3675}
3676
3677impl crate::styleable::Decoratable for Row {
3678    fn background(mut self, color: Color) -> Self {
3679        self.0.deco = self.0.deco.background(color);
3680        self
3681    }
3682    fn border(mut self, width: f32, color: Color) -> Self {
3683        self.0.deco = self.0.deco.border(width, color);
3684        self
3685    }
3686    fn radius(mut self, radius: f32) -> Self {
3687        self.0.deco = self.0.deco.radius(radius);
3688        self
3689    }
3690    fn box_style(mut self, style: BoxStyle) -> Self {
3691        self.0.deco = style;
3692        self
3693    }
3694}
3695
3696impl crate::styleable::Styleable for Column {
3697    fn fill_width(mut self) -> Self {
3698        self.0.style = self.0.style.width(Length::Fill(1.0));
3699        self
3700    }
3701    fn fill_height(mut self) -> Self {
3702        self.0.style = self.0.style.height(Length::Fill(1.0));
3703        self
3704    }
3705    fn fit(mut self) -> Self {
3706        self.0.style = self.0.style.fit();
3707        self
3708    }
3709    fn hit_testable(mut self, on: bool) -> Self {
3710        self.0.style = self.0.style.hit_testable(on);
3711        self
3712    }
3713    fn padding(mut self, padding: impl Into<Edges>) -> Self {
3714        self.0.style = self.0.style.padding(padding);
3715        self
3716    }
3717}
3718
3719impl crate::styleable::Decoratable for Column {
3720    fn background(mut self, color: Color) -> Self {
3721        self.0.deco = self.0.deco.background(color);
3722        self
3723    }
3724    fn border(mut self, width: f32, color: Color) -> Self {
3725        self.0.deco = self.0.deco.border(width, color);
3726        self
3727    }
3728    fn radius(mut self, radius: f32) -> Self {
3729        self.0.deco = self.0.deco.radius(radius);
3730        self
3731    }
3732    fn box_style(mut self, style: BoxStyle) -> Self {
3733        self.0.deco = style;
3734        self
3735    }
3736}
3737
3738impl crate::styleable::Styleable for Stack {
3739    fn fill_width(mut self) -> Self {
3740        self.style = self.style.width(Length::Fill(1.0));
3741        self
3742    }
3743    fn fill_height(mut self) -> Self {
3744        self.style = self.style.height(Length::Fill(1.0));
3745        self
3746    }
3747    fn fit(mut self) -> Self {
3748        self.style = self.style.fit();
3749        self
3750    }
3751    fn hit_testable(mut self, on: bool) -> Self {
3752        self.style = self.style.hit_testable(on);
3753        self
3754    }
3755    fn padding(mut self, padding: impl Into<Edges>) -> Self {
3756        self.style = self.style.padding(padding);
3757        self
3758    }
3759}
3760
3761impl crate::styleable::Decoratable for Stack {
3762    fn background(mut self, color: Color) -> Self {
3763        self.deco = self.deco.background(color);
3764        self
3765    }
3766    fn border(mut self, width: f32, color: Color) -> Self {
3767        self.deco = self.deco.border(width, color);
3768        self
3769    }
3770    fn radius(mut self, radius: f32) -> Self {
3771        self.deco = self.deco.radius(radius);
3772        self
3773    }
3774    fn box_style(mut self, style: BoxStyle) -> Self {
3775        self.deco = style;
3776        self
3777    }
3778}
3779
3780#[cfg(test)]
3781mod aspect_ratio_tests {
3782    use super::*;
3783
3784    #[test]
3785    fn invalid_ratio_falls_back_to_square() {
3786        for bad in [0.0, -2.0, f32::NAN, f32::INFINITY, f32::NEG_INFINITY] {
3787            let v = AspectRatio::new(bad);
3788            assert_eq!(v.layout_style().aspect_ratio, Some(1.0), "ratio {bad}");
3789            let v = AspectRatio::new(2.0).ratio(bad);
3790            assert_eq!(v.layout_style().aspect_ratio, Some(1.0), "ratio {bad}");
3791        }
3792    }
3793
3794    #[test]
3795    fn layout_style_carries_ratio() {
3796        let v = AspectRatio::new(16.0 / 9.0).width(320.0);
3797        let style = v.layout_style();
3798        assert_eq!(style.aspect_ratio, Some(16.0 / 9.0));
3799        assert_eq!(style.width, Length::Px(320.0));
3800    }
3801
3802    #[test]
3803    fn contain_fits_wide_content() {
3804        let (boxed, dx, dy) = aspect_contain(Size::new(800.0, 600.0), 16.0 / 9.0);
3805        assert!((boxed.width - 800.0).abs() < 1e-3, "{boxed:?}");
3806        assert!((boxed.height - 450.0).abs() < 1e-3, "{boxed:?}");
3807        assert!(dx.abs() < 1e-3, "{dx}");
3808        assert!((dy - 75.0).abs() < 1e-3, "{dy}");
3809    }
3810
3811    #[test]
3812    fn contain_fits_tall_content() {
3813        let (boxed, dx, dy) = aspect_contain(Size::new(100.0, 200.0), 2.0);
3814        assert!((boxed.width - 100.0).abs() < 1e-3, "{boxed:?}");
3815        assert!((boxed.height - 50.0).abs() < 1e-3, "{boxed:?}");
3816        assert!(dx.abs() < 1e-3, "{dx}");
3817        assert!((dy - 75.0).abs() < 1e-3, "{dy}");
3818    }
3819
3820    #[test]
3821    fn contain_matching_ratio_is_identity() {
3822        let (boxed, dx, dy) = aspect_contain(Size::new(200.0, 100.0), 2.0);
3823        assert!((boxed.width - 200.0).abs() < 1e-3, "{boxed:?}");
3824        assert!((boxed.height - 100.0).abs() < 1e-3, "{boxed:?}");
3825        assert!(dx.abs() < 1e-3);
3826        assert!(dy.abs() < 1e-3);
3827    }
3828
3829    #[test]
3830    fn contain_degenerate_returns_content() {
3831        let (boxed, dx, dy) = aspect_contain(Size::ZERO, 16.0 / 9.0);
3832        assert_eq!(boxed, Size::ZERO);
3833        assert_eq!((dx, dy), (0.0, 0.0));
3834        let (boxed, dx, dy) = aspect_contain(Size::new(100.0, 100.0), 0.0);
3835        assert_eq!(boxed, Size::new(100.0, 100.0));
3836        assert_eq!((dx, dy), (0.0, 0.0));
3837    }
3838}