-
Notifications
You must be signed in to change notification settings - Fork 0
TreeView
Wire name treeview
Rows that nest, optionally across several columns, with sorting and in-place editing. A ListView is the flat single-column case; where you need indentation, a header, or a second column, this is the trinket.
t=new treeview caption="Name" showheader treelines children={
new column id=size caption="Size" width=10 align=right sortable numeric
new item caption="Report.txt"
new item caption="Folder" expanded children={
new item caption="inner.txt"
}
}
| Property | Type | Default | Meaning |
|---|---|---|---|
caption |
string | — | Header caption over the key (tree) column. |
descending |
flag | false |
Sort direction indicator points down. |
editable |
flag | false |
The key (tree) column joins the row editor (edits the item caption). |
fit_width |
flag | true |
Squeeze columns to the width (no horizontal scrolling). |
fixed_left |
int | 0 |
Visible columns pinned outside horizontal scrolling, from the left. |
fixed_right |
int | 0 |
Visible columns pinned outside horizontal scrolling, from the right. |
indent_width |
int | — | Indent width per tree level. |
key_width |
int | 20 |
Key column width in text cells (scroll mode). |
ledger |
flag | false |
Alternate non-selected rows in the ledger colors. |
selected |
int | -1 |
Selected visible-row index. |
showheader |
flag | false |
Show the column header row. |
showkey |
flag | true |
Show the key (tree) column first. |
sorted |
flag | false |
Show the sort indicator. |
sortedby |
int | -1 |
Sort column: -1 = the key column, else a column index. |
treelines |
flag | false |
Connector lines in the indent space; leaf items get a glyph too. |
Plus the common properties.
activate — An item was activated — double-clicked, or Enter on the current item.
| Field | Type | Meaning |
|---|---|---|
trinket |
uint | The tree's object ID. |
item |
uint | The activated item. |
selected |
int | Row index of the item among the visible rows. |
change — The current item moved.
| Field | Type | Meaning |
|---|---|---|
trinket |
uint | The tree's object ID. |
item |
uint | The item now current. |
selected |
int | Row index of the current item among the visible rows. |
edit — An in-place cell edit was committed.
| Field | Type | Meaning |
|---|---|---|
trinket |
uint | The tree's object ID. |
item |
uint | The edited item. |
column |
int | Index of the edited column. |
value |
string | The committed cell text. |
expand — A branch opened or closed.
| Field | Type | Meaning |
|---|---|---|
trinket |
uint | The tree's object ID. |
item |
uint | The branch item. |
expanded |
flag | Set when the branch opened, unset when it closed. |
sort — The sort changed — a column header was used, or sorting was cleared.
| Field | Type | Meaning |
|---|---|---|
trinket |
uint | The tree's object ID. |
sorted |
flag | Set while a sort is in force. |
sortedby |
int | Index of the column sorted on. |
descending |
flag | Set when the sort runs high to low. |
A treeview is built from three virtual types, and which one a thing is decides where it attaches.
| Type | Attaches to | Is |
|---|---|---|
item |
the treeview, or another item
|
a row |
column |
the treeview | a column of the grid |
cell |
a column
|
one column's value for one row |
Items nest; columns do not. Cells go under the column, never under the treeview — a cell names the row it belongs to by ID rather than sitting inside it:
new treeview children={ new cell item=1 value="x" }
-> treeview: children must be items or columns, got *trinkets.wireCell
There is no fourth part. The tree column — the one holding the captions and
the indentation — is not a column object; it is the treeview itself, and
caption, key_width, showkey and editable are its properties.
Rows are children of the shared virtual item type, the same one
ListView and ComboBox use. Here it may nest:
new treeview children={
new item caption="Fruit" expanded children={
new item caption="Apple"
new item caption="Pear"
}
new item caption="Roots"
}
expanded defaults to false, so a branch built without it starts closed and
its children are not rows yet. The tree above holds four items either way,
but drop the expanded and it has two visible rows instead of four.
Items are addressable after they are built. A correlation key on a nested item reaches it by path:
tv=new treeview children={
a=new item caption="Report.txt"
b=new item caption="Folder" children={
c=new item caption="inner.txt"
}
}
set tv.b expanded
set tv.b.c caption="renamed.txt"
destroy tv.a
set on a live item takes effect immediately, including new children:
set tv.b children={ new item caption="late" }
appends to a branch that is already on screen.
A column is a description of a slice of the grid, not a container of values:
new treeview showheader children={
new column id=size caption="Size" width=10 align=right sortable numeric
new column id=kind caption="Kind" width=12
new item caption="Report.txt"
}
| Property | Type | Default | Meaning |
|---|---|---|---|
align |
left | center | right
|
left |
Cell text alignment. |
caption |
string | — | Header caption. |
editable |
flag | false |
Cells in this column can be edited in place (Enter opens the row editor). |
enum |
int | — | Wire ID of a collection of option objects; the cell editor becomes a choice box. |
enum_store |
key | value
|
value |
What a chosen option stores in the data field (cells always DISPLAY the option value). |
hidden |
flag | false |
Column is not displayed. |
id |
word | — | Stable key cell values are stored under. |
max_width |
int | 0 |
Maximum width in text cells (0 = unbounded). |
min_width |
int | 3 |
Minimum width in text cells. |
numeric |
flag | false |
Sort by each cell's numeric equivalent (parsed once per value). |
optional |
flag | true |
Column appears in the [=] show/hide chooser. |
resizable |
flag | true |
Header divider drag-resizes this column. |
sortable |
flag | false |
Header click requests a sort on this column. |
sortproxy |
int | -1 |
Column index whose values actually sort when this column is chosen (-1 = itself). |
width |
int | 8 |
Width in text cells. |
id is what cells are stored under, so give every column one. Values live on
the item under that key, not on the column, which has a consequence worth
knowing: two columns declared with the same id build without an error and
then show the same value in both, since one key is all there is between
them. A cell sent to either fills both.
Columns are resizable and optional by default, unlike most flags on the
wire. A column built with no flags at all can already be dragged wider at its
divider and hidden from the [=] chooser. Say !resizable or !optional to
take that back.
showheader is what puts the header row on screen; without it the captions
exist but are never drawn, and there is nothing to click to sort.
Values are column-major: each column owns its values, keyed by item.
Within one build script the item IDs do not exist yet, so filling a grid takes two batches. Build the shape, read the IDs out of the reply, then send the values:
tv=new treeview caption="Name" showheader children={
sizec=new column id=size caption="Size" width=10 align=right
a=new item caption="Report.txt"
b=new item caption="Folder" expanded children={
c=new item caption="inner.txt"
}
}
A bare reference statement surfaces an object's wire ID without changing anything, which is how the nested ones are reached:
aid=tv.a
bid=tv.b
cid=tv.b.c
The reply carries aid, bid and cid as numbers, and the values go in
against them:
set tv.sizec children={
new cell item=741 value="12 KB"
new cell item=743 value="--"
new cell item=744 value="1 KB"
}
| Property | Type | Default | Meaning |
|---|---|---|---|
item |
int | — | Wire ID of the item this value belongs to. |
value |
string | — | Cell text for this column and item. |
A cell naming an item that does not exist is accepted and dropped — no error. Since the IDs come from a reply, a wrong one means the batches went out of step, and the symptom is a blank cell rather than a message.
A collection is packaging: a parent that understands one adopts its members
as though they had been written out directly.
| Property | Type | Default | Meaning |
|---|---|---|---|
of |
word | — | Advisory member kind (columns, cells, ...). |
new treeview children={
new collection of=columns children={
new column id=a caption="A" width=5
new column id=b caption="B" width=6
}
new item caption="row"
}
builds the same two columns as writing them inline. of is advisory — it
documents what is inside and is not checked against the members.
Collections earn their keep for the enum below, where the column has to point at a group of objects rather than contain them.
sortable on a column makes its header clickable. The key column is always
sortable and does not opt in.
A click cycles three states, and each one raises sort:
| Click | sorted |
descending |
|---|---|---|
| first | set | unset |
| second | set | set |
| third | unset | unset |
sortedby is the column index, and -1 is the key column:
new treeview sorted sortedby=-1 children={ … } # sorted by name
sort is a request, not a report of work done. The treeview re-orders its
own rows and moves the indicator, and the event tells an application that
holds the real data to re-order that too. An application that sorts server-
side sends back set tv sorted sortedby=1 !descending to match.
numeric sorts a column by each value's numeric equivalent rather than as
text, so 9 KB lands before 10 KB. sortproxy names a different column
whose values do the sorting when this one is chosen — a formatted size
displayed in one column, the byte count sorted in another.
Sorting is stable against edits: changing an item's caption or a cell's value while a sort is in force re-sorts the rows, and the selection stays on the item rather than on the row index.
editable on a column lets its cells be edited; editable on the treeview
does the same for the key column, editing the item's caption.
Return opens the row editor on the current Enter-target column, and the
target starts on the key column — so with both editable, Return edits the
caption first. Left and Right walk the target across columns while the
editor is closed.
A committed edit raises edit with the column index, and the key column
reports column=-1 — the same convention sortedby uses.
Nothing is written to the item by the editor alone. edit is the request;
the value the tree shows afterwards is whatever the application sends back as
a cell.
A column can offer a fixed set of choices instead of free text. The options are a collection, and the column points at it:
kinds=new collection of=options children={
new option key=png value="PNG image"
new option key=txt value="Text"
}
tv=new treeview editable children={
kindc=new column id=kind caption="Kind" editable
a=new item caption="file"
}
An option is a stable key and the text shown for it:
| Property | Type | Default | Meaning |
|---|---|---|---|
key |
word | — | Stable option key. |
value |
string | — | Displayed option value. |
enum takes the collection's numeric wire ID, not its correlation key,
so this is a second batch as well — the number below is whatever the build
reply gave for kinds:
set tv.kindc enum=738 enum_store=key
Writing enum=kinds is an error — enum: expected an integer. Correlation
keys name objects in statement position; they do not resolve inside a
property value.
enum_store decides what a chosen option puts in the data field: value
(the default) stores the text that was shown, key stores the stable key
behind it. Cells always display the value either way, so key is what you
want whenever the display text might be translated or reworded.
| Does | |
|---|---|
Up Down
|
Move the current item. |
Left |
Collapse the branch, or step out to its parent. |
Right |
Expand the branch, or step into its first child. |
S-Left S-Right
|
The same, kept working while the plain arrows walk columns in an editable grid. |
Plus Minus
|
Expand / collapse the current branch. |
* |
Expand everything. |
Home End
|
First / last row. |
PageUp PageDown
|
A screenful. |
Space |
Activate; on a choice cell, open the picker. |
Return |
Edit where a column is editable, otherwise activate. |
| Click | Select. Double-click activates. |
| Header click | Sort, or drag a divider to resize. |
The sort commands and the column chooser (trinket_sort_ascending,
trinket_sort_mode_next, trinket_chooser and their siblings) have no
default key. They are reachable with the mouse, or through the header focus
zone below, or by an application binding a key to them.
Tab moves into the header bar as a stop of its own before leaving the
trinket: one stop for the whole bar, then drilling in cycles the column
captions and the [=] chooser button, with Space sorting the caption under
the cursor.
Expand-all is silent. * opens every branch without raising expand for
any of them. A client tracking expansion state by subscription will be out of
step after it.
A wire-side change does not echo. set tv.b expanded opens the branch and
raises nothing, because the client that sent it already knows. Events report
what the user did.
selected is a row index among the visible rows, so it counts the
children of an open branch and skips those of a closed one. Collapsing a
branch above the selection therefore changes the index of everything under
it, without anything having been selected or deselected.
The events avoid the problem by carrying both: item is the identity, and
selected is where it happens to be sitting. Track the item.
selected has ListView's ordering rule too — it indexes rows that
must exist already, so it belongs after children, not before:
new treeview selected=1 children={new item caption="a"; new item caption="b"}
-> selected = 0
new treeview children={new item caption="a"; new item caption="b"} selected=1
-> selected = 1
No error either way.
fit_width (the default) squeezes the columns into the space available and
there is no horizontal scrolling. Turn it off and the columns keep the widths
they were given, key_width applies to the tree column, and the grid scrolls
sideways.
fixed_left and fixed_right pin that many columns outside the scroll, so
the name stays put while the rest of the row moves.
treelines draws connectors down the indent space and a glyph on each leaf.
indent_width sets how far a level steps. ledger bands the non-selected
rows in the scheme's ledger colors.
showkey can turn the tree column off entirely, which leaves a plain
multi-column grid with no indentation — the treeview used as a table.
ListView — the flat single-column case · ComboBox — a list collapsed into a field · Common Properties · Templates and Aliases
KittyTK — image/tty Trinket Kit · MIT licensed · alpha, 0.1.x
Repository · Issues · Support on ko-fi
Sibling projects: PurfecTerm (terminal emulator) · mew (text editor) · PawScript (language)
Getting Started
Installation Building from Source Running a Display Host Your First Application Examples
Protocol
Protocol Overview Object Model Properties and Values Events Templates and Aliases Common Properties Introspection Transports and Security
Clients
Go Client Python Client C Client
Application Objects
Application · MenuBar · Window · MessageBox
Output Trinkets
Label · ProgressBar · StatusBar
Input Trinkets
TextInput · Editor · Terminal
Button · CheckBox · RadioButton
ListView · ComboBox · TreeView
Layout Trinkets
TabTrinket · Panel
ScrollArea · MDIPane
Separator · Spacer · Splitter
Other Trinkets
Layout Helpers