6 "github.com/nsf/termbox-go"
9 type TreeItem interface {
10 TreeItemStyle(fg, bg Attribute, active bool) (Attribute, Attribute)
14 type renderedTreeItem struct {
23 Generator func(item TreeItem) []TreeItem
24 Listener func(ui *Ui, tree *Tree, item TreeItem)
26 lines []renderedTreeItem
34 func bounded(i, lower, upper int) int {
44 func (t *Tree) uiInitialize(ui *Ui) {
48 func (t *Tree) uiSetActive(active bool) {
53 func (t *Tree) uiSetBounds(x0, y0, x1, y1 int) {
61 func (t *Tree) Rebuild() {
62 if t.Generator == nil {
63 t.lines = []renderedTreeItem{}
67 lines := []renderedTreeItem{}
68 for _, item := range t.Generator(nil) {
69 children := t.rebuild_rec(item, 0)
71 lines = append(lines, children...)
75 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() {
107 for y := t.y0; y < t.y1; y++ {
108 var reader *strings.Reader
111 if line < len(t.lines) {
112 item = t.lines[line].Item
113 level = t.lines[line].Level
114 reader = strings.NewReader(item.String())
116 for x := t.x0; x < t.x1; x++ {
122 if reader != nil && level*2 <= dx {
123 if ch, _, err := reader.ReadRune(); err == nil {
125 fg, bg = item.TreeItemStyle(fg, bg, t.active && t.activeLine == dy)
128 termbox.SetCell(x, y, chr, termbox.Attribute(fg), termbox.Attribute(bg))
134 func (t *Tree) uiKeyEvent(mod Modifier, key Key) {
137 t.activeLine = bounded(t.activeLine-1, 0, len(t.lines)-1)
139 t.activeLine = bounded(t.activeLine+1, 0, len(t.lines)-1)
141 if t.Listener != nil && t.activeLine >= 0 && t.activeLine < len(t.lines) {
142 t.Listener(t.ui, t, t.lines[t.activeLine].Item)
148 func (t *Tree) uiCharacterEvent(ch rune) {