ui: Use code instead of keyCode on browsers but Safari

This commit is contained in:
Hajime Hoshi 2017-04-14 03:02:38 +09:00
parent 469aa2c9a5
commit 0cd692d26a
4 changed files with 204 additions and 31 deletions

View File

@ -31,10 +31,54 @@ import (
"github.com/hajimehoshi/ebiten/internal" "github.com/hajimehoshi/ebiten/internal"
) )
var keyCodeToName map[int]string var (
codeToName map[string]string
keyCodeToNameSafari map[int]string
)
func init() { 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", 0xBC: "Comma",
0xBE: "Period", 0xBE: "Period",
0x12: "Alt", 0x12: "Alt",
@ -60,15 +104,15 @@ func init() {
} }
// ASCII: 0 - 9 // ASCII: 0 - 9
for c := '0'; c <= '9'; c++ { for c := '0'; c <= '9'; c++ {
keyCodeToName[int(c)] = string(c) keyCodeToNameSafari[int(c)] = string(c)
} }
// ASCII: A - Z // ASCII: A - Z
for c := 'A'; c <= 'Z'; c++ { for c := 'A'; c <= 'Z'; c++ {
keyCodeToName[int(c)] = string(c) keyCodeToNameSafari[int(c)] = string(c)
} }
// Function keys // Function keys
for i := 1; i <= 12; i++ { 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 package ui
var keyCodeToKey = map[int]Key{ var codeToKey = map[string]Key{
{{range $code, $name := .KeyCodeToName}}{{$code}}: Key{{$name}}, {{range $code, $name := .CodeToName}}"{{$code}}": Key{{$name}},
{{end}}
}
var keyCodeToKeySafari = map[int]Key{
{{range $code, $name := .KeyCodeToNameSafari}}{{$code}}: Key{{$name}},
{{end}} {{end}}
} }
` `
@ -232,19 +281,28 @@ func main() {
notice := "DO NOT EDIT: This file is auto-generated by genkeys.go." notice := "DO NOT EDIT: This file is auto-generated by genkeys.go."
names := []string{} namesSet := map[string]struct{}{}
namesWithoutMods := []string{} namesWithoutModsSet := map[string]struct{}{}
codes := []int{} codes := []string{}
for code, name := range keyCodeToName { for code, name := range codeToName {
names = append(names, name) namesSet[name] = struct{}{}
codes = append(codes, code) codes = append(codes, code)
if name != "Alt" && name != "Control" && name != "Shift" { 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(names))
sort.Sort(KeyNames(namesWithoutMods)) sort.Sort(KeyNames(namesWithoutMods))
sort.Ints(codes) sort.Strings(codes)
for path, tmpl := range map[string]string{ for path, tmpl := range map[string]string{
"keys.go": ebitenKeysTmpl, "keys.go": ebitenKeysTmpl,
@ -278,7 +336,8 @@ func main() {
"License": license, "License": license,
"Notice": notice, "Notice": notice,
"BuildTag": buildTag, "BuildTag": buildTag,
"KeyCodeToName": keyCodeToName, "CodeToName": codeToName,
"KeyCodeToNameSafari": keyCodeToNameSafari,
"Codes": codes, "Codes": codes,
"KeyNames": names, "KeyNames": names,
"LastKeyName": names[len(names)-1], "LastKeyName": names[len(names)-1],

View File

@ -23,7 +23,8 @@ import (
) )
type input struct { type input struct {
keyPressed map[int]bool keyPressed map[string]bool
keyPressedSafari map[int]bool
mouseButtonPressed map[int]bool mouseButtonPressed map[int]bool
cursorX int cursorX int
cursorY int cursorY int
@ -35,15 +36,24 @@ type input struct {
func (i *input) IsKeyPressed(key Key) bool { func (i *input) IsKeyPressed(key Key) bool {
i.m.RLock() i.m.RLock()
defer i.m.RUnlock() defer i.m.RUnlock()
if i.keyPressed == nil { if i.keyPressed != nil {
i.keyPressed = map[int]bool{} for c, k := range codeToKey {
} if k != key {
for c, k := range keyCodeToKey { continue
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 return false
@ -72,24 +82,42 @@ func (i *input) IsMouseButtonPressed(button MouseButton) bool {
return false return false
} }
func (i *input) keyDown(code int) { func (i *input) keyDown(code string) {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
if i.keyPressed == nil { if i.keyPressed == nil {
i.keyPressed = map[int]bool{} i.keyPressed = map[string]bool{}
} }
i.keyPressed[code] = true i.keyPressed[code] = true
} }
func (i *input) keyUp(code int) { func (i *input) keyUp(code string) {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
if i.keyPressed == nil { if i.keyPressed == nil {
i.keyPressed = map[int]bool{} i.keyPressed = map[string]bool{}
} }
i.keyPressed[code] = false 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) { func (i *input) mouseDown(code int) {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()

View File

@ -18,7 +18,82 @@
package ui 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, 8: KeyBackspace,
9: KeyTab, 9: KeyTab,
13: KeyEnter, 13: KeyEnter,

View File

@ -183,12 +183,23 @@ func initialize() error {
// Keyboard // Keyboard
canvas.Call("addEventListener", "keydown", func(e *js.Object) { canvas.Call("addEventListener", "keydown", func(e *js.Object) {
e.Call("preventDefault") 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) currentInput.keyDown(code)
}) })
canvas.Call("addEventListener", "keyup", func(e *js.Object) { canvas.Call("addEventListener", "keyup", func(e *js.Object) {
e.Call("preventDefault") 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) currentInput.keyUp(code)
}) })