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 );
+
+ }
+
}
}