This repository has been archived by the owner on Jul 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
key.go
332 lines (284 loc) · 8.68 KB
/
key.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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
// Copyright (c) 2018, Randall C. O'Reilly. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// based on golang.org/x/mobile/event:
//
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package key defines an event for physical keyboard keys, for the GoGi GUI
// system.
//
// On-screen software keyboards do not send key events.
package key
import (
"fmt"
"image"
"strings"
"unicode"
"github.com/rcoreilly/goki/gi/oswin"
"github.com/rcoreilly/goki/ki/kit"
)
// key.Event is a low-level immediately-generated key event, tracking press
// and release of keys -- suitable for fine-grained tracking of key events --
// see also key.ChordEvent for events that are generated only on keyboard release,
// and that include the full chord information about all the modifier keys
// that were present when a non-modifier key was released
type Event struct {
oswin.EventBase
// Rune is the meaning of the key event as determined by the
// operating system. The mapping is determined by system-dependent
// current layout, modifiers, lock-states, etc.
//
// If non-negative, it is a Unicode codepoint: pressing the 'a' key
// generates different Runes 'a' or 'A' (but the same Code) depending on
// the state of the shift key.
//
// If -1, the key does not generate a Unicode codepoint. To distinguish
// them, look at Code.
Rune rune
// Code is the identity of the physical key relative to a notional
// "standard" keyboard, independent of current layout, modifiers,
// lock-states, etc
//
// For standard key codes, its value matches USB HID key codes.
// Compare its value to uint32-typed constants in this package, such
// as CodeLeftShift and CodeEscape.
//
// Pressing the regular '2' key and number-pad '2' key (with Num-Lock)
// generate different Codes (but the same Rune).
Code Code
// Modifiers is bitflags representing a set of modifier keys: ModShift,
// ModAlt, etc. -- bit positions are key.Modifiers
Modifiers int32
// Action is the key action taken: Press, Release, or None (for key repeats).
Action Action
// TODO: add a Device ID, for multiple input devices?
}
// key.ChordEvent reports events that are generated only on keyboard release,
// and that include the full chord information about all the modifier keys
// that were present when a non-modifier key was released -- these are
// generally appropriate for most uses
type ChordEvent struct {
Event
}
func (e Event) String() string {
if e.Rune >= 0 {
return fmt.Sprintf("key.Event{%q (%v), %v, %v}", e.Rune, e.Code, e.Modifiers, e.Action)
}
return fmt.Sprintf("key.Event{(%v), %v, %v}", e.Code, e.Modifiers, e.Action)
}
// SetModifiers sets the bitflags based on a list of key.Modifiers
func (e *Event) SetModifiers(mods ...Modifiers) {
for _, m := range mods {
e.Modifiers |= (1 << uint32(m))
}
}
// ChordString returns a string representation of the keyboard event suitable
// for keyboard function maps, etc -- printable runes are sent directly, and
// non-printable ones are converted to their corresponding code names without
// the "Code" prefix
func (e *Event) ChordString() string {
modstr := ""
for m := Shift; m < ModifiersN; m++ {
if e.Modifiers&(1<<uint32(m)) != 0 {
modstr += interface{}(m).(fmt.Stringer).String() + "+"
}
}
if modstr != "" && e.Code == CodeSpacebar { // modified space is not regular space
return modstr + "Spacebar"
}
if unicode.IsPrint(e.Rune) {
return modstr + string(e.Rune)
}
// now convert code
codestr := strings.TrimPrefix(interface{}(e.Code).(fmt.Stringer).String(), "Code")
return modstr + codestr
}
// CodeIsModifier returns true if given code is a modifier key
func CodeIsModifier(c Code) bool {
if c >= CodeLeftControl && c <= CodeRightGUI {
return true
}
return false
}
// Action is the action taken on the key
type Action int32
const (
None Action = iota
Press
Release
ActionN
)
//go:generate stringer -type=Action
var KiT_Action = kit.Enums.AddEnum(ActionN, false, nil)
// Modifiers are used as bitflags representing a set of modifier keys -- see
// SetModifiers method
type Modifiers int32
const (
Shift Modifiers = iota
Control
Alt
Meta // called "Command" on OS X
ModifiersN
)
//go:generate stringer -type=Modifiers
var KiT_Modifiers = kit.Enums.AddEnum(ModifiersN, true, nil) // true = bitflag
// Code is the identity of a key relative to a notional "standard" keyboard.
type Code uint32
// Physical key codes.
//
// For standard key codes, its value matches USB HID key codes.
// TODO: add missing codes.
const (
CodeUnknown Code = 0
CodeA Code = 4
CodeB Code = 5
CodeC Code = 6
CodeD Code = 7
CodeE Code = 8
CodeF Code = 9
CodeG Code = 10
CodeH Code = 11
CodeI Code = 12
CodeJ Code = 13
CodeK Code = 14
CodeL Code = 15
CodeM Code = 16
CodeN Code = 17
CodeO Code = 18
CodeP Code = 19
CodeQ Code = 20
CodeR Code = 21
CodeS Code = 22
CodeT Code = 23
CodeU Code = 24
CodeV Code = 25
CodeW Code = 26
CodeX Code = 27
CodeY Code = 28
CodeZ Code = 29
Code1 Code = 30
Code2 Code = 31
Code3 Code = 32
Code4 Code = 33
Code5 Code = 34
Code6 Code = 35
Code7 Code = 36
Code8 Code = 37
Code9 Code = 38
Code0 Code = 39
CodeReturnEnter Code = 40
CodeEscape Code = 41
CodeDeleteBackspace Code = 42
CodeTab Code = 43
CodeSpacebar Code = 44
CodeHyphenMinus Code = 45 // -
CodeEqualSign Code = 46 // =
CodeLeftSquareBracket Code = 47 // [
CodeRightSquareBracket Code = 48 // ]
CodeBackslash Code = 49 // \
CodeSemicolon Code = 51 // ;
CodeApostrophe Code = 52 // '
CodeGraveAccent Code = 53 // `
CodeComma Code = 54 // ,
CodeFullStop Code = 55 // .
CodeSlash Code = 56 // /
CodeCapsLock Code = 57
CodeF1 Code = 58
CodeF2 Code = 59
CodeF3 Code = 60
CodeF4 Code = 61
CodeF5 Code = 62
CodeF6 Code = 63
CodeF7 Code = 64
CodeF8 Code = 65
CodeF9 Code = 66
CodeF10 Code = 67
CodeF11 Code = 68
CodeF12 Code = 69
CodePause Code = 72
CodeInsert Code = 73
CodeHome Code = 74
CodePageUp Code = 75
CodeDeleteForward Code = 76
CodeEnd Code = 77
CodePageDown Code = 78
CodeRightArrow Code = 79
CodeLeftArrow Code = 80
CodeDownArrow Code = 81
CodeUpArrow Code = 82
CodeKeypadNumLock Code = 83
CodeKeypadSlash Code = 84 // /
CodeKeypadAsterisk Code = 85 // *
CodeKeypadHyphenMinus Code = 86 // -
CodeKeypadPlusSign Code = 87 // +
CodeKeypadEnter Code = 88
CodeKeypad1 Code = 89
CodeKeypad2 Code = 90
CodeKeypad3 Code = 91
CodeKeypad4 Code = 92
CodeKeypad5 Code = 93
CodeKeypad6 Code = 94
CodeKeypad7 Code = 95
CodeKeypad8 Code = 96
CodeKeypad9 Code = 97
CodeKeypad0 Code = 98
CodeKeypadFullStop Code = 99 // .
CodeKeypadEqualSign Code = 103 // =
CodeF13 Code = 104
CodeF14 Code = 105
CodeF15 Code = 106
CodeF16 Code = 107
CodeF17 Code = 108
CodeF18 Code = 109
CodeF19 Code = 110
CodeF20 Code = 111
CodeF21 Code = 112
CodeF22 Code = 113
CodeF23 Code = 114
CodeF24 Code = 115
CodeHelp Code = 117
CodeMute Code = 127
CodeVolumeUp Code = 128
CodeVolumeDown Code = 129
CodeLeftControl Code = 224
CodeLeftShift Code = 225
CodeLeftAlt Code = 226
CodeLeftGUI Code = 227 // Command on mac, ? on windows, ? on linux
CodeRightControl Code = 228
CodeRightShift Code = 229
CodeRightAlt Code = 230
CodeRightGUI Code = 231
// The following codes are not part of the standard USB HID Usage IDs for
// keyboards. See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
//
// Usage IDs are uint16s, so these non-standard values start at 0x10000.
// CodeCompose is the Code for a compose key, sometimes called a multi key,
// used to input non-ASCII characters such as ñ being composed of n and ~.
//
// See https://en.wikipedia.org/wiki/Compose_key
CodeCompose Code = 0x10000
)
// // go: generate stringer -type=Code
// TODO: Given we use runes outside the unicode space, should we provide a
// printing function? Related: it's a little unfortunate that printing a
// key.Event with %v gives not very readable output like:
// {100 7 key.Modifiers() Press}
func (ev Event) Type() oswin.EventType {
return oswin.KeyEvent
}
func (ev Event) HasPos() bool {
return false
}
func (ev Event) Pos() image.Point {
return image.ZP
}
func (ev Event) OnFocus() bool {
return true
}
// check for interface implementation
var _ oswin.Event = &Event{}
func (ev ChordEvent) Type() oswin.EventType {
return oswin.KeyChordEvent
}