From 39b31701854d6431d7a9b002f79a7b6e1715350c Mon Sep 17 00:00:00 2001 From: Philipp Steinhaus <40324631+PSteinhaus@users.noreply.github.com> Date: Sun, 17 Jun 2018 17:38:30 +0200 Subject: [PATCH] input: Enable mouse wheel input (#628) --- input.go | 6 +++++ internal/input/input_glfw.go | 40 ++++++++++++++++++++++++++-------- internal/input/input_js.go | 5 +++++ internal/input/input_mobile.go | 6 +++++ internal/ui/ui_glfw.go | 1 + internal/ui/ui_js.go | 1 + 6 files changed, 50 insertions(+), 9 deletions(-) diff --git a/input.go b/input.go index 7c561fc2d..3633fea79 100644 --- a/input.go +++ b/input.go @@ -52,6 +52,12 @@ func CursorPosition() (x, y int) { return ui.AdjustedCursorPosition() } +// MouseWheel returns the x and y offset of the scroll wheel. +// It returns 0 if the wheel isn't being rolled. +func MouseWheel() (xoff, yoff float64) { + return input.Get().MouseWheel() +} + // IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed. // // This function is concurrent-safe. diff --git a/internal/input/input_glfw.go b/internal/input/input_glfw.go index c1a9ed05b..fa0a96d26 100644 --- a/internal/input/input_glfw.go +++ b/internal/input/input_glfw.go @@ -27,14 +27,17 @@ import ( ) type Input struct { - keyPressed map[glfw.Key]bool - mouseButtonPressed map[glfw.MouseButton]bool - cursorX int - cursorY int - gamepads [16]gamePad - touches []*Touch // This is not updated until GLFW 3.3 is available (#417) - runeBuffer []rune - m sync.RWMutex + keyPressed map[glfw.Key]bool + mouseButtonPressed map[glfw.MouseButton]bool + callbacksInitialized bool + scrollX float64 + scrollY float64 + cursorX int + cursorY int + gamepads [16]gamePad + touches []*Touch // This is not updated until GLFW 3.3 is available (#417) + runeBuffer []rune + m sync.RWMutex } func (i *Input) RuneBuffer() []rune { @@ -49,6 +52,12 @@ func (i *Input) ClearRuneBuffer() { i.runeBuffer = i.runeBuffer[:0] } +func (i *Input) ResetScrollValues() { + i.m.RLock() + defer i.m.RUnlock() + i.scrollX, i.scrollY = 0, 0 +} + func (i *Input) IsKeyPressed(key Key) bool { i.m.RLock() defer i.m.RUnlock() @@ -83,6 +92,12 @@ func (i *Input) IsMouseButtonPressed(button MouseButton) bool { return false } +func (i *Input) MouseWheel() (xoff, yoff float64) { + i.m.RLock() + defer i.m.RUnlock() + return i.scrollX, i.scrollY +} + var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{ glfw.MouseButtonLeft: MouseButtonLeft, glfw.MouseButtonRight: MouseButtonRight, @@ -92,7 +107,7 @@ var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{ func (i *Input) Update(window *glfw.Window, scale float64) { i.m.Lock() defer i.m.Unlock() - if i.runeBuffer == nil { + if !i.callbacksInitialized { i.runeBuffer = make([]rune, 0, 1024) window.SetCharModsCallback(func(w *glfw.Window, char rune, mods glfw.ModifierKey) { if unicode.IsPrint(char) { @@ -101,6 +116,13 @@ func (i *Input) Update(window *glfw.Window, scale float64) { i.m.Unlock() } }) + window.SetScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) { + i.m.Lock() + i.scrollX = xoff + i.scrollY = yoff + i.m.Unlock() + }) + i.callbacksInitialized = true } if i.keyPressed == nil { i.keyPressed = map[glfw.Key]bool{} diff --git a/internal/input/input_js.go b/internal/input/input_js.go index 50ac12a11..a085ab41f 100644 --- a/internal/input/input_js.go +++ b/internal/input/input_js.go @@ -91,6 +91,11 @@ func (i *Input) IsMouseButtonPressed(button MouseButton) bool { return false } +func (i *Input) MouseWheel() (xoff, yoff float64) { + return 0, 0 + // TODO: Mouse scroll functionality is not yet implemented in js +} + func (i *Input) keyDown(code string) { if i.keyPressed == nil { i.keyPressed = map[string]bool{} diff --git a/internal/input/input_mobile.go b/internal/input/input_mobile.go index e2d3ac0ea..65ac3b469 100644 --- a/internal/input/input_mobile.go +++ b/internal/input/input_mobile.go @@ -23,6 +23,8 @@ import ( type Input struct { cursorX int cursorY int + scrollX float64 + scrollY float64 gamepads [16]gamePad touches []*Touch m sync.RWMutex @@ -36,6 +38,10 @@ func (i *Input) IsKeyPressed(key Key) bool { return false } +func (i *Input) MouseWheel() (xoff, yoff float64) { + return 0, 0 +} + func (i *Input) IsMouseButtonPressed(key MouseButton) bool { return false } diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index 0194047e4..f3a83cbf4 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -567,6 +567,7 @@ func (u *userInterface) update(g GraphicsContext) error { }) if err := g.Update(func() { input.Get().ClearRuneBuffer() + input.Get().ResetScrollValues() // The offscreens must be updated every frame (#490). u.updateGraphicsContext(g) }); err != nil { diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index bb9c7e27c..3abc9d3c9 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -194,6 +194,7 @@ func (u *userInterface) update(g GraphicsContext) error { u.updateGraphicsContext(g) if err := g.Update(func() { input.Get().ClearRuneBuffer() + // TODO: insert ResetScrollValues() counterpart to 'ui_glfw.go' here // The offscreens must be updated every frame (#490). u.updateGraphicsContext(g) }); err != nil {