feather_ui/component/
flexbox.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2025 Fundament Research Institute <https://fundament.institute>
3
4use crate::layout::{Desc, Layout, flex};
5use crate::persist::{FnPersist, VectorMap};
6use crate::{SourceID, layout};
7use derive_where::derive_where;
8use std::rc::Rc;
9use std::sync::Arc;
10
11use super::ChildOf;
12
13#[derive(feather_macro::StateMachineChild)]
14#[derive_where(Clone)]
15pub struct FlexBox<T> {
16    pub id: Arc<SourceID>,
17    props: Rc<T>,
18    children: im::Vector<Option<Box<ChildOf<dyn flex::Prop>>>>,
19}
20
21impl<T: flex::Prop + 'static> FlexBox<T> {
22    pub fn new(
23        id: Arc<SourceID>,
24        props: T,
25        children: im::Vector<Option<Box<ChildOf<dyn flex::Prop>>>>,
26    ) -> Self {
27        Self {
28            id,
29            props: props.into(),
30            children,
31        }
32    }
33}
34
35impl<T: flex::Prop + 'static> super::Component for FlexBox<T> {
36    type Props = T;
37
38    fn layout(
39        &self,
40        manager: &mut crate::StateManager,
41        driver: &crate::graphics::Driver,
42        window: &Arc<SourceID>,
43    ) -> Box<dyn Layout<T>> {
44        let mut map = VectorMap::new(crate::persist::Persist::new(
45            |child: &Option<Box<ChildOf<dyn flex::Prop>>>| -> Option<Box<dyn Layout<<dyn flex::Prop as Desc>::Child>>> {
46                Some(child.as_ref()?.layout(manager, driver,window))
47            })
48        );
49
50        let (_, children) = map.call(Default::default(), &self.children);
51        Box::new(layout::Node::<T, dyn flex::Prop> {
52            props: self.props.clone(),
53            children,
54            id: Arc::downgrade(&self.id),
55            renderable: None,
56            layer: None,
57        })
58    }
59}