Skip to main content

ferroui_diagnostics/diagnostics/view_models/
event_owner_tree_node.rs

1//! Port of `Diagnostics/ViewModels/EventOwnerTreeNode.cs`.
2
3use super::{EventTreeNode, EventTreeNodeBase, EventTreeNodeKind, EventsPageViewModel};
4use ferroui_base::collections::FerroList;
5use ferroui_base::interactivity::RoutedEvent;
6use ferroui_base::TypeInfo;
7use std::rc::{Rc, Weak};
8
9/// The node of the type that owns a group of routed events: its children
10/// are the nodes of the events, and enabling or disabling it enables or
11/// disables all of them.
12///
13/// The part of the deriving class of a node (see
14/// [`EventTreeNodeKind`]); the class adds no state of its own.
15pub struct EventOwnerTreeNode {
16    _private: (),
17}
18
19impl EventOwnerTreeNode {
20    /// C# `new EventOwnerTreeNode(Type type, IEnumerable<RoutedEvent> events, EventsPageViewModel vm)`:
21    /// the node of `type_` with a child for each of `events`, ordered by
22    /// name, expanded.
23    pub fn new(
24        type_: &'static TypeInfo,
25        events: impl IntoIterator<Item = RoutedEvent>,
26        vm: &Weak<EventsPageViewModel>,
27    ) -> Rc<EventTreeNodeBase> {
28        let this = EventTreeNodeBase::new(None, type_.name().to_string(), |_| {
29            EventTreeNodeKind::Owner(EventOwnerTreeNode { _private: () })
30        });
31
32        let mut events: Vec<RoutedEvent> = events.into_iter().collect();
33        // `OrderBy` is a stable sort.
34        events.sort_by(|x, y| x.name().cmp(y.name()));
35        this.set_children(Some(FerroList::from_items(
36            events.into_iter().map(|e| EventTreeNode::new(&this, e, vm.clone())),
37        )));
38        this.set_is_expanded(true);
39        this
40    }
41
42    /// The override of the setter of `IsEnabled`: enables or disables every
43    /// child with the node, unless the change comes from a child.
44    pub(crate) fn set_is_enabled(this: &EventTreeNodeBase, value: Option<bool>) {
45        if this.is_enabled() != value {
46            this.base_set_is_enabled(value);
47
48            if this.update_children.get() && value.is_some() {
49                let children = this.children().expect("the children of an owner node are set when it is created");
50                for child in children.to_vec() {
51                    // `try { .. } finally { .. }` upstream.
52                    child.update_parent.set(false);
53                    child.set_is_enabled(value);
54                    child.update_parent.set(true);
55                }
56            }
57        }
58    }
59}