Widgets
Each is a small thing that draws itself and answers events. The hard parts — modality, overlays, scrolling, focus order, the pointer — belong to the tree, which is why a widget stays small and why anything assembled from them behaves like the rest.
Every widget below is on this page, live. New ones arrive one at a time; the descriptions are the modules’ own.
A single-line editable text field.
Caret, placeholder, submit on Enter, dead keys, and selection: focus takes the whole field, a press places the caret, a second takes the word, a third takes everything. Ctrl or Option and an arrow move by word, and copy, cut and paste go through the application as the editor’s do. Deliberately absent for now: undo.
A multi-line text editor that edits through a document it does not own.
It asks only for the lines it is about to paint, so a file too big to load can sit behind it. Selection — a press, a word, a line — word motion, undo, paging, go-to-line, match highlighting, and bars down the side and along the bottom that are absent, not greyed, when the text fits.
What the tree owns
These are properties of the scene graph rather than things you place. That is what keeps a modal from needing flags, a drawer from needing a second surface, and an on-screen keyboard from stealing the caret out of the field it is typing into.
A modal is a scene pushed over a dimmed backdrop in the same buffer. Nothing underneath needs disabling: it simply stops receiving input.
A panel that slides in from an edge and dims what is behind it. Escape, or a press on the dim, slides it out.
Neither modal nor dimming — which is what lets the on-screen keyboard type into the field above it without the field ever losing its caret.
Owned by the tree so they paint above every widget and below the pointer.
Transient messages that fade on the tree’s own clock.
What a Select or a menu opens into, above everything, closed by Escape or a press outside.
Mark a node scrollable and it becomes a viewport: wheel, page keys, touch-drag, clipping and hit testing all agree, because one reflow computes them.
Tab moves through the tree in file order, and focus below the fold scrolls itself into view.
On a bare panel there is nothing else to draw a pointer, so the tree composites one — and moving it costs two sprite-sized rectangles.
Missing one? Assemble it.
There was no table widget when the record editor was written, so a row became a full-width Button with Labels on top: labels are not interactive, so a click falls through them and arrives as a selection. That is how most of the widgets you will miss get built — and some of them, like Table, later became real ones.