diff --git a/vtm-tests/test/org/oscim/layers/MapEventLayerTest.java b/vtm-tests/test/org/oscim/layers/MapEventLayerTest.java new file mode 100644 index 000000000..bb84499ea --- /dev/null +++ b/vtm-tests/test/org/oscim/layers/MapEventLayerTest.java @@ -0,0 +1,143 @@ +package org.oscim.layers; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; +import org.oscim.event.Gesture; +import org.oscim.event.MotionEvent; +import org.oscim.map.Animator; +import org.oscim.map.Map; +import org.oscim.map.ViewController; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class MapEventLayerTest { + private MapEventLayer layer; + private Map mockMap; + private ViewController mockViewport; + private Animator mockAnimator; + private ArgumentCaptor argumentCaptor; + + @Before + public void setUp() throws Exception { + mockMap = Mockito.mock(Map.class); + mockViewport = Mockito.mock(ViewController.class); + mockAnimator = Mockito.mock(Animator.class); + layer = new MapEventLayer(mockMap); + when(mockMap.viewport()).thenReturn(mockViewport); + when(mockMap.animator()).thenReturn(mockAnimator); + when(mockMap.getHeight()).thenReturn(6); + argumentCaptor = ArgumentCaptor.forClass(float.class); + } + + @Test + public void shouldNotBeNull() throws Exception { + assertThat(layer).isNotNull(); + } + + @Test + public void doubleTap_shouldAnimateZoom() throws Exception { + simulateDoubleTap(); + verify(mockAnimator).animateZoom(300, 2, 0, 0); + } + + @Test + public void doubleTap_shouldAnimateZoomAfterDoubleTouchDrag() throws Exception { + simulateDoubleTouchDragUp(); + simulateDoubleTap(); + verify(mockAnimator).animateZoom(300, 2, 0, 0); + } + + @Test + public void doubleTouchDrag_shouldNotAnimateZoom() throws Exception { + simulateDoubleTouchDragUp(); + verify(mockAnimator, never()).animateZoom(any(long.class), any(double.class), + any(float.class), any(float.class)); + } + + @Test + public void doubleTouchDragUp_shouldDecreaseContentScale() throws Exception { + simulateDoubleTouchDragUp(); + verify(mockViewport).scaleMap(argumentCaptor.capture(), any(float.class), any(float.class)); + assertThat(argumentCaptor.getValue()).isLessThan(1); + } + + @Test + public void doubleTouchDragDown_shouldIncreaseContentScale() throws Exception { + simulateDoubleTouchDragDown(); + verify(mockViewport).scaleMap(argumentCaptor.capture(), any(float.class), any(float.class)); + assertThat(argumentCaptor.getValue()).isGreaterThan(1); + } + + private void simulateDoubleTap() { + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_DOWN, 1, 1)); + layer.onGesture(Gesture.DOUBLE_TAP, new TestMotionEvent(MotionEvent.ACTION_UP, 1, 1)); + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_UP, 1, 1)); + } + + private void simulateDoubleTouchDragUp() { + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_DOWN, 1, 1)); + layer.onGesture(Gesture.DOUBLE_TAP, new TestMotionEvent(MotionEvent.ACTION_MOVE, 1, 0)); + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_MOVE, 1, 0)); + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_UP, 1, 0)); + } + + private void simulateDoubleTouchDragDown() { + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_DOWN, 1, 1)); + layer.onGesture(Gesture.DOUBLE_TAP, new TestMotionEvent(MotionEvent.ACTION_MOVE, 1, 2)); + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_MOVE, 1, 2)); + layer.onTouchEvent(new TestMotionEvent(MotionEvent.ACTION_UP, 1, 2)); + } + + class TestMotionEvent extends MotionEvent { + final int action; + final float x; + final float y; + + public TestMotionEvent(int action, float x, float y) { + this.action = action; + this.x = x; + this.y = y; + } + + @Override + public long getTime() { + return 0; + } + + @Override + public int getAction() { + return action; + } + + @Override + public float getX() { + return x; + } + + @Override + public float getY() { + return y; + } + + @Override + public float getX(int idx) { + return x; + } + + @Override + public float getY(int idx) { + return y; + } + + @Override + public int getPointerCount() { + return 0; + } + } +} diff --git a/vtm/src/org/oscim/layers/MapEventLayer.java b/vtm/src/org/oscim/layers/MapEventLayer.java index 90f56cbe7..a30c4933f 100644 --- a/vtm/src/org/oscim/layers/MapEventLayer.java +++ b/vtm/src/org/oscim/layers/MapEventLayer.java @@ -54,6 +54,7 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen private boolean mDown; private boolean mDoubleTap; + private boolean mDrag; private float mPrevX1; private float mPrevY1; @@ -136,6 +137,12 @@ public boolean onTouchEvent(MotionEvent e) { } if (action == MotionEvent.ACTION_UP) { mDown = false; + if (mDoubleTap && !mDrag) { + mMap.animator().animateZoom(300, 2, 0, 0); + } + + mDrag = false; + if (mStartMove < 0) return true; @@ -200,7 +207,8 @@ private boolean onActionMove(MotionEvent e) { return true; } // FIXME limit scale properly - mViewport.scaleMap(1 - my / (height / 6), 0, 0); + mDrag = true; + mViewport.scaleMap(1 + my / (height / 6), 0, 0); mMap.updateMap(true); mStartMove = -1; return true;