-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontrol.go
129 lines (107 loc) · 2.48 KB
/
control.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
package main
import (
"fmt"
"github.com/go-vgo/robotgo"
hook "github.com/robotn/gohook"
)
type ErrNoReactionForKey struct {
Key rune
}
func (keyerr ErrNoReactionForKey) Error() string {
return fmt.Sprint("Ignoring key ", keyerr.Key)
}
type ChatWheelI interface {
ReactOnKey(hook.Event) error
}
type WheelController struct {
Start *WheelFrame
Current *WheelFrame
}
func (wc *WheelController) getCurrOpts() []WheelItemI {
return wc.Current.Items
}
func (wc *WheelController) ReactOnKey(ev hook.Event) error {
kchar := ev.Keychar
if isBackspace(kchar) {
return nil
}
if wc.Current == nil {
if kchar == getActivatingChar() {
removePreviousCharacters(1)
wc.Current = wc.Start.Response()
}
return nil
}
i := deductIndFrom(kchar)
removePreviousCharacters(wc.Current.FrameSize+1)
opts := wc.getCurrOpts()
if isOutOfBounds(i, opts) {
wc.Current = nil
return ErrNoReactionForKey{kchar}
}
whi := opts[i].Response()
wc.Current = whi
return nil
}
func removePreviousCharacters(n int) {
for i := 0; i < n; i++ {
robotgo.KeyPress(robotgo.Left, robotgo.Shift)
}
robotgo.KeyPress(robotgo.Backspace)
}
func (wc *WheelController) addItem(nextI int, it WheelItemI) {
if nextI >= getFrameCap() - 1 {
var oldKey rune
it, oldKey = reassignAndSwapKeys(it, makeKey(0))
slider := makeWheelFrame(oldKey, ">>")
wc.Current.addItem(slider)
wc.Current = slider
}
wc.Current.addItem(it)
}
type WheelItemI interface {
Response() *WheelFrame
GetTag() string
}
func makeWheelFrame(key rune, prompt string) *WheelFrame {
wf := WheelFrame{key, prompt, nil, 0}
return &wf
}
type WheelFrame struct {
Key rune
Prompt string
Items []WheelItemI
FrameSize int
}
func (wf *WheelFrame) Response() *WheelFrame {
for _, wi := range wf.Items {
robotgo.TypeStr(wi.GetTag())
}
return wf
}
func (wf *WheelFrame) GetTag() string {
return makeTag(wf.Key, wf.Prompt)
}
func (wf *WheelFrame) addItem(whi WheelItemI) {
wf.Items = append(wf.Items, whi)
wf.FrameSize += len(whi.GetTag())
}
type WheelChatOption struct {
Key rune
Prompt string
Text string
}
func (wco WheelChatOption) GetTag() string {
return makeTag(wco.Key, wco.Prompt)
}
func (wco WheelChatOption) Response() *WheelFrame {
robotgo.TypeStr(wco.Text)
return nil
}
func makeWheelChatOption(key rune, prompt string, phrase string) WheelChatOption {
MAX_INTRO_LEN := getIntroLen()
if len(prompt) > MAX_INTRO_LEN {
prompt = prompt[:MAX_INTRO_LEN-2] + ".."
}
return WheelChatOption{key, prompt, phrase}
}