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  }