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