Tree
private readonly Tree<VltNode> _nodes;
private readonly VltFile _vlt;
_nodes = new Tree<VltNode>(options.Keymap)
{
Render = node => node.Name,
OnExpanding = node => node.Children = _vlt.LoadChildren(node.Value),
OnActivate = node => ViewKind.Node,
Roots = roots,
};
Widgets are built in the view's constructor, so options is the ArlecchinoOptions the container
hands it, and region is the region the view draws the widget into.
Nodes
TreeNode<T> carries the value, its children and whether it is open:
var roots = projects
.Select(project => new TreeNode<Project>(project))
.ToList();
A node with no children is a leaf and gets no marker. Rows are indented two columns per level and
prefixed with ▾ / ▸.
Keys and clicks
| Input | Does |
|---|---|
→ | Expands the node under the cursor, then steps into it |
← | Collapses it, then walks up to the parent |
Confirm | Toggles a branch, or activates a leaf through OnActivate |
| Click on the marker | Toggles that node without activating it |
| Click elsewhere | Selects the row; a second click activates it |
Movement, paging and the wheel come from the ListBox inside.
Filling children in late
OnExpanding fires just before a node opens, which is where children are filled in for a tree that
loads level by level:
OnExpanding = node => node.Children = _vlt.LoadChildren(node.Value),
That keeps a large hierarchy cheap: nothing below a closed node is ever read. Work that has to leave the thread goes through an async atom and posts the children back rather than blocking the frame.
ExpandAll() and CollapseAll() walk the whole thing.
A worked example
samples/Arlecchino.Sample shows a tree beside the rest of its gallery, with the branches folded in
until they are opened:
dotnet run --project samples/Arlecchino.Sample -- --frame widgets 100x24