Tree views, a styles example, and the Readme for all of it

A tree node is a TreeViewItem: a header and items, patched by key as a
list's items are. The chosen node is chosen by its key, once the nodes are
there, and a click sends the key. SelectedItem is a direct property, which
a clear does not reset, so no choice is set as null.

The Readme now covers menus and keys, dialogs, styles and themes, and the
new controls. docs/styles.png is examples/styles.bjo.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-25 18:10:53 +01:00
parent e3c54c4348
commit 8941425f05
6 changed files with 321 additions and 10 deletions

View file

@ -22,6 +22,7 @@
list-box tabs tab
menu-bar submenu menu-item menu-separator
toggle-switch radio number-input date-picker auto-complete expander
tree-view tree-node
column row grid scroll border flow dock
;; Wrappers.
keyed at paint with-context-menu tooltip at-top at-bottom at-left at-right classed
@ -44,7 +45,7 @@
ListBoxKind TabsKind TabKind
MenuBarKind MenuItemKind SeparatorKind ContextKind ContextMenuKind
ToggleSwitchKind RadioKind NumberKind DateKind AutoCompleteKind
ExpanderKind WrapKind DockKind
ExpanderKind WrapKind DockKind TreeKind TreeNodeKind
ColumnKind RowKind GridKind ScrollKind BorderKind)))
;; A property of a control. A kind takes only some of them; the app ignores
@ -84,14 +85,16 @@
(: PropExpanded bool) ; whether an expander shows its content
(: PropDate string) ; a date picker's date, as "2026-10-25"
(: PropDockSide int) ; where a view is in its dock: 0 to 3
(: PropClasses (Vec string))))) ; the classes that styles match
(: PropClasses (Vec string)) ; the classes that styles match
(: PropChosenKey string)))) ; the key of a tree's chosen node
;; An event, and the message it sends.
(type (: (On %m) (Union (: OnClick %m)
(: OnInput (-> string %m))
(: OnToggle (-> bool %m))
(: OnSlide (-> double %m))
(: OnSelect (-> int %m)))))
(: OnSelect (-> int %m))
(: OnPick (-> string %m)))))
;; One control and what is in it.
;;
@ -393,6 +396,28 @@
(children [child])
(key None)))
;; A tree of nodes made by `tree-node`, with the node whose key is `chosen`
;; chosen, or none for "". A click on a node sends `(on-pick key)`.
(: (-> string (-> string %m) (#:width double) (#:height double) (#:margin double)
#:rest (View %m) (View %m)))
(defun (tree-view chosen on-pick #:width 0.0 #:height 0.0 #:margin 0.0 #:rest nodes)
(View (kind TreeKind)
(props (with-layout [(PropChosenKey chosen)] width height margin 0.0))
(events [(OnPick on-pick)])
(children (array->vec nodes))
(key None)))
;; A node of a tree, known by `key`, which must be one of its own in the
;; tree. It opens to show `children`, more nodes, and is open at first when
;; `#:expanded`; after that it is opened and closed by the user.
(: (-> string string (#:expanded bool) #:rest (View %m) (View %m)))
(defun (tree-node key header #:expanded #f #:rest children)
(View (kind TreeNodeKind)
(props [(PropLabel header) (PropExpanded expanded)])
(events [])
(children (array->vec children))
(key (Some key))))
;; A checkbox that is `checked?`. A click sends `(on-toggle checked)`, with
;; the new state.
(: (-> string bool (-> bool %m) (#:enabled bool) (#:margin double) (View %m)))