From 9ed623acb195c7b89028f0d7e1b74e47e5fd1360 Mon Sep 17 00:00:00 2001 From: Tobrun Van Nuland Date: Tue, 19 Sep 2017 14:59:39 +0200 Subject: [android] - disable rotation gesture when pinch zooming --- .../gesturedetectors/TwoFingerGestureDetector.java | 5 +- .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 156 +++++++++++---------- 2 files changed, 81 insertions(+), 80 deletions(-) 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 71fb9aa168..db492b6556 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 @@ -54,8 +54,7 @@ public abstract class TwoFingerGestureDetector extends BaseGestureDetector { ViewConfiguration config = ViewConfiguration.get(context); - // We divide edge slop by 2 to make rotation gesture happen more easily #6870 - edgeSlop = config.getScaledEdgeSlop() / 2; + edgeSlop = config.getScaledEdgeSlop(); } @Override @@ -222,4 +221,4 @@ public abstract class TwoFingerGestureDetector extends BaseGestureDetector { return focus.y; } -} +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java index d2973bf558..bff5e9bed2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java @@ -50,13 +50,14 @@ final class MapGestureDetector { private PointF focalPoint; - private boolean twoTap = false; - private boolean zoomStarted = false; - private boolean dragStarted = false; - private boolean quickZoom = false; - private boolean scrollInProgress = false; - private boolean scaleGestureOccurred = false; - private boolean recentScaleGestureOccurred = false; + private boolean twoTap; + private boolean quickZoom; + private boolean tiltGestureOccurred; + private boolean scrollGestureOccurred; + + private boolean scaleGestureOccurred; + private boolean recentScaleGestureOccurred; + private long scaleBeginTime; MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings, TrackingSettings trackingSettings, AnnotationManager annotationManager, @@ -145,8 +146,8 @@ final class MapGestureDetector { } // Check two finger gestures first - rotateGestureDetector.onTouchEvent(event); scaleGestureDetector.onTouchEvent(event); + rotateGestureDetector.onTouchEvent(event); shoveGestureDetector.onTouchEvent(event); // Handle two finger tap @@ -193,10 +194,10 @@ final class MapGestureDetector { } // Scroll / Pan Has Stopped - if (scrollInProgress) { + if (scrollGestureOccurred) { MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapDragEndEvent( getLocationFromGesture(event.getX(), event.getY()), transform)); - scrollInProgress = false; + scrollGestureOccurred = false; cameraChangeDispatcher.onCameraIdle(); } @@ -393,20 +394,18 @@ final class MapGestureDetector { return false; } - if (dragStarted) { - return false; - } - - if (scaleGestureOccurred) { + if (tiltGestureOccurred) { return false; } - if (!scrollInProgress) { - scrollInProgress = true; + if (!scrollGestureOccurred) { + scrollGestureOccurred = true; // Cancel any animation - transform.cancelTransitions(); - cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + if (!scaleGestureOccurred) { + transform.cancelTransitions(); + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + } MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(e1.getX(), e1.getY()), @@ -431,8 +430,7 @@ final class MapGestureDetector { */ private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { - long beginTime = 0; - float scaleFactor = 1.0f; + private float scaleFactor = 1.0f; // Called when two fingers first touch the screen @Override @@ -441,9 +439,8 @@ final class MapGestureDetector { return false; } - scaleGestureOccurred = true; recentScaleGestureOccurred = true; - beginTime = detector.getEventTime(); + scaleBeginTime = detector.getEventTime(); MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), MapboxEvent.GESTURE_PINCH_START, transform)); @@ -454,9 +451,8 @@ final class MapGestureDetector { @Override public void onScaleEnd(ScaleGestureDetector detector) { scaleGestureOccurred = false; - beginTime = 0; + scaleBeginTime = 0; scaleFactor = 1.0f; - zoomStarted = false; cameraChangeDispatcher.onCameraIdle(); } @@ -468,27 +464,27 @@ final class MapGestureDetector { return super.onScale(detector); } - // If scale is large enough ignore a tap - scaleFactor *= detector.getScaleFactor(); - if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) { - // notify camera change listener - cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); - zoomStarted = true; + if (tiltGestureOccurred) { + return false; } // Ignore short touches in case it is a tap // Also ignore small scales long time = detector.getEventTime(); - long interval = time - beginTime; - if (!zoomStarted && (interval <= ViewConfiguration.getTapTimeout())) { + long interval = time - scaleBeginTime; + if (!scaleGestureOccurred && (interval <= ViewConfiguration.getTapTimeout())) { return false; } - if (!zoomStarted) { - return false; + // If scale is large enough ignore a tap + scaleFactor *= detector.getScaleFactor(); + if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) { + // notify camera change listener + cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); + scaleGestureOccurred = true; } - if (dragStarted) { + if (!scaleGestureOccurred) { return false; } @@ -506,7 +502,7 @@ final class MapGestureDetector { // Scale the map if (focalPoint != null) { // arround user provided focal point - transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(2), focalPoint.x, focalPoint.y); + transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2), focalPoint.x, focalPoint.y); } else if (quickZoom) { cameraChangeDispatcher.onCameraMove(); // clamp scale factors we feed to core #7514 @@ -514,12 +510,13 @@ final class MapGestureDetector { MapboxConstants.MINIMUM_SCALE_FACTOR_CLAMP, MapboxConstants.MAXIMUM_SCALE_FACTOR_CLAMP); // around center map - transform.zoomBy(Math.log(scaleFactor) / Math.log(2), uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + transform.zoomBy(Math.log(scaleFactor) / Math.log(Math.PI / 2), + uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); } else { // around gesture - transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(2), detector.getFocusX(), detector.getFocusY()); + transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2), + detector.getFocusX(), detector.getFocusY()); } - return true; } } @@ -529,9 +526,11 @@ final class MapGestureDetector { */ private class RotateGestureListener extends RotateGestureDetector.SimpleOnRotateGestureListener { - long beginTime = 0; - float totalAngle = 0.0f; - boolean started = false; + private static final long ROTATE_INVOKE_WAIT_TIME = 1500; + + private long beginTime = 0; + private float totalAngle = 0.0f; + private boolean started = false; // Called when two fingers first touch the screen @Override @@ -544,9 +543,6 @@ final class MapGestureDetector { cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_ROTATION_START, transform)); return true; } @@ -563,28 +559,32 @@ final class MapGestureDetector { // Called for rotation @Override public boolean onRotate(RotateGestureDetector detector) { - if (!trackingSettings.isRotateGestureCurrentlyEnabled() || dragStarted) { + if (!trackingSettings.isRotateGestureCurrentlyEnabled() || tiltGestureOccurred) { return false; } - // If rotate is large enough ignore a tap - // Also is zoom already started, don't rotate - totalAngle += detector.getRotationDegreesDelta(); - if (totalAngle > 20.0f || totalAngle < -20.0f) { - started = true; - } - // Ignore short touches in case it is a tap // Also ignore small rotate long time = detector.getEventTime(); long interval = time - beginTime; - if (!started && (interval <= ViewConfiguration.getTapTimeout())) { + if (!started && (interval <= ViewConfiguration.getTapTimeout() || isScaleGestureActive(time))) { return false; } + // If rotate is large enough ignore a tap + // Also is zoom already started, don't rotate + totalAngle += detector.getRotationDegreesDelta(); + if (totalAngle > 35.0f || totalAngle < -35.0f) { + MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_ROTATION_START, transform)); + started = true; + } + if (!started) { return false; } + // rotation constitutes translation of anything except the center of // rotation, so cancel both location and bearing tracking if required trackingSettings.resetTrackingModesIfRequired(true, true, false); @@ -603,6 +603,13 @@ final class MapGestureDetector { } return true; } + + private boolean isScaleGestureActive(long time) { + long scaleExecutionTime = time - scaleBeginTime; + boolean scaleGestureStarted = scaleBeginTime != 0; + boolean scaleOffsetTimeValid = scaleExecutionTime > ROTATE_INVOKE_WAIT_TIME; + return (scaleGestureStarted && scaleOffsetTimeValid) || scaleGestureOccurred; + } } /** @@ -610,9 +617,8 @@ final class MapGestureDetector { */ private class ShoveGestureListener implements ShoveGestureDetector.OnShoveGestureListener { - long beginTime = 0; - float totalDelta = 0.0f; - boolean started = false; + private long beginTime = 0; + private float totalDelta = 0.0f; @Override public boolean onShoveBegin(ShoveGestureDetector detector) { @@ -622,10 +628,6 @@ final class MapGestureDetector { // notify camera change listener cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE); - beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_PITCH_START, transform)); return true; } @@ -633,8 +635,7 @@ final class MapGestureDetector { public void onShoveEnd(ShoveGestureDetector detector) { beginTime = 0; totalDelta = 0.0f; - started = false; - dragStarted = false; + tiltGestureOccurred = false; } @Override @@ -643,22 +644,26 @@ final class MapGestureDetector { return false; } - // If tilt is large enough ignore a tap - // Also if zoom already started, don't tilt - totalDelta += detector.getShovePixelsDelta(); - if (!zoomStarted && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) { - started = true; - } - // Ignore short touches in case it is a tap // Also ignore small tilt long time = detector.getEventTime(); long interval = time - beginTime; - if (!started && (interval <= ViewConfiguration.getTapTimeout())) { + if (!tiltGestureOccurred && (interval <= ViewConfiguration.getTapTimeout())) { return false; } - if (!started) { + // If tilt is large enough ignore a tap + // Also if zoom already started, don't tilt + totalDelta += detector.getShovePixelsDelta(); + if (!tiltGestureOccurred && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) { + tiltGestureOccurred = true; + beginTime = detector.getEventTime(); + MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_PITCH_START, transform)); + } + + if (!tiltGestureOccurred) { return false; } @@ -669,9 +674,6 @@ final class MapGestureDetector { // Tilt the map transform.setTilt(pitch); - - dragStarted = true; - return true; } } @@ -691,4 +693,4 @@ final class MapGestureDetector { void setOnScrollListener(MapboxMap.OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } -} +} \ No newline at end of file -- cgit v1.2.1