From 83b2d4b1123e429578282c747e620e946b257518 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 1 Sep 2019 22:47:40 +0900 Subject: [PATCH] input: driver.Key now distinguishes left/right modifier keys This is a preparation for event package, that will have key enum. Updates #926 --- examples/keyboard/main.go | 2 +- genkeys.go | 71 +++++++---- input.go | 24 +++- internal/driver/keys.go | 12 +- internal/uidriver/glfw/keys.go | 13 +- internal/uidriver/js/keys.go | 33 +++-- keys.go | 216 ++++++++++++++++++++++++++++++++- 7 files changed, 322 insertions(+), 49 deletions(-) diff --git a/examples/keyboard/main.go b/examples/keyboard/main.go index 09c480511..b8d0d241b 100644 --- a/examples/keyboard/main.go +++ b/examples/keyboard/main.go @@ -46,7 +46,7 @@ func init() { } func update(screen *ebiten.Image) error { - pressed := []ebiten.Key{} + var pressed []ebiten.Key for k := ebiten.Key(0); k <= ebiten.KeyMax; k++ { if ebiten.IsKeyPressed(k) { pressed = append(pressed, k) diff --git a/genkeys.go b/genkeys.go index 7afc37d4b..e8e655149 100644 --- a/genkeys.go +++ b/genkeys.go @@ -88,10 +88,13 @@ func init() { nameToJSKeyCodes = map[string][]string{ "Comma": {"Comma"}, "Period": {"Period"}, - "Alt": {"AltLeft", "AltRight"}, + "LeftAlt": {"AltLeft"}, + "RightAlt": {"AltRight"}, "CapsLock": {"CapsLock"}, - "Control": {"ControlLeft", "ControlRight"}, - "Shift": {"ShiftLeft", "ShiftRight"}, + "LeftControl": {"ControlLeft"}, + "RightControl": {"ControlRight"}, + "LeftShift": {"ShiftLeft"}, + "RightShift": {"ShiftRight"}, "Enter": {"Enter"}, "Space": {"Space"}, "Tab": {"Tab"}, @@ -164,13 +167,14 @@ func init() { } func init() { + // TODO: How should we treat modifier keys? Now 'left' modifier keys are available. keyCodeToNameEdge = map[int]string{ 0xbc: "Comma", 0xbe: "Period", - 0x12: "Alt", + 0x12: "LeftAlt", 0x14: "CapsLock", - 0x11: "Control", - 0x10: "Shift", + 0x11: "LeftControl", + 0x10: "LeftShift", 0x0D: "Enter", 0x20: "Space", 0x09: "Tab", @@ -249,10 +253,23 @@ type Key int // Keys. const ( -{{range $index, $name := .EbitenKeyNames}}Key{{$name}} Key = Key(driver.Key{{$name}}) -{{end}} KeyMax Key = Key{{.LastEbitenKeyName}} +{{range $index, $name := .EbitenKeyNamesWithoutMods}}Key{{$name}} Key = Key(driver.Key{{$name}}) +{{end}} KeyAlt Key = Key(driver.KeyReserved0) + KeyControl Key = Key(driver.KeyReserved1) + KeyShift Key = Key(driver.KeyReserved2) + KeyMax Key = KeyShift ) +func (k Key) isValid() bool { + switch k { + {{range $name := .EbitenKeyNames}}case Key{{$name}}: + return true + {{end}} + default: + return false + } +} + // String returns a string representing the key. // // If k is an undefined key, String returns an empty string. @@ -282,8 +299,10 @@ package driver type Key int const ( -{{range $index, $name := .EbitenKeyNames}}Key{{$name}}{{if eq $index 0}} Key = iota{{end}} -{{end}} +{{range $index, $name := .DriverKeyNames}}Key{{$name}}{{if eq $index 0}} Key = iota{{end}} +{{end}} KeyReserved0 + KeyReserved1 + KeyReserved2 ) ` @@ -301,14 +320,8 @@ import ( ) var glfwKeyCodeToKey = map[glfw.Key]driver.Key{ -{{range $index, $name := .EbitenKeyNamesWithoutMods}}glfw.Key{{$name}}: driver.Key{{$name}}, +{{range $index, $name := .DriverKeyNames}}glfw.Key{{$name}}: driver.Key{{$name}}, {{end}} - glfw.KeyLeftAlt: driver.KeyAlt, - glfw.KeyRightAlt: driver.KeyAlt, - glfw.KeyLeftControl: driver.KeyControl, - glfw.KeyRightControl: driver.KeyControl, - glfw.KeyLeftShift: driver.KeyShift, - glfw.KeyRightShift: driver.KeyShift, } ` @@ -442,15 +455,31 @@ func main() { ebitenKeyNames := []string{} ebitenKeyNamesWithoutMods := []string{} + driverKeyNames := []string{} for name := range nameToJSKeyCodes { - ebitenKeyNames = append(ebitenKeyNames, name) - if name != "Alt" && name != "Control" && name != "Shift" { + driverKeyNames = append(driverKeyNames, name) + if !strings.HasSuffix(name, "Alt") && !strings.HasSuffix(name, "Control") && !strings.HasSuffix(name, "Shift") { + ebitenKeyNames = append(ebitenKeyNames, name) ebitenKeyNamesWithoutMods = append(ebitenKeyNamesWithoutMods, name) + continue + } + if name == "LeftAlt" { + ebitenKeyNames = append(ebitenKeyNames, "Alt") + continue + } + if name == "LeftControl" { + ebitenKeyNames = append(ebitenKeyNames, "Control") + continue + } + if name == "LeftShift" { + ebitenKeyNames = append(ebitenKeyNames, "Shift") + continue } } sort.Slice(ebitenKeyNames, keyNamesLess(ebitenKeyNames)) sort.Slice(ebitenKeyNamesWithoutMods, keyNamesLess(ebitenKeyNamesWithoutMods)) + sort.Slice(driverKeyNames, keyNamesLess(driverKeyNames)) for path, tmpl := range map[string]string{ "keys.go": ebitenKeysTmpl, @@ -494,7 +523,7 @@ func main() { KeyCodeToNameEdge map[int]string EbitenKeyNames []string EbitenKeyNamesWithoutMods []string - LastEbitenKeyName string + DriverKeyNames []string NameToGLFWKeys map[string]glfw.Key }{ License: license, @@ -504,7 +533,7 @@ func main() { KeyCodeToNameEdge: keyCodeToNameEdge, EbitenKeyNames: ebitenKeyNames, EbitenKeyNamesWithoutMods: ebitenKeyNamesWithoutMods, - LastEbitenKeyName: ebitenKeyNames[len(ebitenKeyNames)-1], + DriverKeyNames: driverKeyNames, NameToGLFWKeys: nameToGLFWKeys, }); err != nil { log.Fatal(err) diff --git a/input.go b/input.go index 533bd8895..b0647e568 100644 --- a/input.go +++ b/input.go @@ -42,7 +42,29 @@ func InputChars() []rune { // // IsKeyPressed is concurrent-safe. func IsKeyPressed(key Key) bool { - return uidriver.Get().Input().IsKeyPressed(driver.Key(key)) + // There are keys that are invalid values as ebiten.Key (e.g., driver.KeyLeftAlt). + // Skip such values. + if !key.isValid() { + return false + } + + var keys []driver.Key + switch key { + case KeyAlt: + keys = append(keys, driver.KeyLeftAlt, driver.KeyRightAlt) + case KeyControl: + keys = append(keys, driver.KeyLeftControl, driver.KeyRightControl) + case KeyShift: + keys = append(keys, driver.KeyLeftShift, driver.KeyRightShift) + default: + keys = append(keys, driver.Key(key)) + } + for _, k := range keys { + if uidriver.Get().Input().IsKeyPressed(k) { + return true + } + } + return false } // CursorPosition returns a position of a mouse cursor relative to the game screen (window). The cursor position is diff --git a/internal/driver/keys.go b/internal/driver/keys.go index eb861f046..b3e6a6f24 100644 --- a/internal/driver/keys.go +++ b/internal/driver/keys.go @@ -55,13 +55,11 @@ const ( KeyX KeyY KeyZ - KeyAlt KeyApostrophe KeyBackslash KeyBackspace KeyCapsLock KeyComma - KeyControl KeyDelete KeyDown KeyEnd @@ -101,7 +99,10 @@ const ( KeyKPMultiply KeyKPSubtract KeyLeft + KeyLeftAlt KeyLeftBracket + KeyLeftControl + KeyLeftShift KeyMenu KeyMinus KeyNumLock @@ -111,12 +112,17 @@ const ( KeyPeriod KeyPrintScreen KeyRight + KeyRightAlt KeyRightBracket + KeyRightControl + KeyRightShift KeyScrollLock KeySemicolon - KeyShift KeySlash KeySpace KeyTab KeyUp + KeyReserved0 + KeyReserved1 + KeyReserved2 ) diff --git a/internal/uidriver/glfw/keys.go b/internal/uidriver/glfw/keys.go index dbb8847ac..fc14aff07 100644 --- a/internal/uidriver/glfw/keys.go +++ b/internal/uidriver/glfw/keys.go @@ -107,7 +107,10 @@ var glfwKeyCodeToKey = map[glfw.Key]driver.Key{ glfw.KeyKPMultiply: driver.KeyKPMultiply, glfw.KeyKPSubtract: driver.KeyKPSubtract, glfw.KeyLeft: driver.KeyLeft, + glfw.KeyLeftAlt: driver.KeyLeftAlt, glfw.KeyLeftBracket: driver.KeyLeftBracket, + glfw.KeyLeftControl: driver.KeyLeftControl, + glfw.KeyLeftShift: driver.KeyLeftShift, glfw.KeyMenu: driver.KeyMenu, glfw.KeyMinus: driver.KeyMinus, glfw.KeyNumLock: driver.KeyNumLock, @@ -117,18 +120,14 @@ var glfwKeyCodeToKey = map[glfw.Key]driver.Key{ glfw.KeyPeriod: driver.KeyPeriod, glfw.KeyPrintScreen: driver.KeyPrintScreen, glfw.KeyRight: driver.KeyRight, + glfw.KeyRightAlt: driver.KeyRightAlt, glfw.KeyRightBracket: driver.KeyRightBracket, + glfw.KeyRightControl: driver.KeyRightControl, + glfw.KeyRightShift: driver.KeyRightShift, glfw.KeyScrollLock: driver.KeyScrollLock, glfw.KeySemicolon: driver.KeySemicolon, glfw.KeySlash: driver.KeySlash, glfw.KeySpace: driver.KeySpace, glfw.KeyTab: driver.KeyTab, glfw.KeyUp: driver.KeyUp, - - glfw.KeyLeftAlt: driver.KeyAlt, - glfw.KeyRightAlt: driver.KeyAlt, - glfw.KeyLeftControl: driver.KeyControl, - glfw.KeyRightControl: driver.KeyControl, - glfw.KeyLeftShift: driver.KeyShift, - glfw.KeyRightShift: driver.KeyShift, } diff --git a/internal/uidriver/js/keys.go b/internal/uidriver/js/keys.go index a00a683f1..236dee5f3 100644 --- a/internal/uidriver/js/keys.go +++ b/internal/uidriver/js/keys.go @@ -56,9 +56,6 @@ var keyToCodes = map[driver.Key][]string{ driver.KeyA: { "KeyA", }, - driver.KeyAlt: { - "AltLeft", "AltRight", - }, driver.KeyApostrophe: { "Quote", }, @@ -80,9 +77,6 @@ var keyToCodes = map[driver.Key][]string{ driver.KeyComma: { "Comma", }, - driver.KeyControl: { - "ControlLeft", "ControlRight", - }, driver.KeyD: { "KeyD", }, @@ -227,9 +221,18 @@ var keyToCodes = map[driver.Key][]string{ driver.KeyLeft: { "ArrowLeft", }, + driver.KeyLeftAlt: { + "AltLeft", + }, driver.KeyLeftBracket: { "BracketLeft", }, + driver.KeyLeftControl: { + "ControlLeft", + }, + driver.KeyLeftShift: { + "ShiftLeft", + }, driver.KeyM: { "KeyM", }, @@ -275,9 +278,18 @@ var keyToCodes = map[driver.Key][]string{ driver.KeyRight: { "ArrowRight", }, + driver.KeyRightAlt: { + "AltRight", + }, driver.KeyRightBracket: { "BracketRight", }, + driver.KeyRightControl: { + "ControlRight", + }, + driver.KeyRightShift: { + "ShiftRight", + }, driver.KeyS: { "KeyS", }, @@ -287,9 +299,6 @@ var keyToCodes = map[driver.Key][]string{ driver.KeySemicolon: { "Semicolon", }, - driver.KeyShift: { - "ShiftLeft", "ShiftRight", - }, driver.KeySlash: { "Slash", }, @@ -329,9 +338,9 @@ var keyCodeToKeyEdge = map[int]driver.Key{ 8: driver.KeyBackspace, 9: driver.KeyTab, 13: driver.KeyEnter, - 16: driver.KeyShift, - 17: driver.KeyControl, - 18: driver.KeyAlt, + 16: driver.KeyLeftShift, + 17: driver.KeyLeftControl, + 18: driver.KeyLeftAlt, 19: driver.KeyPause, 20: driver.KeyCapsLock, 27: driver.KeyEscape, diff --git a/keys.go b/keys.go index 3ac3844be..116f981eb 100644 --- a/keys.go +++ b/keys.go @@ -65,13 +65,11 @@ const ( KeyX Key = Key(driver.KeyX) KeyY Key = Key(driver.KeyY) KeyZ Key = Key(driver.KeyZ) - KeyAlt Key = Key(driver.KeyAlt) KeyApostrophe Key = Key(driver.KeyApostrophe) KeyBackslash Key = Key(driver.KeyBackslash) KeyBackspace Key = Key(driver.KeyBackspace) KeyCapsLock Key = Key(driver.KeyCapsLock) KeyComma Key = Key(driver.KeyComma) - KeyControl Key = Key(driver.KeyControl) KeyDelete Key = Key(driver.KeyDelete) KeyDown Key = Key(driver.KeyDown) KeyEnd Key = Key(driver.KeyEnd) @@ -124,14 +122,224 @@ const ( KeyRightBracket Key = Key(driver.KeyRightBracket) KeyScrollLock Key = Key(driver.KeyScrollLock) KeySemicolon Key = Key(driver.KeySemicolon) - KeyShift Key = Key(driver.KeyShift) KeySlash Key = Key(driver.KeySlash) KeySpace Key = Key(driver.KeySpace) KeyTab Key = Key(driver.KeyTab) KeyUp Key = Key(driver.KeyUp) - KeyMax Key = KeyUp + KeyAlt Key = Key(driver.KeyReserved0) + KeyControl Key = Key(driver.KeyReserved1) + KeyShift Key = Key(driver.KeyReserved2) + KeyMax Key = KeyShift ) +func (k Key) isValid() bool { + switch k { + case Key0: + return true + case Key1: + return true + case Key2: + return true + case Key3: + return true + case Key4: + return true + case Key5: + return true + case Key6: + return true + case Key7: + return true + case Key8: + return true + case Key9: + return true + case KeyA: + return true + case KeyB: + return true + case KeyC: + return true + case KeyD: + return true + case KeyE: + return true + case KeyF: + return true + case KeyG: + return true + case KeyH: + return true + case KeyI: + return true + case KeyJ: + return true + case KeyK: + return true + case KeyL: + return true + case KeyM: + return true + case KeyN: + return true + case KeyO: + return true + case KeyP: + return true + case KeyQ: + return true + case KeyR: + return true + case KeyS: + return true + case KeyT: + return true + case KeyU: + return true + case KeyV: + return true + case KeyW: + return true + case KeyX: + return true + case KeyY: + return true + case KeyZ: + return true + case KeyAlt: + return true + case KeyApostrophe: + return true + case KeyBackslash: + return true + case KeyBackspace: + return true + case KeyCapsLock: + return true + case KeyComma: + return true + case KeyControl: + return true + case KeyDelete: + return true + case KeyDown: + return true + case KeyEnd: + return true + case KeyEnter: + return true + case KeyEqual: + return true + case KeyEscape: + return true + case KeyF1: + return true + case KeyF2: + return true + case KeyF3: + return true + case KeyF4: + return true + case KeyF5: + return true + case KeyF6: + return true + case KeyF7: + return true + case KeyF8: + return true + case KeyF9: + return true + case KeyF10: + return true + case KeyF11: + return true + case KeyF12: + return true + case KeyGraveAccent: + return true + case KeyHome: + return true + case KeyInsert: + return true + case KeyKP0: + return true + case KeyKP1: + return true + case KeyKP2: + return true + case KeyKP3: + return true + case KeyKP4: + return true + case KeyKP5: + return true + case KeyKP6: + return true + case KeyKP7: + return true + case KeyKP8: + return true + case KeyKP9: + return true + case KeyKPAdd: + return true + case KeyKPDecimal: + return true + case KeyKPDivide: + return true + case KeyKPEnter: + return true + case KeyKPEqual: + return true + case KeyKPMultiply: + return true + case KeyKPSubtract: + return true + case KeyLeft: + return true + case KeyLeftBracket: + return true + case KeyMenu: + return true + case KeyMinus: + return true + case KeyNumLock: + return true + case KeyPageDown: + return true + case KeyPageUp: + return true + case KeyPause: + return true + case KeyPeriod: + return true + case KeyPrintScreen: + return true + case KeyRight: + return true + case KeyRightBracket: + return true + case KeyScrollLock: + return true + case KeySemicolon: + return true + case KeyShift: + return true + case KeySlash: + return true + case KeySpace: + return true + case KeyTab: + return true + case KeyUp: + return true + + default: + return false + } +} + // String returns a string representing the key. // // If k is an undefined key, String returns an empty string.