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