-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscrollview.go
123 lines (105 loc) · 2.8 KB
/
scrollview.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
123
package windeau
import (
"github.com/nsf/termbox-go"
)
const (
SVMoreUp string = "/\\more/\\"
SVMoreDown string = "\\/more\\/"
)
type Scrollview struct {
Parent Drawable
Entries []string
Position int
Handler EventHandler
visibleRowCount int
}
func MakeScrollview(parent *FocusableWindow, entries []string, handler EventHandler) *Scrollview {
scrollview := &Scrollview{Entries: entries, Position: -1, Handler: handler}
scrollview.SetParent(parent)
return scrollview
}
func (s *Scrollview) SetParent(parent Drawable) {
s.Parent = parent
s.determineVisibleRowCount()
}
func (s *Scrollview) IsRoot() bool {
return false
}
func (s *Scrollview) IsFocused() bool {
return s.Parent.IsFocused()
}
func (s *Scrollview) GetRect() Rect {
return s.Parent.GetRect().ShrinkBy(1)
}
func (s *Scrollview) WithinBox(x, y int) bool {
return s.Parent.WithinBox(x, y)
}
func (s *Scrollview) GetEntries() []string {
return s.Entries
}
func (s *Scrollview) GetPosition() int {
return s.Position
}
func (s *Scrollview) SetPosition(position int) int {
if position >= 0 && position < len(s.GetEntries()) {
s.Position = position
}
return s.Position
}
func (s *Scrollview) SetHandler(handler EventHandler) {
s.Handler = handler
}
func (s *Scrollview) Draw() {
if s.Parent == nil {
panic("Parent cannot be nil for a Scrollview")
}
s.Parent.Draw()
rect := s.GetRect()
for i := 0; i < s.visibleRowCount; i++ {
entry := i + s.startingPosition()
if i >= len(s.GetEntries()) {
break
}
fg, bg := termbox.ColorWhite, termbox.ColorDefault
if s.Position == entry && s.IsFocused() {
bg = termbox.ColorBlue
}
x := rect.X
y := rect.Y + i
message := s.GetEntries()[entry]
DrawStringWithinSize(message, x, y, rect.Width, fg, bg)
}
s.hintMoreDataExists()
}
func (s *Scrollview) startingPosition() int {
halfway := s.visibleRowCount / 2
numberOfEntries := len(s.GetEntries())
switch {
case numberOfEntries < s.visibleRowCount:
return 0
case s.Position < s.visibleRowCount:
return 0
case s.Position >= numberOfEntries-s.visibleRowCount:
return numberOfEntries - s.visibleRowCount
default:
return s.Position - halfway
}
}
func (s *Scrollview) determineVisibleRowCount() {
bindingBox := s.GetRect()
s.visibleRowCount = bindingBox.Height - 1
}
func (s *Scrollview) hintMoreDataExists() {
if len(s.GetEntries()) < s.visibleRowCount {
return
}
parentRect := s.Parent.GetRect()
fg, bg := s.Parent.GetColors()
leftEdge := parentRect.X + parentRect.Width - 2
if s.Position >= s.visibleRowCount {
DrawStringWithinSize(SVMoreUp, leftEdge-len(SVMoreUp), parentRect.Y, parentRect.Width-2, fg, bg)
}
if s.Position < len(s.GetEntries())-s.visibleRowCount {
DrawStringWithinSize(SVMoreDown, leftEdge-len(SVMoreDown), parentRect.Y+parentRect.Height-1, parentRect.Width-2, fg, bg)
}
}