forked from jojomi/gonsole
-
Notifications
You must be signed in to change notification settings - Fork 4
/
list.go
122 lines (100 loc) · 2.53 KB
/
list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package gonsole
import "github.com/nsf/termbox-go"
type List struct {
BaseControl
options []string
selectedIndex int
topIndex int
onSumbit func(int)
}
func NewList(win AppWindow, parent Container, id string) *List {
list := &List{}
list.Init(win, parent, id, "list")
list.SetFocusable(true)
parent.AddControl(list)
return list
}
func (l *List) SelectedItem() int {
return l.selectedIndex
}
func (l *List) Options() []string {
return l.options
}
func (l *List) SetOptions(options []string) {
l.options = options
}
func (l *List) OnSumbit(handler func(int)) {
l.onSumbit = handler
}
func (l *List) Repaint() {
if !l.Dirty() {
return
}
l.BaseControl.Repaint()
contentBox := l.ContentBox()
t := l.Theme()
focused := ""
if l.Focused() {
focused = "focused."
}
count := len(l.options)
if count > contentBox.Height {
count = contentBox.Height
pos := ScrollPos(l.selectedIndex, len(l.options), contentBox.Height)
fg, bg := t.ColorTermbox(focused+"scroll.fg"), t.ColorTermbox(focused+"scroll.bg")
DrawScrollBar(contentBox.Right(), contentBox.Top, contentBox.Height, pos, fg, bg)
contentBox = contentBox.Minus(Sides{Right: 1})
}
for i := 0; i < count; i++ {
fg, bg := t.ColorTermbox(focused+"fg"), t.ColorTermbox(focused+"bg")
if i+l.topIndex == l.selectedIndex {
fg, bg = t.ColorTermbox(focused+"selected.fg"), t.ColorTermbox(focused+"selected.bg")
}
DrawTextSimple(l.options[l.topIndex+i], true, Box{contentBox.Left, contentBox.Top + i, contentBox.Width, 1}, fg, bg)
}
}
func (l *List) ParseEvent(ev *termbox.Event) (handled, repaint bool) {
switch ev.Type {
case termbox.EventKey:
switch ev.Key {
case termbox.KeyArrowDown:
if l.selectedIndex < len(l.options)-1 {
l.selectedIndex++
contentBox := l.ContentBox()
if l.selectedIndex == l.topIndex+contentBox.Height {
l.topIndex++
}
}
return true, true
case termbox.KeyArrowUp:
if l.selectedIndex > 0 {
l.selectedIndex--
if l.selectedIndex < l.topIndex {
l.topIndex--
}
}
return true, true
case termbox.KeyHome:
l.selectedIndex = 0
l.topIndex = 0
return true, true
case termbox.KeyEnd:
l.selectedIndex = len(l.options) - 1
contentBox := l.ContentBox()
if contentBox.Height > 0 {
l.topIndex = len(l.options) - contentBox.Height
}
return true, true
case termbox.KeySpace:
fallthrough
case termbox.KeyEnter:
if l.onSumbit != nil {
l.onSumbit(l.selectedIndex)
}
return true, false
}
case termbox.EventError:
panic(ev.Err)
}
return false, false
}