zng_app/widget/node/
extend.rs
1use std::sync::Arc;
2
3use parking_lot::Mutex;
4use zng_app_proc_macros::ui_node;
5
6use crate::widget::WidgetUpdateMode;
7
8use super::*;
9
10pub fn extend_widget(widget: impl UiNode, build_extension: impl FnOnce(BoxedUiNode) -> BoxedUiNode) -> impl UiNode {
19 let widget = Arc::new(Mutex::new(widget.boxed()));
20 let child = build_extension(ExtendWidgetChildNode { widget: widget.clone() }.boxed());
21 ExtendWidgetNode { widget, child }
22}
23
24struct ExtendWidgetChildNode {
25 widget: Arc<Mutex<BoxedUiNode>>,
26}
27#[ui_node(delegate = self.widget.lock())]
28impl UiNode for ExtendWidgetChildNode {
29 fn is_widget(&self) -> bool {
30 self.widget.lock().is_widget()
31 }
32
33 fn with_context<R, F>(&mut self, update_mode: WidgetUpdateMode, f: F) -> Option<R>
34 where
35 F: FnOnce() -> R,
36 {
37 self.widget.lock().with_context(update_mode, f)
38 }
39}
40
41struct ExtendWidgetNode {
42 widget: Arc<Mutex<BoxedUiNode>>,
43 child: BoxedUiNode,
44}
45#[ui_node(child)]
46impl UiNode for ExtendWidgetNode {
47 fn is_widget(&self) -> bool {
48 self.widget.lock().is_widget()
49 }
50
51 fn with_context<R, F>(&mut self, update_mode: WidgetUpdateMode, f: F) -> Option<R>
52 where
53 F: FnOnce() -> R,
54 {
55 self.widget.lock().with_context(update_mode, f)
56 }
57}