Merge branch 'double-tap-to-zoom'
This commit is contained in:
commit
04ea503184
143
vtm-tests/test/org/oscim/layers/MapEventLayerTest.java
Normal file
143
vtm-tests/test/org/oscim/layers/MapEventLayerTest.java
Normal file
@ -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<Float> 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, 1.0f, -2.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doubleTap_shouldAnimateZoomAfterDoubleTouchDrag() throws Exception {
|
||||
simulateDoubleTouchDragUp();
|
||||
simulateDoubleTap();
|
||||
verify(mockAnimator).animateZoom(300, 2, 1.0f, -2.0f);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -74,14 +75,12 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
protected static final float MIN_SLOP = 25.4f / 2;
|
||||
|
||||
/** 100 ms since start of move to reduce fling scroll */
|
||||
protected static final float FLING_THREHSHOLD = 100;
|
||||
protected static final float FLING_MIN_THREHSHOLD = 100;
|
||||
|
||||
//private final Viewport mViewport;
|
||||
private final VelocityTracker mTracker;
|
||||
|
||||
public MapEventLayer(Map map) {
|
||||
super(map);
|
||||
//mViewport = map.viewport();
|
||||
mTracker = new VelocityTracker();
|
||||
}
|
||||
|
||||
@ -120,6 +119,7 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
mDoubleTap = false;
|
||||
mStartMove = -1;
|
||||
mDown = true;
|
||||
mDrag = false;
|
||||
|
||||
mPrevX1 = e.getX(0);
|
||||
mPrevY1 = e.getY(0);
|
||||
@ -136,29 +136,33 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
}
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
mDown = false;
|
||||
if (mStartMove < 0)
|
||||
return true;
|
||||
if (mDoubleTap && !mDrag) {
|
||||
/* handle double tap zoom */
|
||||
mMap.animator().animateZoom(300, 2,
|
||||
mPrevX1 - mMap.getWidth() / 2,
|
||||
mPrevY1 - mMap.getHeight() / 2);
|
||||
|
||||
mTracker.update(e.getX(), e.getY(), e.getTime());
|
||||
} else if (mStartMove > 0) {
|
||||
/* handle fling gesture */
|
||||
mTracker.update(e.getX(), e.getY(), e.getTime());
|
||||
float vx = mTracker.getVelocityX();
|
||||
float vy = mTracker.getVelocityY();
|
||||
|
||||
float vx = mTracker.getVelocityX();
|
||||
float vy = mTracker.getVelocityY();
|
||||
/* reduce velocity for short moves */
|
||||
float t = e.getTime() - mStartMove;
|
||||
if (t < FLING_MIN_THREHSHOLD) {
|
||||
t = t / FLING_MIN_THREHSHOLD;
|
||||
vy *= t * t;
|
||||
vx *= t * t;
|
||||
}
|
||||
doFling(vx, vy);
|
||||
|
||||
/* reduce velocity for short moves */
|
||||
float t = e.getTime() - mStartMove;
|
||||
if (t < FLING_THREHSHOLD) {
|
||||
t = t / FLING_THREHSHOLD;
|
||||
vy *= t * t;
|
||||
vx *= t * t;
|
||||
}
|
||||
doFling(vx, vy);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (action == MotionEvent.ACTION_CANCEL) {
|
||||
//mStartMove = -1;
|
||||
mDown = false;
|
||||
mDoubleTap = false;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
mStartMove = -1;
|
||||
@ -200,7 +204,8 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
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;
|
||||
@ -302,7 +307,6 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
}
|
||||
|
||||
if (mCanScale || mDoRotate) {
|
||||
|
||||
if (!(mDoScale || mDoRotate)) {
|
||||
/* enter exclusive scale mode */
|
||||
if (Math.abs(deltaPinch) > (CanvasAdapter.dpi
|
||||
@ -330,9 +334,7 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
float fy = (y2 + y1) / 2 - height / 2;
|
||||
|
||||
synchronized (mViewport) {
|
||||
|
||||
if (!mDoTilt) {
|
||||
|
||||
if (rotateBy != 0)
|
||||
mViewport.rotateMap(rotateBy, fx, fy);
|
||||
if (scaleBy != 1)
|
||||
@ -340,10 +342,8 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
|
||||
|
||||
mViewport.moveMap(mx, my);
|
||||
} else {
|
||||
if (tiltBy != 0) {
|
||||
if (tiltBy != 0 && mViewport.tiltMap(-tiltBy))
|
||||
mViewport.moveMap(0, my / 2);
|
||||
mViewport.tiltMap(tiltBy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user