feather_ui/component/
region.rs1use crate::color::sRGB32;
5use crate::component::ChildOf;
6use crate::layout::{Desc, Layout, fixed};
7use crate::persist::{FnPersist, VectorMap};
8use crate::{SourceID, layout};
9use derive_where::derive_where;
10use std::rc::Rc;
11use std::sync::Arc;
12
13#[derive(feather_macro::StateMachineChild)]
14#[derive_where(Clone, Default)]
15pub struct Region<T: Default> {
16 pub id: Arc<SourceID>,
17 pub color: Option<sRGB32>,
18 pub rotation: Option<f32>,
19 props: Rc<T>,
20 children: im::Vector<Option<Box<ChildOf<dyn fixed::Prop>>>>,
21}
22
23impl<T: fixed::Prop + Default + 'static> Region<T> {
24 pub fn new(
25 id: Arc<SourceID>,
26 props: T,
27 children: im::Vector<Option<Box<ChildOf<dyn fixed::Prop>>>>,
28 ) -> Self {
29 Self {
30 id,
31 props: props.into(),
32 children,
33 ..Default::default()
34 }
35 }
36
37 pub fn new_layer(
38 id: Arc<SourceID>,
39 props: T,
40 color: sRGB32,
41 rotation: f32,
42 children: im::Vector<Option<Box<ChildOf<dyn fixed::Prop>>>>,
43 ) -> Self {
44 Self {
45 id,
46 props: props.into(),
47 color: Some(color),
48 rotation: Some(rotation),
49 children,
50 }
51 }
52}
53
54impl<T: fixed::Prop + Default + 'static> super::Component for Region<T>
55where
56 for<'a> &'a T: Into<&'a (dyn fixed::Prop + 'static)>,
57{
58 type Props = T;
59
60 fn layout(
61 &self,
62 manager: &mut crate::StateManager,
63 driver: &crate::graphics::Driver,
64 window: &Arc<SourceID>,
65 ) -> Box<dyn Layout<T>> {
66 let mut map = VectorMap::new(crate::persist::Persist::new(
67 |child: &Option<Box<ChildOf<dyn fixed::Prop>>>| -> Option<Box<dyn Layout<<dyn fixed::Prop as Desc>::Child>>> {
68 Some(child.as_ref()?.layout(manager, driver, window))
69 }));
70
71 let layer = if self.color.is_some() || self.rotation.is_some() {
72 Some((
73 self.color.unwrap_or(sRGB32::white()),
74 self.rotation.unwrap_or_default(),
75 ))
76 } else {
77 None
78 };
79
80 let (_, children) = map.call(Default::default(), &self.children);
81 Box::new(layout::Node::<T, dyn fixed::Prop> {
82 props: self.props.clone(),
83 children,
84 id: Arc::downgrade(&self.id),
85 renderable: None,
86 layer,
87 })
88 }
89}