[android] - take in account focalpoint when performing transformations, simplify zoom methods (#8416)
This commit is contained in:
@@ -107,4 +107,4 @@ public final class Mapbox {
|
||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||
return (activeNetwork != null && activeNetwork.isConnected());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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)}.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
public void setZoom(double zoom, PointF focalPoint, long duration) {
|
||||
if (isDestroyedOn("setZoom")) {
|
||||
return;
|
||||
}
|
||||
setZoom(zoom, CENTER_XY_VALUE, CENTER_XY_VALUE, 0);
|
||||
}
|
||||
|
||||
public void setZoom(double zoom, double cx, double cy, 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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user