-
Notifications
You must be signed in to change notification settings - Fork 34
/
field_editor.go
168 lines (144 loc) Β· 4.56 KB
/
field_editor.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
package main
import (
"fmt"
"unicode"
"github.com/nsf/termbox-go"
)
type FieldEditor struct {
value []rune
cursor_pos int
last_value string
init_value string
width int
fixed int
overwrite bool
at_bol bool
at_eol bool
valid bool
}
// return 0 during processing, 1 when done, -1 when aborted
func (field_editor *FieldEditor) handleKeyEvent(event termbox.Event) (result int) {
result = 0
if len(field_editor.value) == 0 && event.Key != termbox.KeyEsc {
if event.Ch == 0 {
field_editor.setValue([]rune(field_editor.last_value))
} else if len(field_editor.init_value) > 0 {
field_editor.setValue([]rune(field_editor.init_value))
}
}
if field_editor.fixed > 0 {
if len(field_editor.value) > field_editor.fixed {
field_editor.setValue(field_editor.value[:field_editor.fixed])
}
}
if event.Key == termbox.KeyEnter {
// only accept valid input
if field_editor.valid {
result = 1
}
} else if event.Key == termbox.KeyEsc {
if len(field_editor.value) == 0 {
result = -1
}
field_editor.setValue(nil)
} else if event.Key == termbox.KeyArrowLeft {
field_editor.moveCursor(-1)
} else if event.Key == termbox.KeyArrowUp || event.Key == termbox.KeyCtrlA {
field_editor.at_bol = event.Key == termbox.KeyArrowUp
field_editor.setCursorPos(0)
} else if event.Key == termbox.KeyArrowRight {
field_editor.moveCursor(1)
} else if event.Key == termbox.KeyArrowDown || event.Key == termbox.KeyCtrlE {
field_editor.at_eol = event.Key == termbox.KeyArrowDown
field_editor.setCursorPos(len(field_editor.value))
} else if event.Key == termbox.KeyCtrlH || event.Key == termbox.KeyBackspace {
field_editor.delete_back()
} else if event.Key == termbox.KeyCtrlD || event.Key == termbox.KeyDelete {
field_editor.delete_front()
} else if event.Key == termbox.KeyCtrlK {
field_editor.setValue(make([]rune, 0))
} else if unicode.IsPrint(event.Ch) {
field_editor.insert(event.Ch)
} else if event.Key == termbox.KeySpace {
field_editor.insert(' ')
}
return result
}
func (field_editor *FieldEditor) getValue() string {
if len(field_editor.value) > 0 {
return string(field_editor.value)
}
return field_editor.last_value
}
func (field_editor *FieldEditor) setValue(value []rune) {
field_editor.value = value
field_editor.at_bol = false
field_editor.at_eol = false
if field_editor.cursor_pos > len(field_editor.value) {
field_editor.setCursorPos(len(field_editor.value))
}
}
func (field_editor *FieldEditor) setCursorPos(pos int) {
bol := field_editor.at_bol
eol := field_editor.at_eol
if pos < 0 {
pos = 0
bol = true
eol = false
} else if field_editor.fixed > 0 && pos >= field_editor.fixed {
pos = field_editor.fixed - 1
bol = false
eol = true
}
if pos > len(field_editor.value) {
pos = len(field_editor.value)
bol = false
eol = true
}
field_editor.cursor_pos = pos
field_editor.at_bol = bol
field_editor.at_eol = eol
}
func (field_editor *FieldEditor) moveCursor(delta int) {
field_editor.setCursorPos(field_editor.cursor_pos + delta)
}
func (field_editor *FieldEditor) insert(r rune) {
if field_editor.overwrite && field_editor.cursor_pos < len(field_editor.value) {
field_editor.value[field_editor.cursor_pos] = r
} else {
if field_editor.fixed > 0 && field_editor.cursor_pos == field_editor.fixed {
return
}
pos := field_editor.cursor_pos
field_editor.value = append(field_editor.value[:pos], append([]rune{r}, field_editor.value[pos:]...)...)
}
field_editor.moveCursor(1)
}
func (field_editor *FieldEditor) delete_front() {
pos := field_editor.cursor_pos
if pos < len(field_editor.value) {
field_editor.value = append(field_editor.value[:pos], field_editor.value[pos+1:]...)
}
}
func (field_editor *FieldEditor) delete_back() {
pos := field_editor.cursor_pos
if pos == 0 {
return
} else if pos < len(field_editor.value) {
field_editor.value = append(field_editor.value[:pos-1], field_editor.value[pos:]...)
} else {
field_editor.value = field_editor.value[:pos-1]
}
field_editor.moveCursor(-1)
}
func (field_editor *FieldEditor) drawFieldValueAtPoint(style Style, x, y int) int {
termbox.SetCursor(x+1+field_editor.cursor_pos, y)
fg, bg, value := style.field_editor_last_fg, style.field_editor_last_bg, field_editor.last_value
if len(field_editor.value) > 0 || len(field_editor.last_value) == 0 {
fg, bg, value = style.field_editor_fg, style.field_editor_bg, string(field_editor.value)
}
if !field_editor.valid {
fg, bg = style.field_editor_invalid_fg, style.field_editor_invalid_bg
}
return drawStringAtPoint(fmt.Sprintf(" %-*s ", field_editor.width, value), x, y, fg, bg)
}