1#![doc(html_favicon_url = "https://zng-ui.github.io/res/zng-logo-icon.png")]
2#![doc(html_logo_url = "https://zng-ui.github.io/res/zng-logo.png")]
3#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
9#![warn(unused_extern_crates)]
10#![warn(missing_docs)]
11
12zng_wgt::enable_widget_macros!();
13
14use zng_wgt::prelude::*;
15use zng_wgt_wrap::Wrap;
16
17#[widget($crate::Panel)]
19pub struct Panel(WidgetBase);
20
21impl Panel {
22 fn widget_intrinsic(&mut self) {
23 self.widget_builder().push_build_action(|wgt| {
24 if let Some(p) = wgt.capture_property(property_id!(Self::children)) {
25 let list = p.args.ui_node(0).clone();
26 wgt.set_child(node(list, PANEL_FN_VAR));
27 } else {
28 wgt.set_child(node(ArcNode::new(ui_vec![]), PANEL_FN_VAR));
29 }
30 });
31 }
32}
33
34#[property(CHILD, default(ui_vec![]), widget_impl(Panel))]
36pub fn children(wgt: &mut WidgetBuilding, children: impl IntoUiNode) {
37 let _ = children;
38 wgt.expect_property_capture();
39}
40
41context_var! {
42 pub static PANEL_FN_VAR: WidgetFn<PanelArgs> = wgt_fn!(|a: PanelArgs| {
49 Wrap! {
50 children = a.children;
51 }
52 });
53}
54
55#[property(CONTEXT, default(PANEL_FN_VAR), widget_impl(Panel))]
63pub fn panel_fn(child: impl IntoUiNode, panel: impl IntoVar<WidgetFn<PanelArgs>>) -> UiNode {
64 with_context_var(child, PANEL_FN_VAR, panel)
65}
66
67#[non_exhaustive]
71pub struct PanelArgs {
72 pub children: UiNode,
76}
77impl PanelArgs {
78 pub fn new(children: UiNode) -> Self {
80 Self { children }
81 }
82}
83
84pub fn node(children: ArcNode, panel_fn: impl IntoVar<WidgetFn<PanelArgs>>) -> UiNode {
86 let panel_fn = panel_fn.into_var();
87 match_node(UiNode::nil(), move |c, op| match op {
88 UiNodeOp::Init => {
89 WIDGET.sub_var(&panel_fn);
90 *c.node() = panel_fn.get().call(PanelArgs {
91 children: children.take_on_init(),
92 });
93 c.init();
94 }
95 UiNodeOp::Deinit => {
96 c.deinit();
97 *c.node() = UiNode::nil();
98 }
99 UiNodeOp::Update { updates } => {
100 if let Some(f) = panel_fn.get_new() {
101 c.deinit();
102 *c.node() = f(PanelArgs {
103 children: children.take_on_init(),
104 });
105 c.init();
106 } else {
107 c.update(updates);
108 }
109 }
110 _ => {}
111 })
112}