waterui_layout/
container.rs

1//! View wrapper that lets arbitrary [`Layout`] implementations
2//! participate in the `WaterUI` view tree.
3
4use core::fmt::Debug;
5
6use alloc::{boxed::Box, vec::Vec};
7use waterui_core::{
8    AnyView, Native, NativeView, View,
9    view::TupleViews,
10    views::{AnyViews, Views, ViewsExt},
11};
12
13use crate::{Layout, StretchAxis};
14
15/// A view wrapper that executes an arbitrary [`Layout`]
16/// implementation.
17pub struct FixedContainer {
18    layout: Box<dyn Layout>,
19    contents: Vec<AnyView>,
20}
21
22impl Debug for FixedContainer {
23    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24        f.debug_struct("Container")
25            .field("layout", &"Box<dyn Layout>")
26            .field("contents", &self.contents)
27            .finish()
28    }
29}
30
31impl FixedContainer {
32    /// Wraps the supplied layout object and tuple of child views into a
33    /// container view.
34    pub fn new(layout: impl Layout + 'static, contents: impl TupleViews) -> Self {
35        Self {
36            layout: Box::new(layout),
37            contents: contents.into_views(),
38        }
39    }
40
41    /// Returns the boxed layout object together with the collected child views.
42    #[must_use]
43    pub fn into_inner(self) -> (Box<dyn Layout>, Vec<AnyView>) {
44        (self.layout, self.contents)
45    }
46}
47
48impl NativeView for FixedContainer {
49    fn stretch_axis(&self) -> StretchAxis {
50        self.layout.stretch_axis()
51    }
52}
53
54impl View for FixedContainer {
55    fn body(self, _env: &waterui_core::Environment) -> impl View {
56        Native::new(self)
57    }
58
59    fn stretch_axis(&self) -> StretchAxis {
60        self.layout.stretch_axis()
61    }
62}
63
64/// A view wrapper that executes an arbitrary [`Layout`] implementation
65/// with reconstructable views, which can support lazy layouting.
66///
67/// Unlike [`FixedContainer`], this container stores views as an [`AnyViews`]
68/// collection, allowing backends to reconstruct views on-demand for efficient
69/// rendering of large lists.
70#[derive(Debug)]
71pub struct LazyContainer {
72    layout: Box<dyn Layout>,
73    contents: AnyViews<AnyView>,
74}
75
76impl LazyContainer {
77    /// Wraps the supplied layout object and views into a lazy container view.
78    pub fn new<V: View>(
79        layout: impl Layout + 'static,
80        contents: impl Views<View = V> + 'static,
81    ) -> Self {
82        Self {
83            layout: Box::new(layout),
84            contents: AnyViews::new(contents.map(|v| AnyView::new(v))),
85        }
86    }
87    /// Returns the boxed layout object together with the collected child views.
88    #[must_use]
89    pub fn into_inner(self) -> (Box<dyn Layout>, AnyViews<AnyView>) {
90        (self.layout, self.contents)
91    }
92}
93
94impl NativeView for LazyContainer {
95    fn stretch_axis(&self) -> StretchAxis {
96        self.layout.stretch_axis()
97    }
98}
99
100impl View for LazyContainer {
101    fn body(self, _env: &waterui_core::Environment) -> impl View {
102        Native::new(self)
103    }
104
105    fn stretch_axis(&self) -> StretchAxis {
106        self.layout.stretch_axis()
107    }
108}