zng_app/widget/node/
extend.rs1use std::sync::Arc;
2
3use parking_lot::Mutex;
4
5use crate::widget::WidgetUpdateMode;
6
7use super::*;
8
9pub fn extend_widget(widget: impl IntoUiNode, build_extension: impl FnOnce(UiNode) -> UiNode) -> UiNode {
18 let widget = Arc::new(Mutex::new(widget.into_node()));
19 let child = build_extension(UiNode::new(ExtendWidgetChildNode { widget: widget.clone() }));
20 UiNode::new(ExtendWidgetNode { widget, child })
21}
22
23struct ExtendWidgetChildNode {
24 widget: Arc<Mutex<UiNode>>,
25}
26impl UiNodeImpl for ExtendWidgetChildNode {
27 fn children_len(&self) -> usize {
28 1
29 }
30
31 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
32 if index == 0 {
33 visitor(&mut self.widget.lock())
34 }
35 }
36
37 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
38 self.widget.lock().0.as_widget()?;
39 Some(self)
40 }
41}
42impl WidgetUiNodeImpl for ExtendWidgetChildNode {
43 fn with_context(&mut self, update_mode: WidgetUpdateMode, visitor: &mut dyn FnMut()) {
44 if let Some(wgt) = self.widget.lock().0.as_widget() {
45 wgt.with_context(update_mode, visitor);
46 } else {
47 tracing::debug!("extend_widget child is not a widget");
49 }
50 }
51}
52
53struct ExtendWidgetNode {
54 widget: Arc<Mutex<UiNode>>,
55 child: UiNode,
56}
57impl UiNodeImpl for ExtendWidgetNode {
58 fn children_len(&self) -> usize {
59 1
60 }
61
62 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
63 if index == 0 {
64 visitor(&mut self.child)
65 }
66 }
67
68 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
69 self.widget.lock().0.as_widget()?;
70 Some(self)
71 }
72}
73impl WidgetUiNodeImpl for ExtendWidgetNode {
74 fn with_context(&mut self, update_mode: WidgetUpdateMode, visitor: &mut dyn FnMut()) {
75 if let Some(wgt) = self.widget.lock().0.as_widget() {
76 wgt.with_context(update_mode, visitor);
77 } else {
78 tracing::debug!("extend_widget child is not a widget");
80 }
81 }
82}