-
Notifications
You must be signed in to change notification settings - Fork 0
/
menu.go
executable file
·119 lines (107 loc) · 2.3 KB
/
menu.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
/*
* Copyright (c) 2023 Brandon Jordan
*/
package ttuy
import (
"fmt"
"os"
"github.com/eiannone/keyboard"
)
var menuTitle string
var menuOptions []Option
var optionIndex int
var optionCount int
var lastMenuContent string
var lastOptionIndex = -1
const selected = "[x]"
const notSelected = "[ ]"
type Option struct {
Label string
Callback func()
Disabled bool
}
// Menu displays a menu of options and triggers the callback corresponding to the option chosen
func Menu(title string, options []Option) {
menuTitle = title
menuOptions = options
optionIndex = 0
lastOptionIndex = -1
lastMenuContent = ""
optionCount = len(menuOptions)
firstAvailable()
go ReadKeys(handleMenuKeys)
Painter(func() (menu string) {
if lastOptionIndex != optionIndex {
menu = Style(menuTitle, Bold, GreenText) + eol
for i, option := range menuOptions {
switch {
case option.Disabled:
menu += Style(fmt.Sprintf(notSelected+" %s"+eol, option.Label), Dim)
case i == optionIndex:
menu += Style(selected, MagentaText) + fmt.Sprintf(" %s"+eol, option.Label)
default:
menu += fmt.Sprintf(notSelected+" %s"+eol, option.Label)
}
}
lastMenuContent = menu
lastOptionIndex = optionIndex
} else {
menu = lastMenuContent
}
return
})
}
func firstAvailable() {
if !menuOptions[0].Disabled {
return
}
for _, option := range menuOptions {
if !option.Disabled {
continue
}
optionIndex++
}
}
func handleMenuKeys(key keyboard.Key) {
switch key {
case keyboard.KeyCtrlC:
StopPainting()
CursorShow()
os.Exit(0)
case keyboard.KeyArrowUp:
var nextIndex = optionIndex - 1
var nextOptionDisabled = true
for nextOptionDisabled {
if nextIndex > -1 {
nextOptionDisabled = menuOptions[nextIndex].Disabled
if !nextOptionDisabled {
optionIndex = nextIndex
break
}
} else {
break
}
nextIndex--
}
case keyboard.KeyArrowDown:
var nextIndex = optionIndex + 1
var nextOptionDisabled = true
for nextOptionDisabled {
if nextIndex < optionCount {
nextOptionDisabled = menuOptions[nextIndex].Disabled
if !nextOptionDisabled {
optionIndex = nextIndex
break
}
} else {
break
}
nextIndex++
}
case keyboard.KeyEnter:
selectedOption := menuOptions[optionIndex]
selectedOption.Callback()
StopPainting()
return
}
}