-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmenu.go
138 lines (123 loc) · 3.54 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
"time"
)
type menu struct {
options []string
title string
color ui.Color
border bool
selectedColor ui.Color
*fitting
associatedList *widgets.List
// asociado a una accion/seleccion:
selection int
action string
}
func NewMenu() menu {
return menu{border: true, color: ui.ColorYellow, selectedColor: ui.ColorClear, selection: -1}
}
func (theMenu *menu) GetSelection() int {
return theMenu.associatedList.SelectedRow
}
func InitMenu(theMenu *menu) {
menu := widgets.NewList()
menu.Rows = theMenu.options
menu.Title = theMenu.title
menu.TextStyle = ui.NewStyle(theMenu.color)
menu.SelectedRowStyle = ui.NewStyle(theMenu.selectedColor)
menu.SetRect(theMenu.fitting.getRect())
menu.Border = theMenu.border
theMenu.associatedList = menu // LAST LINE
}
func RenderMenu(theMenu *menu) {
ui.Render(theMenu.associatedList)
}
func (theMenu *menu) Poller(askedToPoll <-chan bool) {
polling := false
for {
polling = getRequest(askedToPoll, polling)
if polling {
keyIdentifier := AskForKeyPress()
switch keyIdentifier {
case "":
time.Sleep(time.Millisecond * 20)
case "<Up>", "j":
theMenu.associatedList.ScrollUp()
//theMenu.associatedList.TextStyle = ui.NewStyle()
case "<Down>", "k":
theMenu.associatedList.ScrollDown()
case "<Enter>":
theMenu.selection = theMenu.associatedList.SelectedRow
theMenu.action = keyIdentifier
case "<End>":
theMenu.associatedList.ScrollBottom()
case "<Home>":
theMenu.associatedList.ScrollTop()
default:
theMenu.selection = theMenu.associatedList.SelectedRow
theMenu.action = keyIdentifier
continue
}
theMenu.associatedList.SelectedRowStyle = ui.NewStyle(theMenu.selectedColor)
ui.Render(theMenu.associatedList)
} else if askedToPoll == nil {
//time.Sleep(1000*time.Millisecond) // TODO make this even cleaner. a return would be fantastic
return
} else {
_, ok := <- askedToPoll // CHECK IF CHANNEL CLOSED
if !ok {
time.Sleep(20*time.Millisecond)
return
}
time.Sleep(1000*time.Millisecond)
theMenu.associatedList.SelectedRowStyle = ui.NewStyle(theMenu.color)
}
}
}
type fitting struct { // This stuff aint as stuffy as it looks
widthStart [3]int // 3 unit vector used to position each of the 4 window borders
heightStart [3]int // first two units are used to indicate fraction of window. Last one is a constant character postion
widthEnd [3]int // [1, 2, 3] means the border is positioned 3 character lengths after halfway mark of terminal
heightEnd [3]int // [0, 5, 6] means the border is positioned 6 characters where leftwise terminal border begins. 5 is meaningless
}
func CreateFitting(wS [3]int, hS [3]int, wE [3]int, hE [3]int) *fitting {
var P fitting
if wS[1] == 0 {
wS[1] = 1
}
if wE[1] == 0 {
wE[1] = 1
}
if hS[1] == 0 {
hS[1] = 1
}
if hE[1] == 0 {
hE[1] = 1
}
P.widthStart = wS
P.heightStart = hS
P.widthEnd = wE
P.heightEnd = hE
return &P
}
func (theMenu menu) GetDims() (X int, Y int) {
x1, y1, x2, y2 := theMenu.getRect()
if x1 > x2 {
X = x1 - x2
} else {
X = x2 - x1
}
if y1 > y2 {
Y = y1 - y2
} else {
Y = y2 - y1
}
return X, Y
}
func (P fitting) getRect() (int, int, int, int) {
width, height := ui.TerminalDimensions()
return width*P.widthStart[0]/P.widthStart[1] + P.widthStart[2], height*P.heightStart[0]/P.heightStart[1] + P.heightStart[2], width*P.widthEnd[0]/P.widthEnd[1] + P.widthEnd[2], height*P.heightEnd[0]/P.heightEnd[1] + P.heightEnd[2]
}