From abeca4fe16f3a8c1fc9149d7cb796113622b89a6 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 17 Mar 2017 13:23:53 +0100 Subject: [android] - take in account focalpoint when performing transformations, simplify zoom methods (#8416) --- .../src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 2 +- .../mapbox/mapboxsdk/maps/MapGestureDetector.java | 52 ++++++++------------ .../com/mapbox/mapboxsdk/maps/MapKeyListener.java | 13 +++-- .../java/com/mapbox/mapboxsdk/maps/MapView.java | 56 ++++++++++++++++++++-- .../mapboxsdk/maps/MapZoomButtonController.java | 31 +----------- .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 22 +-------- .../java/com/mapbox/mapboxsdk/maps/Transform.java | 19 ++++---- 7 files changed, 94 insertions(+), 101 deletions(-) (limited to 'platform') diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index 63b8e40fa0..83d04e7023 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -107,4 +107,4 @@ public final class Mapbox { NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return (activeNetwork != null && activeNetwork.isConnected()); } -} +} \ 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 0f4d3197cc..67e55352f4 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 @@ -4,13 +4,13 @@ import android.content.Context; import android.graphics.PointF; import android.location.Location; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.view.ScaleGestureDetectorCompat; import android.view.InputDevice; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.ViewConfiguration; -import android.widget.ZoomButtonsController; import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector; import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector; @@ -92,6 +92,20 @@ final class MapGestureDetector { this.focalPoint = focalPoint; } + /** + * Get the current active gesture focal point. + *

+ * This could be either the user provided focal point in {@link UiSettings#setFocalPoint(PointF)} or the focal point + * defined as a result of {@link TrackingSettings#setMyLocationEnabled(boolean)}. + *

+ * + * @return the current active gesture focal point. + */ + @Nullable + PointF getFocalPoint() { + return focalPoint; + } + /** * Given coordinates from a gesture, use the current projection to translate it into * a Location object. @@ -159,10 +173,10 @@ final class MapGestureDetector { if (twoTap && isTap && !inProgress) { if (focalPoint != null) { - transform.zoom(false, focalPoint.x, focalPoint.y); + transform.zoom(false, focalPoint); } else { PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event); - transform.zoom(false, focalPoint.x, focalPoint.y); + transform.zoom(false, focalPoint); } twoTap = false; return true; @@ -262,10 +276,10 @@ final class MapGestureDetector { // Single finger double tap if (focalPoint != null) { // User provided focal point - transform.zoom(true, focalPoint.x, focalPoint.y); + transform.zoom(true, focalPoint); } else { // Zoom in on gesture - transform.zoom(true, e.getX(), e.getY()); + transform.zoom(true, new PointF(e.getX(), e.getY())); } break; } @@ -636,34 +650,6 @@ final class MapGestureDetector { } } - // This class handles input events from the zoom control buttons - // Zoom controls allow single touch only devices to zoom in and out - private static class OnZoomListener implements ZoomButtonsController.OnZoomListener { - - private UiSettings uiSettings; - private Transform transform; - - OnZoomListener(UiSettings uiSettings, Transform transform) { - this.uiSettings = uiSettings; - this.transform = transform; - } - - // Not used - @Override - public void onVisibilityChanged(boolean visible) { - // Ignore - } - - // Called when user pushes a zoom button - @Override - public void onZoom(boolean zoomIn) { - if (!uiSettings.isZoomGesturesEnabled()) { - return; - } - transform.zoom(zoomIn); - } - } - void setOnMapClickListener(MapboxMap.OnMapClickListener onMapClickListener) { this.onMapClickListener = onMapClickListener; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java index c993cd3ec6..7175242282 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java @@ -1,5 +1,6 @@ package com.mapbox.mapboxsdk.maps; +import android.graphics.PointF; import android.os.Handler; import android.support.annotation.NonNull; import android.view.KeyEvent; @@ -125,7 +126,8 @@ final class MapKeyListener { } // Zoom out - transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + transform.zoom(false, focalPoint); return true; default: @@ -160,7 +162,8 @@ final class MapKeyListener { } // Zoom in - transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + transform.zoom(true, focalPoint); return true; } @@ -214,7 +217,8 @@ final class MapKeyListener { // Only handle if we have not already long pressed if (currentTrackballLongPressTimeOut != null) { // Zoom in - transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + transform.zoom(true, focalPoint); } return true; @@ -255,7 +259,8 @@ final class MapKeyListener { // Check if the trackball is still pressed if (!cancelled) { // Zoom out - transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + PointF pointF = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2); + transform.zoom(false, pointF); // Ensure the up action is not run currentTrackballLongPressTimeOut = null; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index a2b6fb1f42..51566a6587 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -31,6 +31,7 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.ZoomButtonsController; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.R; @@ -147,7 +148,9 @@ public class MapView extends FrameLayout { // user input mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings, trackingSettings, annotations); mapKeyListener = new MapKeyListener(transform, trackingSettings, uiSettings); - mapZoomButtonController = new MapZoomButtonController(this, uiSettings, transform); + + MapZoomControllerListener zoomListener = new MapZoomControllerListener(mapGestureDetector, uiSettings, transform); + mapZoomButtonController = new MapZoomButtonController(this, uiSettings, zoomListener); // inject widgets with MapboxMap compassView.setMapboxMap(mapboxMap); @@ -939,12 +942,59 @@ public class MapView extends FrameLayout { } } + private class MapZoomControllerListener implements ZoomButtonsController.OnZoomListener { + + private final MapGestureDetector mapGestureDetector; + private final UiSettings uiSettings; + private final Transform transform; + + MapZoomControllerListener(MapGestureDetector detector, UiSettings uiSettings, Transform transform) { + this.mapGestureDetector = detector; + this.uiSettings = uiSettings; + this.transform = transform; + } + + // Not used + @Override + public void onVisibilityChanged(boolean visible) { + // Ignore + } + + // Called when user pushes a zoom button on the ZoomButtonController + @Override + public void onZoom(boolean zoomIn) { + if (uiSettings.isZoomGesturesEnabled()) { + onZoom(zoomIn, mapGestureDetector.getFocalPoint()); + } + } + + private void onZoom(boolean zoomIn, @Nullable PointF focalPoint) { + if (focalPoint != null) { + transform.zoom(zoomIn, focalPoint); + } else { + PointF centerPoint = new PointF(getMeasuredWidth() / 2, getMeasuredHeight() / 2); + transform.zoom(zoomIn, centerPoint); + } + } + } + private class CameraZoomInvalidator implements TrackingSettings.CameraZoomInvalidator { + @Override public void zoomTo(double zoomLevel) { - double currentZoomLevel = mapboxMap.getCameraPosition().zoom; + Transform transform = mapboxMap.getTransform(); + double currentZoomLevel = transform.getCameraPosition().zoom; if (currentZoomLevel < zoomLevel) { - mapboxMap.getTransform().setZoom(zoomLevel); + setZoom(zoomLevel, mapGestureDetector.getFocalPoint(), transform); + } + } + + private void setZoom(double zoomLevel, @Nullable PointF focalPoint, @NonNull Transform transform) { + if (focalPoint != null) { + transform.setZoom(zoomLevel, focalPoint); + } else { + PointF centerPoint = new PointF(getMeasuredWidth() / 2, getMeasuredHeight() / 2); + transform.setZoom(zoomLevel, centerPoint); } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java index 06084d906e..16513904c5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java @@ -16,11 +16,11 @@ final class MapZoomButtonController extends ZoomButtonsController { private UiSettings uiSettings; - MapZoomButtonController(@NonNull View ownerView, @NonNull UiSettings uiSettings, @NonNull Transform transform) { + MapZoomButtonController(@NonNull View ownerView, @NonNull UiSettings uiSettings, @NonNull OnZoomListener listener) { super(ownerView); this.uiSettings = uiSettings; setZoomSpeed(MapboxConstants.ANIMATION_DURATION); - setOnZoomListener(new OnZoomListener(uiSettings, transform)); + setOnZoomListener(listener); } @Override @@ -29,31 +29,4 @@ final class MapZoomButtonController extends ZoomButtonsController { super.setVisible(visible); } } - - // Zoom controls allow single touch only devices to zoom in and out - private static class OnZoomListener implements ZoomButtonsController.OnZoomListener { - - private final UiSettings uiSettings; - private final Transform transform; - - OnZoomListener(UiSettings uiSettings, Transform transform) { - this.uiSettings = uiSettings; - this.transform = transform; - } - - // Not used - @Override - public void onVisibilityChanged(boolean visible) { - // Ignore - } - - // Called when user pushes a zoom button - @Override - public void onZoom(boolean zoomIn) { - if (!uiSettings.isZoomGesturesEnabled()) { - return; - } - transform.zoom(zoomIn); - } - } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index e991819e4f..1460f08e10 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -61,8 +61,6 @@ final class NativeMapView { // Listener invoked to return a bitmap of the map private MapboxMap.SnapshotReadyCallback snapshotReadyCallback; - private static final int CENTER_XY_VALUE = -1; - // // Static methods // @@ -380,27 +378,11 @@ final class NativeMapView { return nativeGetScale(); } - public void setZoom(double zoom) { - if (isDestroyedOn("setZoom")) { - return; - } - setZoom(zoom, CENTER_XY_VALUE, CENTER_XY_VALUE, 0); - } - - public void setZoom(double zoom, double cx, double cy, long duration) { + public void setZoom(double zoom, PointF focalPoint, long duration) { if (isDestroyedOn("setZoom")) { return; } - - if (cx != CENTER_XY_VALUE) { - cx = cx / pixelRatio; - } - - if (cy != CENTER_XY_VALUE) { - cy = cy / pixelRatio; - } - - nativeSetZoom(zoom, cx, cy, duration); + nativeSetZoom(zoom, focalPoint.x / pixelRatio, focalPoint.y / pixelRatio, duration); } public double getZoom() { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 2a81ad6752..ec4b903a74 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -1,5 +1,6 @@ package com.mapbox.mapboxsdk.maps; +import android.graphics.PointF; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; @@ -174,27 +175,23 @@ final class Transform implements MapView.OnMapChangedListener { return cameraPosition.zoom; } - void zoom(boolean zoomIn) { - zoom(zoomIn, -1.0f, -1.0f); - } - - void zoom(boolean zoomIn, float x, float y) { + void zoom(boolean zoomIn, @NonNull PointF focalPoint) { // Cancel any animation cancelTransitions(); CameraPosition cameraPosition = invalidateCameraPosition(); if (cameraPosition != null) { - zoom(cameraPosition, zoomIn, x, y); + int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1)); + setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION); } } - private void zoom(@NonNull CameraPosition cameraPosition, boolean zoomIn, float x, float y) { - int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1)); - mapView.setZoom(newZoom, x, y, MapboxConstants.ANIMATION_DURATION); + void setZoom(double zoom, @NonNull PointF focalPoint) { + setZoom(zoom, focalPoint, 0); } - void setZoom(double zoom) { - mapView.setZoom(zoom); + void setZoom(double zoom, @NonNull PointF focalPoint, long duration) { + mapView.setZoom(zoom, focalPoint, duration); } // Direction -- cgit v1.2.1