summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2015-12-01 09:45:29 -0800
committerMinh Nguyễn <mxn@1ec5.org>2015-12-13 17:26:53 -0800
commit96145ef1707516484913447de95f33a77d8a59eb (patch)
tree5892417ee1abef43ab06f18da82e7cd0fd4b76e1 /platform
parentcc35f5a2a7f78cabdb75f75966fb72fa5f447c62 (diff)
downloadqtlocation-mapboxgl-96145ef1707516484913447de95f33a77d8a59eb.tar.gz
[osx] Drop Pin context menu item
Diffstat (limited to 'platform')
-rw-r--r--platform/osx/app/AppDelegate.m18
-rw-r--r--platform/osx/app/MainMenu.xib6
-rw-r--r--platform/osx/sdk/MGLMapView.mm127
3 files changed, 94 insertions, 57 deletions
diff --git a/platform/osx/app/AppDelegate.m b/platform/osx/app/AppDelegate.m
index 4c8ce92ab7..4e6f0746ce 100644
--- a/platform/osx/app/AppDelegate.m
+++ b/platform/osx/app/AppDelegate.m
@@ -271,6 +271,14 @@ static NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken
[self.mapView selectAnnotation:annotation animated:YES];
}
+- (IBAction)removePin:(NSMenuItem *)sender {
+ [self removePinAtPoint:_mouseLocationForMapViewContextMenu];
+}
+
+- (void)removePinAtPoint:(NSPoint)point {
+ [self.mapView removeAnnotation:[self.mapView annotationAtPoint:point]];
+}
+
#pragma mark User interface validation
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
@@ -319,6 +327,13 @@ static NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken
return YES;
}
if (menuItem.action == @selector(dropPin:)) {
+ BOOL isOverAnnotation = [self.mapView annotationAtPoint:_mouseLocationForMapViewContextMenu];
+ menuItem.hidden = isOverAnnotation;
+ return YES;
+ }
+ if (menuItem.action == @selector(removePin:)) {
+ BOOL isOverAnnotation = [self.mapView annotationAtPoint:_mouseLocationForMapViewContextMenu];
+ menuItem.hidden = !isOverAnnotation;
return YES;
}
if (menuItem.action == @selector(toggleTileBoundaries:)) {
@@ -423,7 +438,8 @@ static NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken
- (void)menuWillOpen:(NSMenu *)menu {
if (menu == self.mapViewContextMenu) {
- _mouseLocationForMapViewContextMenu = self.window.mouseLocationOutsideOfEventStream;
+ _mouseLocationForMapViewContextMenu = [self.window.contentView convertPoint:self.window.mouseLocationOutsideOfEventStream
+ toView:self.mapView];
}
}
diff --git a/platform/osx/app/MainMenu.xib b/platform/osx/app/MainMenu.xib
index c96169b094..a47e7dcf75 100644
--- a/platform/osx/app/MainMenu.xib
+++ b/platform/osx/app/MainMenu.xib
@@ -669,6 +669,12 @@
<action selector="dropPin:" target="Voe-Tx-rLC" id="eDR-iw-JUG"/>
</connections>
</menuItem>
+ <menuItem title="Remove Pin" id="rgF-cY-qgP">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="removePin:" target="Voe-Tx-rLC" id="38n-9m-8Wp"/>
+ </connections>
+ </menuItem>
</items>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="MsV-YU-f4X"/>
diff --git a/platform/osx/sdk/MGLMapView.mm b/platform/osx/sdk/MGLMapView.mm
index 76ad50bd30..79067095e8 100644
--- a/platform/osx/sdk/MGLMapView.mm
+++ b/platform/osx/sdk/MGLMapView.mm
@@ -217,6 +217,7 @@ public:
_annotationContextsByAnnotationID = {};
_selectedAnnotationID = MGLAnnotationNotFound;
_lastSelectedAnnotationID = MGLAnnotationNotFound;
+ _annotationsNearbyLastClick = {};
mbgl::CameraOptions options;
options.center = mbgl::LatLng(0, 0);
@@ -873,62 +874,8 @@ public:
return;
}
- // Look for any annotation near the click. An annotation is “near” if the
- // distance between its center and the click is less than the maximum height
- // or width of an installed annotation image.
NSPoint gesturePoint = [gestureRecognizer locationInView:self];
- NSRect queryRect = NSInsetRect({ gesturePoint, NSZeroSize },
- -_unionedAnnotationImageSize.width / 2,
- -_unionedAnnotationImageSize.height / 2);
- queryRect = NSInsetRect(queryRect, -MGLAnnotationImagePaddingForHitTest,
- -MGLAnnotationImagePaddingForHitTest);
- mbgl::LatLngBounds queryBounds = [self convertRectToLatLngBounds:queryRect];
- std::vector<MGLAnnotationID> nearbyAnnotations = _mbglMap->getPointAnnotationsInBounds(queryBounds);
-
- if (nearbyAnnotations.size()) {
- NSRect hitRect = NSInsetRect({ gesturePoint, NSZeroSize },
- -MGLAnnotationImagePaddingForHitTest,
- -MGLAnnotationImagePaddingForHitTest);
- mbgl::util::erase_if(nearbyAnnotations, [&](const MGLAnnotationID annotationID) {
- NSAssert(_annotationContextsByAnnotationID.count(annotationID) != 0, @"Unknown annotation found nearby click");
- id <MGLAnnotation> annotation = [self annotationWithID:annotationID];
- if (!annotation) {
- return true;
- }
-
- MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithID:annotationID];
- if (!annotationImage.selectable) {
- return true;
- }
-
- NSRect annotationRect = [self frameOfImage:annotationImage.image
- centeredAtCoordinate:annotation.coordinate];
- return !!![annotationImage.image hitTestRect:hitRect withImageDestinationRect:annotationRect
- context:nil hints:nil flipped:NO];
- });
- }
-
- MGLAnnotationID hitAnnotationID = MGLAnnotationNotFound;
- if (nearbyAnnotations.size()) {
- std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end());
-
- if (nearbyAnnotations == _annotationsNearbyLastClick) {
- if (_lastSelectedAnnotationID == _annotationsNearbyLastClick.back()
- || _lastSelectedAnnotationID == MGLAnnotationNotFound) {
- hitAnnotationID = _annotationsNearbyLastClick.front();
- } else {
- auto result = std::find(_annotationsNearbyLastClick.begin(),
- _annotationsNearbyLastClick.end(),
- _lastSelectedAnnotationID);
- auto distance = std::distance(_annotationsNearbyLastClick.begin(), result);
- hitAnnotationID = _annotationsNearbyLastClick[distance + 1];
- }
- } else {
- _annotationsNearbyLastClick = nearbyAnnotations;
- hitAnnotationID = _annotationsNearbyLastClick.front();
- }
- }
-
+ MGLAnnotationID hitAnnotationID = [self annotationIDAtPoint:gesturePoint persistingResults:YES];
if (hitAnnotationID != MGLAnnotationNotFound) {
if (hitAnnotationID != _selectedAnnotationID) {
id <MGLAnnotation> annotation = [self annotationWithID:hitAnnotationID];
@@ -1282,6 +1229,73 @@ public:
return self.annotationImagesByIdentifier[identifier];
}
+- (id <MGLAnnotation>)annotationAtPoint:(NSPoint)point {
+ return [self annotationWithID:[self annotationIDAtPoint:point persistingResults:NO]];
+}
+
+- (MGLAnnotationID)annotationIDAtPoint:(NSPoint)point persistingResults:(BOOL)persist {
+ // Look for any annotation near the click. An annotation is “near” if the
+ // distance between its center and the click is less than the maximum height
+ // or width of an installed annotation image.
+ NSRect queryRect = NSInsetRect({ point, NSZeroSize },
+ -_unionedAnnotationImageSize.width / 2,
+ -_unionedAnnotationImageSize.height / 2);
+ queryRect = NSInsetRect(queryRect, -MGLAnnotationImagePaddingForHitTest,
+ -MGLAnnotationImagePaddingForHitTest);
+ mbgl::LatLngBounds queryBounds = [self convertRectToLatLngBounds:queryRect];
+ std::vector<MGLAnnotationID> nearbyAnnotations = _mbglMap->getPointAnnotationsInBounds(queryBounds);
+
+ if (nearbyAnnotations.size()) {
+ NSRect hitRect = NSInsetRect({ point, NSZeroSize },
+ -MGLAnnotationImagePaddingForHitTest,
+ -MGLAnnotationImagePaddingForHitTest);
+ mbgl::util::erase_if(nearbyAnnotations, [&](const MGLAnnotationID annotationID) {
+ NSAssert(_annotationContextsByAnnotationID.count(annotationID) != 0, @"Unknown annotation found nearby click");
+ id <MGLAnnotation> annotation = [self annotationWithID:annotationID];
+ if (!annotation) {
+ return true;
+ }
+
+ MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithID:annotationID];
+ if (!annotationImage.selectable) {
+ return true;
+ }
+
+ NSRect annotationRect = [self frameOfImage:annotationImage.image
+ centeredAtCoordinate:annotation.coordinate];
+ return !!![annotationImage.image hitTestRect:hitRect withImageDestinationRect:annotationRect
+ context:nil hints:nil flipped:NO];
+ });
+ }
+
+ MGLAnnotationID hitAnnotationID = MGLAnnotationNotFound;
+ if (nearbyAnnotations.size()) {
+ std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end());
+
+ if (nearbyAnnotations == _annotationsNearbyLastClick) {
+ if (_lastSelectedAnnotationID == _annotationsNearbyLastClick.back()
+ || _lastSelectedAnnotationID == MGLAnnotationNotFound) {
+ hitAnnotationID = _annotationsNearbyLastClick.front();
+ } else {
+ auto result = std::find(_annotationsNearbyLastClick.begin(),
+ _annotationsNearbyLastClick.end(),
+ _lastSelectedAnnotationID);
+ auto distance = std::distance(_annotationsNearbyLastClick.begin(), result);
+ hitAnnotationID = _annotationsNearbyLastClick[distance + 1];
+ }
+ } else {
+ if (persist) {
+ _annotationsNearbyLastClick = nearbyAnnotations;
+ }
+ if (_annotationsNearbyLastClick.size()) {
+ hitAnnotationID = _annotationsNearbyLastClick.front();
+ }
+ }
+ }
+
+ return hitAnnotationID;
+}
+
- (NS_ARRAY_OF(id <MGLAnnotation>) *)selectedAnnotations {
id <MGLAnnotation> selectedAnnotation = self.selectedAnnotation;
return selectedAnnotation ? @[selectedAnnotation] : @[];
@@ -1391,7 +1405,8 @@ public:
}
- (MGLAnnotationImage *)imageOfAnnotationWithID:(MGLAnnotationID)annotationID {
- if (annotationID == MGLAnnotationNotFound) {
+ if (annotationID == MGLAnnotationNotFound
+ || _annotationContextsByAnnotationID.count(annotationID) == 0) {
return nil;
}