diff options
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros')
5 files changed, 718 insertions, 718 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java index 622e8f759c..b7bcb925a1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java @@ -6,19 +6,19 @@ import android.view.MotionEvent; /** * @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie * (code.almeros.com) - * + * <p> * All rights reserved. - * + * <p> * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * <p> * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * <p> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -33,129 +33,128 @@ import android.view.MotionEvent; * POSSIBILITY OF SUCH DAMAGE. */ public abstract class BaseGestureDetector { - protected final Context mContext; - protected boolean mGestureInProgress; - - protected MotionEvent mPrevEvent; - protected MotionEvent mCurrEvent; - - protected float mCurrPressure; - protected float mPrevPressure; - protected long mTimeDelta; - - /** - * This value is the threshold ratio between the previous combined pressure - * and the current combined pressure. When pressure decreases rapidly - * between events the position values can often be imprecise, as it usually - * indicates that the user is in the process of lifting a pointer off of the - * device. This value was tuned experimentally. - */ - protected static final float PRESSURE_THRESHOLD = 0.67f; - - public BaseGestureDetector(Context context) { - mContext = context; + protected final Context context; + protected boolean gestureInProgress; + + protected MotionEvent prevEvent; + protected MotionEvent currEvent; + + protected float currPressure; + protected float prevPressure; + protected long timeDelta; + + /** + * This value is the threshold ratio between the previous combined pressure + * and the current combined pressure. When pressure decreases rapidly + * between events the position values can often be imprecise, as it usually + * indicates that the user is in the process of lifting a pointer off of the + * device. This value was tuned experimentally. + */ + protected static final float PRESSURE_THRESHOLD = 0.67f; + + public BaseGestureDetector(Context context) { + this.context = context; + } + + /** + * All gesture detectors need to be called through this method to be able to + * detect gestures. This method delegates work to handler methods + * (handleStartProgressEvent, handleInProgressEvent) implemented in + * extending classes. + * + * @param event MotionEvent + * @return {@code true} as handled + */ + public boolean onTouchEvent(MotionEvent event) { + final int actionCode = event.getAction() & MotionEvent.ACTION_MASK; + if (!gestureInProgress) { + handleStartProgressEvent(actionCode, event); + } else { + handleInProgressEvent(actionCode, event); } - - /** - * All gesture detectors need to be called through this method to be able to - * detect gestures. This method delegates work to handler methods - * (handleStartProgressEvent, handleInProgressEvent) implemented in - * extending classes. - * - * @param event MotionEvent - * @return {@code true} as handled - */ - public boolean onTouchEvent(MotionEvent event) { - final int actionCode = event.getAction() & MotionEvent.ACTION_MASK; - if (!mGestureInProgress) { - handleStartProgressEvent(actionCode, event); - } else { - handleInProgressEvent(actionCode, event); - } - return true; - } - - /** - * Called when the current event occurred when NO gesture is in progress - * yet. The handling in this implementation may set the gesture in progress - * (via mGestureInProgress) or out of progress - * - * @param actionCode Action Code from MotionEvent - * @param event MotionEvent - */ - protected abstract void handleStartProgressEvent(int actionCode, - MotionEvent event); - - /** - * Called when the current event occurred when a gesture IS in progress. The - * handling in this implementation may set the gesture out of progress (via - * mGestureInProgress). - * - * - * @param actionCode Action Code from MotionEvent - * @param event MotionEvent - */ - protected abstract void handleInProgressEvent(int actionCode, - MotionEvent event); - - protected void updateStateByEvent(MotionEvent curr) { - final MotionEvent prev = mPrevEvent; - - // Reset mCurrEvent - if (mCurrEvent != null) { - mCurrEvent.recycle(); - mCurrEvent = null; - } - mCurrEvent = MotionEvent.obtain(curr); - - // Delta time - mTimeDelta = curr.getEventTime() - prev.getEventTime(); - - // Pressure - mCurrPressure = curr.getPressure(curr.getActionIndex()); - mPrevPressure = prev.getPressure(prev.getActionIndex()); + return true; + } + + /** + * Called when the current event occurred when NO gesture is in progress + * yet. The handling in this implementation may set the gesture in progress + * (via gestureInProgress) or out of progress + * + * @param actionCode Action Code from MotionEvent + * @param event MotionEvent + */ + protected abstract void handleStartProgressEvent(int actionCode, + MotionEvent event); + + /** + * Called when the current event occurred when a gesture IS in progress. The + * handling in this implementation may set the gesture out of progress (via + * gestureInProgress). + * + * @param actionCode Action Code from MotionEvent + * @param event MotionEvent + */ + protected abstract void handleInProgressEvent(int actionCode, + MotionEvent event); + + protected void updateStateByEvent(MotionEvent curr) { + final MotionEvent prev = prevEvent; + + // Reset currEvent + if (currEvent != null) { + currEvent.recycle(); + currEvent = null; } + currEvent = MotionEvent.obtain(curr); - protected void resetState() { - if (mPrevEvent != null) { - mPrevEvent.recycle(); - mPrevEvent = null; - } - if (mCurrEvent != null) { - mCurrEvent.recycle(); - mCurrEvent = null; - } - mGestureInProgress = false; - } + // Delta time + timeDelta = curr.getEventTime() - prev.getEventTime(); - /** - * Returns {@code true} if a gesture is currently in progress. - * - * @return {@code true} if a gesture is currently in progress, {@code false} - * otherwise. - */ - public boolean isInProgress() { - return mGestureInProgress; - } + // Pressure + currPressure = curr.getPressure(curr.getActionIndex()); + prevPressure = prev.getPressure(prev.getActionIndex()); + } - /** - * Return the time difference in milliseconds between the previous accepted - * GestureDetector event and the current GestureDetector event. - * - * @return Time difference since the last move event in milliseconds. - */ - public long getTimeDelta() { - return mTimeDelta; + protected void resetState() { + if (prevEvent != null) { + prevEvent.recycle(); + prevEvent = null; } - - /** - * Return the event time of the current GestureDetector event being - * processed. - * - * @return Current GestureDetector event time in milliseconds. - */ - public long getEventTime() { - return mCurrEvent.getEventTime(); + if (currEvent != null) { + currEvent.recycle(); + currEvent = null; } + gestureInProgress = false; + } + + /** + * Returns {@code true} if a gesture is currently in progress. + * + * @return {@code true} if a gesture is currently in progress, {@code false} + * otherwise. + */ + public boolean isInProgress() { + return gestureInProgress; + } + + /** + * Return the time difference in milliseconds between the previous accepted + * GestureDetector event and the current GestureDetector event. + * + * @return Time difference since the last move event in milliseconds. + */ + public long getTimeDelta() { + return timeDelta; + } + + /** + * Return the event time of the current GestureDetector event being + * processed. + * + * @return Current GestureDetector event time in milliseconds. + */ + public long getEventTime() { + return currEvent.getEventTime(); + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java index 2430f3f920..bc7dda6159 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java @@ -7,19 +7,19 @@ import android.view.MotionEvent; /** * @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie * (code.almeros.com) - * + * <p> * All rights reserved. - * + * <p> * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * <p> * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * <p> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -35,151 +35,151 @@ import android.view.MotionEvent; */ public class MoveGestureDetector extends BaseGestureDetector { - /** - * Listener which must be implemented which is used by MoveGestureDetector - * to perform callbacks to any implementing class which is registered to a - * MoveGestureDetector via the constructor. - * - * @see MoveGestureDetector.SimpleOnMoveGestureListener - */ - public interface OnMoveGestureListener { - public boolean onMove(MoveGestureDetector detector); - - public boolean onMoveBegin(MoveGestureDetector detector); - - public void onMoveEnd(MoveGestureDetector detector); + /** + * Listener which must be implemented which is used by MoveGestureDetector + * to perform callbacks to any implementing class which is registered to a + * MoveGestureDetector via the constructor. + * + * @see MoveGestureDetector.SimpleOnMoveGestureListener + */ + public interface OnMoveGestureListener { + public boolean onMove(MoveGestureDetector detector); + + public boolean onMoveBegin(MoveGestureDetector detector); + + public void onMoveEnd(MoveGestureDetector detector); + } + + /** + * Helper class which may be extended and where the methods may be + * implemented. This way it is not necessary to implement all methods of + * OnMoveGestureListener. + */ + public static class SimpleOnMoveGestureListener implements + OnMoveGestureListener { + public boolean onMove(MoveGestureDetector detector) { + return false; } - /** - * Helper class which may be extended and where the methods may be - * implemented. This way it is not necessary to implement all methods of - * OnMoveGestureListener. - */ - public static class SimpleOnMoveGestureListener implements - OnMoveGestureListener { - public boolean onMove(MoveGestureDetector detector) { - return false; - } - - public boolean onMoveBegin(MoveGestureDetector detector) { - return true; - } + public boolean onMoveBegin(MoveGestureDetector detector) { + return true; + } - public void onMoveEnd(MoveGestureDetector detector) { - // Do nothing, overridden implementation may be used - } + public void onMoveEnd(MoveGestureDetector detector) { + // Do nothing, overridden implementation may be used } + } - private static final PointF FOCUS_DELTA_ZERO = new PointF(); + private static final PointF FOCUS_DELTA_ZERO = new PointF(); - private final OnMoveGestureListener mListener; + private final OnMoveGestureListener listener; - private PointF mFocusExternal = new PointF(); - private PointF mFocusDeltaExternal = new PointF(); + private PointF focusExternal = new PointF(); + private PointF focusDeltaExternal = new PointF(); - public MoveGestureDetector(Context context, OnMoveGestureListener listener) { - super(context); - mListener = listener; - } + public MoveGestureDetector(Context context, OnMoveGestureListener listener) { + super(context); + this.listener = listener; + } - @Override - protected void handleStartProgressEvent(int actionCode, MotionEvent event) { - switch (actionCode) { - case MotionEvent.ACTION_DOWN: - resetState(); // In case we missed an UP/CANCEL event + @Override + protected void handleStartProgressEvent(int actionCode, MotionEvent event) { + switch (actionCode) { + case MotionEvent.ACTION_DOWN: + resetState(); // In case we missed an UP/CANCEL event - mPrevEvent = MotionEvent.obtain(event); - mTimeDelta = 0; + prevEvent = MotionEvent.obtain(event); + timeDelta = 0; - updateStateByEvent(event); - break; + updateStateByEvent(event); + break; - case MotionEvent.ACTION_MOVE: - mGestureInProgress = mListener.onMoveBegin(this); - break; - } + case MotionEvent.ACTION_MOVE: + gestureInProgress = listener.onMoveBegin(this); + break; } - - @Override - protected void handleInProgressEvent(int actionCode, MotionEvent event) { - switch (actionCode) { - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mListener.onMoveEnd(this); - resetState(); - break; - - case MotionEvent.ACTION_MOVE: - updateStateByEvent(event); - - // Only accept the event if our relative pressure is within - // a certain limit. This can help filter shaky data as a - // finger is lifted. - if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) { - final boolean updatePrevious = mListener.onMove(this); - if (updatePrevious) { - mPrevEvent.recycle(); - mPrevEvent = MotionEvent.obtain(event); - } - } - break; + } + + @Override + protected void handleInProgressEvent(int actionCode, MotionEvent event) { + switch (actionCode) { + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + listener.onMoveEnd(this); + resetState(); + break; + + case MotionEvent.ACTION_MOVE: + updateStateByEvent(event); + + // Only accept the event if our relative pressure is within + // a certain limit. This can help filter shaky data as a + // finger is lifted. + if (currPressure / prevPressure > PRESSURE_THRESHOLD) { + final boolean updatePrevious = listener.onMove(this); + if (updatePrevious) { + prevEvent.recycle(); + prevEvent = MotionEvent.obtain(event); + } } + break; } - - protected void updateStateByEvent(MotionEvent curr) { - super.updateStateByEvent(curr); - - final MotionEvent prev = mPrevEvent; - - // Focus intenal - PointF mCurrFocusInternal = determineFocalPoint(curr); - PointF mPrevFocusInternal = determineFocalPoint(prev); - - // Focus external - // - Prevent skipping of focus delta when a finger is added or removed - boolean mSkipNextMoveEvent = prev.getPointerCount() != curr - .getPointerCount(); - mFocusDeltaExternal = mSkipNextMoveEvent ? FOCUS_DELTA_ZERO - : new PointF(mCurrFocusInternal.x - mPrevFocusInternal.x, - mCurrFocusInternal.y - mPrevFocusInternal.y); - - // - Don't directly use mFocusInternal (or skipping will occur). Add - // unskipped delta values to mFocusExternal instead. - mFocusExternal.x += mFocusDeltaExternal.x; - mFocusExternal.y += mFocusDeltaExternal.y; + } + + protected void updateStateByEvent(MotionEvent curr) { + super.updateStateByEvent(curr); + + final MotionEvent prev = prevEvent; + + // Focus intenal + PointF currFocusInternal = determineFocalPoint(curr); + PointF prevFocusInternal = determineFocalPoint(prev); + + // Focus external + // - Prevent skipping of focus delta when a finger is added or removed + boolean skipNextMoveEvent = prev.getPointerCount() != curr + .getPointerCount(); + focusDeltaExternal = skipNextMoveEvent ? FOCUS_DELTA_ZERO + : new PointF(currFocusInternal.x - prevFocusInternal.x, + currFocusInternal.y - prevFocusInternal.y); + + // - Don't directly use mFocusInternal (or skipping will occur). Add + // unskipped delta values to focusExternal instead. + focusExternal.x += focusDeltaExternal.x; + focusExternal.y += focusDeltaExternal.y; + } + + /** + * Determine (multi)finger focal point (a.k.a. center point between all + * fingers) + * + * @param motionEvent a {@link MotionEvent} object. + * @return PointF focal point + */ + private PointF determineFocalPoint(MotionEvent motionEvent) { + // Number of fingers on screen + final int pCount = motionEvent.getPointerCount(); + float x = 0.0f; + float y = 0.0f; + + for (int i = 0; i < pCount; i++) { + x += motionEvent.getX(i); + y += motionEvent.getY(i); } - /** - * Determine (multi)finger focal point (a.k.a. center point between all - * fingers) - * - * @param e - * @return PointF focal point - */ - private PointF determineFocalPoint(MotionEvent e) { - // Number of fingers on screen - final int pCount = e.getPointerCount(); - float x = 0.0f; - float y = 0.0f; - - for (int i = 0; i < pCount; i++) { - x += e.getX(i); - y += e.getY(i); - } - - return new PointF(x / pCount, y / pCount); - } + return new PointF(x / pCount, y / pCount); + } - public float getFocusX() { - return mFocusExternal.x; - } + public float getFocusX() { + return focusExternal.x; + } - public float getFocusY() { - return mFocusExternal.y; - } + public float getFocusY() { + return focusExternal.y; + } - public PointF getFocusDelta() { - return mFocusDeltaExternal; - } + public PointF getFocusDelta() { + return focusDeltaExternal; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java index 124fe8509c..8c111a68df 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java @@ -6,19 +6,19 @@ import android.view.MotionEvent; /** * @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie * (code.almeros.com) - * + * <p> * All rights reserved. - * + * <p> * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * <p> * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * <p> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -34,147 +34,147 @@ import android.view.MotionEvent; */ public class RotateGestureDetector extends TwoFingerGestureDetector { - /** - * Listener which must be implemented which is used by RotateGestureDetector - * to perform callbacks to any implementing class which is registered to a - * RotateGestureDetector via the constructor. - * - * @see RotateGestureDetector.SimpleOnRotateGestureListener - */ - public interface OnRotateGestureListener { - public boolean onRotate(RotateGestureDetector detector); - - public boolean onRotateBegin(RotateGestureDetector detector); + /** + * Listener which must be implemented which is used by RotateGestureDetector + * to perform callbacks to any implementing class which is registered to a + * RotateGestureDetector via the constructor. + * + * @see RotateGestureDetector.SimpleOnRotateGestureListener + */ + public interface OnRotateGestureListener { + public boolean onRotate(RotateGestureDetector detector); + + public boolean onRotateBegin(RotateGestureDetector detector); + + public void onRotateEnd(RotateGestureDetector detector); + } + + /** + * Helper class which may be extended and where the methods may be + * implemented. This way it is not necessary to implement all methods of + * OnRotateGestureListener. + */ + public static class SimpleOnRotateGestureListener implements + OnRotateGestureListener { + public boolean onRotate(RotateGestureDetector detector) { + return false; + } - public void onRotateEnd(RotateGestureDetector detector); + public boolean onRotateBegin(RotateGestureDetector detector) { + return true; } - /** - * Helper class which may be extended and where the methods may be - * implemented. This way it is not necessary to implement all methods of - * OnRotateGestureListener. - */ - public static class SimpleOnRotateGestureListener implements - OnRotateGestureListener { - public boolean onRotate(RotateGestureDetector detector) { - return false; + public void onRotateEnd(RotateGestureDetector detector) { + // Do nothing, overridden implementation may be used + } + } + + private final OnRotateGestureListener listener; + private boolean sloppyGesture; + + public RotateGestureDetector(Context context, + OnRotateGestureListener listener) { + super(context); + this.listener = listener; + } + + @Override + protected void handleStartProgressEvent(int actionCode, MotionEvent event) { + switch (actionCode) { + case MotionEvent.ACTION_POINTER_DOWN: + // At least the second finger is on screen now + + resetState(); // In case we missed an UP/CANCEL event + prevEvent = MotionEvent.obtain(event); + timeDelta = 0; + + updateStateByEvent(event); + + // See if we have a sloppy gesture + sloppyGesture = isSloppyGesture(event); + if (!sloppyGesture) { + // No, start gesture now + gestureInProgress = listener.onRotateBegin(this); } + break; - public boolean onRotateBegin(RotateGestureDetector detector) { - return true; + case MotionEvent.ACTION_MOVE: + if (!sloppyGesture) { + break; } - public void onRotateEnd(RotateGestureDetector detector) { - // Do nothing, overridden implementation may be used + // See if we still have a sloppy gesture + sloppyGesture = isSloppyGesture(event); + if (!sloppyGesture) { + // No, start normal gesture now + gestureInProgress = listener.onRotateBegin(this); } - } - private final OnRotateGestureListener mListener; - private boolean mSloppyGesture; + break; - public RotateGestureDetector(Context context, - OnRotateGestureListener listener) { - super(context); - mListener = listener; - } - - @Override - protected void handleStartProgressEvent(int actionCode, MotionEvent event) { - switch (actionCode) { - case MotionEvent.ACTION_POINTER_DOWN: - // At least the second finger is on screen now - - resetState(); // In case we missed an UP/CANCEL event - mPrevEvent = MotionEvent.obtain(event); - mTimeDelta = 0; - - updateStateByEvent(event); - - // See if we have a sloppy gesture - mSloppyGesture = isSloppyGesture(event); - if (!mSloppyGesture) { - // No, start gesture now - mGestureInProgress = mListener.onRotateBegin(this); - } - break; - - case MotionEvent.ACTION_MOVE: - if (!mSloppyGesture) { - break; - } - - // See if we still have a sloppy gesture - mSloppyGesture = isSloppyGesture(event); - if (!mSloppyGesture) { - // No, start normal gesture now - mGestureInProgress = mListener.onRotateBegin(this); - } - - break; - - case MotionEvent.ACTION_POINTER_UP: - if (!mSloppyGesture) { - break; - } - - break; + case MotionEvent.ACTION_POINTER_UP: + if (!sloppyGesture) { + break; } + + break; } + } - @Override - protected void handleInProgressEvent(int actionCode, MotionEvent event) { - switch (actionCode) { - case MotionEvent.ACTION_POINTER_UP: - // Gesture ended but - updateStateByEvent(event); - - if (!mSloppyGesture) { - mListener.onRotateEnd(this); - } - - resetState(); - break; - - case MotionEvent.ACTION_CANCEL: - if (!mSloppyGesture) { - mListener.onRotateEnd(this); - } - - resetState(); - break; - - case MotionEvent.ACTION_MOVE: - updateStateByEvent(event); - - // Only accept the event if our relative pressure is within - // a certain limit. This can help filter shaky data as a - // finger is lifted. - if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) { - final boolean updatePrevious = mListener.onRotate(this); - if (updatePrevious) { - mPrevEvent.recycle(); - mPrevEvent = MotionEvent.obtain(event); - } - } - break; + @Override + protected void handleInProgressEvent(int actionCode, MotionEvent event) { + switch (actionCode) { + case MotionEvent.ACTION_POINTER_UP: + // Gesture ended but + updateStateByEvent(event); + + if (!sloppyGesture) { + listener.onRotateEnd(this); } - } - @Override - protected void resetState() { - super.resetState(); - mSloppyGesture = false; - } + resetState(); + break; - /** - * Return the rotation difference from the previous rotate event to the - * current event. - * - * @return The current rotation //difference in degrees. - */ - public float getRotationDegreesDelta() { - double diffRadians = Math.atan2(mPrevFingerDiffY, mPrevFingerDiffX) - - Math.atan2(mCurrFingerDiffY, mCurrFingerDiffX); - return (float) (diffRadians * 180.0 / Math.PI); + case MotionEvent.ACTION_CANCEL: + if (!sloppyGesture) { + listener.onRotateEnd(this); + } + + resetState(); + break; + + case MotionEvent.ACTION_MOVE: + updateStateByEvent(event); + + // Only accept the event if our relative pressure is within + // a certain limit. This can help filter shaky data as a + // finger is lifted. + if (currPressure / prevPressure > PRESSURE_THRESHOLD) { + final boolean updatePrevious = listener.onRotate(this); + if (updatePrevious) { + prevEvent.recycle(); + prevEvent = MotionEvent.obtain(event); + } + } + break; } + } + + @Override + protected void resetState() { + super.resetState(); + sloppyGesture = false; + } + + /** + * Return the rotation difference from the previous rotate event to the + * current event. + * + * @return The current rotation //difference in degrees. + */ + public float getRotationDegreesDelta() { + double diffRadians = Math.atan2(prevFingerDiffY, prevFingerDiffX) + - Math.atan2(currFingerDiffY, currFingerDiffX); + return (float) (diffRadians * 180.0 / Math.PI); + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java index 254597105b..9396578e48 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java @@ -5,21 +5,21 @@ import android.view.MotionEvent; /** * @author Robert Nordan (robert.nordan@norkart.no) - * + * <p> * Copyright (c) 2013, Norkart AS - * + * <p> * All rights reserved. - * + * <p> * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * <p> * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * <p> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -35,179 +35,180 @@ import android.view.MotionEvent; */ public class ShoveGestureDetector extends TwoFingerGestureDetector { - /** - * Listener which must be implemented which is used by ShoveGestureDetector - * to perform callbacks to any implementing class which is registered to a - * ShoveGestureDetector via the constructor. - * - * @see ShoveGestureDetector.SimpleOnShoveGestureListener - */ - public interface OnShoveGestureListener { - public boolean onShove(ShoveGestureDetector detector); + /** + * Listener which must be implemented which is used by ShoveGestureDetector + * to perform callbacks to any implementing class which is registered to a + * ShoveGestureDetector via the constructor. + * + * @see ShoveGestureDetector.SimpleOnShoveGestureListener + */ + public interface OnShoveGestureListener { + public boolean onShove(ShoveGestureDetector detector); + + public boolean onShoveBegin(ShoveGestureDetector detector); + + public void onShoveEnd(ShoveGestureDetector detector); + } + + /** + * Helper class which may be extended and where the methods may be + * implemented. This way it is not necessary to implement all methods of + * OnShoveGestureListener. + */ + public static class SimpleOnShoveGestureListener implements + OnShoveGestureListener { + public boolean onShove(ShoveGestureDetector detector) { + return false; + } - public boolean onShoveBegin(ShoveGestureDetector detector); + public boolean onShoveBegin(ShoveGestureDetector detector) { + return true; + } - public void onShoveEnd(ShoveGestureDetector detector); + public void onShoveEnd(ShoveGestureDetector detector) { + // Do nothing, overridden implementation may be used } + } + + private float prevAverageY; + private float currAverageY; + + private final OnShoveGestureListener listener; + private boolean sloppyGesture; + + public ShoveGestureDetector(Context context, OnShoveGestureListener listener) { + super(context); + this.listener = listener; + } - /** - * Helper class which may be extended and where the methods may be - * implemented. This way it is not necessary to implement all methods of - * OnShoveGestureListener. - */ - public static class SimpleOnShoveGestureListener implements - OnShoveGestureListener { - public boolean onShove(ShoveGestureDetector detector) { - return false; + @Override + protected void handleStartProgressEvent(int actionCode, MotionEvent event) { + switch (actionCode) { + case MotionEvent.ACTION_POINTER_DOWN: + // At least the second finger is on screen now + + resetState(); // In case we missed an UP/CANCEL event + prevEvent = MotionEvent.obtain(event); + timeDelta = 0; + + updateStateByEvent(event); + + // See if we have a sloppy gesture + sloppyGesture = isSloppyGesture(event); + if (!sloppyGesture) { + // No, start gesture now + gestureInProgress = listener.onShoveBegin(this); } + break; - public boolean onShoveBegin(ShoveGestureDetector detector) { - return true; + case MotionEvent.ACTION_MOVE: + if (!sloppyGesture) { + break; } - public void onShoveEnd(ShoveGestureDetector detector) { - // Do nothing, overridden implementation may be used + // See if we still have a sloppy gesture + sloppyGesture = isSloppyGesture(event); + if (!sloppyGesture) { + // No, start normal gesture now + gestureInProgress = listener.onShoveBegin(this); } - } - private float mPrevAverageY; - private float mCurrAverageY; + break; - private final OnShoveGestureListener mListener; - private boolean mSloppyGesture; + case MotionEvent.ACTION_POINTER_UP: + if (!sloppyGesture) { + break; + } - public ShoveGestureDetector(Context context, OnShoveGestureListener listener) { - super(context); - mListener = listener; + break; } + } - @Override - protected void handleStartProgressEvent(int actionCode, MotionEvent event) { - switch (actionCode) { - case MotionEvent.ACTION_POINTER_DOWN: - // At least the second finger is on screen now - - resetState(); // In case we missed an UP/CANCEL event - mPrevEvent = MotionEvent.obtain(event); - mTimeDelta = 0; - - updateStateByEvent(event); - - // See if we have a sloppy gesture - mSloppyGesture = isSloppyGesture(event); - if (!mSloppyGesture) { - // No, start gesture now - mGestureInProgress = mListener.onShoveBegin(this); - } - break; - - case MotionEvent.ACTION_MOVE: - if (!mSloppyGesture) { - break; - } - - // See if we still have a sloppy gesture - mSloppyGesture = isSloppyGesture(event); - if (!mSloppyGesture) { - // No, start normal gesture now - mGestureInProgress = mListener.onShoveBegin(this); - } - - break; - - case MotionEvent.ACTION_POINTER_UP: - if (!mSloppyGesture) { - break; - } - - break; - } - } + @Override + protected void handleInProgressEvent(int actionCode, MotionEvent event) { + switch (actionCode) { + case MotionEvent.ACTION_POINTER_UP: + // Gesture ended but + updateStateByEvent(event); - @Override - protected void handleInProgressEvent(int actionCode, MotionEvent event) { - switch (actionCode) { - case MotionEvent.ACTION_POINTER_UP: - // Gesture ended but - updateStateByEvent(event); - - if (!mSloppyGesture) { - mListener.onShoveEnd(this); - } - - resetState(); - break; - - case MotionEvent.ACTION_CANCEL: - if (!mSloppyGesture) { - mListener.onShoveEnd(this); - } - - resetState(); - break; - - case MotionEvent.ACTION_MOVE: - updateStateByEvent(event); - - // Only accept the event if our relative pressure is within - // a certain limit. This can help filter shaky data as a - // finger is lifted. Also check that shove is meaningful. - if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD - && Math.abs(getShovePixelsDelta()) > 0.5f) { - final boolean updatePrevious = mListener.onShove(this); - if (updatePrevious) { - mPrevEvent.recycle(); - mPrevEvent = MotionEvent.obtain(event); - } - } - break; + if (!sloppyGesture) { + listener.onShoveEnd(this); } - } - - @Override - protected void resetState() { - super.resetState(); - mSloppyGesture = false; - mPrevAverageY = 0.0f; - mCurrAverageY = 0.0f; - } - @Override - protected void updateStateByEvent(MotionEvent curr) { - super.updateStateByEvent(curr); + resetState(); + break; - final MotionEvent prev = mPrevEvent; - float py0 = prev.getY(0); - float py1 = prev.getY(1); - mPrevAverageY = (py0 + py1) / 2.0f; + case MotionEvent.ACTION_CANCEL: + if (!sloppyGesture) { + listener.onShoveEnd(this); + } - float cy0 = curr.getY(0); - float cy1 = curr.getY(1); - mCurrAverageY = (cy0 + cy1) / 2.0f; + resetState(); + break; + + case MotionEvent.ACTION_MOVE: + updateStateByEvent(event); + + // Only accept the event if our relative pressure is within + // a certain limit. This can help filter shaky data as a + // finger is lifted. Also check that shove is meaningful. + if (currPressure / prevPressure > PRESSURE_THRESHOLD + && Math.abs(getShovePixelsDelta()) > 0.5f) { + final boolean updatePrevious = listener.onShove(this); + if (updatePrevious) { + prevEvent.recycle(); + prevEvent = MotionEvent.obtain(event); + } + } + break; } - - @Override - protected boolean isSloppyGesture(MotionEvent event) { - boolean sloppy = super.isSloppyGesture(event); - if (sloppy) - return true; - - // If it's not traditionally sloppy, we check if the angle between - // fingers - // is acceptable. - double angle = Math.abs(Math.atan2(mCurrFingerDiffY, mCurrFingerDiffX)); - // about 20 degrees, left or right - return !((0.0f < angle && angle < 0.35f) || 2.79f < angle - && angle < Math.PI); + } + + @Override + protected void resetState() { + super.resetState(); + sloppyGesture = false; + prevAverageY = 0.0f; + currAverageY = 0.0f; + } + + @Override + protected void updateStateByEvent(MotionEvent curr) { + super.updateStateByEvent(curr); + + final MotionEvent prev = prevEvent; + float py0 = prev.getY(0); + float py1 = prev.getY(1); + prevAverageY = (py0 + py1) / 2.0f; + + float cy0 = curr.getY(0); + float cy1 = curr.getY(1); + currAverageY = (cy0 + cy1) / 2.0f; + } + + @Override + protected boolean isSloppyGesture(MotionEvent event) { + boolean sloppy = super.isSloppyGesture(event); + if (sloppy) { + return true; } - /** - * Return the distance in pixels from the previous shove event to the - * current event. - * - * @return The current distance in pixels. - */ - public float getShovePixelsDelta() { - return mCurrAverageY - mPrevAverageY; - } + // If it's not traditionally sloppy, we check if the angle between + // fingers + // is acceptable. + double angle = Math.abs(Math.atan2(currFingerDiffY, currFingerDiffX)); + // about 20 degrees, left or right + return !((0.0f < angle && angle < 0.35f) || 2.79f < angle + && angle < Math.PI); + } + + /** + * Return the distance in pixels from the previous shove event to the + * current event. + * + * @return The current distance in pixels. + */ + public float getShovePixelsDelta() { + return currAverageY - prevAverageY; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java index 694bea9f30..71fb9aa168 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java @@ -9,19 +9,19 @@ import android.view.ViewConfiguration; /** * @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie * (code.almeros.com) - * + * <p> * All rights reserved. - * + * <p> * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * <p> * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * <p> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -37,189 +37,189 @@ import android.view.ViewConfiguration; */ public abstract class TwoFingerGestureDetector extends BaseGestureDetector { - private final float mEdgeSlop; - - protected float mPrevFingerDiffX; - protected float mPrevFingerDiffY; - protected float mCurrFingerDiffX; - protected float mCurrFingerDiffY; - - private float mCurrLen; - private float mPrevLen; - - private PointF mFocus; - - public TwoFingerGestureDetector(Context context) { - super(context); - - ViewConfiguration config = ViewConfiguration.get(context); - - // We divide edge slop by 2 to make rotation gesture happen more easily #6870 - mEdgeSlop = config.getScaledEdgeSlop() / 2; - } - - @Override - protected abstract void handleStartProgressEvent(int actionCode, - MotionEvent event); - - @Override - protected abstract void handleInProgressEvent(int actionCode, - MotionEvent event); - - protected void updateStateByEvent(MotionEvent curr) { - super.updateStateByEvent(curr); - - final MotionEvent prev = mPrevEvent; - - mCurrLen = -1; - mPrevLen = -1; - - // Previous - final float px0 = prev.getX(0); - final float py0 = prev.getY(0); - final float px1 = prev.getX(1); - final float py1 = prev.getY(1); - final float pvx = px1 - px0; - final float pvy = py1 - py0; - mPrevFingerDiffX = pvx; - mPrevFingerDiffY = pvy; - - // Current - final float cx0 = curr.getX(0); - final float cy0 = curr.getY(0); - final float cx1 = curr.getX(1); - final float cy1 = curr.getY(1); - final float cvx = cx1 - cx0; - final float cvy = cy1 - cy0; - mCurrFingerDiffX = cvx; - mCurrFingerDiffY = cvy; - mFocus = determineFocalPoint(curr); + private final float edgeSlop; + + protected float prevFingerDiffX; + protected float prevFingerDiffY; + protected float currFingerDiffX; + protected float currFingerDiffY; + + private float currLen; + private float prevLen; + + private PointF focus; + + public TwoFingerGestureDetector(Context context) { + super(context); + + ViewConfiguration config = ViewConfiguration.get(context); + + // We divide edge slop by 2 to make rotation gesture happen more easily #6870 + edgeSlop = config.getScaledEdgeSlop() / 2; + } + + @Override + protected abstract void handleStartProgressEvent(int actionCode, + MotionEvent event); + + @Override + protected abstract void handleInProgressEvent(int actionCode, + MotionEvent event); + + protected void updateStateByEvent(MotionEvent curr) { + super.updateStateByEvent(curr); + + final MotionEvent prev = prevEvent; + + currLen = -1; + prevLen = -1; + + // Previous + final float px0 = prev.getX(0); + final float py0 = prev.getY(0); + final float px1 = prev.getX(1); + final float py1 = prev.getY(1); + final float pvx = px1 - px0; + final float pvy = py1 - py0; + prevFingerDiffX = pvx; + prevFingerDiffY = pvy; + + // Current + final float cx0 = curr.getX(0); + final float cy0 = curr.getY(0); + final float cx1 = curr.getX(1); + final float cy1 = curr.getY(1); + final float cvx = cx1 - cx0; + final float cvy = cy1 - cy0; + currFingerDiffX = cvx; + currFingerDiffY = cvy; + focus = determineFocalPoint(curr); + } + + /** + * Return the current distance between the two pointers forming the gesture + * in progress. + * + * @return Distance between pointers in pixels. + */ + public float getCurrentSpan() { + if (currLen == -1) { + final float cvx = currFingerDiffX; + final float cvy = currFingerDiffY; + currLen = (float) Math.sqrt(cvx * cvx + cvy * cvy); } - - /** - * Return the current distance between the two pointers forming the gesture - * in progress. - * - * @return Distance between pointers in pixels. - */ - public float getCurrentSpan() { - if (mCurrLen == -1) { - final float cvx = mCurrFingerDiffX; - final float cvy = mCurrFingerDiffY; - mCurrLen = (float) Math.sqrt(cvx * cvx + cvy * cvy); - } - return mCurrLen; + return currLen; + } + + /** + * Return the previous distance between the two pointers forming the gesture + * in progress. + * + * @return Previous distance between pointers in pixels. + */ + public float getPreviousSpan() { + if (prevLen == -1) { + final float pvx = prevFingerDiffX; + final float pvy = prevFingerDiffY; + prevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy); } - - /** - * Return the previous distance between the two pointers forming the gesture - * in progress. - * - * @return Previous distance between pointers in pixels. - */ - public float getPreviousSpan() { - if (mPrevLen == -1) { - final float pvx = mPrevFingerDiffX; - final float pvy = mPrevFingerDiffY; - mPrevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy); - } - return mPrevLen; + return prevLen; + } + + /** + * MotionEvent has no getRawX(int) method; simulate it pending future API + * approval. + * + * @param event Motion Event + * @param pointerIndex Pointer Index + * @return Raw x value or 0 + */ + protected static float getRawX(MotionEvent event, int pointerIndex) { + float offset = event.getRawX() - event.getX(); + if (pointerIndex < event.getPointerCount()) { + return event.getX(pointerIndex) + offset; } - - /** - * MotionEvent has no getRawX(int) method; simulate it pending future API - * approval. - * - * @param event Motion Event - * @param pointerIndex Pointer Index - * @return Raw x value or 0 - */ - protected static float getRawX(MotionEvent event, int pointerIndex) { - float offset = event.getRawX() - event.getX(); - if (pointerIndex < event.getPointerCount()) { - return event.getX(pointerIndex) + offset; - } - return 0.0f; + return 0.0f; + } + + /** + * MotionEvent has no getRawY(int) method; simulate it pending future API + * approval. + * + * @param event Motion Event + * @param pointerIndex Pointer Index + * @return Raw y value or 0 + */ + protected static float getRawY(MotionEvent event, int pointerIndex) { + float offset = event.getRawY() - event.getY(); + if (pointerIndex < event.getPointerCount()) { + return event.getY(pointerIndex) + offset; } - - /** - * MotionEvent has no getRawY(int) method; simulate it pending future API - * approval. - * - * @param event Motion Event - * @param pointerIndex Pointer Index - * @return Raw y value or 0 - */ - protected static float getRawY(MotionEvent event, int pointerIndex) { - float offset = event.getRawY() - event.getY(); - if (pointerIndex < event.getPointerCount()) { - return event.getY(pointerIndex) + offset; - } - return 0.0f; + return 0.0f; + } + + /** + * Check if we have a sloppy gesture. Sloppy gestures can happen if the edge + * of the user's hand is touching the screen, for example. + * + * @param event Motion Event + * @return {@code true} if is sloppy gesture, {@code false} if not + */ + protected boolean isSloppyGesture(MotionEvent event) { + // As orientation can change, query the metrics in touch down + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + float rightSlopEdge = metrics.widthPixels - edgeSlop; + float bottomSlopEdge = metrics.heightPixels - edgeSlop; + + final float edgeSlop = this.edgeSlop; + + final float x0 = event.getRawX(); + final float y0 = event.getRawY(); + final float x1 = getRawX(event, 1); + final float y1 = getRawY(event, 1); + + boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlopEdge + || y0 > bottomSlopEdge; + boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlopEdge + || y1 > bottomSlopEdge; + + if (p0sloppy && p1sloppy) { + return true; + } else if (p0sloppy) { + return true; + } else if (p1sloppy) { + return true; } - - /** - * Check if we have a sloppy gesture. Sloppy gestures can happen if the edge - * of the user's hand is touching the screen, for example. - * - * @param event Motion Event - * @return {@code true} if is sloppy gesture, {@code false} if not - */ - protected boolean isSloppyGesture(MotionEvent event) { - // As orientation can change, query the metrics in touch down - DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); - float mRightSlopEdge = metrics.widthPixels - mEdgeSlop; - float mBottomSlopEdge = metrics.heightPixels - mEdgeSlop; - - final float edgeSlop = mEdgeSlop; - - final float x0 = event.getRawX(); - final float y0 = event.getRawY(); - final float x1 = getRawX(event, 1); - final float y1 = getRawY(event, 1); - - boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > mRightSlopEdge - || y0 > mBottomSlopEdge; - boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > mRightSlopEdge - || y1 > mBottomSlopEdge; - - if (p0sloppy && p1sloppy) { - return true; - } else if (p0sloppy) { - return true; - } else if (p1sloppy) { - return true; - } - return false; + return false; + } + + /** + * Determine (multi)finger focal point (a.k.a. center point between all + * fingers) + * + * @param motionEvent Motion Event + * @return PointF focal point + */ + public static PointF determineFocalPoint(MotionEvent motionEvent) { + // Number of fingers on screen + final int pCount = motionEvent.getPointerCount(); + float x = 0.0f; + float y = 0.0f; + + for (int i = 0; i < pCount; i++) { + x += motionEvent.getX(i); + y += motionEvent.getY(i); } - /** - * Determine (multi)finger focal point (a.k.a. center point between all - * fingers) - * - * @param e Motion Event - * @return PointF focal point - */ - public static PointF determineFocalPoint(MotionEvent e) { - // Number of fingers on screen - final int pCount = e.getPointerCount(); - float x = 0.0f; - float y = 0.0f; - - for (int i = 0; i < pCount; i++) { - x += e.getX(i); - y += e.getY(i); - } - - return new PointF(x / pCount, y / pCount); - } + return new PointF(x / pCount, y / pCount); + } - public float getFocusX() { - return mFocus.x; - } + public float getFocusX() { + return focus.x; + } - public float getFocusY() { - return mFocus.y; - } + public float getFocusY() { + return focus.y; + } } |