From 0cd692d26ae3ea4b70725e0d736ca0092434ee5f Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 14 Apr 2017 03:02:38 +0900 Subject: [PATCH] ui: Use code instead of keyCode on browsers but Safari --- genkeys.go | 89 ++++++++++++++++++++++++++++++++++------- internal/ui/input_js.go | 54 +++++++++++++++++++------ internal/ui/keys_js.go | 77 ++++++++++++++++++++++++++++++++++- internal/ui/ui_js.go | 15 ++++++- 4 files changed, 204 insertions(+), 31 deletions(-) diff --git a/genkeys.go b/genkeys.go index 93ac8f015..eb05e411a 100644 --- a/genkeys.go +++ b/genkeys.go @@ -31,10 +31,54 @@ import ( "github.com/hajimehoshi/ebiten/internal" ) -var keyCodeToName map[int]string +var ( + codeToName map[string]string + keyCodeToNameSafari map[int]string +) func init() { - keyCodeToName = map[int]string{ + codeToName = map[string]string{ + "Comma": "Comma", + "Period": "Period", + "AltLeft": "Alt", + "AltRight": "Alt", + "CapsLock": "CapsLock", + "ControlLeft": "Control", + "ControlRight": "Control", + "ShiftLeft": "Shift", + "ShiftRight": "Shift", + "Enter": "Enter", + "Space": "Space", + "Tab": "Tab", + "Delete": "Delete", + "End": "End", + "Home": "Home", + "Insert": "Insert", + "PageDown": "PageDown", + "PageUp": "PageUp", + "ArrowDown": "Down", + "ArrowLeft": "Left", + "ArrowRight": "Right", + "ArrowUp": "Up", + "Escape": "Escape", + "Backspace": "Backspace", + } + // ASCII: 0 - 9 + for c := '0'; c <= '9'; c++ { + codeToName["Digit"+string(c)] = string(c) + } + // ASCII: A - Z + for c := 'A'; c <= 'Z'; c++ { + codeToName["Key"+string(c)] = string(c) + } + // Function keys + for i := 1; i <= 12; i++ { + codeToName["F"+strconv.Itoa(i)] = "F" + strconv.Itoa(i) + } +} + +func init() { + keyCodeToNameSafari = map[int]string{ 0xBC: "Comma", 0xBE: "Period", 0x12: "Alt", @@ -60,15 +104,15 @@ func init() { } // ASCII: 0 - 9 for c := '0'; c <= '9'; c++ { - keyCodeToName[int(c)] = string(c) + keyCodeToNameSafari[int(c)] = string(c) } // ASCII: A - Z for c := 'A'; c <= 'Z'; c++ { - keyCodeToName[int(c)] = string(c) + keyCodeToNameSafari[int(c)] = string(c) } // Function keys for i := 1; i <= 12; i++ { - keyCodeToName[0x70+i-1] = "F" + strconv.Itoa(i) + keyCodeToNameSafari[0x70+i-1] = "F" + strconv.Itoa(i) } } @@ -140,8 +184,13 @@ const uiKeysJSTmpl = `{{.License}} package ui -var keyCodeToKey = map[int]Key{ -{{range $code, $name := .KeyCodeToName}}{{$code}}: Key{{$name}}, +var codeToKey = map[string]Key{ +{{range $code, $name := .CodeToName}}"{{$code}}": Key{{$name}}, +{{end}} +} + +var keyCodeToKeySafari = map[int]Key{ +{{range $code, $name := .KeyCodeToNameSafari}}{{$code}}: Key{{$name}}, {{end}} } ` @@ -232,19 +281,28 @@ func main() { notice := "DO NOT EDIT: This file is auto-generated by genkeys.go." - names := []string{} - namesWithoutMods := []string{} - codes := []int{} - for code, name := range keyCodeToName { - names = append(names, name) + namesSet := map[string]struct{}{} + namesWithoutModsSet := map[string]struct{}{} + codes := []string{} + for code, name := range codeToName { + namesSet[name] = struct{}{} codes = append(codes, code) if name != "Alt" && name != "Control" && name != "Shift" { - namesWithoutMods = append(namesWithoutMods, name) + namesWithoutModsSet[name] = struct{}{} } } + names := []string{} + namesWithoutMods := []string{} + for n := range namesSet { + names = append(names, n) + } + for n := range namesWithoutModsSet { + namesWithoutMods = append(namesWithoutMods, n) + } + sort.Sort(KeyNames(names)) sort.Sort(KeyNames(namesWithoutMods)) - sort.Ints(codes) + sort.Strings(codes) for path, tmpl := range map[string]string{ "keys.go": ebitenKeysTmpl, @@ -278,7 +336,8 @@ func main() { "License": license, "Notice": notice, "BuildTag": buildTag, - "KeyCodeToName": keyCodeToName, + "CodeToName": codeToName, + "KeyCodeToNameSafari": keyCodeToNameSafari, "Codes": codes, "KeyNames": names, "LastKeyName": names[len(names)-1], diff --git a/internal/ui/input_js.go b/internal/ui/input_js.go index 898f9b3c2..e18e28dd2 100644 --- a/internal/ui/input_js.go +++ b/internal/ui/input_js.go @@ -23,7 +23,8 @@ import ( ) type input struct { - keyPressed map[int]bool + keyPressed map[string]bool + keyPressedSafari map[int]bool mouseButtonPressed map[int]bool cursorX int cursorY int @@ -35,15 +36,24 @@ type input struct { func (i *input) IsKeyPressed(key Key) bool { i.m.RLock() defer i.m.RUnlock() - if i.keyPressed == nil { - i.keyPressed = map[int]bool{} - } - for c, k := range keyCodeToKey { - if k != key { - continue + if i.keyPressed != nil { + for c, k := range codeToKey { + if k != key { + continue + } + if i.keyPressed[c] { + return true + } } - if i.keyPressed[c] { - return true + } + if i.keyPressedSafari != nil { + for c, k := range keyCodeToKeySafari { + if k != key { + continue + } + if i.keyPressedSafari[c] { + return true + } } } return false @@ -72,24 +82,42 @@ func (i *input) IsMouseButtonPressed(button MouseButton) bool { return false } -func (i *input) keyDown(code int) { +func (i *input) keyDown(code string) { i.m.Lock() defer i.m.Unlock() if i.keyPressed == nil { - i.keyPressed = map[int]bool{} + i.keyPressed = map[string]bool{} } i.keyPressed[code] = true } -func (i *input) keyUp(code int) { +func (i *input) keyUp(code string) { i.m.Lock() defer i.m.Unlock() if i.keyPressed == nil { - i.keyPressed = map[int]bool{} + i.keyPressed = map[string]bool{} } i.keyPressed[code] = false } +func (i *input) keyDownSafari(code int) { + i.m.Lock() + defer i.m.Unlock() + if i.keyPressedSafari == nil { + i.keyPressedSafari = map[int]bool{} + } + i.keyPressedSafari[code] = true +} + +func (i *input) keyUpSafari(code int) { + i.m.Lock() + defer i.m.Unlock() + if i.keyPressedSafari == nil { + i.keyPressedSafari = map[int]bool{} + } + i.keyPressedSafari[code] = false +} + func (i *input) mouseDown(code int) { i.m.Lock() defer i.m.Unlock() diff --git a/internal/ui/keys_js.go b/internal/ui/keys_js.go index bbe735a38..ecf664a46 100644 --- a/internal/ui/keys_js.go +++ b/internal/ui/keys_js.go @@ -18,7 +18,82 @@ package ui -var keyCodeToKey = map[int]Key{ +var codeToKey = map[string]Key{ + "AltLeft": KeyAlt, + "AltRight": KeyAlt, + "ArrowDown": KeyDown, + "ArrowLeft": KeyLeft, + "ArrowRight": KeyRight, + "ArrowUp": KeyUp, + "Backspace": KeyBackspace, + "CapsLock": KeyCapsLock, + "Comma": KeyComma, + "ControlLeft": KeyControl, + "ControlRight": KeyControl, + "Delete": KeyDelete, + "Digit0": Key0, + "Digit1": Key1, + "Digit2": Key2, + "Digit3": Key3, + "Digit4": Key4, + "Digit5": Key5, + "Digit6": Key6, + "Digit7": Key7, + "Digit8": Key8, + "Digit9": Key9, + "End": KeyEnd, + "Enter": KeyEnter, + "Escape": KeyEscape, + "F1": KeyF1, + "F10": KeyF10, + "F11": KeyF11, + "F12": KeyF12, + "F2": KeyF2, + "F3": KeyF3, + "F4": KeyF4, + "F5": KeyF5, + "F6": KeyF6, + "F7": KeyF7, + "F8": KeyF8, + "F9": KeyF9, + "Home": KeyHome, + "Insert": KeyInsert, + "KeyA": KeyA, + "KeyB": KeyB, + "KeyC": KeyC, + "KeyD": KeyD, + "KeyE": KeyE, + "KeyF": KeyF, + "KeyG": KeyG, + "KeyH": KeyH, + "KeyI": KeyI, + "KeyJ": KeyJ, + "KeyK": KeyK, + "KeyL": KeyL, + "KeyM": KeyM, + "KeyN": KeyN, + "KeyO": KeyO, + "KeyP": KeyP, + "KeyQ": KeyQ, + "KeyR": KeyR, + "KeyS": KeyS, + "KeyT": KeyT, + "KeyU": KeyU, + "KeyV": KeyV, + "KeyW": KeyW, + "KeyX": KeyX, + "KeyY": KeyY, + "KeyZ": KeyZ, + "PageDown": KeyPageDown, + "PageUp": KeyPageUp, + "Period": KeyPeriod, + "ShiftLeft": KeyShift, + "ShiftRight": KeyShift, + "Space": KeySpace, + "Tab": KeyTab, +} + +var keyCodeToKeySafari = map[int]Key{ 8: KeyBackspace, 9: KeyTab, 13: KeyEnter, diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index 137b5e202..cfd7d9851 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -183,12 +183,23 @@ func initialize() error { // Keyboard canvas.Call("addEventListener", "keydown", func(e *js.Object) { e.Call("preventDefault") - code := e.Get("keyCode").Int() + if e.Get("code") == js.Undefined { + // Assume that UA is Safari. + code := e.Get("keyCode").Int() + currentInput.keyDownSafari(code) + return + } + code := e.Get("code").String() currentInput.keyDown(code) }) canvas.Call("addEventListener", "keyup", func(e *js.Object) { e.Call("preventDefault") - code := e.Get("keyCode").Int() + if e.Get("code") == js.Undefined { + // Assume that UA is Safari. + code := e.Get("keyCode").Int() + currentInput.keyUpSafari(code) + } + code := e.Get("code").String() currentInput.keyUp(code) })