github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/io/key/key.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 /* 4 Package key implements key and text events and operations. 5 6 The InputOp operations is used for declaring key input handlers. Use 7 an implementation of the Queue interface from package ui to receive 8 events. 9 */ 10 package key 11 12 import ( 13 "strings" 14 15 "github.com/gop9/olt/gio/internal/opconst" 16 "github.com/gop9/olt/gio/io/event" 17 "github.com/gop9/olt/gio/op" 18 ) 19 20 // InputOp declares a handler ready for key events. 21 // Key events are in general only delivered to the 22 // focused key handler. Set the Focus flag to request 23 // the focus. 24 type InputOp struct { 25 Key event.Key 26 Focus bool 27 } 28 29 // HideInputOp request that any on screen text input 30 // be hidden. 31 type HideInputOp struct{} 32 33 // A FocusEvent is generated when a handler gains or loses 34 // focus. 35 type FocusEvent struct { 36 Focus bool 37 } 38 39 // An Event is generated when a key is pressed. For text input 40 // use EditEvent. 41 type Event struct { 42 // Rune is the meaning of the key event as determined by the 43 // operating system. The mapping is determined by system-dependent 44 // current layout, modifiers, lock-states, etc. 45 // 46 // If non-negative, it is a Unicode codepoint: pressing the 'a' key 47 // generates different Runes 'a' or 'A' (but the same Code) depending on 48 // the state of the shift key. 49 // 50 // If -1, the key does not generate a Unicode codepoint. To distinguish 51 // them, look at Code. 52 Rune rune 53 54 // Code is the identity of the physical key relative to a notional 55 // "standard" keyboard, independent of current layout, modifiers, 56 // lock-states, etc 57 // 58 // For standard key codes, its value matches USB HID key codes. 59 // Compare its value to uint32-typed constants in this package, such 60 // as CodeLeftShift and CodeEscape. 61 // 62 // Pressing the regular '2' key and number-pad '2' key (with Num-Lock) 63 // generate different Codes (but the same Rune). 64 Code Code 65 // Name of the key. For letters, the upper case form is used, via 66 // unicode.ToUpper. The shift modifier is taken into account, all other 67 // modifiers are ignored. For example, the "shift-1" and "ctrl-shift-1" 68 // combinations both give the Name "!" with the US keyboard layout. 69 Name string 70 // Modifiers is the set of active modifiers when the key was pressed. 71 Modifiers Modifiers 72 73 // Direction is the direction of the key event: DirPress, DirRelease, 74 // or DirNone (for key repeats). 75 Direction Direction 76 } 77 78 // An EditEvent is generated when text is input. 79 type EditEvent struct { 80 Text string 81 } 82 83 // Direction is the direction of the key event. 84 type Direction uint8 85 86 const ( 87 DirNone Direction = 0 88 DirPress Direction = 1 89 DirRelease Direction = 2 90 ) 91 92 // Modifiers 93 type Modifiers uint32 94 95 // Code is the identity of a key relative to a notional "standard" keyboard. 96 type Code uint32 97 98 // Physical key codes. 99 // 100 // For standard key codes, its value matches USB HID key codes. 101 // TODO: add missing codes. 102 const ( 103 CodeUnknown Code = 0 104 105 CodeA Code = 4 106 CodeB Code = 5 107 CodeC Code = 6 108 CodeD Code = 7 109 CodeE Code = 8 110 CodeF Code = 9 111 CodeG Code = 10 112 CodeH Code = 11 113 CodeI Code = 12 114 CodeJ Code = 13 115 CodeK Code = 14 116 CodeL Code = 15 117 CodeM Code = 16 118 CodeN Code = 17 119 CodeO Code = 18 120 CodeP Code = 19 121 CodeQ Code = 20 122 CodeR Code = 21 123 CodeS Code = 22 124 CodeT Code = 23 125 CodeU Code = 24 126 CodeV Code = 25 127 CodeW Code = 26 128 CodeX Code = 27 129 CodeY Code = 28 130 CodeZ Code = 29 131 132 Code1 Code = 30 133 Code2 Code = 31 134 Code3 Code = 32 135 Code4 Code = 33 136 Code5 Code = 34 137 Code6 Code = 35 138 Code7 Code = 36 139 Code8 Code = 37 140 Code9 Code = 38 141 Code0 Code = 39 142 143 CodeReturnEnter Code = 40 144 CodeEscape Code = 41 145 CodeDeleteBackspace Code = 42 146 CodeTab Code = 43 147 CodeSpacebar Code = 44 148 CodeHyphenMinus Code = 45 // - 149 CodeEqualSign Code = 46 // = 150 CodeLeftSquareBracket Code = 47 // [ 151 CodeRightSquareBracket Code = 48 // ] 152 CodeBackslash Code = 49 // \ 153 CodeSemicolon Code = 51 // ; 154 CodeApostrophe Code = 52 // ' 155 CodeGraveAccent Code = 53 // ` 156 CodeComma Code = 54 // , 157 CodeFullStop Code = 55 // . 158 CodeSlash Code = 56 // / 159 CodeCapsLock Code = 57 160 161 CodeF1 Code = 58 162 CodeF2 Code = 59 163 CodeF3 Code = 60 164 CodeF4 Code = 61 165 CodeF5 Code = 62 166 CodeF6 Code = 63 167 CodeF7 Code = 64 168 CodeF8 Code = 65 169 CodeF9 Code = 66 170 CodeF10 Code = 67 171 CodeF11 Code = 68 172 CodeF12 Code = 69 173 174 CodePause Code = 72 175 CodeInsert Code = 73 176 CodeHome Code = 74 177 CodePageUp Code = 75 178 CodeDeleteForward Code = 76 179 CodeEnd Code = 77 180 CodePageDown Code = 78 181 182 CodeRightArrow Code = 79 183 CodeLeftArrow Code = 80 184 CodeDownArrow Code = 81 185 CodeUpArrow Code = 82 186 187 CodeKeypadNumLock Code = 83 188 CodeKeypadSlash Code = 84 // / 189 CodeKeypadAsterisk Code = 85 // * 190 CodeKeypadHyphenMinus Code = 86 // - 191 CodeKeypadPlusSign Code = 87 // + 192 CodeKeypadEnter Code = 88 193 CodeKeypad1 Code = 89 194 CodeKeypad2 Code = 90 195 CodeKeypad3 Code = 91 196 CodeKeypad4 Code = 92 197 CodeKeypad5 Code = 93 198 CodeKeypad6 Code = 94 199 CodeKeypad7 Code = 95 200 CodeKeypad8 Code = 96 201 CodeKeypad9 Code = 97 202 CodeKeypad0 Code = 98 203 CodeKeypadFullStop Code = 99 // . 204 CodeKeypadEqualSign Code = 103 // = 205 206 CodeF13 Code = 104 207 CodeF14 Code = 105 208 CodeF15 Code = 106 209 CodeF16 Code = 107 210 CodeF17 Code = 108 211 CodeF18 Code = 109 212 CodeF19 Code = 110 213 CodeF20 Code = 111 214 CodeF21 Code = 112 215 CodeF22 Code = 113 216 CodeF23 Code = 114 217 CodeF24 Code = 115 218 219 CodeHelp Code = 117 220 221 CodeMute Code = 127 222 CodeVolumeUp Code = 128 223 CodeVolumeDown Code = 129 224 225 CodeLeftControl Code = 224 226 CodeLeftShift Code = 225 227 CodeLeftAlt Code = 226 228 CodeLeftGUI Code = 227 229 CodeRightControl Code = 228 230 CodeRightShift Code = 229 231 CodeRightAlt Code = 230 232 CodeRightGUI Code = 231 233 234 // The following codes are not part of the standard USB HID Usage IDs for 235 // keyboards. See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf 236 // 237 // Usage IDs are uint16s, so these non-standard values start at 0x10000. 238 239 // CodeCompose is the Code for a compose key, sometimes called a multi key, 240 // used to input non-ASCII characters such as ñ being composed of n and ~. 241 // 242 // See https://en.wikipedia.org/wiki/Compose_key 243 CodeCompose Code = 0x10000 244 ) 245 246 const ( 247 // ModCtrl is the ctrl modifier key. 248 ModCtrl Modifiers = 1 << iota 249 // ModCommand is the command modifier key 250 // found on Apple keyboards. 251 ModCommand 252 // ModShift is the shift modifier key. 253 //ModShift 254 // ModAlt is the alt modifier key, or the option 255 // key on Apple keyboards. 256 //ModAlt 257 // ModSuper is the "logo" modifier key, often 258 // represented by a Windows logo. 259 ModSuper 260 261 ModShift Modifiers = 1 << 0 262 ModControl Modifiers = 1 << 1 263 ModAlt Modifiers = 1 << 2 264 ModMeta Modifiers = 1 << 3 // called "Command" on OS X 265 ) 266 267 const ( 268 // Names for special keys. 269 NameLeftArrow = "←" 270 NameRightArrow = "→" 271 NameUpArrow = "↑" 272 NameDownArrow = "↓" 273 NameReturn = "⏎" 274 NameEnter = "⌤" 275 NameEscape = "⎋" 276 NameHome = "⇱" 277 NameEnd = "⇲" 278 NameDeleteBackward = "⌫" 279 NameDeleteForward = "⌦" 280 NamePageUp = "⇞" 281 NamePageDown = "⇟" 282 NameTab = "⇥" 283 ) 284 285 // Contain reports whether m contains all modifiers 286 // in m2. 287 func (m Modifiers) Contain(m2 Modifiers) bool { 288 return m&m2 == m2 289 } 290 291 func (h InputOp) Add(o *op.Ops) { 292 data := o.Write(opconst.TypeKeyInputLen, h.Key) 293 data[0] = byte(opconst.TypeKeyInput) 294 if h.Focus { 295 data[1] = 1 296 } 297 } 298 299 func (h HideInputOp) Add(o *op.Ops) { 300 data := o.Write(opconst.TypeHideInputLen) 301 data[0] = byte(opconst.TypeHideInput) 302 } 303 304 func (EditEvent) ImplementsEvent() {} 305 func (Event) ImplementsEvent() {} 306 func (FocusEvent) ImplementsEvent() {} 307 308 func (e Event) String() string { 309 return "{" + string(e.Name) + " " + e.Modifiers.String() + "}" 310 } 311 312 func (m Modifiers) String() string { 313 var strs []string 314 if m.Contain(ModCtrl) { 315 strs = append(strs, "ModCtrl") 316 } 317 if m.Contain(ModCommand) { 318 strs = append(strs, "ModCommand") 319 } 320 if m.Contain(ModShift) { 321 strs = append(strs, "ModShift") 322 } 323 if m.Contain(ModAlt) { 324 strs = append(strs, "ModAlt") 325 } 326 if m.Contain(ModSuper) { 327 strs = append(strs, "ModSuper") 328 } 329 return strings.Join(strs, "|") 330 }