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 UiNodeExpand 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.