1 package uiterm // import "layeh.com/barnard/uiterm"
6 "github.com/nsf/termbox-go"
9 type TreeItem interface {
10 TreeItemStyle(fg, bg Attribute, active bool) (Attribute, Attribute)
14 type renderedTreeItem struct {
22 Generator func(item TreeItem) []TreeItem
23 Listener func(ui *Ui, tree *Tree, item TreeItem)
25 lines []renderedTreeItem
33 func bounded(i, lower, upper int) int {
43 func (t *Tree) uiInitialize(ui *Ui) {
47 func (t *Tree) uiSetActive(active bool) {
52 func (t *Tree) uiSetBounds(x0, y0, x1, y1 int) {
60 func (t *Tree) Rebuild() {
61 if t.Generator == nil {
62 t.lines = []renderedTreeItem{}
66 lines := []renderedTreeItem{}
67 for _, item := range t.Generator(nil) {
68 children := t.rebuild_rec(item, 0)
70 lines = append(lines, children...)
74 t.activeLine = bounded(t.activeLine, 0, len(t.lines)-1)
78 func (t *Tree) rebuild_rec(parent TreeItem, level int) []renderedTreeItem {
82 lines := []renderedTreeItem{
88 for _, item := range t.Generator(parent) {
89 children := t.rebuild_rec(item, level+1)
91 lines = append(lines, children...)
97 func (t *Tree) uiDraw() {
106 for y := t.y0; y < t.y1; y++ {
107 var reader *strings.Reader
110 if line < len(t.lines) {
111 item = t.lines[line].Item
112 level = t.lines[line].Level
113 reader = strings.NewReader(item.String())
115 for x := t.x0; x < t.x1; x++ {
121 if reader != nil && level*2 <= dx {
122 if ch, _, err := reader.ReadRune(); err == nil {
124 fg, bg = item.TreeItemStyle(fg, bg, t.active && t.activeLine == dy)
127 termbox.SetCell(x, y, chr, termbox.Attribute(fg), termbox.Attribute(bg))
133 func (t *Tree) uiKeyEvent(mod Modifier, key Key) {
136 t.activeLine = bounded(t.activeLine-1, 0, len(t.lines)-1)
138 t.activeLine = bounded(t.activeLine+1, 0, len(t.lines)-1)
140 if t.Listener != nil && t.activeLine >= 0 && t.activeLine < len(t.lines) {
141 t.Listener(t.ui, t, t.lines[t.activeLine].Item)
147 func (t *Tree) uiCharacterEvent(ch rune) {