-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathviewActions.go
255 lines (224 loc) · 5.58 KB
/
viewActions.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package main
import (
"errors"
"fmt"
"github.com/jroimartin/gocui"
aur "github.com/logrusorgru/aurora"
)
var popupDisplayed = false
// togglePopup toggles the popup window's visibility by bringing it to
// either the very front or very back.
func togglePopup() {
if !popupDisplayed {
g.SetViewOnTop(popup)
g.SetViewOnTop(searchOutline)
g.SetViewOnTop(searchSymbol)
g.SetViewOnTop(search)
g.SetCurrentView(search)
setTitle(searchOutline, "Enter brewery and beer name...")
} else {
setTitle(popup, "")
g.SetViewOnBottom(popup)
g.SetViewOnBottom(searchSymbol)
g.SetViewOnBottom(searchOutline)
g.SetViewOnBottom(search)
g.SetCurrentView(input)
}
popupDisplayed = !popupDisplayed
}
// updatePromptSymbol highlights the selected mode.
func updatePromptSymbol() {
v, _ := g.View(promptSymbol)
v.Clear()
switch mode := c.GetMode(); mode {
case stocking:
fmt.Fprintf(v, "%s >>", aur.BgBrown("Stocking"))
case serving:
fmt.Fprintf(v, "%s >>", aur.BgGreen("Serving"))
}
}
// clearView clears a given gocui view and hides the cursor.
func clearView(view string) {
g.Update(func(g *gocui.Gui) error {
v, err := g.View(view)
if err != nil {
return err
}
v.Clear()
x, y := v.Cursor()
v.MoveCursor(-x, -y, true)
return nil
})
}
// promptEditor handles keyboard input for the input line of a prompt.
func promptEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
if ch != 0 && mod == 0 {
v.EditWrite(ch)
return
}
switch key {
case gocui.KeySpace:
v.EditWrite(' ')
case gocui.KeyBackspace, gocui.KeyBackspace2:
v.EditDelete(true)
case gocui.KeyDelete:
v.EditDelete(false)
case gocui.KeyInsert:
v.Overwrite = !v.Overwrite
case gocui.KeyArrowDown:
_ = v.SetCursor(len(v.Buffer())-1, 0)
case gocui.KeyArrowUp:
v.MoveCursor(0, -1, false)
case gocui.KeyArrowLeft:
v.MoveCursor(-1, 0, false)
case gocui.KeyArrowRight:
}
}
// displayError displays an error message in a bright red popup.
//
// TODO: Make it possible to escape from this popup (using hideError)
func displayError(e error) error {
maxX, maxY := g.Size()
x0 := maxX / 6
y0 := maxY / 6
x1 := (5 * maxX) / 6
y1 := (5 * maxY) / 6
if v, err := g.SetView(errorView, x0, y0, x1, y1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
v.Title = "ERROR"
v.Frame = true
v.Wrap = true
v.Autoscroll = true
v.BgColor = gocui.ColorRed
v.FgColor = gocui.ColorWhite
v.Clear()
fmt.Fprintln(v, e.Error())
g.SetCurrentView(v.Name())
}
return nil
}
// hideError hides the error view.
//
// TODO: figure out why this isn't being called by the ESC keybinding.
func hideError(g *gocui.Gui, _ *gocui.View) error {
g.DeleteView(errorView)
return nil
}
// popupScrollUp moves the cursor selection a row up in the popup.
func popupScrollUp(_ *gocui.Gui, v *gocui.View) error {
err := moveViewCursorUp(v)
if err != nil {
logAllError(err)
}
return nil
}
// popupScrollDown moves the cursor selection a row down in the popup.
func popupScrollDown(_ *gocui.Gui, v *gocui.View) error {
err := moveViewCursorDown(v, false)
if err != nil {
logAllError(err)
}
return err
}
// moveViewCursorDown moves the cursor selection a row down in a given view.
func moveViewCursorDown(v *gocui.View, allowEmpty bool) error {
cx, cy := v.Cursor()
ox, oy := v.Origin()
nextLine, err := getNextViewLine(v)
if err != nil {
return err
}
if !allowEmpty && nextLine == "" {
return nil
}
if err := v.SetCursor(cx, cy+1); err != nil {
if err := v.SetOrigin(ox, oy+1); err != nil {
return err
}
}
return nil
}
// moveViewCursorUp moves the cursor selection a row up in a given view.
func moveViewCursorUp(v *gocui.View) (err error) {
cx, cy := v.Cursor()
ox, oy := v.Origin()
switch {
case cy == 0 && oy == 0: // already at the top
return nil
case cy > 0: // cursor has priority over origin
if err = v.SetCursor(cx, cy-1); err != nil {
return err
}
return nil
case oy > 0:
if err = v.SetOrigin(ox, oy-1); err != nil {
return err
}
return nil
default:
return errors.New("invalid cursor or origin position")
}
}
// getViewLine fetches the text shown in the row highlighted by
// the user's cursor position.
func getViewLine(v *gocui.View) (string, error) {
var l string
var err error
_, cy := v.Cursor()
if l, err = v.Line(cy); err != nil {
l = ""
}
return l, err
}
// getViewLine fetches the text shown in the row belwo the one
// highlighted by the user's cursor position.
func getNextViewLine(v *gocui.View) (string, error) {
var l string
var err error
_, cy := v.Cursor()
if l, err = v.Line(cy + 1); err != nil {
l = ""
}
return l, err
}
// resetViewCursor sets the user's cursor position to the topmost
// row of a given gocui view.
func resetViewCursor(v *gocui.View) error {
ox, _ := v.Origin()
cx, _ := v.Cursor()
if err := v.SetCursor(ox, 0); err != nil {
if err := v.SetOrigin(cx, 0); err != nil {
return err
}
}
return nil
}
// scrollView scrolls the user's current highlighted selection in a gocui view
// by the given number of rows.
//
// Positive dy corresponds to a downward movement, while negative dy moves the
// cursor up. If the cursor cannot be moved, it is clipped to the maximum or
// minimum row.
func scrollView(v *gocui.View, dy int) error {
if v != nil {
v.Autoscroll = false
ox, oy := v.Origin()
_, height := v.Size()
if dy > 0 {
if l, _ := v.Line(height); l == "" {
return nil
}
}
if err := v.SetOrigin(ox, oy+dy); err != nil {
return err
}
}
return nil
}
// setTitle sets the title of a view in the main gocui object.
func setTitle(view string, title string) {
v, _ := g.View(view)
v.Title = title
}