6 "github.com/nsf/termbox-go"
9 type TreeItem interface {
10 TreeItemStyle(active bool) (Attribute, Attribute)
14 type renderedTreeItem struct {
20 type TreeFunc func(item TreeItem) []TreeItem
21 type TreeListener func(ui *Ui, tree *Tree, item TreeItem)
29 lines []renderedTreeItem
37 func bounded(i, lower, upper int) int {
47 func (t *Tree) uiInitialize(ui *Ui) {
51 func (t *Tree) uiSetActive(active bool) {
55 func (t *Tree) uiSetBounds(x0, y0, x1, y1 int) {
62 func (t *Tree) Rebuild() {
63 if t.Generator == nil {
64 t.lines = []renderedTreeItem{}
68 lines := []renderedTreeItem{}
69 for _, item := range t.Generator(nil) {
70 children := t.rebuild_rec(item, 0)
72 lines = append(lines, children...)
76 t.activeLine = bounded(t.activeLine, 0, len(t.lines)-1)
79 func (t *Tree) rebuild_rec(parent TreeItem, level int) []renderedTreeItem {
83 lines := []renderedTreeItem{
89 for _, item := range t.Generator(parent) {
90 children := t.rebuild_rec(item, level+1)
92 lines = append(lines, children...)
98 func (t *Tree) uiDraw() {
104 for y := t.y0; y < t.y1; y++ {
105 var reader *strings.Reader
108 if line < len(t.lines) {
109 item = t.lines[line].Item
110 level = t.lines[line].Level
111 reader = strings.NewReader(item.String())
113 for x := t.x0; x < t.x1; x++ {
119 if reader != nil && level*2 <= dx {
120 if ch, _, err := reader.ReadRune(); err == nil {
122 fg, bg = item.TreeItemStyle(t.active && t.activeLine == dy)
125 termbox.SetCell(x, y, chr, termbox.Attribute(fg), termbox.Attribute(bg))
131 func (t *Tree) uiKeyEvent(mod Modifier, key Key) {
134 t.activeLine = bounded(t.activeLine-1, 0, len(t.lines)-1)
136 t.activeLine = bounded(t.activeLine+1, 0, len(t.lines)-1)
138 if t.Listener != nil && t.activeLine >= 0 && t.activeLine < len(t.lines) {
139 t.Listener(t.ui, t, t.lines[t.activeLine].Item)
145 func (t *Tree) uiCharacterEvent(ch rune) {