Skip to main content

Module tree_data_slice

Module tree_data_slice 

Source
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 the T: PartialEq bound), 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_drop plumbing; 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§

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