summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-01-12 21:48:48 -0800
committerMinh Nguyễn <mxn@1ec5.org>2016-01-14 00:39:57 -0800
commita3d4aeefecadc3717dc27a53ae170a4c0e878ce8 (patch)
tree4604a47c870743e8e35ed2f433f536cb0d26f3d1 /platform
parentac4b1b7479fe5d60f1112d5a47846a498af5c8a5 (diff)
downloadqtlocation-mapboxgl-a3d4aeefecadc3717dc27a53ae170a4c0e878ce8.tar.gz
[osx] Consistent origins in gesture recognizers
Cleaned up gesture recognizers, flipping the origins of anchor points only and always before calling mbgl methods. This exposed the fact that the cursor locking feature during drag-zoom/rotate/tilt was broken, so I fixed it to match MapKit behavior exactly and also account for modifier changes in mid-gesture.
Diffstat (limited to 'platform')
-rw-r--r--platform/osx/src/MGLMapView.mm70
1 files changed, 42 insertions, 28 deletions
diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm
index 82e5e20c1c..505adb20a3 100644
--- a/platform/osx/src/MGLMapView.mm
+++ b/platform/osx/src/MGLMapView.mm
@@ -159,6 +159,7 @@ public:
double _scaleAtBeginningOfGesture;
CLLocationDirection _directionAtBeginningOfGesture;
CGFloat _pitchAtBeginningOfGesture;
+ BOOL _didHideCursorDuringGesture;
MGLAnnotationContextMap _annotationContextsByAnnotationTag;
MGLAnnotationTag _selectedAnnotationTag;
@@ -870,7 +871,7 @@ public:
- (void)scaleBy:(double)scaleFactor atPoint:(NSPoint)point animated:(BOOL)animated {
[self willChangeValueForKey:@"centerCoordinate"];
[self willChangeValueForKey:@"zoomLevel"];
- mbgl::PrecisionPoint center(point.x, point.y);
+ mbgl::PrecisionPoint center(point.x, self.bounds.size.height - point.y);
_mbglMap->scaleBy(scaleFactor, center, MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
[self didChangeValueForKey:@"zoomLevel"];
[self didChangeValueForKey:@"centerCoordinate"];
@@ -1078,9 +1079,35 @@ public:
- (void)handlePanGesture:(NSPanGestureRecognizer *)gestureRecognizer {
NSPoint delta = [gestureRecognizer translationInView:self];
NSPoint endPoint = [gestureRecognizer locationInView:self];
- NSPoint startPoint = NSMakePoint(endPoint.x - delta.x, self.bounds.size.height - (endPoint.y - delta.y));
+ NSPoint startPoint = NSMakePoint(endPoint.x - delta.x, endPoint.y - delta.y);
NSEventModifierFlags flags = [NSApp currentEvent].modifierFlags;
+ if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
+ [self.window invalidateCursorRectsForView:self];
+ _mbglMap->setGestureInProgress(true);
+
+ if (![self isPanningWithGesture]) {
+ // Hide the cursor except when panning.
+ CGDisplayHideCursor(kCGDirectMainDisplay);
+ _didHideCursorDuringGesture = YES;
+ }
+ } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
+ || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
+ _mbglMap->setGestureInProgress(false);
+ [self.window invalidateCursorRectsForView:self];
+
+ if (_didHideCursorDuringGesture) {
+ _didHideCursorDuringGesture = NO;
+ // Move the cursor back to the start point and show it again, creating
+ // the illusion that it has stayed in place during the entire gesture.
+ CGPoint cursorPoint = [self convertPoint:startPoint toView:nil];
+ cursorPoint = [self.window convertRectToScreen:{ startPoint, NSZeroSize }].origin;
+ cursorPoint.y = [NSScreen mainScreen].frame.size.height - cursorPoint.y;
+ CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cursorPoint);
+ CGDisplayShowCursor(kCGDirectMainDisplay);
+ }
+ }
+
if (flags & NSShiftKeyMask) {
// Shift-drag to zoom.
if (!self.zoomEnabled) {
@@ -1090,25 +1117,16 @@ public:
_mbglMap->cancelTransitions();
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- _mbglMap->setGestureInProgress(true);
_scaleAtBeginningOfGesture = _mbglMap->getScale();
} else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
CGFloat newZoomLevel = log2f(_scaleAtBeginningOfGesture) - delta.y / 75;
[self scaleBy:powf(2, newZoomLevel) / _mbglMap->getScale() atPoint:startPoint animated:NO];
- } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
- || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
- _mbglMap->setGestureInProgress(false);
- // Maps.app locks the cursor to the start point, but that would
- // interfere with the pan gesture recognizer. Just move the cursor
- // back at the end of the gesture.
- CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, startPoint);
}
} else if (flags & NSAlternateKeyMask) {
// Option-drag to rotate and/or tilt.
_mbglMap->cancelTransitions();
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- _mbglMap->setGestureInProgress(true);
_directionAtBeginningOfGesture = self.direction;
_pitchAtBeginningOfGesture = _mbglMap->getPitch();
} else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
@@ -1122,29 +1140,27 @@ public:
if (self.pitchEnabled) {
_mbglMap->setPitch(_pitchAtBeginningOfGesture + delta.y / 5);
}
- } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
- || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
- _mbglMap->setGestureInProgress(false);
}
} else if (self.scrollEnabled) {
// Otherwise, drag to pan.
_mbglMap->cancelTransitions();
- if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- [self.window invalidateCursorRectsForView:self];
- _mbglMap->setGestureInProgress(true);
- } else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
+ if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
delta.y *= -1;
[self offsetCenterCoordinateBy:delta animated:NO];
[gestureRecognizer setTranslation:NSZeroPoint inView:self];
- } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
- || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
- _mbglMap->setGestureInProgress(false);
- [self.window invalidateCursorRectsForView:self];
}
}
}
+/// Returns whether the user is panning using a gesture.
+- (BOOL)isPanningWithGesture {
+ NSGestureRecognizerState state = _panGestureRecognizer.state;
+ NSEventModifierFlags flags = [NSApp currentEvent].modifierFlags;
+ return ((state == NSGestureRecognizerStateBegan || state == NSGestureRecognizerStateChanged)
+ && !(flags & NSShiftKeyMask || flags & NSAlternateKeyMask));
+}
+
/// Pinch to zoom.
- (void)handleMagnificationGesture:(NSMagnificationGestureRecognizer *)gestureRecognizer {
if (!self.zoomEnabled) {
@@ -1200,7 +1216,7 @@ public:
_mbglMap->cancelTransitions();
NSPoint gesturePoint = [gestureRecognizer locationInView:self];
- [self scaleBy:0.5 atPoint:NSMakePoint(gesturePoint.x, self.bounds.size.height - gesturePoint.y) animated:YES];
+ [self scaleBy:0.5 atPoint:gesturePoint animated:YES];
}
/// Double-click or double-tap to zoom in.
@@ -1212,7 +1228,7 @@ public:
_mbglMap->cancelTransitions();
NSPoint gesturePoint = [gestureRecognizer locationInView:self];
- [self scaleBy:2 atPoint:NSMakePoint(gesturePoint.x, self.bounds.size.height - gesturePoint.y) animated:YES];
+ [self scaleBy:2 atPoint:gesturePoint animated:YES];
}
- (void)smartMagnifyWithEvent:(NSEvent *)event {
@@ -1223,7 +1239,7 @@ public:
_mbglMap->cancelTransitions();
NSPoint gesturePoint = [self convertPoint:event.locationInWindow fromView:nil];
- [self scaleBy:0.5 atPoint:NSMakePoint(gesturePoint.x, self.bounds.size.height - gesturePoint.y) animated:YES];
+ [self scaleBy:0.5 atPoint:gesturePoint animated:YES];
}
/// Rotate fingers to rotate.
@@ -1260,7 +1276,6 @@ public:
_mbglMap->cancelTransitions();
NSPoint gesturePoint = [self convertPoint:event.locationInWindow fromView:nil];
- gesturePoint.y = self.bounds.size.height - gesturePoint.y;
double zoomDelta = event.scrollingDeltaY / 4;
[self scaleBy:exp2(zoomDelta) atPoint:gesturePoint animated:YES];
}
@@ -2001,8 +2016,7 @@ public:
- (void)resetCursorRects {
// Drag to pan has a grabbing hand cursor.
- if (_panGestureRecognizer.state == NSGestureRecognizerStateBegan
- || _panGestureRecognizer.state == NSGestureRecognizerStateChanged) {
+ if ([self isPanningWithGesture]) {
[self addCursorRect:self.bounds cursor:[NSCursor closedHandCursor]];
return;
}