From 53907d8b7a43d658f651619cf7f67b4f1e8c6c39 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 22 Oct 2019 20:08:49 -0400 Subject: [PATCH] v0.7.5e: added scroll wheel support --- .../java/com/watabou/input/InputHandler.java | 23 ++++++ .../java/com/watabou/input/ScrollEvent.java | 71 +++++++++++++++++++ .../java/com/watabou/noosa/PointerArea.java | 16 ++--- .../java/com/watabou/noosa/ScrollArea.java | 58 +++++++++++++++ .../scenes/CellSelector.java | 21 +++++- .../shatteredpixeldungeon/ui/ScrollPane.java | 63 +++++++++------- 6 files changed, 214 insertions(+), 38 deletions(-) create mode 100644 SPD-classes/src/main/java/com/watabou/input/ScrollEvent.java create mode 100644 SPD-classes/src/main/java/com/watabou/noosa/ScrollArea.java 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 e454bfa86..465c5386f 100644 --- a/SPD-classes/src/main/java/com/watabou/input/InputHandler.java +++ b/SPD-classes/src/main/java/com/watabou/input/InputHandler.java @@ -23,12 +23,14 @@ package com.watabou.input; import com.badlogic.gdx.InputAdapter; import com.watabou.noosa.Game; +import com.watabou.utils.PointF; public class InputHandler extends InputAdapter { public void processAllEvents(){ PointerEvent.processPointerEvents(); KeyEvent.processKeyEvents(); + ScrollEvent.processScrollEvents(); } // ********************* @@ -59,6 +61,18 @@ public class InputHandler extends InputAdapter { return true; } + //TODO tracking this should probably be in PointerEvent + private static PointF pointerHoverPos = new PointF(); + + @Override + public boolean mouseMoved(int screenX, int screenY) { + screenX /= (Game.dispWidth / (float)Game.width); + screenY /= (Game.dispHeight / (float)Game.height); + pointerHoverPos.x = screenX; + pointerHoverPos.y = screenY; + return true; + } + // ***************** // *** Key Input *** // ***************** @@ -85,4 +99,13 @@ public class InputHandler extends InputAdapter { return true; } + // ******************** + // *** Scroll Input *** + // ******************** + + @Override + public boolean scrolled(int amount) { + ScrollEvent.addScrollEvent( new ScrollEvent(pointerHoverPos, amount)); + return true; + } } diff --git a/SPD-classes/src/main/java/com/watabou/input/ScrollEvent.java b/SPD-classes/src/main/java/com/watabou/input/ScrollEvent.java new file mode 100644 index 000000000..975d8e7d0 --- /dev/null +++ b/SPD-classes/src/main/java/com/watabou/input/ScrollEvent.java @@ -0,0 +1,71 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2019 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.watabou.input; + +import com.watabou.utils.PointF; +import com.watabou.utils.Signal; + +import java.util.ArrayList; + +public class ScrollEvent { + + public PointF pos; + public int amount; + + public ScrollEvent(PointF mousePos, int amount){ + this.amount = amount; + this.pos = mousePos; + } + + // ********************** + // *** Static members *** + // ********************** + + private static Signal scrollSignal = new Signal<>( true ); + + public static void addScrollListener( Signal.Listener listener ){ + scrollSignal.add(listener); + } + + public static void removeScrollListener( Signal.Listener listener ){ + scrollSignal.remove(listener); + } + + public static void clearListeners(){ + scrollSignal.removeAll(); + } + + //Accumulated key events + private static ArrayList scrollEvents = new ArrayList<>(); + + public static synchronized void addScrollEvent( ScrollEvent event ){ + scrollEvents.add( event ); + } + + public static synchronized void processScrollEvents(){ + for (ScrollEvent k : scrollEvents){ + scrollSignal.dispatch(k); + } + scrollEvents.clear(); + } + +} 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 f95af503d..51787a807 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/PointerArea.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/PointerArea.java @@ -34,14 +34,14 @@ public class PointerArea extends Visual implements Signal.Listener //if true, this PointerArea will always block input, even when it is inactive public boolean blockWhenInactive = false; - public PointerArea(Visual target ) { + public PointerArea( Visual target ) { super( 0, 0, 0, 0 ); this.target = target; PointerEvent.addPointerListener( this ); } - public PointerArea(float x, float y, float width, float height ) { + public PointerArea( float x, float y, float width, float height ) { super( x, y, width, height ); this.target = this; @@ -99,17 +99,13 @@ public class PointerArea extends Visual implements Signal.Listener } } - protected void onPointerDown( PointerEvent event ) { - } + protected void onPointerDown( PointerEvent event ) { } - protected void onPointerUp( PointerEvent event) { - } + protected void onPointerUp( PointerEvent event) { } - protected void onClick( PointerEvent event ) { - } + protected void onClick( PointerEvent event ) { } - protected void onDrag( PointerEvent event ) { - } + protected void onDrag( PointerEvent event ) { } public void reset() { curEvent = null; diff --git a/SPD-classes/src/main/java/com/watabou/noosa/ScrollArea.java b/SPD-classes/src/main/java/com/watabou/noosa/ScrollArea.java new file mode 100644 index 000000000..22edb23a2 --- /dev/null +++ b/SPD-classes/src/main/java/com/watabou/noosa/ScrollArea.java @@ -0,0 +1,58 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2019 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.watabou.noosa; + +import com.watabou.input.ScrollEvent; +import com.watabou.utils.Signal; + +//pointer area with additional support for detecting scrolling events +public class ScrollArea extends PointerArea { + + public ScrollArea( Visual target ){ + super( target ); + ScrollEvent.addScrollListener( scrollListener ); + } + + public ScrollArea(float x, float y, float width, float height ) { + super( x, y, width, height ); + ScrollEvent.addScrollListener( scrollListener ); + } + + private Signal.Listener scrollListener = new Signal.Listener() { + @Override + public boolean onSignal(ScrollEvent event) { + if (event != null && target.overlapsScreenPoint( (int)event.pos.x, (int)event.pos.y )){ + onScroll( event ); + return true; + } + return false; + } + }; + + protected void onScroll( ScrollEvent event ){ } + + @Override + public void destroy() { + super.destroy(); + ScrollEvent.removeScrollListener( scrollListener ); + } +} 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 2c952fe33..522c0395e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/CellSelector.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/CellSelector.java @@ -29,12 +29,13 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.watabou.input.PointerEvent; +import com.watabou.input.ScrollEvent; import com.watabou.noosa.Camera; -import com.watabou.noosa.PointerArea; +import com.watabou.noosa.ScrollArea; import com.watabou.utils.GameMath; import com.watabou.utils.PointF; -public class CellSelector extends PointerArea { +public class CellSelector extends ScrollArea { public Listener listener = null; @@ -47,6 +48,22 @@ public class CellSelector extends PointerArea { camera = map.camera(); dragThreshold = PixelScene.defaultZoom * DungeonTilemap.SIZE / 2; + + mouseZoom = camera.zoom; + } + + private float mouseZoom; + + @Override + protected void onScroll( ScrollEvent event ) { + float diff = event.amount/10f; + + //scale zoom difference so zooming is consistent + diff /= ((camera.zoom+1)/camera.zoom)-1; + diff = Math.min(1, diff); + mouseZoom = GameMath.gate( PixelScene.minZoom, mouseZoom - diff, PixelScene.maxZoom ); + + zoom( (int)Math.floor(mouseZoom) ); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java index bde3a2cb7..ae40eb891 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java @@ -23,9 +23,10 @@ package com.shatteredpixel.shatteredpixeldungeon.ui; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.watabou.input.PointerEvent; +import com.watabou.input.ScrollEvent; import com.watabou.noosa.Camera; import com.watabou.noosa.ColorBlock; -import com.watabou.noosa.PointerArea; +import com.watabou.noosa.ScrollArea; import com.watabou.noosa.ui.Component; import com.watabou.utils.Point; import com.watabou.utils.PointF; @@ -39,11 +40,6 @@ public class ScrollPane extends Component { protected Component content; protected ColorBlock thumb; - protected float minX; - protected float minY; - protected float maxX; - protected float maxY; - public ScrollPane( Component content ) { super(); @@ -107,7 +103,7 @@ public class ScrollPane extends Component { public void onClick( float x, float y ) { } - public class PointerController extends PointerArea { + public class PointerController extends ScrollArea { private float dragThreshold; @@ -115,6 +111,14 @@ public class ScrollPane extends Component { super( 0, 0, 0, 0 ); dragThreshold = PixelScene.defaultZoom * 8; } + + @Override + protected void onScroll(ScrollEvent event) { + PointF newPt = new PointF(lastPos); + newPt.y -= event.amount * content.camera.zoom * 10; + scroll(newPt); + dragging = false; + } @Override protected void onPointerUp( PointerEvent event ) { @@ -138,25 +142,7 @@ public class ScrollPane extends Component { protected void onDrag( PointerEvent event ) { if (dragging) { - Camera c = content.camera; - - c.shift( PointF.diff( lastPos, event.current ).invScale( c.zoom ) ); - if (c.scroll.x + width > content.width()) { - c.scroll.x = content.width() - width; - } - if (c.scroll.x < 0) { - c.scroll.x = 0; - } - if (c.scroll.y + height > content.height()) { - c.scroll.y = content.height() - height; - } - if (c.scroll.y < 0) { - c.scroll.y = 0; - } - - thumb.y = y + height * c.scroll.y / content.height(); - - lastPos.set( event.current ); + scroll(event.current); } else if (PointF.distance( event.current, event.start ) > dragThreshold) { @@ -166,5 +152,30 @@ public class ScrollPane extends Component { } } + + private void scroll( PointF current ){ + + Camera c = content.camera; + + c.shift( PointF.diff( lastPos, current ).invScale( c.zoom ) ); + if (c.scroll.x + width > content.width()) { + c.scroll.x = content.width() - width; + } + if (c.scroll.x < 0) { + c.scroll.x = 0; + } + if (c.scroll.y + height > content.height()) { + c.scroll.y = content.height() - height; + } + if (c.scroll.y < 0) { + c.scroll.y = 0; + } + + thumb.y = y + height * c.scroll.y / content.height(); + + lastPos.set( current ); + + } + } }