maycoon_widgets/
container.rs1use maycoon_core::app::context::AppContext;
2use maycoon_core::app::info::AppInfo;
3use maycoon_core::app::update::Update;
4use maycoon_core::layout::{LayoutNode, LayoutStyle, StyleNode};
5use maycoon_core::signal::MaybeSignal;
6use maycoon_core::vgi::Scene;
7use maycoon_core::widget::{BoxedWidget, Widget, WidgetChildrenExt, WidgetLayoutExt};
8use maycoon_theme::id::WidgetId;
9use maycoon_theme::theme::Theme;
10
11#[derive(Default)]
22pub struct Container {
23 style: MaybeSignal<LayoutStyle>,
24 children: Vec<BoxedWidget>,
25}
26
27impl Container {
28 #[inline(always)]
30 pub fn new(children: Vec<BoxedWidget>) -> Self {
31 Self {
32 style: LayoutStyle::default().into(),
33 children: children.into_iter().collect(),
34 }
35 }
36}
37
38impl WidgetChildrenExt for Container {
39 #[inline(always)]
40 fn set_children(&mut self, children: Vec<BoxedWidget>) {
41 self.children = children.into_iter().collect();
42 }
43
44 #[inline(always)]
45 fn add_child(&mut self, child: impl Widget + 'static) {
46 self.children.push(Box::new(child));
47 }
48}
49
50impl WidgetLayoutExt for Container {
51 #[inline(always)]
52 fn set_layout_style(&mut self, layout_style: impl Into<MaybeSignal<LayoutStyle>>) {
53 self.style = layout_style.into();
54 }
55}
56
57impl Widget for Container {
58 #[inline(always)]
59 fn render(
60 &mut self,
61 scene: &mut dyn Scene,
62 theme: &mut dyn Theme,
63 layout_node: &LayoutNode,
64 info: &AppInfo,
65 context: AppContext,
66 ) {
67 for (i, child) in self.children.iter_mut().enumerate() {
68 child.render(
69 scene,
70 theme,
71 &layout_node.children[i],
72 info,
73 context.clone(),
74 );
75 }
76 }
77
78 #[inline(always)]
79 fn layout_style(&self) -> StyleNode {
80 let style = self.style.get().clone();
81
82 let mut children = Vec::with_capacity(self.children.len());
83
84 for child in &self.children {
85 children.push(child.layout_style());
86 }
87
88 StyleNode { style, children }
89 }
90
91 #[inline(always)]
92 fn update(&mut self, layout: &LayoutNode, context: AppContext, info: &AppInfo) -> Update {
93 let mut update = Update::empty();
94
95 for (i, child) in self.children.iter_mut().enumerate() {
96 update.insert(child.update(&layout.children[i], context.clone(), info));
97 }
98
99 update
100 }
101
102 #[inline(always)]
103 fn widget_id(&self) -> WidgetId {
104 WidgetId::new("maycoon-widgets", "Container")
105 }
106}