Function zng_app::widget::node::match_node
source · pub fn match_node<C: UiNode>(
child: C,
closure: impl FnMut(&mut MatchNodeChild<BoxedUiNode>, UiNodeOp<'_>) + Send + 'static,
) -> impl UiNode
Expand description
Creates a node that is implemented as a closure that matches over UiNodeOp
and delegates to another child node.
The closure node can delegate to child
, when the closure
itself does not delegate, the child
methods
are called after the closure returns. See MatchNodeChild
for more details.
This is a convenient way of declaring anonymous nodes, such as those that implement a property function. By leveraging closure captures, state can be easily declared and used, without the verbosity of declaring a struct.
§Examples
The example declares a property node that implements multiple UI node operations.
#[property(LAYOUT)]
pub fn count_layout(child: impl UiNode, enabled: impl IntoVar<bool>) -> impl UiNode {
let enabled = enabled.into_var();
let mut layout_count = 0;
match_node(child, move |child, op| match op {
UiNodeOp::Init => {
WIDGET.sub_var(&enabled);
}
UiNodeOp::Update { .. } => {
if let Some(true) = enabled.get_new() {
println!("layout count reset");
layout_count = 0;
}
}
UiNodeOp::Measure { wm, desired_size } => {
let s = child.measure(wm);
*desired_size = LAYOUT.constraints().fill_size_or(s);
}
UiNodeOp::Layout { wl, final_size } => {
if enabled.get() {
layout_count += 1;
println!("layout {layout_count}");
}
let s = child.layout(wl);
*final_size = LAYOUT.constraints().fill_size_or(s);
}
_ => {}
})
}
§See Also
See also match_node_list
that delegates to multiple children, match_node_leaf
that declares a leaf node (no child)
and match_widget
that can extend a widget node.
Note that the child type is changed to BoxedUiNode
when build with the feature = "dyn_node"
, if you want to access the
child directly using MatchNodeChild::child
you can use match_node_typed
instead.