Lists, trees & tables
Lists, trees and tables
Three widgets cover the "rows of data" cases, sharing one row renderer (selection fill, hover wash, icon, label) so they look consistent and restyle together through the theme.
ListView— flat selectable rows with optional leading icon, a per-row checkbox, dimming, and drag-to-reorder.TreeView— a hierarchy with disclosure triangles, indentation, collapsible groups, per-row visibility toggles, and multi-select.Table— multi-column rows with a header strip and column weights.
Selection that behaves
Item views act on synthesized intent, which is what makes selection feel right:
- a click (press + release, no drag) selects a row — so a drag never accidentally selects;
- a drag past the threshold begins a reorder (lists) rather than a selection;
- the disclosure triangle toggles a group, while clicking the row elsewhere selects it — the two are separate hit-zones, so you can select a parent without collapsing it.
TreeView owns a selected set plus an anchor and reports the whole set through onSelectionChanged:
tree->onSelectionChanged = [&](const std::vector<int>& ids){ doc.setSelection(ids); };
// Shift-click = range from the anchor over the visible rows;
// Cmd/Ctrl-click = toggle one; plain click = replace.
Range-select walks the visible flattened rows between the anchor and the clicked row, so Shift-selection matches what the user sees, and a double-click on a group expands or collapses all of its descendants.
Right-click and context
A right-press selects (or, in a tree, fires onContextMenu without disturbing the selection) and opens a MenuPopup on the app's popup layer — returning unhandled for the drag, so a modal menu does not steal the capture. The whole pattern — multi-select, range, reorder, context menu — is what the Editor's Outliner is built from, driving a Prism document's selection directly.
Scrolling
Wrap a tall item view in a ScrollView and it clips and scrolls (wheel or thumb-drag), showing a gutter only on overflow. Combined with the per-region buffering, a long, scrolling list stays smooth because only the scroll view's layer repaints as it moves.