Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

OnCameraIdle hook into quickzoom gesture #9339

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener;
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveCanceledListener;
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener;
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener;
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener;

class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraMoveListener,
MapboxMap.OnCameraMoveCanceledListener, OnCameraIdleListener {
Expand Down Expand Up @@ -59,9 +59,11 @@ public void onCameraMoveCanceled() {

@Override
public void onCameraIdle() {
if (onCameraIdleListener != null && !idle) {
if (!idle) {
idle = true;
onCameraIdleListener.onCameraIdle();
if (onCameraIdleListener != null) {
onCameraIdleListener.onCameraIdle();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ final class MapGestureDetector {
private boolean quickZoom = false;
private boolean scrollInProgress = false;
private boolean scaleGestureOccurred = false;
private boolean recentScaleGestureOccurred = false;

MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings,
TrackingSettings trackingSettings, AnnotationManager annotationManager,
Expand Down Expand Up @@ -148,7 +149,7 @@ boolean onTouchEvent(@NonNull MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
// First pointer down, reset scaleGestureOccurred, used to avoid triggering a fling after a scale gesture #7666
scaleGestureOccurred = false;
recentScaleGestureOccurred = false;
transform.setGestureInProgress(true);
break;

Expand Down Expand Up @@ -274,7 +275,7 @@ public boolean onDoubleTapEvent(MotionEvent e) {
break;
case MotionEvent.ACTION_UP:
if (quickZoom) {
// insert here?
cameraChangeDispatcher.onCameraIdle();
quickZoom = false;
break;
}
Expand Down Expand Up @@ -341,7 +342,7 @@ public void onLongPress(MotionEvent motionEvent) {

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if ((!trackingSettings.isScrollGestureCurrentlyEnabled()) || scaleGestureOccurred) {
if ((!trackingSettings.isScrollGestureCurrentlyEnabled()) || recentScaleGestureOccurred) {
// don't allow a fling is scroll is disabled
// and ignore when a scale gesture has occurred
return false;
Expand Down Expand Up @@ -392,12 +393,17 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float d
return false;
}

if (scaleGestureOccurred) {
return false;
}

if (!scrollInProgress) {
scrollInProgress = true;

// Cancel any animation
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);

MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent(
getLocationFromGesture(e1.getX(), e1.getY()),
MapboxEvent.GESTURE_PAN_START, transform));
Expand Down Expand Up @@ -432,6 +438,7 @@ public boolean onScaleBegin(ScaleGestureDetector detector) {
}

scaleGestureOccurred = true;
recentScaleGestureOccurred = true;
beginTime = detector.getEventTime();
MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapClickEvent(
getLocationFromGesture(detector.getFocusX(), detector.getFocusY()),
Expand All @@ -442,9 +449,11 @@ public boolean onScaleBegin(ScaleGestureDetector detector) {
// Called when fingers leave screen
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
scaleGestureOccurred = false;
beginTime = 0;
scaleFactor = 1.0f;
zoomStarted = false;
cameraChangeDispatcher.onCameraIdle();
}

// Called each time a finger moves
Expand Down Expand Up @@ -480,6 +489,9 @@ public boolean onScale(ScaleGestureDetector detector) {
}

// Gesture is a quickzoom if there aren't two fingers
if (!quickZoom && !twoTap) {
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
}
quickZoom = !twoTap;

// make an assumption here; if the zoom center is specified by the gesture, it's NOT going
Expand All @@ -492,6 +504,7 @@ public boolean onScale(ScaleGestureDetector detector) {
// arround user provided focal point
transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(2), focalPoint.x, focalPoint.y);
} else if (quickZoom) {
cameraChangeDispatcher.onCameraMove();
// clamp scale factors we feed to core #7514
float scaleFactor = MathUtils.clamp(detector.getScaleFactor(),
MapboxConstants.MINIMUM_SCALE_FACTOR_CLAMP,
Expand Down Expand Up @@ -553,7 +566,7 @@ public boolean onRotate(RotateGestureDetector detector) {
// If rotate is large enough ignore a tap
// Also is zoom already started, don't rotate
totalAngle += detector.getRotationDegreesDelta();
if (!zoomStarted && ((totalAngle > 20.0f) || (totalAngle < -20.0f))) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Guardiola31337 the removal of zoomstarted indicates that both scale as rotation can occur at the same time. I tried reimplementing to make it work but introduced too many changes. I'm punting on this for now, will write a follow up ticket.

if (totalAngle > 20.0f || totalAngle < -20.0f) {
started = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ void zoom(boolean zoomIn, @NonNull PointF focalPoint) {
if (cameraPosition != null) {
int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1));
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION);
} else {
// we are not transforming, notify about being idle
cameraChangeDispatcher.onCameraIdle();
}
}

Expand All @@ -227,8 +230,8 @@ void setZoom(double zoom, @NonNull PointF focalPoint, long duration) {
@Override
public void onMapChanged(int change) {
if (change == MapView.REGION_DID_CHANGE_ANIMATED) {
mapView.removeOnMapChangedListener(this);
cameraChangeDispatcher.onCameraIdle();
mapView.removeOnMapChangedListener(this);
}
}
});
Expand Down Expand Up @@ -327,7 +330,7 @@ void moveBy(double offsetX, double offsetY, long duration) {
mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@Override
public void onMapChanged(int change) {
if (change == MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED) {
if (change == MapView.REGION_DID_CHANGE_ANIMATED) {
mapView.removeOnMapChangedListener(this);
cameraChangeDispatcher.onCameraIdle();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,17 @@ protected void onDraw(Canvas canvas) {
}

// draw foreground
if (myBearingTrackingMode == MyBearingTracking.NONE || !compassListener.isSensorAvailable()) {
if (myBearingTrackingMode == MyBearingTracking.NONE) {
if (foregroundDrawable != null) {
foregroundDrawable.draw(canvas);
}
} else if (foregroundBearingDrawable != null && foregroundBounds != null) {
foregroundBearingDrawable.draw(canvas);
if (myBearingTrackingMode == MyBearingTracking.GPS || compassListener.isSensorAvailable()) {
foregroundBearingDrawable.draw(canvas);
} else {
// We are tracking MyBearingTracking.COMPASS, but sensor is not available.
foregroundDrawable.draw(canvas);
}
}
}

Expand Down Expand Up @@ -774,9 +779,9 @@ private class CompassListener implements SensorEventListener {
private final SensorManager sensorManager;

private Sensor rotationVectorSensor;
float[] matrix = new float[9];
float[] orientation = new float[3];

private float[] matrix = new float[9];
private float[] orientation = new float[3];
private boolean reportMissingSensor = true;
// Compass data
private long compassUpdateNextTimestamp = 0;

Expand All @@ -794,7 +799,8 @@ public void onPause() {
}

public boolean isSensorAvailable() {
if (rotationVectorSensor == null) {
if (rotationVectorSensor == null && reportMissingSensor) {
reportMissingSensor = false;
Timber.e("Sensor.TYPE_ROTATION_VECTOR is missing from this device. Unable to use MyBearingTracking.COMPASS.");
}
return rotationVectorSensor != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class CameraPositionActivity extends AppCompatActivity implements OnMapRe

private MapView mapView;
private MapboxMap mapboxMap;
Copy link
Contributor

@Guardiola31337 Guardiola31337 Jun 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private field 'mapboxMap' is assigned but never accessed

cc/ @tobrun

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a requirement for our autogenerated tests, see https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java#L43 where we use reflection on the mapboxMap field. In this specific case we could easily make it accessed by mapboxMap invocations below.

private FloatingActionButton fab;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -40,13 +41,14 @@ protected void onCreate(Bundle savedInstanceState) {
}

@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
public void onMapReady(@NonNull final MapboxMap map) {
mapboxMap = map;

mapboxMap.setOnCameraIdleListener(new MapboxMap.OnCameraIdleListener() {
@Override
public void onCameraIdle() {
Timber.e("OnCameraIdle");
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_green_dark));
}
});

Expand All @@ -61,6 +63,7 @@ public void onCameraMoveCanceled() {
@Override
public void onCameraMove() {
Timber.e("OnCameraMove");
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_orange_dark));
}
});

Expand All @@ -71,12 +74,13 @@ public void onCameraMove() {
@Override
public void onCameraMoveStarted(int reason) {
// reason ranges from 1 <-> 3
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_red_dark));
Timber.e("OnCameraMoveStarted: %s", REASONS[reason - 1]);
}
});

// add a listener to FAB
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, R.color.primary));
fab.setOnClickListener(new View.OnClickListener() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ protected void onPause() {
@Override
protected void onStop() {
super.onStop();
LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this);
if (lostApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this);
lostApiClient.unregisterConnectionCallbacks(this);
lostApiClient.disconnect();
}
Expand Down