From 79a7a2470742c3d244d77eeed62e8f1aa41f8273 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 8 Feb 2022 15:20:54 -0500 Subject: [PATCH] v1.2.0: added hover-based pointer events --- .../java/com/watabou/input/InputHandler.java | 15 +++------ .../java/com/watabou/input/PointerEvent.java | 33 ++++++++++++++----- .../java/com/watabou/noosa/PointerArea.java | 31 +++++++++++++---- .../scenes/CellSelector.java | 2 +- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/SPD-classes/src/main/java/com/watabou/input/InputHandler.java b/SPD-classes/src/main/java/com/watabou/input/InputHandler.java index e3a46d750..00c21f21a 100644 --- a/SPD-classes/src/main/java/com/watabou/input/InputHandler.java +++ b/SPD-classes/src/main/java/com/watabou/input/InputHandler.java @@ -27,7 +27,6 @@ import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.InputMultiplexer; import com.badlogic.gdx.InputProcessor; import com.watabou.noosa.Game; -import com.watabou.utils.PointF; public class InputHandler extends InputAdapter { @@ -91,29 +90,25 @@ public class InputHandler extends InputAdapter { @Override public synchronized boolean touchDown(int screenX, int screenY, int pointer, int button) { Gdx.input.setOnscreenKeyboardVisible(false); //in-game events never need keyboard, so hide it - PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, pointer, true)); + PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, pointer, PointerEvent.Type.DOWN)); return true; } @Override public synchronized boolean touchUp(int screenX, int screenY, int pointer, int button) { - PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, pointer, false)); + PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, pointer, PointerEvent.Type.UP)); return true; } @Override public synchronized boolean touchDragged(int screenX, int screenY, int pointer) { - PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, pointer, true)); + PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, pointer, PointerEvent.Type.DOWN)); return true; } - //TODO tracking this should probably be in PointerEvent - private static PointF pointerHoverPos = new PointF(); - @Override public boolean mouseMoved(int screenX, int screenY) { - pointerHoverPos.x = screenX; - pointerHoverPos.y = screenY; + PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, -1, PointerEvent.Type.HOVER)); return true; } @@ -147,7 +142,7 @@ public class InputHandler extends InputAdapter { @Override public boolean scrolled(float amountX, float amountY) { - ScrollEvent.addScrollEvent( new ScrollEvent(pointerHoverPos, amountY)); + ScrollEvent.addScrollEvent( new ScrollEvent(PointerEvent.lastHoverPos, amountY)); return true; } } diff --git a/SPD-classes/src/main/java/com/watabou/input/PointerEvent.java b/SPD-classes/src/main/java/com/watabou/input/PointerEvent.java index b5444f1ca..16f1848fb 100644 --- a/SPD-classes/src/main/java/com/watabou/input/PointerEvent.java +++ b/SPD-classes/src/main/java/com/watabou/input/PointerEvent.java @@ -28,16 +28,24 @@ import java.util.ArrayList; import java.util.HashMap; public class PointerEvent { - + + public enum Type { + DOWN, + UP, + HOVER + } + public PointF start; public PointF current; public int id; - public boolean down; + public Type type; + public boolean handled; //for hover events, to ensure hover always ends even with overlapping elements - public PointerEvent( int x, int y, int id, boolean down){ + public PointerEvent( int x, int y, int id, Type type){ start = current = new PointF(x, y); this.id = id; - this.down = down; + this.type = type; + handled = false; } public void update( PointerEvent other ){ @@ -49,7 +57,12 @@ public class PointerEvent { } public PointerEvent up() { - down = false; + if (type == Type.DOWN) type = Type.UP; + return this; + } + + public PointerEvent handle(){ + handled = true; return this; } @@ -74,6 +87,7 @@ public class PointerEvent { // Accumulated pointer events private static ArrayList pointerEvents = new ArrayList<>(); private static HashMap activePointers = new HashMap<>(); + static PointF lastHoverPos = new PointF(); public static synchronized void addPointerEvent( PointerEvent event ){ pointerEvents.add( event ); @@ -81,19 +95,22 @@ public class PointerEvent { public static synchronized void processPointerEvents(){ for (PointerEvent p : pointerEvents){ + if (p.type == Type.HOVER){ + lastHoverPos.set(p.current); + } if (activePointers.containsKey(p.id)){ PointerEvent existing = activePointers.get(p.id); existing.current = p.current; - if (existing.down == p.down){ + if (existing.type == p.type){ pointerSignal.dispatch( null ); - } else if (p.down) { + } else if (p.type == Type.DOWN) { pointerSignal.dispatch( existing ); } else { activePointers.remove(existing.id); pointerSignal.dispatch(existing.up()); } } else { - if (p.down) { + if (p.type == Type.DOWN) { activePointers.put(p.id, p); } pointerSignal.dispatch(p); diff --git a/SPD-classes/src/main/java/com/watabou/noosa/PointerArea.java b/SPD-classes/src/main/java/com/watabou/noosa/PointerArea.java index ba94b5154..ffceec0f6 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/PointerArea.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/PointerArea.java @@ -30,6 +30,7 @@ public class PointerArea extends Visual implements Signal.Listener public Visual target; protected PointerEvent curEvent = null; + protected boolean hovered = false; public int blockLevel = BLOCK_WHEN_ACTIVE; public static final int ALWAYS_BLOCK = 0; //Always block input to overlapping elements @@ -54,7 +55,7 @@ public class PointerArea extends Visual implements Signal.Listener @Override public boolean onSignal( PointerEvent event ) { - + boolean hit = event != null && target.overlapsScreenPoint( (int)event.current.x, (int)event.current.y ); if (!isActive()) { @@ -63,16 +64,16 @@ public class PointerArea extends Visual implements Signal.Listener if (hit) { - boolean returnValue = (event.down || event == curEvent); + boolean returnValue = (event.type == PointerEvent.Type.DOWN || event == curEvent); - if (event.down) { + if (event.type == PointerEvent.Type.DOWN) { if (curEvent == null) { curEvent = event; } onPointerDown( event ); - } else { + } else if (event.type == PointerEvent.Type.UP) { onPointerUp( event ); @@ -81,6 +82,15 @@ public class PointerArea extends Visual implements Signal.Listener onClick( event ); } + } else if (event.type == PointerEvent.Type.HOVER) { + if (event.handled && hovered){ + hovered = false; + onHoverEnd(event); + } else if (!event.handled && !hovered){ + hovered = true; + onHoverStart(event); + } + event.handle(); } return returnValue && blockLevel != NEVER_BLOCK; @@ -89,11 +99,14 @@ public class PointerArea extends Visual implements Signal.Listener if (event == null && curEvent != null) { onDrag(curEvent); - } - - else if (curEvent != null && !event.down) { + + } else if (curEvent != null && event.type == PointerEvent.Type.UP) { onPointerUp( event ); curEvent = null; + + } else if (event != null && event.type == PointerEvent.Type.HOVER && hovered){ + hovered = false; + onHoverEnd(event); } return false; @@ -108,6 +121,10 @@ public class PointerArea extends Visual implements Signal.Listener protected void onClick( PointerEvent event ) { } protected void onDrag( PointerEvent event ) { } + + protected void onHoverStart( PointerEvent event ) { } + + protected void onHoverEnd( PointerEvent event ) { } public void reset() { curEvent = null; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/CellSelector.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/CellSelector.java index 7226eb224..17c3c265f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/CellSelector.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/CellSelector.java @@ -166,7 +166,7 @@ public class CellSelector extends ScrollArea { if (event != curEvent && another == null) { - if (!curEvent.down) { + if (curEvent.type == PointerEvent.Type.UP) { curEvent = event; onPointerDown( event ); return;