v1.2.0: added hover-based pointer events

This commit is contained in:
Evan Debenham 2022-02-08 15:20:54 -05:00
parent d2f139e6fa
commit 79a7a24707
4 changed files with 55 additions and 26 deletions

View File

@ -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;
}
}

View File

@ -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<PointerEvent> pointerEvents = new ArrayList<>();
private static HashMap<Integer, PointerEvent> 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);

View File

@ -30,6 +30,7 @@ public class PointerArea extends Visual implements Signal.Listener<PointerEvent>
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<PointerEvent>
@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<PointerEvent>
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<PointerEvent>
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<PointerEvent>
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<PointerEvent>
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;

View File

@ -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;