Expand description
TreeCheckedModel — per-node checkbox state for a tree, with optional
descendant→ancestor tristate aggregation.
Companion to crate::CheckedModel for trees. Defaults to the standard
“Outlook folder selection” semantic: a parent’s state is Checked if all
descendants are checked, Unchecked if none, Indeterminate otherwise;
toggling a parent cascades Checked/Unchecked down to all descendants.
Set the mode to AggregateMode::None to give every node independent
state instead. The model is a share-by-clone handle (Rc<RefCell<…>>
internally) — cloning produces a second view onto the same checkbox state.
External writes (e.g. a Checkbox widget bound to
signal_for(node) setting it directly) trigger the same
cascade-and-recompute pass as the model’s own
check/uncheck/toggle methods, via per-node observers. A
re-entry guard prevents the cascade pass from re-firing
observers it triggers itself.
§Example
let tree = TreeModel::new();
let root = tree.insert_root(0, "root");
let child_a = tree.insert_child(root, 0, "a");
let child_b = tree.insert_child(root, 1, "b");
let model = TreeCheckedModel::new(tree);
// Pre-register signal chains before mutating.
let _ = (model.signal_for(root), model.signal_for(child_a), model.signal_for(child_b));
model.check(child_a);
assert_eq!(model.check_state(root), CheckState::Indeterminate);
model.check(child_b);
assert_eq!(model.check_state(root), CheckState::Checked);§Limitation: tree-mutation desync
signal_for(node) and bool_signal_for(node) cache signals keyed
by NodeId. The cache is never invalidated. If the underlying
TreeModel<T> mutates (remove, move_node, etc.) the cached
entry for a removed NodeId lingers indefinitely:
checked_nodes()may include a staleNodeIdwhose underlying tree node no longer exists. Callers that consume this list should validate each id against the current tree state before acting on it.bool_signal_for/signal_forfor a removed node still return their cached signal handle. Setting it has no observable effect on the tree (the cascade walkstree.children(node)which is empty for a freed node).
This is an acceptable trade-off because NodeIds are not reused
by TreeModel (slotmap keys are versioned), so a stale id can
never alias a fresh node. If a future use case needs strict
invalidation on removal, subscribe to TreeModel’s change events
and clear the relevant entries. Tracked as out-of-scope for V1.
Structs§
- Tree
Checked Model - Per-node checkbox state for a
TreeModel<T>, with optional descendant→ancestor tristate aggregation.
Enums§
- Aggregate
Mode - How a parent’s
CheckStaterelates to its descendants.