From 9d436db91742d54f865b63bd981249ab8aa9ecc4 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Fri, 19 Apr 2024 22:00:23 -0700 Subject: [PATCH] Add IsFingerDown boolean to the Event object IsFingerDown will be true as long as at least one finger has registered a TouchDown event but not yet a TouchUp. The calling program can check this boolean to distinguish a mouse movement from a physical mouse to a probable touch based swipe. --- event/event.go | 8 +++++++- sdl/events.go | 21 ++++++++++++++++++++- sdl/sdl.go | 17 ++++++++++++----- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/event/event.go b/event/event.go index 4b8c82a..ddb7faa 100644 --- a/event/event.go +++ b/event/event.go @@ -34,13 +34,19 @@ type State struct { WindowResized bool // Touch state - Touching bool + Touching bool // A touch event this tick TouchNumFingers int TouchCenterX int TouchCenterY int GestureRotated float64 GesturePinched float64 + // Will be true if at least one finger is currently still held down on + // a touch screen. Meaning a FingerDown event happened in the past, but + // not yet a FingerUp event. If IsFingerDown, you can extrapolate that + // mouse movement events were actually touch swipes and not a mouse. + IsFingerDown bool + // Game controller events. // NOTE: for SDL2 you will need to call GameControllerEventState(1) // from veandco/go-sdl2/sdl for events to be read by SDL2. diff --git a/sdl/events.go b/sdl/events.go index 4a8dd54..d75f474 100644 --- a/sdl/events.go +++ b/sdl/events.go @@ -24,7 +24,7 @@ func (r *Renderer) Poll() (*event.State, error) { // Reset some events. s.WindowResized = false - // s.Touching = false + s.Touching = false // helper function to push keyboard key names on keyDown events only. pushKey := func(name string, state uint8) { @@ -108,6 +108,25 @@ func (r *Renderer) Poll() (*event.State, error) { t.Timestamp, sdl.GetTicks(), t.Type, t.Which, t.X, t.Y, ) } + case *sdl.TouchFingerEvent: + if DebugTouchEvents { + fmt.Printf("[%d ms] tick:%d TouchFinger type:%d Finger=%d TouchID=%+v Pressure=%f XY=%f,%f\n", + t.Timestamp, sdl.GetTicks(), t.Type, t.FingerID, t.TouchID, t.Pressure, t.X, t.Y, + ) + } + s.Touching = true + s.TouchNumFingers = 1 + s.TouchCenterX = int(t.X) + s.TouchCenterY = int(t.Y) + + // Track which finger(s) are down or up. + if t.Type == sdl.FINGERDOWN { + r.fingersDown[t.FingerID] = nil + } else if t.Type == sdl.FINGERUP { + delete(r.fingersDown, t.FingerID) + } + + s.IsFingerDown = len(r.fingersDown) > 0 case *sdl.MultiGestureEvent: if DebugTouchEvents { fmt.Printf("[%d ms] tick:%d MultiGesture type:%d Num=%d TouchID=%+v Dt=%f Dd=%f XY=%f,%f\n", diff --git a/sdl/sdl.go b/sdl/sdl.go index 23676ba..1c882b2 100644 --- a/sdl/sdl.go +++ b/sdl/sdl.go @@ -28,6 +28,12 @@ type Renderer struct { textures map[string]*Texture // cached textures textureMu sync.RWMutex + // Touch screens: track which finger(s) are currently down, if one finger is + // down then the events.IsFingerDown will be true. The calling program can + // tell whether a MouseMove event is a mouse or a finger swipe if it happens + // while IsFingerDown is set. + fingersDown map[sdl.FingerID]interface{} + // Optimizations to minimize SDL calls. lastColor render.Color } @@ -35,11 +41,12 @@ type Renderer struct { // New creates the SDL renderer. func New(title string, width, height int) *Renderer { return &Renderer{ - events: event.NewState(), - title: title, - width: int32(width), - height: int32(height), - textures: map[string]*Texture{}, + events: event.NewState(), + title: title, + width: int32(width), + height: int32(height), + textures: map[string]*Texture{}, + fingersDown: map[sdl.FingerID]interface{}{}, } }