move fling gesture detector to MapEventLayer

This commit is contained in:
Hannes Janetzek 2013-07-08 11:48:35 +02:00
parent 4d9d678669
commit 7229d8d596
6 changed files with 212 additions and 67 deletions

View File

@ -52,5 +52,10 @@ public class AndroidMotionEvent extends MotionEvent {
return mEvent.getPointerCount(); return mEvent.getPointerCount();
} }
@Override
public long getTime() {
return mEvent.getEventTime();
}
} }

View File

@ -2,7 +2,10 @@ package org.oscim.gdx;
import org.oscim.backend.input.MotionEvent; import org.oscim.backend.input.MotionEvent;
public class GdxMotionEvent extends MotionEvent { import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
public class GdxMotionEvent extends MotionEvent implements InputProcessor{
@Override @Override
public int getAction() { public int getAction() {
@ -34,4 +37,50 @@ public class GdxMotionEvent extends MotionEvent {
return 0; return 0;
} }
@Override
public long getTime() {
return 0;
}
// -------- InputProcessor ----------
@Override
public boolean keyDown(int keycode) {
return false;
}
@Override
public boolean keyUp(int keycode) {
return false;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
} }

View File

@ -28,6 +28,8 @@ public abstract class MotionEvent {
public static final int ACTION_POINTER_INDEX_MASK = 0xff00; public static final int ACTION_POINTER_INDEX_MASK = 0xff00;
public static final int ACTION_POINTER_INDEX_SHIFT = 8; public static final int ACTION_POINTER_INDEX_SHIFT = 8;
public abstract long getTime();
public abstract int getAction(); public abstract int getAction();
public abstract float getX(); public abstract float getX();

View File

@ -25,6 +25,7 @@ public abstract class InputLayer extends Layer {
super(mapView); super(mapView);
} }
/** /**
* By default does nothing (<code>return false</code>). If you handled the * By default does nothing (<code>return false</code>). If you handled the
* Event, return <code>true</code>, otherwise return <code>false</code>. If * Event, return <code>true</code>, otherwise return <code>false</code>. If
@ -146,26 +147,26 @@ public abstract class InputLayer extends Layer {
return false; return false;
} }
/** ///**
* By default does nothing (<code>return false</code>). If you handled the // * By default does nothing (<code>return false</code>). If you handled the
* Event, return <code>true</code>, otherwise return <code>false</code>. If // * Event, return <code>true</code>, otherwise return <code>false</code>. If
* you returned <code>true</code> none of the following Overlays or the // * you returned <code>true</code> none of the following Overlays or the
* underlying {@link MapView} has the chance to handle this event. // * underlying {@link MapView} has the chance to handle this event.
* // *
* @param pEvent1 // * @param pEvent1
* ... // * ...
* @param pEvent2 // * @param pEvent2
* ... // * ...
* @param pVelocityX // * @param pVelocityX
* ... // * ...
* @param pVelocityY // * @param pVelocityY
* ... // * ...
* @return ... // * @return ...
*/ // */
public boolean onFling(MotionEvent pEvent1, MotionEvent pEvent2, //public boolean onFling(MotionEvent pEvent1, MotionEvent pEvent2,
float pVelocityX, float pVelocityY) { // float pVelocityX, float pVelocityY) {
return false; // return false;
} //}
/** /**
* By default does nothing (<code>return false</code>). If you handled the * By default does nothing (<code>return false</code>). If you handled the

View File

@ -62,15 +62,20 @@ public class MapEventLayer extends InputLayer {
protected static final float PINCH_TILT_THRESHOLD = 1f; protected static final float PINCH_TILT_THRESHOLD = 1f;
private final MapViewPosition mMapPosition; private final MapViewPosition mMapPosition;
private final VelocityTracker mTracker;
public MapEventLayer(MapView mapView) { public MapEventLayer(MapView mapView) {
super(mapView); super(mapView);
mMapPosition = mapView.getMapViewPosition(); mMapPosition = mapView.getMapViewPosition();
mTracker = new VelocityTracker();
} }
private long mPrevTime;
@Override @Override
public boolean onTouchEvent(MotionEvent e) { public boolean onTouchEvent(MotionEvent e) {
mPrevTime = e.getTime();
int action = getAction(e); int action = getAction(e);
if (action == MotionEvent.ACTION_DOWN) { if (action == MotionEvent.ACTION_DOWN) {
@ -82,10 +87,13 @@ public class MapEventLayer extends InputLayer {
mPrevX = e.getX(0); mPrevX = e.getX(0);
mPrevY = e.getY(0); mPrevY = e.getY(0);
return true; //onActionDown(e);
mTracker.start(mPrevX, mPrevY, e.getTime());
return true;
} else if (action == MotionEvent.ACTION_MOVE) { } else if (action == MotionEvent.ACTION_MOVE) {
return onActionMove(e); return onActionMove(e);
} else if (action == MotionEvent.ACTION_UP) { } else if (action == MotionEvent.ACTION_UP) {
onFling(mTracker.getVelocityX(), mTracker.getVelocityY());
return true; return true;
} else if (action == MotionEvent.ACTION_CANCEL) { } else if (action == MotionEvent.ACTION_CANCEL) {
mDoubleTap = false; mDoubleTap = false;
@ -116,6 +124,8 @@ public class MapEventLayer extends InputLayer {
float width = mMapView.getWidth(); float width = mMapView.getWidth();
float height = mMapView.getHeight(); float height = mMapView.getHeight();
mTracker.update(x1, y1, e.getTime());
// return if detect a new gesture, as indicated by a large jump // return if detect a new gesture, as indicated by a large jump
if (Math.abs(mx) > JUMP_THRESHOLD || Math.abs(my) > JUMP_THRESHOLD) if (Math.abs(mx) > JUMP_THRESHOLD || Math.abs(my) > JUMP_THRESHOLD)
return true; return true;
@ -133,6 +143,7 @@ public class MapEventLayer extends InputLayer {
} }
if (e.getPointerCount() < 2) { if (e.getPointerCount() < 2) {
if (mx > 1 || mx < -1 || my > 1 || my < -1) { if (mx > 1 || mx < -1 || my > 1 || my < -1) {
mMapPosition.moveMap(mx, my); mMapPosition.moveMap(mx, my);
mMapView.updateMap(true); mMapView.updateMap(true);
@ -281,9 +292,7 @@ public class MapEventLayer extends InputLayer {
return false; return false;
} }
@Override private boolean onFling(float velocityX, float velocityY) {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (mWasMulti) if (mWasMulti)
return true; return true;
@ -303,7 +312,7 @@ public class MapEventLayer extends InputLayer {
// float move = Math.min(mMapView.getWidth(), mMapView.getHeight()) * 2 / 3; // float move = Math.min(mMapView.getWidth(), mMapView.getHeight()) * 2 / 3;
// mMapPosition.animateTo(vx * move, vy * move, 250); // mMapPosition.animateTo(vx * move, vy * move, 250);
//} else { //} else {
float s = (200 / CanvasAdapter.dpi); float s = 1; //(200 / CanvasAdapter.dpi);
mMapPosition.animateFling( mMapPosition.animateFling(
Math.round(velocityX * s), Math.round(velocityX * s),
@ -320,4 +329,102 @@ public class MapEventLayer extends InputLayer {
+ " " + mBeginTilt); + " " + mBeginTilt);
} }
/*******************************************************************************
* Copyright 2011 See libgdx AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
class VelocityTracker {
int sampleSize = 10;
float lastX, lastY;
float deltaX, deltaY;
long lastTime;
int numSamples;
float[] meanX = new float[sampleSize];
float[] meanY = new float[sampleSize];
long[] meanTime = new long[sampleSize];
public void start (float x, float y, long timeStamp) {
lastX = x;
lastY = y;
deltaX = 0;
deltaY = 0;
numSamples = 0;
for (int i = 0; i < sampleSize; i++) {
meanX[i] = 0;
meanY[i] = 0;
meanTime[i] = 0;
}
lastTime = timeStamp;
}
public void update (float x, float y, long timeStamp) {
long currTime = timeStamp;
deltaX = x - lastX;
deltaY = y - lastY;
lastX = x;
lastY = y;
long deltaTime = currTime - lastTime;
lastTime = currTime;
int index = numSamples % sampleSize;
meanX[index] = deltaX;
meanY[index] = deltaY;
meanTime[index] = deltaTime;
numSamples++;
}
public float getVelocityX () {
float meanX = getAverage(this.meanX, numSamples);
float meanTime = getAverage(this.meanTime, numSamples) / 1000.0f;
if (meanTime == 0) return 0;
return meanX / meanTime;
}
public float getVelocityY () {
float meanY = getAverage(this.meanY, numSamples);
float meanTime = getAverage(this.meanTime, numSamples) / 1000.0f;
if (meanTime == 0) return 0;
return meanY / meanTime;
}
private float getAverage (float[] values, int numSamples) {
numSamples = Math.min(sampleSize, numSamples);
float sum = 0;
for (int i = 0; i < numSamples; i++) {
sum += values[i];
}
return sum / numSamples;
}
private long getAverage (long[] values, int numSamples) {
numSamples = Math.min(sampleSize, numSamples);
long sum = 0;
for (int i = 0; i < numSamples; i++) {
sum += values[i];
}
if (numSamples == 0) return 0;
return sum / numSamples;
}
private float getSum (float[] values, int numSamples) {
numSamples = Math.min(sampleSize, numSamples);
float sum = 0;
for (int i = 0; i < numSamples; i++) {
sum += values[i];
}
if (numSamples == 0) return 0;
return sum;
}
}
} }

View File

@ -29,21 +29,14 @@ import org.oscim.layers.Layer;
import org.oscim.layers.overlay.Overlay.Snappable; import org.oscim.layers.overlay.Overlay.Snappable;
import org.oscim.renderer.RenderLayer; import org.oscim.renderer.RenderLayer;
public class LayerManager extends AbstractList<Layer> public class LayerManager extends AbstractList<Layer> {
//implements OnGestureListener,
//OnDoubleTapListener
{
private final static String TAG = LayerManager.class.getName(); private final static String TAG = LayerManager.class.getName();
private final static boolean debugInput = false; private final static boolean debugInput = false;
//private final GestureDetector mGestureDetector;
private final CopyOnWriteArrayList<Layer> mLayerList; private final CopyOnWriteArrayList<Layer> mLayerList;
LayerManager() { LayerManager() {
mLayerList = new CopyOnWriteArrayList<Layer>(); mLayerList = new CopyOnWriteArrayList<Layer>();
//mGestureDetector = new GestureDetector(context, this);
//mGestureDetector.setOnDoubleTapListener(this);
} }
@Override @Override
@ -109,7 +102,6 @@ public class LayerManager extends AbstractList<Layer>
} }
} }
Layer[] mLayers; Layer[] mLayers;
InputLayer[] mInputLayer; InputLayer[] mInputLayer;
@ -169,12 +161,12 @@ public class LayerManager extends AbstractList<Layer>
action == MotionEvent.ACTION_UP); action == MotionEvent.ACTION_UP);
} }
// if (handleGesture) { // if (handleGesture) {
// if (mGestureDetector.onTouchEvent(e)) // if (mGestureDetector.onTouchEvent(e))
// return true; // return true;
// //
// mCancelGesture = false; // mCancelGesture = false;
// } // }
if (onTouchEvent(e)) if (onTouchEvent(e))
return true; return true;
@ -253,7 +245,6 @@ public class LayerManager extends AbstractList<Layer>
/* GestureDetector.OnDoubleTapListener */ /* GestureDetector.OnDoubleTapListener */
//@Override
public boolean onDoubleTap(final MotionEvent e) { public boolean onDoubleTap(final MotionEvent e) {
if (mDirtyLayers) if (mDirtyLayers)
@ -269,7 +260,6 @@ public class LayerManager extends AbstractList<Layer>
return false; return false;
} }
//@Override
public boolean onDoubleTapEvent(final MotionEvent e) { public boolean onDoubleTapEvent(final MotionEvent e) {
if (mDirtyLayers) if (mDirtyLayers)
updateLayers(); updateLayers();
@ -284,7 +274,6 @@ public class LayerManager extends AbstractList<Layer>
return false; return false;
} }
//@Override
public boolean onSingleTapConfirmed(final MotionEvent e) { public boolean onSingleTapConfirmed(final MotionEvent e) {
if (mDirtyLayers) if (mDirtyLayers)
updateLayers(); updateLayers();
@ -300,8 +289,6 @@ public class LayerManager extends AbstractList<Layer>
} }
/* OnGestureListener */ /* OnGestureListener */
//@Override
public boolean onDown(final MotionEvent pEvent) { public boolean onDown(final MotionEvent pEvent) {
if (mDirtyLayers) if (mDirtyLayers)
updateLayers(); updateLayers();
@ -316,23 +303,22 @@ public class LayerManager extends AbstractList<Layer>
return false; return false;
} }
//@Override ////@Override
public boolean onFling(final MotionEvent pEvent1, final MotionEvent pEvent2, //public boolean onFling(final MotionEvent pEvent1, final MotionEvent pEvent2,
final float pVelocityX, final float pVelocityY) { // final float pVelocityX, final float pVelocityY) {
if (mDirtyLayers) // if (mDirtyLayers)
updateLayers(); // updateLayers();
//
// for (InputLayer o : mInputLayer) {
// if (o.onFling(pEvent1, pEvent2, pVelocityX, pVelocityY)) {
// if (debugInput)
// Log.d(TAG, "onFling\t" + o.getClass());
// return true;
// }
// }
// return false;
//}
for (InputLayer o : mInputLayer) {
if (o.onFling(pEvent1, pEvent2, pVelocityX, pVelocityY)) {
if (debugInput)
Log.d(TAG, "onFling\t" + o.getClass());
return true;
}
}
return false;
}
//@Override
public void onLongPress(final MotionEvent pEvent) { public void onLongPress(final MotionEvent pEvent) {
if (mCancelGesture) if (mCancelGesture)
return; return;
@ -345,7 +331,6 @@ public class LayerManager extends AbstractList<Layer>
return; return;
} }
//@Override
public boolean onScroll(final MotionEvent pEvent1, final MotionEvent pEvent2, public boolean onScroll(final MotionEvent pEvent1, final MotionEvent pEvent2,
final float pDistanceX, final float pDistanceY) { final float pDistanceX, final float pDistanceY) {
if (mDirtyLayers) if (mDirtyLayers)
@ -361,7 +346,6 @@ public class LayerManager extends AbstractList<Layer>
return false; return false;
} }
//@Override
public void onShowPress(final MotionEvent pEvent) { public void onShowPress(final MotionEvent pEvent) {
if (mDirtyLayers) if (mDirtyLayers)
updateLayers(); updateLayers();
@ -371,7 +355,6 @@ public class LayerManager extends AbstractList<Layer>
} }
//@Override
public boolean onSingleTapUp(final MotionEvent pEvent) { public boolean onSingleTapUp(final MotionEvent pEvent) {
if (mDirtyLayers) if (mDirtyLayers)
updateLayers(); updateLayers();
@ -386,8 +369,6 @@ public class LayerManager extends AbstractList<Layer>
return false; return false;
} }
// /** // /**
// * Gets the optional TilesLayer class. // * Gets the optional TilesLayer class.
// * // *