Expand description
TreeDataSlice — the reusable TreeDataSource engine for an external,
indent-ordered tree (a Qleany entity store, a database, a virtual
filesystem) that is NOT mirrored into a TreeModel.
TreeSlice gives per-view expand state + flattening +
divergence to a TreeModel. TreeDataSlice gives the same machinery to
a source whose identity is a domain key (K = i64 entity id, a tagged enum,
…) and whose natural shape is a flat, pre-order, indent-annotated row stream
— the shape an outline is genuinely stored in (Scrivener-class binders /
chapters / scenes, OPML, Markdown headings). The app hands over
Vec<TreeRow<K, T>> ({ key, item, depth }, document order) on every
(re)load; the engine owns everything else:
- tree derivation — parent links + child index + roots + structural depth, derived from the indent sequence (an item’s parent is the nearest preceding row of strictly smaller depth; depth-0 rows are roots);
- per-view expand state — a
K-keyed set, so two slices over the same source expand independently and expand survives a full re-source; - collapse-aware flattening into the visible row list;
- divergence (
first_changed_index) — the common-prefix of the old vs new visible rows, comparing key + depth + has-children + expand and item content (hence theT: PartialEqbound), so a consumer caching per-row state (a measured row height) keeps its valid prefix across reloads and expand toggles; - DnD mechanism — the cycle guard +
can_accept/accept_dropplumbing; domain policy is injected as closures (TreeDataSlice::set_drag_policy,TreeDataSlice::set_drop_resolver,TreeDataSlice::set_reorder).
It is a cheap Rc-handle (clone = share, like ListModel / SceneModel):
pass one clone to TreeView::from_source and keep another to drive
reload / set_rows from
the app.
§Wiring an external source
use teksilo_data::{TreeDataSlice, TreeRow};
use teksilo_data::dnd_types::{DragEligibility, DropPosition};
// key = entity id, item = the row's display data
let slice: TreeDataSlice<u64, String> = TreeDataSlice::new();
slice.set_expand_new_nodes(true); // new nodes appear expanded
slice.set_source(|| vec![ // your `rows::load`
TreeRow::new(1, "Binder".to_string(), 0),
TreeRow::new(2, "Chapter".to_string(), 1),
TreeRow::new(3, "Scene".to_string(), 2),
]);
slice.set_drag_policy(|key| if *key == 1 { DragEligibility::NoDrag } else { DragEligibility::CanDrag });
slice.set_reorder(|_dragged, _target, _pos: DropPosition| { /* backend move + undo */ true });
slice.reload();
assert_eq!(slice.visible_count(), 3); // all expanded
// let view = TreeView::from_source(slice.clone(), delegate);Structs§
- Tree
Data Slice - Per-view flattened projection of an external, indent-ordered tree source. See the module documentation.
- TreeRow
- One row the app hands to a
TreeDataSlice, in document (pre-)order.