From bdaff72af916a5ff8e7012e2da4ce126c1dc4cbd Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 27 May 2016 01:31:30 +0900 Subject: [PATCH] input: Implement Touches function (WIP) (#101) --- input.go | 17 ++++++++++++++++ internal/ui/input.go | 43 ++++++++++++++++++++++++++++++++++------- internal/ui/input_js.go | 7 +++++++ internal/ui/ui_js.go | 31 ++++++++++++++++------------- 4 files changed, 78 insertions(+), 20 deletions(-) diff --git a/input.go b/input.go index 5e02babc4..3321efaab 100644 --- a/input.go +++ b/input.go @@ -35,6 +35,9 @@ func CursorPosition() (x, y int) { // IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed. // // This function is concurrent-safe. +// +// Note that touch events not longer affect this function's result as of 1.4.0-alpha. +// Use Touches instead. func IsMouseButtonPressed(mouseButton MouseButton) bool { return ui.CurrentInput().IsMouseButtonPressed(ui.MouseButton(mouseButton)) } @@ -78,3 +81,17 @@ func GamepadButtonNum(id int) int { func IsGamepadButtonPressed(id int, button GamepadButton) bool { return ui.CurrentInput().IsGamepadButtonPressed(id, ui.GamepadButton(button)) } + +type Touch interface { + ID() int + Position() (x, y int) +} + +func Touches() []Touch { + t := ui.CurrentInput().Touches() + tt := make([]Touch, len(t)) + for i := 0; i < len(tt); i++ { + tt[i] = t[i] + } + return tt +} diff --git a/internal/ui/input.go b/internal/ui/input.go index d96905de7..fe4541147 100644 --- a/internal/ui/input.go +++ b/internal/ui/input.go @@ -28,6 +28,12 @@ type Input interface { GamepadAxisNum(id int) int GamepadButtonNum(id int) int IsGamepadButtonPressed(id int, button GamepadButton) bool + Touches() []Touch +} + +type Touch interface { + ID() int + Position() (x, y int) } type input struct { @@ -36,16 +42,10 @@ type input struct { cursorX int cursorY int gamepads [16]gamePad + touches []touch m sync.RWMutex } -type gamePad struct { - axisNum int - axes [16]float64 - buttonNum int - buttonPressed [256]bool -} - func CurrentInput() Input { return currentInput } @@ -103,3 +103,32 @@ func (i *input) IsGamepadButtonPressed(id int, button GamepadButton) bool { } return i.gamepads[id].buttonPressed[button] } + +func (in *input) Touches() []Touch { + t := make([]Touch, len(in.touches)) + for i := 0; i < len(t); i++ { + t[i] = &in.touches[i] + } + return t +} + +type gamePad struct { + axisNum int + axes [16]float64 + buttonNum int + buttonPressed [256]bool +} + +type touch struct { + id int + x int + y int +} + +func (t *touch) ID() int { + return t.id +} + +func (t *touch) Position() (x, y int) { + return t.x, t.y +} diff --git a/internal/ui/input_js.go b/internal/ui/input_js.go index 36f5b1dee..5dcd21da8 100644 --- a/internal/ui/input_js.go +++ b/internal/ui/input_js.go @@ -112,3 +112,10 @@ func (i *input) updateGamepads() { } } } + +func (i *input) updateTouches(t []touch) { + i.m.Lock() + defer i.m.Unlock() + i.touches = make([]touch, len(t)) + copy(i.touches, t) +} diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index 022de465f..ec4195b2b 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -112,6 +112,20 @@ func (u *userInterface) FinishRendering() error { return nil } +func touchEventToTouches(e *js.Object) []touch { + scale := currentUI.scale + j := e.Get("targetTouches") + t := make([]touch, j.Get("length").Int()) + for i := 0; i < len(t); i++ { + jj := j.Call("item", i) + target := jj.Get("target") + t[i].id = jj.Get("identifier").Int() + t[i].x = (jj.Get("clientX").Int() - target.Get("left").Int()) / scale + t[i].y = (jj.Get("clientY").Int() - target.Get("top").Int()) / scale + } + return t +} + func initialize() (*opengl.Context, error) { // Do nothing in node.js. if js.Global.Get("require") != js.Undefined { @@ -194,27 +208,18 @@ func initialize() (*opengl.Context, error) { e.Call("preventDefault") }) - // Touch (emulating mouse events) - // TODO: Create indimendent touch functions + // Touch canvas.Call("addEventListener", "touchstart", func(e *js.Object) { e.Call("preventDefault") - currentInput.mouseDown(0) - touches := e.Get("changedTouches") - touch := touches.Index(0) - setMouseCursorFromEvent(touch) + currentInput.updateTouches(touchEventToTouches(e)) }) canvas.Call("addEventListener", "touchend", func(e *js.Object) { e.Call("preventDefault") - currentInput.mouseUp(0) - touches := e.Get("changedTouches") - touch := touches.Index(0) - setMouseCursorFromEvent(touch) + currentInput.updateTouches(touchEventToTouches(e)) }) canvas.Call("addEventListener", "touchmove", func(e *js.Object) { e.Call("preventDefault") - touches := e.Get("changedTouches") - touch := touches.Index(0) - setMouseCursorFromEvent(touch) + currentInput.updateTouches(touchEventToTouches(e)) }) // Gamepad