mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 05:18:21 +00:00
Captured/uncaptured mode in input package+comments
This commit is contained in:
@ -33,25 +33,12 @@ type Window struct {
|
|||||||
|
|
||||||
func (w *Window) handleInputs() {
|
func (w *Window) handleInputs() {
|
||||||
|
|
||||||
input.EventLoopStart()
|
|
||||||
imIo := imgui.CurrentIO()
|
imIo := imgui.CurrentIO()
|
||||||
|
|
||||||
imguiCaptureMouse := imIo.WantCaptureMouse()
|
imguiCaptureMouse := imIo.WantCaptureMouse()
|
||||||
imguiCaptureKeyboard := imIo.WantCaptureKeyboard()
|
imguiCaptureKeyboard := imIo.WantCaptureKeyboard()
|
||||||
|
|
||||||
// These two are to fix a bug where state isn't cleared
|
input.EventLoopStart(imguiCaptureMouse, imguiCaptureKeyboard)
|
||||||
// even after imgui captures the keyboard/mouse.
|
|
||||||
//
|
|
||||||
// For example, if player is moving due to key held and then imgui captures the keyboard,
|
|
||||||
// the player keeps moving even when the key is no longer pressed because the input system never
|
|
||||||
// receives the key up event.
|
|
||||||
if imguiCaptureMouse {
|
|
||||||
input.ClearMouseState()
|
|
||||||
}
|
|
||||||
|
|
||||||
if imguiCaptureKeyboard {
|
|
||||||
input.ClearKeyboardState()
|
|
||||||
}
|
|
||||||
|
|
||||||
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||||
|
|
||||||
@ -65,18 +52,12 @@ func (w *Window) handleInputs() {
|
|||||||
|
|
||||||
case *sdl.MouseWheelEvent:
|
case *sdl.MouseWheelEvent:
|
||||||
|
|
||||||
if !imguiCaptureMouse {
|
input.HandleMouseWheelEvent(e)
|
||||||
input.HandleMouseWheelEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
imIo.AddMouseWheelDelta(float32(e.X), float32(e.Y))
|
imIo.AddMouseWheelDelta(float32(e.X), float32(e.Y))
|
||||||
|
|
||||||
case *sdl.KeyboardEvent:
|
case *sdl.KeyboardEvent:
|
||||||
|
|
||||||
if !imguiCaptureKeyboard {
|
input.HandleKeyboardEvent(e)
|
||||||
input.HandleKeyboardEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
imIo.AddKeyEvent(nmageimgui.SdlScancodeToImGuiKey(e.Keysym.Scancode), e.Type == sdl.KEYDOWN)
|
imIo.AddKeyEvent(nmageimgui.SdlScancodeToImGuiKey(e.Keysym.Scancode), e.Type == sdl.KEYDOWN)
|
||||||
|
|
||||||
// Send modifier key updates to imgui
|
// Send modifier key updates to imgui
|
||||||
@ -101,10 +82,7 @@ func (w *Window) handleInputs() {
|
|||||||
|
|
||||||
case *sdl.MouseButtonEvent:
|
case *sdl.MouseButtonEvent:
|
||||||
|
|
||||||
if !imguiCaptureMouse {
|
input.HandleMouseBtnEvent(e)
|
||||||
input.HandleMouseBtnEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
isPressed := e.State == sdl.PRESSED
|
isPressed := e.State == sdl.PRESSED
|
||||||
|
|
||||||
if e.Button == sdl.BUTTON_LEFT {
|
if e.Button == sdl.BUTTON_LEFT {
|
||||||
@ -117,9 +95,7 @@ func (w *Window) handleInputs() {
|
|||||||
|
|
||||||
case *sdl.MouseMotionEvent:
|
case *sdl.MouseMotionEvent:
|
||||||
|
|
||||||
if !imguiCaptureMouse {
|
input.HandleMouseMotionEvent(e)
|
||||||
input.HandleMouseMotionEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
case *sdl.WindowEvent:
|
case *sdl.WindowEvent:
|
||||||
|
|
||||||
|
|||||||
185
input/input.go
185
input/input.go
@ -1,6 +1,23 @@
|
|||||||
|
// The input package provides an interface to mouse and keyboard inputs
|
||||||
|
// like key clicks and releases, along with some higher level constructs like
|
||||||
|
// pressed/released this frames, double clicks, and normalized inputs.
|
||||||
|
//
|
||||||
|
// The input package has two sets of functions for most cases, where one
|
||||||
|
// is in the form 'xy' and the other 'xyCaptured'. The captured form
|
||||||
|
// always returns normal events even if the mouse or keyboard are captured
|
||||||
|
// by the UI system. The 'xy' form however will return zero/false if the
|
||||||
|
// respective input device is currently captured (with the exception of mouse position, that is always correctly returned).
|
||||||
|
//
|
||||||
|
// For most cases, you want to use the 'xy' form. For example, you only want to receive
|
||||||
|
// key down events for game character movement when the UI isn't capturing the keyboard,
|
||||||
|
// because otherwise the character will move while typing in a UI textbox.
|
||||||
|
//
|
||||||
|
// The functions IsMouseCaptured and IsKeyboardCaptured are also available.
|
||||||
package input
|
package input
|
||||||
|
|
||||||
import "github.com/veandco/go-sdl2/sdl"
|
import (
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
)
|
||||||
|
|
||||||
type keyState struct {
|
type keyState struct {
|
||||||
Key sdl.Keycode
|
Key sdl.Keycode
|
||||||
@ -31,15 +48,22 @@ type mouseWheelState struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
keyMap = make(map[sdl.Keycode]keyState)
|
mouseWheel = mouseWheelState{}
|
||||||
mouseBtnMap = make(map[int]mouseBtnState)
|
mouseMotion = mouseMotionState{}
|
||||||
mouseMotion = mouseMotionState{}
|
mouseBtnMap = make(map[int]mouseBtnState)
|
||||||
mouseWheel = mouseWheelState{}
|
keyMap = make(map[sdl.Keycode]keyState)
|
||||||
quitRequested bool
|
|
||||||
|
isQuitRequested bool
|
||||||
|
isMouseCaptured bool
|
||||||
|
isKeyboardCaptured bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func EventLoopStart() {
|
func EventLoopStart(mouseGotCaptured, keyboardGotCaptured bool) {
|
||||||
|
|
||||||
|
isMouseCaptured = mouseGotCaptured
|
||||||
|
isKeyboardCaptured = keyboardGotCaptured
|
||||||
|
|
||||||
|
// Update per-frame state
|
||||||
for k, v := range keyMap {
|
for k, v := range keyMap {
|
||||||
v.IsPressedThisFrame = false
|
v.IsPressedThisFrame = false
|
||||||
v.IsReleasedThisFrame = false
|
v.IsReleasedThisFrame = false
|
||||||
@ -59,7 +83,7 @@ func EventLoopStart() {
|
|||||||
mouseWheel.XDelta = 0
|
mouseWheel.XDelta = 0
|
||||||
mouseWheel.YDelta = 0
|
mouseWheel.YDelta = 0
|
||||||
|
|
||||||
quitRequested = false
|
isQuitRequested = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearKeyboardState() {
|
func ClearKeyboardState() {
|
||||||
@ -73,11 +97,19 @@ func ClearMouseState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func HandleQuitEvent(e *sdl.QuitEvent) {
|
func HandleQuitEvent(e *sdl.QuitEvent) {
|
||||||
quitRequested = true
|
isQuitRequested = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsMouseCaptured() bool {
|
||||||
|
return isMouseCaptured
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsKeyboardCaptured() bool {
|
||||||
|
return isKeyboardCaptured
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsQuitClicked() bool {
|
func IsQuitClicked() bool {
|
||||||
return quitRequested
|
return isQuitRequested
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleKeyboardEvent(e *sdl.KeyboardEvent) {
|
func HandleKeyboardEvent(e *sdl.KeyboardEvent) {
|
||||||
@ -123,18 +155,36 @@ func HandleMouseWheelEvent(e *sdl.MouseWheelEvent) {
|
|||||||
mouseWheel.YDelta = e.Y
|
mouseWheel.YDelta = e.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMousePos returns the window coordinates of the mouse
|
// GetMousePos returns the window coordinates of the mouse regardless of whether the mouse is captured or not
|
||||||
func GetMousePos() (x, y int32) {
|
func GetMousePos() (x, y int32) {
|
||||||
return mouseMotion.XPos, mouseMotion.YPos
|
return mouseMotion.XPos, mouseMotion.YPos
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMouseMotion returns how many pixels were moved last frame
|
// GetMouseMotion returns how many pixels were moved last frame
|
||||||
func GetMouseMotion() (xDelta, yDelta int32) {
|
func GetMouseMotion() (xDelta, yDelta int32) {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetMouseMotionCaptured()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMouseMotionCaptured() (xDelta, yDelta int32) {
|
||||||
return mouseMotion.XDelta, mouseMotion.YDelta
|
return mouseMotion.XDelta, mouseMotion.YDelta
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMouseMotionNorm() (xDelta, yDelta int32) {
|
func GetMouseMotionNorm() (xDelta, yDelta int32) {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetMouseMotionNormCaptured()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMouseMotionNormCaptured() (xDelta, yDelta int32) {
|
||||||
|
|
||||||
x, y := mouseMotion.XDelta, mouseMotion.YDelta
|
x, y := mouseMotion.XDelta, mouseMotion.YDelta
|
||||||
if x > 0 {
|
if x > 0 {
|
||||||
x = 1
|
x = 1
|
||||||
@ -152,12 +202,31 @@ func GetMouseMotionNorm() (xDelta, yDelta int32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetMouseWheelMotion() (xDelta, yDelta int32) {
|
func GetMouseWheelMotion() (xDelta, yDelta int32) {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetMouseWheelMotionCaptured()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMouseWheelMotionCaptured() (xDelta, yDelta int32) {
|
||||||
return mouseWheel.XDelta, mouseWheel.YDelta
|
return mouseWheel.XDelta, mouseWheel.YDelta
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMouseWheelXNorm returns 1 if mouse wheel xDelta > 0, -1 if xDelta < 0, and 0 otherwise
|
// GetMouseWheelXNorm returns 1 if mouse wheel xDelta > 0, -1 if xDelta < 0, and 0 otherwise
|
||||||
func GetMouseWheelXNorm() int32 {
|
func GetMouseWheelXNorm() int32 {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetMouseWheelXNormCaptured()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMouseWheelXNormCaptured returns 1 if mouse wheel xDelta > 0, -1 if xDelta < 0, and 0 otherwise
|
||||||
|
func GetMouseWheelXNormCaptured() int32 {
|
||||||
|
|
||||||
if mouseWheel.XDelta > 0 {
|
if mouseWheel.XDelta > 0 {
|
||||||
return 1
|
return 1
|
||||||
} else if mouseWheel.XDelta < 0 {
|
} else if mouseWheel.XDelta < 0 {
|
||||||
@ -167,9 +236,19 @@ func GetMouseWheelXNorm() int32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns 1 if mouse wheel yDelta > 0, -1 if yDelta < 0, and 0 otherwise
|
// GetMouseWheelYNorm returns 1 if mouse wheel yDelta > 0, -1 if yDelta < 0, and 0 otherwise
|
||||||
func GetMouseWheelYNorm() int32 {
|
func GetMouseWheelYNorm() int32 {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetMouseWheelYNormCaptured()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMouseWheelYNormCaptured returns 1 if mouse wheel yDelta > 0, -1 if yDelta < 0, and 0 otherwise
|
||||||
|
func GetMouseWheelYNormCaptured() int32 {
|
||||||
|
|
||||||
if mouseWheel.YDelta > 0 {
|
if mouseWheel.YDelta > 0 {
|
||||||
return 1
|
return 1
|
||||||
} else if mouseWheel.YDelta < 0 {
|
} else if mouseWheel.YDelta < 0 {
|
||||||
@ -181,6 +260,15 @@ func GetMouseWheelYNorm() int32 {
|
|||||||
|
|
||||||
func KeyClicked(kc sdl.Keycode) bool {
|
func KeyClicked(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
if isKeyboardCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeyClickedCaptured(kc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyClickedCaptured(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
ks, ok := keyMap[kc]
|
ks, ok := keyMap[kc]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -191,6 +279,15 @@ func KeyClicked(kc sdl.Keycode) bool {
|
|||||||
|
|
||||||
func KeyReleased(kc sdl.Keycode) bool {
|
func KeyReleased(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
if isKeyboardCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeyReleasedCaptured(kc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyReleasedCaptured(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
ks, ok := keyMap[kc]
|
ks, ok := keyMap[kc]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -201,6 +298,15 @@ func KeyReleased(kc sdl.Keycode) bool {
|
|||||||
|
|
||||||
func KeyDown(kc sdl.Keycode) bool {
|
func KeyDown(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
if isKeyboardCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeyDownCaptured(kc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyDownCaptured(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
ks, ok := keyMap[kc]
|
ks, ok := keyMap[kc]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -211,6 +317,15 @@ func KeyDown(kc sdl.Keycode) bool {
|
|||||||
|
|
||||||
func KeyUp(kc sdl.Keycode) bool {
|
func KeyUp(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
if isKeyboardCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeyUpCaptured(kc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyUpCaptured(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
ks, ok := keyMap[kc]
|
ks, ok := keyMap[kc]
|
||||||
if !ok {
|
if !ok {
|
||||||
return true
|
return true
|
||||||
@ -221,6 +336,15 @@ func KeyUp(kc sdl.Keycode) bool {
|
|||||||
|
|
||||||
func MouseClicked(mb int) bool {
|
func MouseClicked(mb int) bool {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseClickedCaptued(mb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseClickedCaptued(mb int) bool {
|
||||||
|
|
||||||
btn, ok := mouseBtnMap[mb]
|
btn, ok := mouseBtnMap[mb]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -231,6 +355,15 @@ func MouseClicked(mb int) bool {
|
|||||||
|
|
||||||
func MouseDoubleClicked(mb int) bool {
|
func MouseDoubleClicked(mb int) bool {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseDoubleClickedCaptured(mb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseDoubleClickedCaptured(mb int) bool {
|
||||||
|
|
||||||
btn, ok := mouseBtnMap[mb]
|
btn, ok := mouseBtnMap[mb]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -240,6 +373,16 @@ func MouseDoubleClicked(mb int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MouseReleased(mb int) bool {
|
func MouseReleased(mb int) bool {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseReleasedCaptured(mb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseReleasedCaptured(mb int) bool {
|
||||||
|
|
||||||
btn, ok := mouseBtnMap[mb]
|
btn, ok := mouseBtnMap[mb]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -250,6 +393,15 @@ func MouseReleased(mb int) bool {
|
|||||||
|
|
||||||
func MouseDown(mb int) bool {
|
func MouseDown(mb int) bool {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseDownCaptued(mb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseDownCaptued(mb int) bool {
|
||||||
|
|
||||||
btn, ok := mouseBtnMap[mb]
|
btn, ok := mouseBtnMap[mb]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -260,6 +412,15 @@ func MouseDown(mb int) bool {
|
|||||||
|
|
||||||
func MouseUp(mb int) bool {
|
func MouseUp(mb int) bool {
|
||||||
|
|
||||||
|
if isMouseCaptured {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseUpCaptured(mb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseUpCaptured(mb int) bool {
|
||||||
|
|
||||||
btn, ok := mouseBtnMap[mb]
|
btn, ok := mouseBtnMap[mb]
|
||||||
if !ok {
|
if !ok {
|
||||||
return true
|
return true
|
||||||
|
|||||||
Reference in New Issue
Block a user