MyGo
Tree

Collections

Tree

Items that open and close, built inside the items they belong to.

Tree

ui.Tree creates a tree whose items ui.TreeItem builds, each inside the item it belongs to. An item's children show while its *bool is true; a click on its arrow opens or closes it, and Clicked reports a click elsewhere on it, or Enter, for choosing it, which Selected shows.

item := func(path, label string, open *bool, children func()) {
	if ui.TreeItem(c, label, open, children).Selected(app.chosen == path).Clicked() {
		app.chosen = path
	}
}
ui.Tree(c, func() {
	item("src", "src", &app.srcOpen, func() {
		item("src/main.go", "main.go", nil, nil)
	})
	item("go.mod", "go.mod", nil, nil)
})

Nil children, or a nil open, makes a leaf.

Keyboard

The tree is one stop of Tab, which goes to the item that had the focus last, or the one Selected. While an item has the keyboard focus, Up and Down move it to the items around, Home and End to the first and the last, Right opens the item or moves to its first child, and Left closes it or moves to its parent; right to left, Left opens and Right closes. Typing the first letters of an item moves to it, and the same letter again to the next item starting with it.

A tree builds every item it shows. For trees of thousands of items, or with columns, use an outline, which builds only the rows in view.

Without a look

ui.TreeBase is a tree without a look, for rows of your own, as a JSON viewer's: a Root column holding the items, each made by Item, whose Row you style and fill, and whose Group builds the items inside it, in a column below the row, while its *bool is true (a nil one makes a leaf). The tree has the keys and the focus of Tree's, and Depth says how deep an item is, to indent its row by. A key given with Context.Key before Item keeps the focus on an item as items above it open and close.

var node func(n *Node)
tree := ui.TreeBase(c)
tree.Root.Children(func() {
	node = func(n *Node) {
		c.Key(n.path)
		item := tree.Item(n.open) // nil for a leaf
		row := item.Row.Gap(4).Padding(3, 8).PaddingStart(8 + 16*float32(item.Depth())).Radius(6)
		if app.chosen == n.path {
			row.Background(t.Surface)
		}
		if row.Clicked() {
			app.chosen = n.path
		}
		row.Children(func() {
			if n.open != nil {
				arrow := ui.Icon(c, chevron).Size(16, 16)
				if *n.open {
					arrow.Rotate(90)
				}
				if arrow.Clicked() {
					*n.open = !*n.open
				}
			}
			ui.Text(c, n.key).FontWeight(500)
			ui.Text(c, n.value).TextColor(t.TextMuted)
		})
		item.Group(func() {
			for _, kid := range n.children {
				node(kid)
			}
		}) // nil while closed; style it, as with a line along it
	}
	for _, n := range app.roots {
		node(n)
	}
})

Tree is TreeBase with the theme's look. TreeBase builds every item that shows; for trees of thousands of items, use an outline with a Prefix of your own. See custom widgets.

Accessibility

Assistive technology sees a tree of items, each with its level, open or closed when it has children, and which of the items shown it is, as an outline's rows; it opens and closes them as the arrows do.