Skip to content

UXOutlineView

UXOutlineView is a table whose rows have a hierarchy. It makes three additions to UXTableView: a data source that speaks in items and children rather than rows and columns; a flattening pass that derives the visible row list from the expanded tree; and an indent with a disclosure triangle that toggles a row open or shut.

An outline view is a table whose row list is derived from a tree and re-derived whenever a node opens or closes. There is no second drawing path, no second hit test and no second scrolling model. An outline row is a table row, so everything downstream works as it does for a table.

#use <UXKit>
protocol UXOutlineDataSource {
i32 numberOfChildren(UXOutlineView* o, Object* item);
Object* childOfItem(UXOutlineView* o, Object* item, i32 i);
bool isExpandable(UXOutlineView* o, Object* item);
u8* valueForItem(UXOutlineView* o, Object* item, i32 col);
}

item is nil for the root, so one method answers both “what are the top-level rows?” and “what are this node’s children?”.

Lifetime rule (inherited from the table): valueForItem’s string goes straight into the realized cell and is not copied. It must outlive the row.

class FileTree : Object <UXOutlineDataSource> {
i32 numberOfChildren(UXOutlineView* o, Object* item) {
return item == (Object*)0 ? root.count() : ((Node* ?)item).count();
}
Object* childOfItem(UXOutlineView* o, Object* item, i32 i) { ... }
bool isExpandable(UXOutlineView* o, Object* item) { return ((Node* ?)item).isDir(); }
u8* valueForItem(UXOutlineView* o, Object* item, i32 col) { return ((Node* ?)item).name(); }
}
UXOutlineView* tree = new UXOutlineView();
tree.setOutlineSource(src);
tree.addColumn((u8*)"Name", 200);

Source · setOutlineSource The visible list · visibleCount · nodeAt · rowForItem Expansion · isExpanded · setExpanded

void setOutlineSource(UXOutlineDataSource* d)

Attaches the item-tree source. The table’s row/column source is unused, because the outline derives rows itself.

i32 visibleCount(void)

How many rows the current expansion state produces.

UXOutlineNode* nodeAt(i32 r)

The visible line at a row: the item, its depth, and whether it is open. See UXOutlineNode.

i32 rowForItem(pointer item)

The row currently showing an item, or -1 when it is folded away.

bool isExpanded(Object* item)

Whether the item is open. Expansion is stored against the item, not a row index, because a row index changes as soon as anything above it opens or shuts.

void setExpanded(Object* item, bool open)

Opens or closes an item programmatically; the next reload re-derives the row list. The disclosure triangle calls this method.

The outline overrides three table hooks. countRows flattens (depth-first, emitting a line for every item whose ancestors are all open). newRow makes an UXOutlineRow that draws the triangle and indents. configureRow pushes the first column right by the row’s depth. Drawing, hit-testing, selection, scrolling and the native realizations all belong to the table and are unchanged.

UXOutlineView on Web

The flattened tree as toolkit-drawn rows, with the disclosure triangle in the indent gutter.