summaryrefslogtreecommitdiff
path: root/platform/osx/sdk
diff options
context:
space:
mode:
Diffstat (limited to 'platform/osx/sdk')
-rw-r--r--platform/osx/sdk/Info.plist22
-rw-r--r--platform/osx/sdk/MGLAccountManager.m66
-rw-r--r--platform/osx/sdk/MGLAccountManager_Private.h10
-rw-r--r--platform/osx/sdk/MGLAnnotationImage.m25
-rw-r--r--platform/osx/sdk/MGLAttributionButton.h11
-rw-r--r--platform/osx/sdk/MGLAttributionButton.m46
-rw-r--r--platform/osx/sdk/MGLCompassCell.h5
-rw-r--r--platform/osx/sdk/MGLCompassCell.m31
-rw-r--r--platform/osx/sdk/MGLMapView+IBAdditions.m114
-rw-r--r--platform/osx/sdk/MGLMapView.mm1784
-rw-r--r--platform/osx/sdk/MGLMapView_Private.h12
-rw-r--r--platform/osx/sdk/MGLOpenGLLayer.h10
-rw-r--r--platform/osx/sdk/MGLOpenGLLayer.mm49
-rw-r--r--platform/osx/sdk/Mapbox.m27
-rw-r--r--platform/osx/sdk/NSBundle+MGLAdditions.h16
-rw-r--r--platform/osx/sdk/NSBundle+MGLAdditions.m22
-rw-r--r--platform/osx/sdk/NSProcessInfo+MGLAdditions.h9
-rw-r--r--platform/osx/sdk/NSProcessInfo+MGLAdditions.m11
-rw-r--r--platform/osx/sdk/framework-osx.gypi46
-rw-r--r--platform/osx/sdk/resources/MGLAnnotationCallout.xib53
-rw-r--r--platform/osx/sdk/resources/default_marker.pdfbin2601 -> 0 bytes
-rw-r--r--platform/osx/sdk/resources/mapbox.pdfbin3762 -> 0 bytes
22 files changed, 95 insertions, 2274 deletions
diff --git a/platform/osx/sdk/Info.plist b/platform/osx/sdk/Info.plist
new file mode 100644
index 0000000000..aeebbb5072
--- /dev/null
+++ b/platform/osx/sdk/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>0.0.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>0.0.0</string>
+</dict>
+</plist>
diff --git a/platform/osx/sdk/MGLAccountManager.m b/platform/osx/sdk/MGLAccountManager.m
deleted file mode 100644
index d6bc82defe..0000000000
--- a/platform/osx/sdk/MGLAccountManager.m
+++ /dev/null
@@ -1,66 +0,0 @@
-#import "MGLAccountManager_Private.h"
-
-#import <mbgl/osx/MGLMapView.h>
-
-#import "NSBundle+MGLAdditions.h"
-#import "NSProcessInfo+MGLAdditions.h"
-#import "../../darwin/NSString+MGLAdditions.h"
-
-@interface MGLAccountManager ()
-
-@property (atomic) NSString *accessToken;
-
-@end
-
-@implementation MGLAccountManager
-
-#pragma mark - Internal
-
-+ (void)load {
- mgl_linkBundleCategory();
- mgl_linkStringCategory();
- mgl_linkProcessInfoCategory();
-
- [MGLMapView restorableStateKeyPaths];
-
- // Read the initial configuration from Info.plist.
- NSString *accessToken = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxAccessToken"];
- if (accessToken.length) {
- self.accessToken = accessToken;
- }
-}
-
-// Can be called from any thread.
-//
-+ (instancetype)sharedManager {
- static dispatch_once_t onceToken;
- static MGLAccountManager *_sharedManager;
- void (^setupBlock)() = ^{
- dispatch_once(&onceToken, ^{
- _sharedManager = [[self alloc] init];
- });
- };
- if (![[NSThread currentThread] isMainThread]) {
- dispatch_sync(dispatch_get_main_queue(), ^{
- setupBlock();
- });
- }
- else {
- setupBlock();
- }
- return _sharedManager;
-}
-
-+ (void)setAccessToken:(NSString *)accessToken {
- accessToken = [accessToken stringByTrimmingCharactersInSet:
- [NSCharacterSet whitespaceAndNewlineCharacterSet]];
- if (![accessToken length]) return;
-
- [MGLAccountManager sharedManager].accessToken = accessToken;
-}
-
-+ (NSString *)accessToken {
- return [MGLAccountManager sharedManager].accessToken;
-}
-
-@end
diff --git a/platform/osx/sdk/MGLAccountManager_Private.h b/platform/osx/sdk/MGLAccountManager_Private.h
deleted file mode 100644
index c0b8d2666a..0000000000
--- a/platform/osx/sdk/MGLAccountManager_Private.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#import <mbgl/osx/MGLAccountManager.h>
-
-@interface MGLAccountManager (Private)
-
-/** Returns the shared instance of the `MGLAccountManager` class. */
-+ (instancetype)sharedManager;
-
-@property (atomic) NSString *accessToken;
-
-@end
diff --git a/platform/osx/sdk/MGLAnnotationImage.m b/platform/osx/sdk/MGLAnnotationImage.m
deleted file mode 100644
index 855105fded..0000000000
--- a/platform/osx/sdk/MGLAnnotationImage.m
+++ /dev/null
@@ -1,25 +0,0 @@
-#import <mbgl/osx/MGLAnnotationImage.h>
-
-@interface MGLAnnotationImage ()
-
-@property (nonatomic) NSImage *image;
-@property (nonatomic) NSString *reuseIdentifier;
-
-@end
-
-@implementation MGLAnnotationImage
-
-+ (instancetype)annotationImageWithImage:(NSImage *)image reuseIdentifier:(NSString *)reuseIdentifier {
- return [[self alloc] initWithImage:image reuseIdentifier:reuseIdentifier];
-}
-
-- (instancetype)initWithImage:(NSImage *)image reuseIdentifier:(NSString *)reuseIdentifier {
- if (self = [super init]) {
- _image = image;
- _reuseIdentifier = [reuseIdentifier copy];
- _selectable = YES;
- }
- return self;
-}
-
-@end
diff --git a/platform/osx/sdk/MGLAttributionButton.h b/platform/osx/sdk/MGLAttributionButton.h
deleted file mode 100644
index 7bc0fa5357..0000000000
--- a/platform/osx/sdk/MGLAttributionButton.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#import <Cocoa/Cocoa.h>
-
-@interface MGLAttributionButton : NSButton
-
-- (instancetype)initWithTitle:(NSString *)title URL:(NSURL *)url;
-
-@property (nonatomic) NSURL *URL;
-
-- (IBAction)openURL:(id)sender;
-
-@end
diff --git a/platform/osx/sdk/MGLAttributionButton.m b/platform/osx/sdk/MGLAttributionButton.m
deleted file mode 100644
index 642f71f608..0000000000
--- a/platform/osx/sdk/MGLAttributionButton.m
+++ /dev/null
@@ -1,46 +0,0 @@
-#import "MGLAttributionButton.h"
-
-@implementation MGLAttributionButton {
- NSTrackingRectTag _trackingAreaTag;
-}
-
-- (instancetype)initWithTitle:(NSString *)title URL:(NSURL *)url {
- if (self = [super initWithFrame:NSZeroRect]) {
- self.bordered = NO;
- self.bezelStyle = NSRegularSquareBezelStyle;
-
- NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc] initWithString:@"© "
- attributes:@{
- NSFontAttributeName: [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]],
- }];
- [attributedTitle appendAttributedString:
- [[NSAttributedString alloc] initWithString:title
- attributes:@{
- NSFontAttributeName: [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]],
- NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),
- }]];
- self.attributedTitle = attributedTitle;
- [self sizeToFit];
-
- _URL = url;
- self.toolTip = _URL.absoluteString;
-
- self.target = self;
- self.action = @selector(openURL:);
- }
- return self;
-}
-
-- (BOOL)wantsLayer {
- return YES;
-}
-
-- (void)resetCursorRects {
- [self addCursorRect:self.bounds cursor:[NSCursor pointingHandCursor]];
-}
-
-- (IBAction)openURL:(__unused id)sender {
- [[NSWorkspace sharedWorkspace] openURL:self.URL];
-}
-
-@end
diff --git a/platform/osx/sdk/MGLCompassCell.h b/platform/osx/sdk/MGLCompassCell.h
deleted file mode 100644
index 8c89b43e18..0000000000
--- a/platform/osx/sdk/MGLCompassCell.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#import <Cocoa/Cocoa.h>
-
-@interface MGLCompassCell : NSSliderCell
-
-@end
diff --git a/platform/osx/sdk/MGLCompassCell.m b/platform/osx/sdk/MGLCompassCell.m
deleted file mode 100644
index 88911de2ff..0000000000
--- a/platform/osx/sdk/MGLCompassCell.m
+++ /dev/null
@@ -1,31 +0,0 @@
-#import "MGLCompassCell.h"
-
-@implementation MGLCompassCell
-
-- (instancetype)init {
- if (self = [super init]) {
- self.sliderType = NSCircularSlider;
- self.numberOfTickMarks = 4;
- self.minValue = -360;
- self.maxValue = 0;
- }
- return self;
-}
-
-- (void)drawKnob:(NSRect)knobRect {
- NSBezierPath *trianglePath = [NSBezierPath bezierPath];
- [trianglePath moveToPoint:NSMakePoint(NSMinX(knobRect), NSMaxY(knobRect))];
- [trianglePath lineToPoint:NSMakePoint(NSMaxX(knobRect), NSMaxY(knobRect))];
- [trianglePath lineToPoint:NSMakePoint(NSMidX(knobRect), NSMinY(knobRect))];
- [trianglePath closePath];
- NSAffineTransform *transform = [NSAffineTransform transform];
- [transform translateXBy:NSMidX(knobRect) yBy:NSMidY(knobRect)];
- [transform scaleBy:0.8];
- [transform rotateByDegrees:self.doubleValue];
- [transform translateXBy:-NSMidX(knobRect) yBy:-NSMidY(knobRect)];
- [trianglePath transformUsingAffineTransform:transform];
- [[NSColor redColor] setFill];
- [trianglePath fill];
-}
-
-@end
diff --git a/platform/osx/sdk/MGLMapView+IBAdditions.m b/platform/osx/sdk/MGLMapView+IBAdditions.m
deleted file mode 100644
index 504bc789de..0000000000
--- a/platform/osx/sdk/MGLMapView+IBAdditions.m
+++ /dev/null
@@ -1,114 +0,0 @@
-#import <mbgl/osx/MGLMapView+IBAdditions.h>
-
-#import "MGLMapView_Private.h"
-
-@implementation MGLMapView (IBAdditions)
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingStyleURL__ {
- return [NSSet setWithObject:@"styleURL"];
-}
-
-- (nullable NSString *)styleURL__ {
- return self.styleURL.absoluteString;
-}
-
-- (void)setStyleURL__:(nullable NSString *)URLString {
- URLString = [URLString stringByTrimmingCharactersInSet:
- [NSCharacterSet whitespaceAndNewlineCharacterSet]];
- NSURL *url = URLString.length ? [NSURL URLWithString:URLString] : nil;
- if (URLString.length && !url) {
- [NSException raise:@"Invalid style URL"
- format:@"“%@” is not a valid style URL.", URLString];
- }
- self.styleURL = url;
-}
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingLatitude {
- return [NSSet setWithObjects:@"centerCoordinate", nil];
-}
-
-- (double)latitude {
- return self.centerCoordinate.latitude;
-}
-
-- (void)setLatitude:(double)latitude {
- if (!isnan(self.pendingLongitude)) {
- self.centerCoordinate = CLLocationCoordinate2DMake(latitude, self.pendingLongitude);
- self.pendingLatitude = NAN;
- self.pendingLongitude = NAN;
- } else {
- // Not enough info to make a valid center coordinate yet. Stash this
- // latitude away until the longitude is set too.
- self.pendingLatitude = latitude;
- }
-}
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingLongitude {
- return [NSSet setWithObjects:@"centerCoordinate", nil];
-}
-
-- (double)longitude {
- return self.centerCoordinate.longitude;
-}
-
-- (void)setLongitude:(double)longitude {
- if (!isnan(self.pendingLatitude)) {
- self.centerCoordinate = CLLocationCoordinate2DMake(self.pendingLatitude, longitude);
- self.pendingLatitude = NAN;
- self.pendingLongitude = NAN;
- } else {
- // Not enough info to make a valid center coordinate yet. Stash this
- // longitude away until the latitude is set too.
- self.pendingLongitude = longitude;
- }
-}
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingAllowsZooming {
- return [NSSet setWithObject:@"zoomEnabled"];
-}
-
-- (BOOL)allowsZooming {
- return self.zoomEnabled;
-}
-
-- (void)setAllowsZooming:(BOOL)allowsZooming {
- self.zoomEnabled = allowsZooming;
-}
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingAllowsScrolling {
- return [NSSet setWithObject:@"scrollEnabled"];
-}
-
-- (BOOL)allowsScrolling {
- return self.scrollEnabled;
-}
-
-- (void)setAllowsScrolling:(BOOL)allowsScrolling {
- self.scrollEnabled = allowsScrolling;
-}
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingAllowsRotating {
- return [NSSet setWithObject:@"rotateEnabled"];
-}
-
-- (BOOL)allowsRotating {
- return self.rotateEnabled;
-}
-
-- (void)setAllowsRotating:(BOOL)allowsRotating {
- self.rotateEnabled = allowsRotating;
-}
-
-+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingAllowsTilting {
- return [NSSet setWithObject:@"pitchEnabled"];
-}
-
-- (BOOL)allowsTilting {
- return self.pitchEnabled;
-}
-
-- (void)setAllowsTilting:(BOOL)allowsTilting {
- self.pitchEnabled = allowsTilting;
-}
-
-@end
diff --git a/platform/osx/sdk/MGLMapView.mm b/platform/osx/sdk/MGLMapView.mm
deleted file mode 100644
index 350b59e208..0000000000
--- a/platform/osx/sdk/MGLMapView.mm
+++ /dev/null
@@ -1,1784 +0,0 @@
-#import "MGLMapView_Private.h"
-#import "MGLAccountManager_Private.h"
-#import "MGLAttributionButton.h"
-#import "MGLCompassCell.h"
-#import "MGLOpenGLLayer.h"
-#import "MGLStyle.h"
-
-#import "../../darwin/MGLGeometry_Private.h"
-#import "../../darwin/MGLMultiPoint_Private.h"
-
-#import <mbgl/darwin/MGLPolygon.h>
-#import <mbgl/darwin/MGLPolyline.h>
-#import <mbgl/osx/MGLAnnotationImage.h>
-#import <mbgl/osx/MGLMapViewDelegate.h>
-
-#import <mbgl/mbgl.hpp>
-#import <mbgl/annotation/point_annotation.hpp>
-#import <mbgl/map/camera.hpp>
-#import <mbgl/platform/darwin/reachability.h>
-#import <mbgl/platform/gl.hpp>
-#import <mbgl/sprite/sprite_image.hpp>
-#import <mbgl/storage/default_file_source.hpp>
-#import <mbgl/storage/network_status.hpp>
-#import <mbgl/storage/sqlite_cache.hpp>
-#import <mbgl/util/constants.hpp>
-#import <mbgl/util/math.hpp>
-#import <mbgl/util/std.hpp>
-
-#import <map>
-#import <unordered_set>
-
-#import "NSBundle+MGLAdditions.h"
-#import "NSProcessInfo+MGLAdditions.h"
-#import "../../darwin/NSException+MGLAdditions.h"
-#import "../../darwin/NSString+MGLAdditions.h"
-
-#import <QuartzCore/QuartzCore.h>
-
-class MGLMapViewImpl;
-class MGLAnnotationContext;
-
-const CGFloat MGLOrnamentPadding = 12;
-
-const NSTimeInterval MGLAnimationDuration = 0.3;
-const CGFloat MGLKeyPanningIncrement = 150;
-const CLLocationDegrees MGLKeyRotationIncrement = 25;
-
-static NSString * const MGLVendorDirectoryName = @"com.mapbox.MapboxGL";
-
-static NSString * const MGLDefaultStyleMarkerSymbolName = @"default_marker";
-static NSString * const MGLAnnotationSpritePrefix = @"com.mapbox.sprites.";
-const CGFloat MGLAnnotationImagePaddingForHitTest = 4;
-const CGFloat MGLAnnotationImagePaddingForCallout = 4;
-
-struct MGLAttribution {
- NSString *title;
- NSString *urlString;
-} MGLAttributions[] = {
- { @"Mapbox", @"https://www.mapbox.com/about/maps/" },
- { @"OpenStreetMap", @"http://www.openstreetmap.org/about/" },
-};
-
-typedef uint32_t MGLAnnotationID;
-enum { MGLAnnotationNotFound = UINT32_MAX };
-typedef std::map<MGLAnnotationID, MGLAnnotationContext> MGLAnnotationContextMap;
-
-/// Returns an NSImage for the default marker image.
-NSImage *MGLDefaultMarkerImage() {
- NSString *path = [[NSBundle mgl_resourceBundle] pathForResource:MGLDefaultStyleMarkerSymbolName
- ofType:@"pdf"];
- return [[NSImage alloc] initWithContentsOfFile:path];
-}
-
-std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) {
- return std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<float, std::chrono::seconds::period>(duration));
-}
-
-/// Converts the given color into an mbgl::Color in calibrated RGB space.
-mbgl::Color MGLColorObjectFromNSColor(NSColor *color) {
- if (!color) {
- return {{ 0, 0, 0, 0 }};
- }
- CGFloat r, g, b, a;
- [[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&r green:&g blue:&b alpha:&a];
- return {{ (float)r, (float)g, (float)b, (float)a }};
-}
-
-class MGLAnnotationContext {
-public:
- id <MGLAnnotation> annotation;
- NSString *symbolIdentifier;
-};
-
-@interface MGLMapView () <NSPopoverDelegate, MGLMultiPointDelegate>
-
-@property (nonatomic, readwrite) NSSegmentedControl *zoomControls;
-@property (nonatomic, readwrite) NSSlider *compass;
-@property (nonatomic, readwrite) NSImageView *logoView;
-@property (nonatomic, readwrite) NSView *attributionView;
-
-@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLAnnotationImage *) *annotationImagesByIdentifier;
-@property (nonatomic) NSPopover *calloutForSelectedAnnotation;
-
-@property (nonatomic, readwrite, getter=isDormant) BOOL dormant;
-
-@end
-
-@implementation MGLMapView {
- mbgl::Map *_mbglMap;
- MGLMapViewImpl *_mbglView;
- std::shared_ptr<mbgl::SQLiteCache> _mbglFileCache;
- mbgl::DefaultFileSource *_mbglFileSource;
-
- NSPanGestureRecognizer *_panGestureRecognizer;
- NSMagnificationGestureRecognizer *_magnificationGestureRecognizer;
- NSRotationGestureRecognizer *_rotationGestureRecognizer;
- double _scaleAtBeginningOfGesture;
- CLLocationDirection _directionAtBeginningOfGesture;
- CGFloat _pitchAtBeginningOfGesture;
-
- MGLAnnotationContextMap _annotationContextsByAnnotationID;
- MGLAnnotationID _selectedAnnotationID;
- MGLAnnotationID _lastSelectedAnnotationID;
- NSSize _unionedAnnotationImageSize;
- std::vector<MGLAnnotationID> _annotationsNearbyLastClick;
- BOOL _wantsToolTipRects;
- BOOL _wantsCursorRects;
- BOOL _delegateHasAlphasForShapeAnnotations;
- BOOL _delegateHasStrokeColorsForShapeAnnotations;
- BOOL _delegateHasFillColorsForShapeAnnotations;
- BOOL _delegateHasLineWidthsForShapeAnnotations;
-
- BOOL _isTargetingInterfaceBuilder;
- CLLocationDegrees _pendingLatitude;
- CLLocationDegrees _pendingLongitude;
-}
-
-#pragma mark Lifecycle
-
-- (instancetype)initWithFrame:(NSRect)frameRect {
- if (self = [super initWithFrame:frameRect]) {
- [self commonInit];
- self.styleURL = nil;
- }
- return self;
-}
-
-- (instancetype)initWithFrame:(CGRect)frame styleURL:(nullable NSURL *)styleURL {
- if (self = [super initWithFrame:frame]) {
- [self commonInit];
- self.styleURL = styleURL;
- }
- return self;
-}
-
-- (instancetype)initWithCoder:(nonnull NSCoder *)decoder {
- if (self = [super initWithCoder:decoder]) {
- [self commonInit];
- }
- return self;
-}
-
-- (void)awakeFromNib {
- [super awakeFromNib];
-
- self.styleURL = nil;
-}
-
-+ (NSArray *)restorableStateKeyPaths {
- return @[@"zoomLevel", @"direction"];
-}
-
-- (void)commonInit {
- _isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
-
- _mbglView = new MGLMapViewImpl(self, [NSScreen mainScreen].backingScaleFactor);
-
- // Place the cache in a location that can be shared among all the
- // applications that embed the Mapbox OS X SDK.
- NSURL *cacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory
- inDomain:NSUserDomainMask
- appropriateForURL:nil
- create:YES
- error:nil];
- cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:MGLVendorDirectoryName];
- [[NSFileManager defaultManager] createDirectoryAtURL:cacheDirectoryURL
- withIntermediateDirectories:YES
- attributes:nil
- error:nil];
- NSURL *cacheURL = [cacheDirectoryURL URLByAppendingPathComponent:@"cache.db"];
- NSString *cachePath = cacheURL ? cacheURL.path : @"";
- _mbglFileCache = mbgl::SharedSQLiteCache::get(cachePath.UTF8String);
- _mbglFileSource = new mbgl::DefaultFileSource(_mbglFileCache.get());
-
- _mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
-
- self.layer = _isTargetingInterfaceBuilder ? [CALayer layer] : [MGLOpenGLLayer layer];
-
- // Observe for changes to the global access token (and find out the current one).
- [[MGLAccountManager sharedManager] addObserver:self
- forKeyPath:@"accessToken"
- options:(NSKeyValueObservingOptionInitial |
- NSKeyValueObservingOptionNew)
- context:NULL];
-
- // Notify map object when network reachability status changes.
- MGLReachability *reachability = [MGLReachability reachabilityForInternetConnection];
- reachability.reachableBlock = ^(MGLReachability *) {
- mbgl::NetworkStatus::Reachable();
- };
- [reachability startNotifier];
-
- [self installZoomControls];
- [self installCompass];
- [self installLogoView];
- [self installAttributionView];
- [self installGestureRecognizers];
-
- _annotationImagesByIdentifier = [NSMutableDictionary dictionary];
- _annotationContextsByAnnotationID = {};
- _selectedAnnotationID = MGLAnnotationNotFound;
- _lastSelectedAnnotationID = MGLAnnotationNotFound;
- _annotationsNearbyLastClick = {};
-
- mbgl::CameraOptions options;
- options.center = mbgl::LatLng(0, 0);
- options.zoom = _mbglMap->getMinZoom();
- _mbglMap->jumpTo(options);
-}
-
-- (void)installZoomControls {
- _zoomControls = [[NSSegmentedControl alloc] initWithFrame:NSZeroRect];
- _zoomControls.wantsLayer = YES;
- _zoomControls.layer.opacity = 0.9;
- [(NSSegmentedCell *)_zoomControls.cell setTrackingMode:NSSegmentSwitchTrackingMomentary];
- _zoomControls.continuous = YES;
- _zoomControls.segmentCount = 2;
- [_zoomControls setLabel:@"−" forSegment:0];
- [(NSSegmentedCell *)_zoomControls.cell setTag:0 forSegment:0];
- [(NSSegmentedCell *)_zoomControls.cell setToolTip:@"Zoom Out" forSegment:0];
- [_zoomControls setLabel:@"+" forSegment:1];
- [(NSSegmentedCell *)_zoomControls.cell setTag:1 forSegment:1];
- [(NSSegmentedCell *)_zoomControls.cell setToolTip:@"Zoom In" forSegment:1];
- _zoomControls.target = self;
- _zoomControls.action = @selector(zoomInOrOut:);
- _zoomControls.controlSize = NSRegularControlSize;
- [_zoomControls sizeToFit];
- _zoomControls.translatesAutoresizingMaskIntoConstraints = NO;
- [self addSubview:_zoomControls];
-}
-
-- (void)installCompass {
- _compass = [[NSSlider alloc] initWithFrame:NSZeroRect];
- _compass.wantsLayer = YES;
- _compass.layer.opacity = 0.9;
- _compass.cell = [[MGLCompassCell alloc] init];
- _compass.continuous = YES;
- _compass.target = self;
- _compass.action = @selector(rotate:);
- [_compass sizeToFit];
- _compass.translatesAutoresizingMaskIntoConstraints = NO;
- [self addSubview:_compass];
-}
-
-- (void)installLogoView {
- _logoView = [[NSImageView alloc] initWithFrame:NSZeroRect];
- _logoView.wantsLayer = YES;
- NSImage *logoImage = [[NSImage alloc] initWithContentsOfFile:
- [[NSBundle mgl_resourceBundle] pathForResource:@"mapbox" ofType:@"pdf"]];
- logoImage.alignmentRect = NSInsetRect(logoImage.alignmentRect, 3, 3);
- _logoView.image = logoImage;
- _logoView.translatesAutoresizingMaskIntoConstraints = NO;
- _logoView.accessibilityTitle = @"Mapbox";
- [self addSubview:_logoView];
-}
-
-- (void)installAttributionView {
- _attributionView = [[NSView alloc] initWithFrame:NSZeroRect];
- _attributionView.wantsLayer = YES;
- _attributionView.layer.opacity = 0.6;
- CIFilter *attributionBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
- [attributionBlurFilter setDefaults];
- CIFilter *attributionColorFilter = [CIFilter filterWithName:@"CIColorControls"];
- [attributionColorFilter setDefaults];
- [attributionColorFilter setValue:@(0.1) forKey:kCIInputBrightnessKey];
- _attributionView.backgroundFilters = @[attributionColorFilter, attributionBlurFilter];
- _attributionView.layer.cornerRadius = 4;
- _attributionView.translatesAutoresizingMaskIntoConstraints = NO;
- [self addSubview:_attributionView];
- [self updateAttributionView];
-}
-
-- (void)installGestureRecognizers {
- self.acceptsTouchEvents = YES;
- _scrollEnabled = YES;
- _zoomEnabled = YES;
- _rotateEnabled = YES;
- _pitchEnabled = YES;
-
- _panGestureRecognizer = [[NSPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
- _panGestureRecognizer.delaysKeyEvents = YES;
- [self addGestureRecognizer:_panGestureRecognizer];
-
- NSClickGestureRecognizer *clickGestureRecognizer = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(handleClickGesture:)];
- clickGestureRecognizer.delaysPrimaryMouseButtonEvents = NO;
- [self addGestureRecognizer:clickGestureRecognizer];
-
- NSClickGestureRecognizer *secondaryClickGestureRecognizer = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(handleSecondaryClickGesture:)];
- secondaryClickGestureRecognizer.buttonMask = 0x2;
- [self addGestureRecognizer:secondaryClickGestureRecognizer];
-
- NSClickGestureRecognizer *doubleClickGestureRecognizer = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleClickGesture:)];
- doubleClickGestureRecognizer.numberOfClicksRequired = 2;
- doubleClickGestureRecognizer.delaysPrimaryMouseButtonEvents = NO;
- [self addGestureRecognizer:doubleClickGestureRecognizer];
-
- _magnificationGestureRecognizer = [[NSMagnificationGestureRecognizer alloc] initWithTarget:self action:@selector(handleMagnificationGesture:)];
- [self addGestureRecognizer:_magnificationGestureRecognizer];
-
- _rotationGestureRecognizer = [[NSRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotationGesture:)];
- [self addGestureRecognizer:_rotationGestureRecognizer];
-}
-
-- (void)updateAttributionView {
- self.attributionView.subviews = @[];
-
- for (NSUInteger i = 0; i < sizeof(MGLAttributions) / sizeof(MGLAttributions[0]); i++) {
- NSURL *url = [NSURL URLWithString:MGLAttributions[i].urlString];
- NSButton *button = [[MGLAttributionButton alloc] initWithTitle:MGLAttributions[i].title URL:url];
- button.controlSize = NSMiniControlSize;
- button.translatesAutoresizingMaskIntoConstraints = NO;
-
- NSView *previousView = self.attributionView.subviews.lastObject;
- [self.attributionView addSubview:button];
-
- [_attributionView addConstraint:
- [NSLayoutConstraint constraintWithItem:button
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:_attributionView
- attribute:NSLayoutAttributeBottom
- multiplier:1
- constant:0]];
- [_attributionView addConstraint:
- [NSLayoutConstraint constraintWithItem:button
- attribute:NSLayoutAttributeLeading
- relatedBy:NSLayoutRelationEqual
- toItem:previousView ? previousView : _attributionView
- attribute:previousView ? NSLayoutAttributeTrailing : NSLayoutAttributeLeading
- multiplier:1
- constant:8]];
- }
-}
-
-- (void)dealloc {
- [[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"accessToken"];
-
- [self.calloutForSelectedAnnotation close];
- self.calloutForSelectedAnnotation = nil;
-
- if (_mbglMap) {
- delete _mbglMap;
- _mbglMap = nullptr;
- }
- if (_mbglFileSource) {
- delete _mbglFileSource;
- _mbglFileSource = nullptr;
- }
- if (_mbglView) {
- delete _mbglView;
- _mbglView = nullptr;
- }
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(__unused void *)context {
- // Synchronize mbgl::Map’s access token with the global one in MGLAccountManager.
- if ([keyPath isEqualToString:@"accessToken"] && object == [MGLAccountManager sharedManager]) {
- NSString *accessToken = change[NSKeyValueChangeNewKey];
- if (![accessToken isKindOfClass:[NSNull class]]) {
- _mbglFileSource->setAccessToken((std::string)[accessToken UTF8String]);
- }
- }
-}
-
-- (void)setDelegate:(id<MGLMapViewDelegate>)delegate {
- _delegate = delegate;
-
- _delegateHasAlphasForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:alphaForShapeAnnotation:)];
- _delegateHasStrokeColorsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:strokeColorForShapeAnnotation:)];
- _delegateHasFillColorsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:fillColorForPolygonAnnotation:)];
- _delegateHasLineWidthsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:lineWidthForPolylineAnnotation:)];
-}
-
-#pragma mark Style
-
-- (nonnull NSURL *)styleURL {
- NSString *styleURLString = @(_mbglMap->getStyleURL().c_str()).mgl_stringOrNilIfEmpty;
- return styleURLString ? [NSURL URLWithString:styleURLString] : [MGLStyle streetsStyleURL];
-}
-
-- (void)setStyleURL:(nullable NSURL *)styleURL {
- if (_isTargetingInterfaceBuilder) {
- return;
- }
-
- if (!styleURL) {
- if (![MGLAccountManager accessToken]) {
- return;
- }
- styleURL = [MGLStyle streetsStyleURL];
- }
-
- if (![styleURL scheme]) {
- // Assume a relative path into the application’s resource folder.
- styleURL = [NSURL URLWithString:[@"asset://" stringByAppendingString:[styleURL absoluteString]]];
- }
-
- _mbglMap->setStyleURL([[styleURL absoluteString] UTF8String]);
-}
-
-- (IBAction)reloadStyle:(__unused id)sender {
- NSURL *styleURL = self.styleURL;
- _mbglMap->setStyleURL("");
- self.styleURL = styleURL;
-}
-
-#pragma mark View hierarchy and drawing
-
-- (void)viewWillMoveToWindow:(NSWindow *)newWindow {
- [self deselectAnnotation:self.selectedAnnotation animated:NO];
- if (!self.dormant && !newWindow) {
- self.dormant = YES;
- _mbglMap->pause();
- }
-}
-
-- (void)viewDidMoveToWindow {
- if (self.dormant && self.window) {
- _mbglMap->resume();
- self.dormant = NO;
- }
-}
-
-- (BOOL)wantsLayer {
- return YES;
-}
-
-- (BOOL)wantsBestResolutionOpenGLSurface {
- return !_isTargetingInterfaceBuilder;
-}
-
-- (void)setFrame:(NSRect)frame {
- super.frame = frame;
- if (!_isTargetingInterfaceBuilder) {
- _mbglMap->update(mbgl::Update::Dimensions);
- }
-}
-
-- (void)updateConstraints {
- [self addConstraint:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:_zoomControls
- attribute:NSLayoutAttributeBottom
- multiplier:1
- constant:MGLOrnamentPadding]];
- [self addConstraint:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeTrailing
- relatedBy:NSLayoutRelationEqual
- toItem:_zoomControls
- attribute:NSLayoutAttributeTrailing
- multiplier:1
- constant:MGLOrnamentPadding]];
-
- [self addConstraint:
- [NSLayoutConstraint constraintWithItem:_compass
- attribute:NSLayoutAttributeCenterX
- relatedBy:NSLayoutRelationEqual
- toItem:_zoomControls
- attribute:NSLayoutAttributeCenterX
- multiplier:1
- constant:0]];
- [self addConstraint:
- [NSLayoutConstraint constraintWithItem:_zoomControls
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:_compass
- attribute:NSLayoutAttributeBottom
- multiplier:1
- constant:8]];
-
- [self addConstraint:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:_logoView
- attribute:NSLayoutAttributeBottom
- multiplier:1
- constant:MGLOrnamentPadding - _logoView.image.alignmentRect.origin.y]];
- [self addConstraint:
- [NSLayoutConstraint constraintWithItem:_logoView
- attribute:NSLayoutAttributeLeading
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeLeading
- multiplier:1
- constant:MGLOrnamentPadding - _logoView.image.alignmentRect.origin.x]];
-
- [self addConstraint:[NSLayoutConstraint constraintWithItem:_logoView
- attribute:NSLayoutAttributeBaseline
- relatedBy:NSLayoutRelationEqual
- toItem:_attributionView
- attribute:NSLayoutAttributeBaseline
- multiplier:1
- constant:_logoView.image.alignmentRect.origin.y]];
- [self addConstraint:[NSLayoutConstraint constraintWithItem:_attributionView
- attribute:NSLayoutAttributeLeading
- relatedBy:NSLayoutRelationEqual
- toItem:_logoView
- attribute:NSLayoutAttributeTrailing
- multiplier:1
- constant:8]];
- [self addConstraint:[NSLayoutConstraint constraintWithItem:_attributionView.subviews.firstObject
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:_attributionView
- attribute:NSLayoutAttributeTop
- multiplier:1
- constant:0]];
- [self addConstraint:[NSLayoutConstraint constraintWithItem:_attributionView
- attribute:NSLayoutAttributeTrailing
- relatedBy:NSLayoutRelationEqual
- toItem:_attributionView.subviews.lastObject
- attribute:NSLayoutAttributeTrailing
- multiplier:1
- constant:8]];
-
- [super updateConstraints];
-}
-
-- (void)renderSync {
- if (!self.dormant) {
- CGFloat zoomFactor = _mbglMap->getMaxZoom() - _mbglMap->getMinZoom() + 1;
- CGFloat cpuFactor = (CGFloat)[NSProcessInfo processInfo].processorCount;
- CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000;
- CGFloat sizeFactor = ((CGFloat)_mbglMap->getWidth() / mbgl::util::tileSize) * ((CGFloat)_mbglMap->getHeight() / mbgl::util::tileSize);
-
- NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5;
-
- _mbglMap->setSourceTileCacheSize(cacheSize);
- _mbglMap->renderSync();
-
-// [self updateUserLocationAnnotationView];
- }
-}
-
-- (void)invalidate {
- MGLAssertIsMainThread();
-
- [self.layer setNeedsDisplay];
-}
-
-- (void)notifyMapChange:(mbgl::MapChange)change {
- // Ignore map updates when the Map object isn't set.
- if (!_mbglMap) {
- return;
- }
-
- switch (change) {
- case mbgl::MapChangeRegionWillChange:
- case mbgl::MapChangeRegionWillChangeAnimated:
- {
- if ([self.delegate respondsToSelector:@selector(mapView:regionWillChangeAnimated:)]) {
- BOOL animated = change == mbgl::MapChangeRegionWillChangeAnimated;
- [self.delegate mapView:self regionWillChangeAnimated:animated];
- }
- break;
- }
- case mbgl::MapChangeRegionIsChanging:
- {
- [self updateCompass];
- [self updateAnnotationCallouts];
-
- if ([self.delegate respondsToSelector:@selector(mapViewRegionIsChanging:)]) {
- [self.delegate mapViewRegionIsChanging:self];
- }
- break;
- }
- case mbgl::MapChangeRegionDidChange:
- case mbgl::MapChangeRegionDidChangeAnimated:
- {
- [self updateZoomControls];
- [self updateCompass];
- [self updateAnnotationCallouts];
- [self updateAnnotationTrackingAreas];
-
- if ([self.delegate respondsToSelector:@selector(mapView:regionDidChangeAnimated:)]) {
- BOOL animated = change == mbgl::MapChangeRegionDidChangeAnimated;
- [self.delegate mapView:self regionDidChangeAnimated:animated];
- }
- break;
- }
- case mbgl::MapChangeWillStartLoadingMap:
- {
- if ([self.delegate respondsToSelector:@selector(mapViewWillStartLoadingMap:)]) {
- [self.delegate mapViewWillStartLoadingMap:self];
- }
- break;
- }
- case mbgl::MapChangeDidFinishLoadingMap:
- {
- if ([self.delegate respondsToSelector:@selector(mapViewDidFinishLoadingMap:)]) {
- [self.delegate mapViewDidFinishLoadingMap:self];
- }
- break;
- }
- case mbgl::MapChangeDidFailLoadingMap:
- {
- // Not yet implemented.
- break;
- }
- case mbgl::MapChangeWillStartRenderingMap:
- {
- if ([self.delegate respondsToSelector:@selector(mapViewWillStartRenderingMap:)]) {
- [self.delegate mapViewWillStartRenderingMap:self];
- }
- break;
- }
- case mbgl::MapChangeDidFinishRenderingMap:
- case mbgl::MapChangeDidFinishRenderingMapFullyRendered:
- {
- if ([self.delegate respondsToSelector:@selector(mapViewDidFinishRenderingMap:fullyRendered:)]) {
- BOOL fullyRendered = change == mbgl::MapChangeDidFinishRenderingMapFullyRendered;
- [self.delegate mapViewDidFinishRenderingMap:self fullyRendered:fullyRendered];
- }
- break;
- }
- case mbgl::MapChangeWillStartRenderingFrame:
- {
- if ([self.delegate respondsToSelector:@selector(mapViewWillStartRenderingFrame:)]) {
- [self.delegate mapViewWillStartRenderingFrame:self];
- }
- break;
- }
- case mbgl::MapChangeDidFinishRenderingFrame:
- case mbgl::MapChangeDidFinishRenderingFrameFullyRendered:
- {
- if ([self.delegate respondsToSelector:@selector(mapViewDidFinishRenderingFrame:fullyRendered:)]) {
- BOOL fullyRendered = change == mbgl::MapChangeDidFinishRenderingFrameFullyRendered;
- [self.delegate mapViewDidFinishRenderingFrame:self fullyRendered:fullyRendered];
- }
- break;
- }
- }
-}
-
-#pragma mark Viewport
-
-- (CLLocationCoordinate2D)centerCoordinate {
- return MGLLocationCoordinate2DFromLatLng(_mbglMap->getLatLng());
-}
-
-- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate {
- [self setCenterCoordinate:centerCoordinate animated:NO];
-}
-
-- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate animated:(BOOL)animated {
- [self willChangeValueForKey:@"centerCoordinate"];
- _mbglMap->setLatLng(MGLLatLngFromLocationCoordinate2D(centerCoordinate),
- MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
- [self didChangeValueForKey:@"centerCoordinate"];
-}
-
-- (void)offsetCenterCoordinateBy:(NSPoint)delta animated:(BOOL)animated {
- [self willChangeValueForKey:@"centerCoordinate"];
- _mbglMap->cancelTransitions();
- _mbglMap->moveBy({ delta.x, delta.y },
- MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
- [self didChangeValueForKey:@"centerCoordinate"];
-}
-
-- (double)zoomLevel {
- return _mbglMap->getZoom();
-}
-
-- (void)setZoomLevel:(double)zoomLevel {
- [self setZoomLevel:zoomLevel animated:NO];
-}
-
-- (void)setZoomLevel:(double)zoomLevel animated:(BOOL)animated {
- _mbglMap->setZoom(zoomLevel, MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
-}
-
-- (void)scaleBy:(double)scaleFactor atPoint:(NSPoint)point animated:(BOOL)animated {
- [self willChangeValueForKey:@"zoomLevel"];
- mbgl::PrecisionPoint center(point.x, point.y);
- _mbglMap->scaleBy(scaleFactor, center, MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
- [self didChangeValueForKey:@"zoomLevel"];
-}
-
-- (double)maximumZoomLevel {
- return _mbglMap->getMaxZoom();
-}
-
-- (double)minimumZoomLevel {
- return _mbglMap->getMinZoom();
-}
-
-- (IBAction)zoomInOrOut:(NSSegmentedControl *)sender {
- switch (sender.selectedSegment) {
- case 0:
- [self moveToEndOfParagraph:sender];
- break;
- case 1:
- [self moveToBeginningOfParagraph:sender];
- break;
- default:
- break;
- }
-}
-
-- (CLLocationDirection)direction {
- return mbgl::util::wrap(_mbglMap->getBearing(), 0., 360.);
-}
-
-- (void)setDirection:(CLLocationDirection)direction {
- [self setDirection:direction animated:NO];
-}
-
-- (void)setDirection:(CLLocationDirection)direction animated:(BOOL)animated {
- [self willChangeValueForKey:@"direction"];
- _mbglMap->setBearing(direction, MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
- [self didChangeValueForKey:@"direction"];
-}
-
-- (void)offsetDirectionBy:(CLLocationDegrees)delta animated:(BOOL)animated {
- [self willChangeValueForKey:@"direction"];
- _mbglMap->cancelTransitions();
- _mbglMap->setBearing(_mbglMap->getBearing() + delta, MGLDurationInSeconds(animated ? MGLAnimationDuration : 0));
- [self didChangeValueForKey:@"direction"];
-}
-
-+ (NSSet *)keyPathsForValuesAffectingVisibleCoordinateBounds {
- return [NSSet setWithObjects:@"centerCoordinate", @"zoomLevel", @"direction", @"bounds", nil];
-}
-
-- (MGLCoordinateBounds)visibleCoordinateBounds {
- return [self convertRectToCoordinateBounds:self.bounds];
-}
-
-- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds {
- [self setVisibleCoordinateBounds:bounds animated:NO];
-}
-
-- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds animated:(BOOL)animated {
- [self setVisibleCoordinateBounds:bounds edgePadding:NSEdgeInsetsZero animated:animated];
-}
-
-- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets animated:(BOOL)animated {
- _mbglMap->cancelTransitions();
-
- mbgl::EdgeInsets mbglInsets = {insets.top, insets.left, insets.bottom, insets.right};
- mbgl::CameraOptions options = _mbglMap->cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), mbglInsets);
- if (animated) {
- options.duration = MGLDurationInSeconds(MGLAnimationDuration);
- }
-
- [self willChangeValueForKey:@"visibleCoordinateBounds"];
- options.transitionFinishFn = ^() {
- [self didChangeValueForKey:@"visibleCoordinateBounds"];
- };
- _mbglMap->easeTo(options);
-}
-
-#pragma mark Mouse events and gestures
-
-- (BOOL)acceptsFirstResponder {
- return YES;
-}
-
-- (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));
-
- NSEventModifierFlags flags = [NSApp currentEvent].modifierFlags;
- if (flags & NSShiftKeyMask) {
- if (!self.zoomEnabled) {
- return;
- }
-
- _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) {
- _mbglMap->cancelTransitions();
-
- if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- _mbglMap->setGestureInProgress(true);
- _directionAtBeginningOfGesture = self.direction;
- _pitchAtBeginningOfGesture = _mbglMap->getPitch();
- } else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
- mbgl::PrecisionPoint center(startPoint.x, startPoint.y);
- if (self.rotateEnabled) {
- CLLocationDirection newDirection = _directionAtBeginningOfGesture - delta.x / 10;
- [self willChangeValueForKey:@"direction"];
- _mbglMap->setBearing(newDirection, center);
- [self didChangeValueForKey:@"direction"];
- }
- if (self.pitchEnabled) {
- _mbglMap->setPitch(_pitchAtBeginningOfGesture + delta.y / 5);
- }
- } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
- || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
- _mbglMap->setGestureInProgress(false);
- }
- } else if (self.scrollEnabled) {
- _mbglMap->cancelTransitions();
-
- if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- [self.window invalidateCursorRectsForView:self];
- _mbglMap->setGestureInProgress(true);
- } else 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];
- }
- }
-}
-
-- (void)handleMagnificationGesture:(NSMagnificationGestureRecognizer *)gestureRecognizer {
- if (!self.zoomEnabled) {
- return;
- }
-
- _mbglMap->cancelTransitions();
-
- if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- _mbglMap->setGestureInProgress(true);
- _scaleAtBeginningOfGesture = _mbglMap->getScale();
- } else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
- NSPoint zoomInPoint = [gestureRecognizer locationInView:self];
- mbgl::PrecisionPoint center(zoomInPoint.x, self.bounds.size.height - zoomInPoint.y);
- if (gestureRecognizer.magnification > -1) {
- [self willChangeValueForKey:@"zoomLevel"];
- [self willChangeValueForKey:@"centerCoordinate"];
- _mbglMap->setScale(_scaleAtBeginningOfGesture * (1 + gestureRecognizer.magnification), center);
- [self didChangeValueForKey:@"centerCoordinate"];
- [self didChangeValueForKey:@"zoomLevel"];
- }
- } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
- || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
- _mbglMap->setGestureInProgress(false);
- }
-}
-
-- (void)handleClickGesture:(NSClickGestureRecognizer *)gestureRecognizer {
- if (gestureRecognizer.state != NSGestureRecognizerStateEnded) {
- return;
- }
-
- NSPoint gesturePoint = [gestureRecognizer locationInView:self];
- MGLAnnotationID hitAnnotationID = [self annotationIDAtPoint:gesturePoint persistingResults:YES];
- if (hitAnnotationID != MGLAnnotationNotFound) {
- if (hitAnnotationID != _selectedAnnotationID) {
- id <MGLAnnotation> annotation = [self annotationWithID:hitAnnotationID];
- NSAssert(annotation, @"Cannot select nonexistent annotation with ID %i", hitAnnotationID);
- [self selectAnnotation:annotation animated:YES];
- }
- } else {
- [self deselectAnnotation:self.selectedAnnotation animated:YES];
- }
-}
-
-- (void)handleSecondaryClickGesture:(NSClickGestureRecognizer *)gestureRecognizer {
- if (!self.zoomEnabled) {
- return;
- }
-
- _mbglMap->cancelTransitions();
-
- NSPoint gesturePoint = [gestureRecognizer locationInView:self];
- [self scaleBy:0.5 atPoint:NSMakePoint(gesturePoint.x, self.bounds.size.height - gesturePoint.y) animated:YES];
-}
-
-- (void)handleDoubleClickGesture:(NSClickGestureRecognizer *)gestureRecognizer {
- if (!self.zoomEnabled) {
- return;
- }
-
- _mbglMap->cancelTransitions();
-
- NSPoint gesturePoint = [gestureRecognizer locationInView:self];
- [self scaleBy:2 atPoint:NSMakePoint(gesturePoint.x, self.bounds.size.height - gesturePoint.y) animated:YES];
-}
-
-- (void)handleRotationGesture:(NSRotationGestureRecognizer *)gestureRecognizer {
- if (!self.rotateEnabled) {
- return;
- }
-
- _mbglMap->cancelTransitions();
-
- if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
- _mbglMap->setGestureInProgress(true);
- _directionAtBeginningOfGesture = self.direction;
- } else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
- NSPoint rotationPoint = [gestureRecognizer locationInView:self];
- mbgl::PrecisionPoint center(rotationPoint.x, rotationPoint.y);
- _mbglMap->setBearing(_directionAtBeginningOfGesture + gestureRecognizer.rotationInDegrees, center);
- } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded
- || gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
- _mbglMap->setGestureInProgress(false);
- }
-}
-
-- (BOOL)wantsScrollEventsForSwipeTrackingOnAxis:(__unused NSEventGestureAxis)axis {
- return YES;
-}
-
-- (void)scrollWheel:(NSEvent *)event {
- // https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#10_7Dragging
- if (event.phase == NSEventPhaseNone && event.momentumPhase == NSEventPhaseNone) {
- // A traditional, vertical scroll wheel zooms instead of panning.
- if (self.zoomEnabled && std::abs(event.scrollingDeltaX) < std::abs(event.scrollingDeltaY)) {
- _mbglMap->cancelTransitions();
-
- [self willChangeValueForKey:@"zoomLevel"];
- [self willChangeValueForKey:@"centerCoordinate"];
- NSPoint gesturePoint = [self convertPoint:event.locationInWindow fromView:nil];
- mbgl::PrecisionPoint center(gesturePoint.x, self.bounds.size.height - gesturePoint.y);
- _mbglMap->scaleBy(exp2(event.scrollingDeltaY / 20), center);
- [self didChangeValueForKey:@"centerCoordinate"];
- [self didChangeValueForKey:@"zoomLevel"];
- }
- } else if (self.scrollEnabled
- && _magnificationGestureRecognizer.state == NSGestureRecognizerStatePossible
- && _rotationGestureRecognizer.state == NSGestureRecognizerStatePossible) {
- _mbglMap->cancelTransitions();
-
- CGFloat x = event.scrollingDeltaX;
- CGFloat y = event.scrollingDeltaY;
- if (x || y) {
- [self offsetCenterCoordinateBy:NSMakePoint(x, y) animated:NO];
- }
-
- if (event.momentumPhase != NSEventPhaseNone) {
- [self offsetCenterCoordinateBy:NSMakePoint(x, y) animated:NO];
- }
- }
-}
-
-#pragma mark Keyboard events
-
-- (void)keyDown:(NSEvent *)event {
- if (event.modifierFlags & NSNumericPadKeyMask) {
- [self interpretKeyEvents:@[event]];
- } else {
- [super keyDown:event];
- }
-}
-
-- (IBAction)moveUp:(__unused id)sender {
- [self offsetCenterCoordinateBy:NSMakePoint(0, MGLKeyPanningIncrement) animated:YES];
-}
-
-- (IBAction)moveDown:(__unused id)sender {
- [self offsetCenterCoordinateBy:NSMakePoint(0, -MGLKeyPanningIncrement) animated:YES];
-}
-
-- (IBAction)moveLeft:(__unused id)sender {
- [self offsetCenterCoordinateBy:NSMakePoint(MGLKeyPanningIncrement, 0) animated:YES];
-}
-
-- (IBAction)moveRight:(__unused id)sender {
- [self offsetCenterCoordinateBy:NSMakePoint(-MGLKeyPanningIncrement, 0) animated:YES];
-}
-
-- (IBAction)moveToBeginningOfParagraph:(__unused id)sender {
- if (self.zoomEnabled) {
- [self scaleBy:2 atPoint:NSZeroPoint animated:YES];
- }
-}
-
-- (IBAction)moveToEndOfParagraph:(__unused id)sender {
- if (self.zoomEnabled) {
- [self scaleBy:0.5 atPoint:NSZeroPoint animated:YES];
- }
-}
-
-- (IBAction)moveWordLeft:(__unused id)sender {
- if (self.rotateEnabled) {
- [self offsetDirectionBy:MGLKeyRotationIncrement animated:YES];
- }
-}
-
-- (IBAction)moveWordRight:(__unused id)sender {
- if (self.rotateEnabled) {
- [self offsetDirectionBy:-MGLKeyRotationIncrement animated:YES];
- }
-}
-
-- (void)setZoomEnabled:(BOOL)zoomEnabled {
- _zoomEnabled = zoomEnabled;
- _zoomControls.enabled = zoomEnabled;
- _zoomControls.hidden = !zoomEnabled;
-}
-
-- (void)setRotateEnabled:(BOOL)rotateEnabled {
- _rotateEnabled = rotateEnabled;
- _compass.enabled = rotateEnabled;
- _compass.hidden = !rotateEnabled;
-}
-
-#pragma mark Ornaments
-
-- (void)updateZoomControls {
- [_zoomControls setEnabled:self.zoomLevel > self.minimumZoomLevel forSegment:0];
- [_zoomControls setEnabled:self.zoomLevel < self.maximumZoomLevel forSegment:1];
-}
-
-- (void)updateCompass {
- _compass.doubleValue = -self.direction;
-}
-
-- (IBAction)rotate:(NSSlider *)sender {
- [self setDirection:-sender.doubleValue animated:YES];
-}
-
-#pragma mark Annotations
-
-- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)annotations {
- if (_annotationContextsByAnnotationID.empty()) {
- return nil;
- }
-
- std::vector<id <MGLAnnotation> > annotations;
- std::transform(_annotationContextsByAnnotationID.begin(),
- _annotationContextsByAnnotationID.end(),
- std::back_inserter(annotations),
- ^ id <MGLAnnotation> (const std::pair<MGLAnnotationID, MGLAnnotationContext> &pair) {
- return pair.second.annotation;
- });
- return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()];
-}
-
-- (id <MGLAnnotation>)annotationWithID:(MGLAnnotationID)annotationID {
- if (!_annotationContextsByAnnotationID.count(annotationID)) {
- return nil;
- }
-
- MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationID[annotationID];
- return annotationContext.annotation;
-}
-
-- (MGLAnnotationID)annotationIDForAnnotation:(id <MGLAnnotation>)annotation {
- if (!annotation) {
- return MGLAnnotationNotFound;
- }
-
- for (auto &pair : _annotationContextsByAnnotationID) {
- if (pair.second.annotation == annotation) {
- return pair.first;
- }
- }
- return MGLAnnotationNotFound;
-}
-
-- (void)addAnnotation:(id <MGLAnnotation>)annotation {
- if (annotation) {
- [self addAnnotations:@[annotation]];
- }
-}
-
-- (void)addAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations {
- if (!annotations) {
- return;
- }
-
- BOOL delegateHasImagesForAnnotations = [self.delegate respondsToSelector:@selector(mapView:imageForAnnotation:)];
-
- std::vector<mbgl::PointAnnotation> points;
- std::vector<mbgl::ShapeAnnotation> shapes;
-
- for (id <MGLAnnotation> annotation in annotations) {
- NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
-
- if ([annotation isKindOfClass:[MGLMultiPoint class]]) {
- [(MGLMultiPoint *)annotation addShapeAnnotationObjectToCollection:shapes withDelegate:self];
- } else {
- MGLAnnotationImage *annotationImage = nil;
- if (delegateHasImagesForAnnotations) {
- annotationImage = [self.delegate mapView:self imageForAnnotation:annotation];
- }
- if (!annotationImage) {
- annotationImage = [self dequeueReusableAnnotationImageWithIdentifier:MGLDefaultStyleMarkerSymbolName];
- }
- if (!annotationImage) {
- NSImage *image = MGLDefaultMarkerImage();
- NSRect alignmentRect = image.alignmentRect;
- alignmentRect.origin.y = NSMidY(alignmentRect);
- alignmentRect.size.height /= 2;
- image.alignmentRect = alignmentRect;
- annotationImage = [MGLAnnotationImage annotationImageWithImage:image
- reuseIdentifier:MGLDefaultStyleMarkerSymbolName];
- }
-
- if (!self.annotationImagesByIdentifier[annotationImage.reuseIdentifier]) {
- self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage;
- [self installAnnotationImage:annotationImage];
- }
-
- NSString *symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
- points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName ? [symbolName UTF8String] : "");
-
- if (annotation.toolTip.length) {
- _wantsToolTipRects = YES;
- }
- }
- }
-
- if (points.size()) {
- std::vector<MGLAnnotationID> pointAnnotationIDs = _mbglMap->addPointAnnotations(points);
-
- for (size_t i = 0; i < pointAnnotationIDs.size(); ++i) {
- MGLAnnotationContext context;
- context.annotation = annotations[i];
- context.symbolIdentifier = @(points[i].icon.c_str());
- _annotationContextsByAnnotationID[pointAnnotationIDs[i]] = context;
- }
- }
-
- if (shapes.size()) {
- std::vector<MGLAnnotationID> shapeAnnotationIDs = _mbglMap->addShapeAnnotations(shapes);
-
- for (size_t i = 0; i < shapeAnnotationIDs.size(); ++i) {
- MGLAnnotationContext context;
- context.annotation = annotations[i];
- _annotationContextsByAnnotationID[shapeAnnotationIDs[i]] = context;
- }
- }
-
- [self updateAnnotationTrackingAreas];
-}
-
-- (void)installAnnotationImage:(MGLAnnotationImage *)annotationImage {
- NSImage *image = annotationImage.image;
- NSSize size = image.size;
- if (size.width < 1 || size.height < 1 || !image.valid) {
- return;
- }
-
- // http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431
- [image lockFocus];
- NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, size }];
- [image unlockFocus];
-
- std::string pixelString((const char *)rep.bitmapData, rep.pixelsWide * rep.pixelsHigh * 4 /* RGBA */);
- auto cSpriteImage = std::make_shared<mbgl::SpriteImage>((uint16_t)rep.size.width,
- (uint16_t)rep.size.height,
- (float)(rep.pixelsWide / size.width),
- std::move(pixelString));
- NSString *symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
- _mbglMap->addAnnotationIcon(symbolName.UTF8String, cSpriteImage);
-
- // Create a slop area with a “radius” equal to the annotation image’s entire
- // size, allowing the eventual click to be on any point within this image.
- // Union this slop area with any existing slop areas.
- _unionedAnnotationImageSize = NSMakeSize(MAX(_unionedAnnotationImageSize.width, size.width),
- MAX(_unionedAnnotationImageSize.height, size.height));
-
- if (annotationImage.cursor) {
- _wantsCursorRects = YES;
- }
-}
-
-- (void)removeAnnotation:(id <MGLAnnotation>)annotation {
- if (annotation) {
- [self removeAnnotations:@[annotation]];
- }
-}
-
-- (void)removeAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations {
- if (!annotations) {
- return;
- }
-
- std::vector<MGLAnnotationID> annotationIDsToRemove;
- annotationIDsToRemove.reserve(annotations.count);
-
- for (id <MGLAnnotation> annotation in annotations) {
- NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
-
- MGLAnnotationID annotationID = [self annotationIDForAnnotation:annotation];
- NSAssert(annotationID != MGLAnnotationNotFound, @"No ID for annotation %@", annotation);
- annotationIDsToRemove.push_back(annotationID);
-
- _annotationContextsByAnnotationID.erase(annotationID);
-
- if (annotationID == _selectedAnnotationID) {
- [self deselectAnnotation:annotation animated:NO];
- }
-
- if (annotationID == _lastSelectedAnnotationID) {
- _lastSelectedAnnotationID = MGLAnnotationNotFound;
- }
- }
-
- _mbglMap->removeAnnotations(annotationIDsToRemove);
-
- [self updateAnnotationTrackingAreas];
-}
-
-- (id <MGLAnnotation>)selectedAnnotation {
- if (!_annotationContextsByAnnotationID.count(_selectedAnnotationID)) {
- return nil;
- }
- MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationID.at(_selectedAnnotationID);
- return annotationContext.annotation;
-}
-
-- (nullable MGLAnnotationImage *)dequeueReusableAnnotationImageWithIdentifier:(NSString *)identifier {
- if ([identifier hasPrefix:MGLAnnotationSpritePrefix]) {
- identifier = [identifier substringFromIndex:MGLAnnotationSpritePrefix.length];
- }
- 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);
- std::vector<MGLAnnotationID> nearbyAnnotations = [self annotationIDsInRect:queryRect];
-
- 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;
-}
-
-- (std::vector<MGLAnnotationID>)annotationIDsInRect:(NSRect)rect {
- mbgl::LatLngBounds queryBounds = [self convertRectToLatLngBounds:rect];
- return _mbglMap->getPointAnnotationsInBounds(queryBounds);
-}
-
-- (NS_ARRAY_OF(id <MGLAnnotation>) *)selectedAnnotations {
- id <MGLAnnotation> selectedAnnotation = self.selectedAnnotation;
- return selectedAnnotation ? @[selectedAnnotation] : @[];
-}
-
-- (void)setSelectedAnnotation:(id <MGLAnnotation>)selectedAnnotation {
- _selectedAnnotationID = [self annotationIDForAnnotation:selectedAnnotation];
-}
-
-- (void)setSelectedAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)selectedAnnotations {
- if (!selectedAnnotations.count) {
- return;
- }
-
- id <MGLAnnotation> firstAnnotation = selectedAnnotations[0];
- NSAssert([firstAnnotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
- if ([firstAnnotation isKindOfClass:[MGLMultiPoint class]]) {
- return;
- }
-
- if (MGLCoordinateInCoordinateBounds(firstAnnotation.coordinate, self.visibleCoordinateBounds)) {
- [self selectAnnotation:firstAnnotation animated:NO];
- }
-}
-
-- (void)selectAnnotation:(id <MGLAnnotation>)annotation animated:(BOOL)animated
-{
- if (!annotation || [annotation isKindOfClass:[MGLMultiPoint class]]) {
- return;
- }
-
- id <MGLAnnotation> selectedAnnotation = self.selectedAnnotation;
- if (annotation == selectedAnnotation) {
- return;
- }
-
- [self deselectAnnotation:selectedAnnotation animated:NO];
-
- MGLAnnotationID annotationID = [self annotationIDForAnnotation:annotation];
- if (annotationID == MGLAnnotationNotFound) {
- [self addAnnotation:annotation];
- }
-
- NSRect positioningRect = [self positioningRectForCalloutForAnnotationWithID:annotationID];
- if (NSIsEmptyRect(NSIntersectionRect(positioningRect, self.bounds))) {
- return;
- }
-
- [self willChangeValueForKey:@"selectedAnnotation"];
- _selectedAnnotationID = annotationID;
- _lastSelectedAnnotationID = _selectedAnnotationID;
- [self didChangeValueForKey:@"selectedAnnotation"];
-
- if ([annotation respondsToSelector:@selector(title)]
- && annotation.title
- && !self.calloutForSelectedAnnotation.shown
- && [self.delegate respondsToSelector:@selector(mapView:annotationCanShowCallout:)]
- && [self.delegate mapView:self annotationCanShowCallout:annotation]) {
- NSPopover *callout = [self calloutForAnnotation:annotation];
- callout.animates = animated;
-
- callout.delegate = self;
- self.calloutForSelectedAnnotation = callout;
- NSRectEdge edge = (self.userInterfaceLayoutDirection == NSUserInterfaceLayoutDirectionRightToLeft
- ? NSMinXEdge
- : NSMaxXEdge);
- [callout showRelativeToRect:positioningRect ofView:self preferredEdge:edge];
- }
-}
-
-- (NSPopover *)calloutForAnnotation:(id <MGLAnnotation>)annotation {
- NSPopover *callout = [[NSPopover alloc] init];
- callout.behavior = NSPopoverBehaviorTransient;
-
- NSViewController *viewController;
- if ([self.delegate respondsToSelector:@selector(mapView:calloutViewControllerForAnnotation:)]) {
- viewController = [self.delegate mapView:self calloutViewControllerForAnnotation:annotation];
- }
- if (!viewController) {
- viewController = [[NSViewController alloc] initWithNibName:@"MGLAnnotationCallout"
- bundle:[NSBundle mgl_resourceBundle]];
- }
- NSAssert(viewController, @"Unable to load MGLAnnotationCallout view controller");
- viewController.representedObject = annotation;
- callout.contentViewController = viewController;
-
- return callout;
-}
-
-- (NSRect)positioningRectForCalloutForAnnotationWithID:(MGLAnnotationID)annotationID {
- id <MGLAnnotation> annotation = [self annotationWithID:annotationID];
- if (!annotation) {
- return NSZeroRect;
- }
- NSImage *image = [self imageOfAnnotationWithID:annotationID].image;
- if (!image) {
- return NSZeroRect;
- }
-
- NSRect positioningRect = [self frameOfImage:image centeredAtCoordinate:annotation.coordinate];
- positioningRect = NSOffsetRect(image.alignmentRect, positioningRect.origin.x, positioningRect.origin.y);
- return NSInsetRect(positioningRect, -MGLAnnotationImagePaddingForCallout,
- -MGLAnnotationImagePaddingForCallout);
-}
-
-- (NSRect)frameOfImage:(NSImage *)image centeredAtCoordinate:(CLLocationCoordinate2D)coordinate {
- NSPoint calloutAnchorPoint = [self convertCoordinate:coordinate toPointToView:self];
- return NSInsetRect({ calloutAnchorPoint, NSZeroSize }, -image.size.width / 2, -image.size.height / 2);
-}
-
-- (MGLAnnotationImage *)imageOfAnnotationWithID:(MGLAnnotationID)annotationID {
- if (annotationID == MGLAnnotationNotFound
- || _annotationContextsByAnnotationID.count(annotationID) == 0) {
- return nil;
- }
-
- NSString *customSymbol = _annotationContextsByAnnotationID.at(annotationID).symbolIdentifier;
- NSString *symbolName = customSymbol.length ? customSymbol : MGLDefaultStyleMarkerSymbolName;
-
- return [self dequeueReusableAnnotationImageWithIdentifier:symbolName];
-}
-
-- (void)deselectAnnotation:(id <MGLAnnotation>)annotation animated:(BOOL)animated {
- if (!annotation || self.selectedAnnotation != annotation) {
- return;
- }
-
- NSPopover *callout = self.calloutForSelectedAnnotation;
- callout.animates = animated;
- [callout performClose:self];
-
- self.selectedAnnotation = nil;
-}
-
-- (void)updateAnnotationCallouts {
- NSPopover *callout = self.calloutForSelectedAnnotation;
- if (callout) {
- callout.positioningRect = [self positioningRectForCalloutForAnnotationWithID:_selectedAnnotationID];
- }
-}
-
-#pragma mark MGLMultiPointDelegate methods
-
-- (double)alphaForShapeAnnotation:(MGLShape *)annotation {
- if (_delegateHasAlphasForShapeAnnotations) {
- return [self.delegate mapView:self alphaForShapeAnnotation:annotation];
- }
- return 1.0;
-}
-
-- (mbgl::Color)strokeColorForShapeAnnotation:(MGLShape *)annotation {
- NSColor *color = (_delegateHasStrokeColorsForShapeAnnotations
- ? [self.delegate mapView:self strokeColorForShapeAnnotation:annotation]
- : [NSColor blackColor]);
- return MGLColorObjectFromNSColor(color);
-}
-
-- (mbgl::Color)fillColorForPolygonAnnotation:(MGLPolygon *)annotation {
- NSColor *color = (_delegateHasFillColorsForShapeAnnotations
- ? [self.delegate mapView:self fillColorForPolygonAnnotation:annotation]
- : [NSColor blueColor]);
- return MGLColorObjectFromNSColor(color);
-}
-
-- (CGFloat)lineWidthForPolylineAnnotation:(MGLPolyline *)annotation {
- if (_delegateHasLineWidthsForShapeAnnotations) {
- return [self.delegate mapView:self lineWidthForPolylineAnnotation:(MGLPolyline *)annotation];
- }
- return 3.0;
-}
-
-#pragma mark MGLPopoverDelegate methods
-
-- (void)popoverDidShow:(__unused NSNotification *)notification {
- id <MGLAnnotation> annotation = self.selectedAnnotation;
- if ([self.delegate respondsToSelector:@selector(mapView:didSelectAnnotation:)]) {
- [self.delegate mapView:self didSelectAnnotation:annotation];
- }
-}
-
-- (void)popoverDidClose:(__unused NSNotification *)notification {
- id <MGLAnnotation> annotation = self.calloutForSelectedAnnotation.contentViewController.representedObject;
- self.calloutForSelectedAnnotation = nil;
- self.selectedAnnotation = nil;
-
- if ([self.delegate respondsToSelector:@selector(mapView:didDeselectAnnotation:)]) {
- [self.delegate mapView:self didDeselectAnnotation:annotation];
- }
-}
-
-#pragma mark Overlays
-
-- (void)addOverlay:(id <MGLOverlay>)overlay {
- [self addOverlays:@[overlay]];
-}
-
-- (void)addOverlays:(NS_ARRAY_OF(id <MGLOverlay>) *)overlays
-{
- for (id <MGLOverlay> overlay in overlays) {
- NSAssert([overlay conformsToProtocol:@protocol(MGLOverlay)], @"Overlay does not conform to MGLOverlay");
- }
- [self addAnnotations:overlays];
-}
-
-- (void)removeOverlay:(id <MGLOverlay>)overlay {
- [self removeOverlays:@[overlay]];
-}
-
-- (void)removeOverlays:(NS_ARRAY_OF(id <MGLOverlay>) *)overlays {
- for (id <MGLOverlay> overlay in overlays) {
- NSAssert([overlay conformsToProtocol:@protocol(MGLOverlay)], @"Overlay does not conform to MGLOverlay");
- }
- [self removeAnnotations:overlays];
-}
-
-#pragma mark Tooltips and cursors
-
-- (void)updateAnnotationTrackingAreas {
- if (_wantsToolTipRects) {
- [self removeAllToolTips];
- std::vector<MGLAnnotationID> annotationIDs = [self annotationIDsInRect:self.bounds];
- for (MGLAnnotationID annotationID : annotationIDs) {
- MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithID:annotationID];
- id <MGLAnnotation> annotation = [self annotationWithID:annotationID];
- if (annotation.toolTip.length) {
- NSImage *image = annotationImage.image;
- NSRect annotationRect = [self frameOfImage:image
- centeredAtCoordinate:annotation.coordinate];
- annotationRect = NSOffsetRect(image.alignmentRect, annotationRect.origin.x, annotationRect.origin.y);
- if (!NSIsEmptyRect(annotationRect)) {
- [self addToolTipRect:annotationRect owner:self userData:(void *)(NSUInteger)annotationID];
- }
- }
- if (annotationImage.cursor) {
- _wantsCursorRects = YES;
- }
- }
- }
-
- if (_wantsCursorRects) {
- [self.window invalidateCursorRectsForView:self];
- }
-}
-
-- (NSString *)view:(__unused NSView *)view stringForToolTip:(__unused NSToolTipTag)tag point:(__unused NSPoint)point userData:(void *)data {
- if ((NSUInteger)data >= MGLAnnotationNotFound) {
- return nil;
- }
- MGLAnnotationID annotationID = (NSUInteger)data;
- id <MGLAnnotation> annotation = [self annotationWithID:annotationID];
- return annotation.toolTip;
-}
-
-- (void)resetCursorRects {
- if (_panGestureRecognizer.state == NSGestureRecognizerStateBegan
- || _panGestureRecognizer.state == NSGestureRecognizerStateChanged) {
- [self addCursorRect:self.bounds cursor:[NSCursor closedHandCursor]];
- return;
- }
- if (!_wantsCursorRects) {
- return;
- }
-
- std::vector<MGLAnnotationID> annotationIDs = [self annotationIDsInRect:self.bounds];
- for (MGLAnnotationID annotationID : annotationIDs) {
- id <MGLAnnotation> annotation = [self annotationWithID:annotationID];
- MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithID:annotationID];
- if (annotationImage.cursor) {
- NSImage *image = annotationImage.image;
- NSRect annotationRect = [self frameOfImage:image
- centeredAtCoordinate:annotation.coordinate];
- annotationRect = NSOffsetRect(image.alignmentRect, annotationRect.origin.x, annotationRect.origin.y);
- [self addCursorRect:annotationRect cursor:annotationImage.cursor];
- }
- }
-}
-
-#pragma mark Interface Builder methods
-
-- (void)prepareForInterfaceBuilder {
- [super prepareForInterfaceBuilder];
-
- // Color the background a glorious Mapbox teal.
- self.layer.borderColor = [NSColor colorWithRed:59/255.
- green:178/255.
- blue:208/255.
- alpha:0.8].CGColor;
- self.layer.borderWidth = 2;
- self.layer.backgroundColor = [NSColor colorWithRed:59/255.
- green:178/255.
- blue:208/255.
- alpha:0.6].CGColor;
-
- // Place a playful marker right smack dab in the middle.
- self.layer.contents = MGLDefaultMarkerImage();
- self.layer.contentsGravity = kCAGravityCenter;
- self.layer.contentsScale = [NSScreen mainScreen].backingScaleFactor;
-}
-
-#pragma mark Geometric methods
-
-- (CLLocationCoordinate2D)convertPoint:(NSPoint)point toCoordinateFromView:(nullable NSView *)view {
- return MGLLocationCoordinate2DFromLatLng([self convertPoint:point toLatLngFromView:view]);
-}
-
-- (mbgl::LatLng)convertPoint:(NSPoint)point toLatLngFromView:(nullable NSView *)view {
- NSPoint convertedPoint = [self convertPoint:point fromView:view];
- return _mbglMap->latLngForPixel(mbgl::PrecisionPoint(convertedPoint.x, convertedPoint.y));
-}
-
-- (NSPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(nullable NSView *)view {
- return [self convertLatLng:MGLLatLngFromLocationCoordinate2D(coordinate) toPointToView:view];
-}
-
-- (NSPoint)convertLatLng:(mbgl::LatLng)latLng toPointToView:(nullable NSView *)view {
- mbgl::vec2<double> pixel = _mbglMap->pixelForLatLng(latLng);
- return [self convertPoint:NSMakePoint(pixel.x, pixel.y) toView:view];
-}
-
-- (MGLCoordinateBounds)convertRectToCoordinateBounds:(NSRect)rect {
- return MGLCoordinateBoundsFromLatLngBounds([self convertRectToLatLngBounds:rect]);
-}
-
-- (mbgl::LatLngBounds)convertRectToLatLngBounds:(NSRect)rect {
- mbgl::LatLngBounds bounds = mbgl::LatLngBounds::getExtendable();
- bounds.extend([self convertPoint:rect.origin toLatLngFromView:self]);
- bounds.extend([self convertPoint:{ NSMaxX(rect), NSMinY(rect) } toLatLngFromView:self]);
- bounds.extend([self convertPoint:{ NSMaxX(rect), NSMaxY(rect) } toLatLngFromView:self]);
- bounds.extend([self convertPoint:{ NSMinX(rect), NSMaxY(rect) } toLatLngFromView:self]);
-
- // The world is wrapping if a point just outside the bounds is also within
- // the rect.
- mbgl::LatLng outsideLatLng;
- if (bounds.sw.longitude > -180) {
- outsideLatLng = {
- (bounds.sw.latitude + bounds.ne.latitude) / 2,
- bounds.sw.longitude - 1,
- };
- } else if (bounds.ne.longitude < 180) {
- outsideLatLng = {
- (bounds.sw.latitude + bounds.ne.latitude) / 2,
- bounds.ne.longitude + 1,
- };
- }
-
- // If the world is wrapping, extend the bounds to cover all longitudes.
- if (NSPointInRect([self convertLatLng:outsideLatLng toPointToView:self], rect)) {
- bounds.sw.longitude = -180;
- bounds.ne.longitude = 180;
- }
-
- return bounds;
-}
-
-- (CLLocationDistance)metersPerPixelAtLatitude:(CLLocationDegrees)latitude {
- return _mbglMap->getMetersPerPixelAtLatitude(latitude, self.zoomLevel);
-}
-
-#pragma mark Debugging
-
-- (MGLMapDebugMaskOptions)debugMask {
- mbgl::MapDebugOptions options = _mbglMap->getDebug();
- MGLMapDebugMaskOptions mask = 0;
- if (options & mbgl::MapDebugOptions::TileBorders) {
- mask |= MGLMapDebugTileBoundariesMask;
- }
- if (options & mbgl::MapDebugOptions::ParseStatus) {
- mask |= MGLMapDebugTileInfoMask;
- }
- if (options & mbgl::MapDebugOptions::Timestamps) {
- mask |= MGLMapDebugTimestampsMask;
- }
- if (options & mbgl::MapDebugOptions::Collision) {
- mask |= MGLMapDebugCollisionBoxesMask;
- }
- return mask;
-}
-
-- (void)setDebugMask:(MGLMapDebugMaskOptions)debugMask {
- mbgl::MapDebugOptions options = mbgl::MapDebugOptions::NoDebug;
- if (debugMask & MGLMapDebugTileBoundariesMask) {
- options |= mbgl::MapDebugOptions::TileBorders;
- }
- if (debugMask & MGLMapDebugTileInfoMask) {
- options |= mbgl::MapDebugOptions::ParseStatus;
- }
- if (debugMask & MGLMapDebugTimestampsMask) {
- options |= mbgl::MapDebugOptions::Timestamps;
- }
- if (debugMask & MGLMapDebugCollisionBoxesMask) {
- options |= mbgl::MapDebugOptions::Collision;
- }
- _mbglMap->setDebug(options);
-}
-
-class MGLMapViewImpl : public mbgl::View {
-public:
- MGLMapViewImpl(MGLMapView *nativeView_, const float scaleFactor_)
- : nativeView(nativeView_), scaleFactor(scaleFactor_) {}
- virtual ~MGLMapViewImpl() {}
-
-
- float getPixelRatio() const override {
- return scaleFactor;
- }
-
- std::array<uint16_t, 2> getSize() const override {
- return {{ static_cast<uint16_t>(nativeView.bounds.size.width),
- static_cast<uint16_t>(nativeView.bounds.size.height) }};
- }
-
- std::array<uint16_t, 2> getFramebufferSize() const override {
- NSRect bounds = [nativeView convertRectToBacking:nativeView.bounds];
- return {{ static_cast<uint16_t>(bounds.size.width),
- static_cast<uint16_t>(bounds.size.height) }};
- }
-
- void notify() override {}
-
- void notifyMapChange(mbgl::MapChange change) override {
- assert([[NSThread currentThread] isMainThread]);
- [nativeView notifyMapChange:change];
- }
-
- void activate() override {
- MGLOpenGLLayer *layer = (MGLOpenGLLayer *)nativeView.layer;
- if ([NSOpenGLContext currentContext] != layer.openGLContext) {
- [layer.openGLContext makeCurrentContext];
-
- mbgl::gl::InitializeExtensions([](const char *name) {
- static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- if (!framework) {
- throw std::runtime_error("Failed to load OpenGL framework.");
- }
-
- CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
- void *symbol = CFBundleGetFunctionPointerForName(framework, str);
- CFRelease(str);
-
- return reinterpret_cast<mbgl::gl::glProc>(symbol);
- });
- }
- }
-
- void deactivate() override {
- [NSOpenGLContext clearCurrentContext];
- }
-
- void invalidate() override {
- [nativeView performSelectorOnMainThread:@selector(invalidate)
- withObject:nil
- waitUntilDone:NO];
- }
-
- void beforeRender() override {
- activate();
- }
-
- void afterRender() override {}
-
-private:
- __weak MGLMapView *nativeView = nullptr;
- const float scaleFactor;
-};
-
-@end
diff --git a/platform/osx/sdk/MGLMapView_Private.h b/platform/osx/sdk/MGLMapView_Private.h
deleted file mode 100644
index 3b37ce24b4..0000000000
--- a/platform/osx/sdk/MGLMapView_Private.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#import <mbgl/osx/MGLMapView.h>
-
-@interface MGLMapView (Private)
-
-@property (nonatomic, readonly, getter=isDormant) BOOL dormant;
-
-@property (nonatomic) CLLocationDegrees pendingLatitude;
-@property (nonatomic) CLLocationDegrees pendingLongitude;
-
-- (void)renderSync;
-
-@end
diff --git a/platform/osx/sdk/MGLOpenGLLayer.h b/platform/osx/sdk/MGLOpenGLLayer.h
deleted file mode 100644
index 9429b01bb5..0000000000
--- a/platform/osx/sdk/MGLOpenGLLayer.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#import <Cocoa/Cocoa.h>
-
-#import "MGLTypes.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface MGLOpenGLLayer : NSOpenGLLayer
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/platform/osx/sdk/MGLOpenGLLayer.mm b/platform/osx/sdk/MGLOpenGLLayer.mm
deleted file mode 100644
index 06a7be961c..0000000000
--- a/platform/osx/sdk/MGLOpenGLLayer.mm
+++ /dev/null
@@ -1,49 +0,0 @@
-#import "MGLOpenGLLayer.h"
-
-#import "MGLMapView_Private.h"
-
-#import <mbgl/platform/gl.hpp>
-
-@implementation MGLOpenGLLayer
-
-- (MGLMapView *)mapView {
- return (MGLMapView *)super.view;
-}
-
-//- (BOOL)isAsynchronous {
-// return YES;
-//}
-
-- (BOOL)needsDisplayOnBoundsChange {
- return YES;
-}
-
-- (CGRect)frame {
- return self.view.bounds;
-}
-
-- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask {
- NSOpenGLPixelFormatAttribute pfas[] = {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAClosestPolicy,
- NSOpenGLPFAAccumSize, 32,
- NSOpenGLPFAColorSize, 24,
- NSOpenGLPFAAlphaSize, 8,
- NSOpenGLPFADepthSize, 16,
- NSOpenGLPFAStencilSize, 8,
- NSOpenGLPFAScreenMask, mask,
- 0
- };
- return [[NSOpenGLPixelFormat alloc] initWithAttributes:pfas];
-}
-
-- (BOOL)canDrawInOpenGLContext:(__unused NSOpenGLContext *)context pixelFormat:(__unused NSOpenGLPixelFormat *)pixelFormat forLayerTime:(__unused CFTimeInterval)t displayTime:(__unused const CVTimeStamp *)ts {
- return !self.mapView.dormant;
-}
-
-- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat forLayerTime:(CFTimeInterval)t displayTime:(const CVTimeStamp *)ts {
- [self.mapView renderSync];
- [super drawInOpenGLContext:context pixelFormat:pixelFormat forLayerTime:t displayTime:ts];
-}
-
-@end
diff --git a/platform/osx/sdk/Mapbox.m b/platform/osx/sdk/Mapbox.m
new file mode 100644
index 0000000000..08d12579fe
--- /dev/null
+++ b/platform/osx/sdk/Mapbox.m
@@ -0,0 +1,27 @@
+#import <mbgl/osx/Mapbox.h>
+
+#import "../src/NSBundle+MGLAdditions.h"
+#import "../src/NSProcessInfo+MGLAdditions.h"
+#import "../../darwin/NSString+MGLAdditions.h"
+
+__attribute__((constructor))
+static void InitializeMapbox() {
+ static int initialized = 0;
+ if (initialized) {
+ return;
+ }
+
+ mgl_linkBundleCategory();
+ mgl_linkStringCategory();
+ mgl_linkProcessInfoCategory();
+
+ [MGLAccountManager class];
+ [MGLAnnotationImage class];
+ [MGLMapView class];
+ [MGLMultiPoint class];
+ [MGLPointAnnotation class];
+ [MGLPolygon class];
+ [MGLPolyline class];
+ [MGLShape class];
+ [MGLStyle class];
+}
diff --git a/platform/osx/sdk/NSBundle+MGLAdditions.h b/platform/osx/sdk/NSBundle+MGLAdditions.h
deleted file mode 100644
index c09ba38a5d..0000000000
--- a/platform/osx/sdk/NSBundle+MGLAdditions.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLTypes.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-void mgl_linkBundleCategory();
-
-@interface NSBundle (MGLAdditions)
-
-+ (instancetype)mgl_resourceBundle;
-+ (NSString *)mgl_resourceBundlePath;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/platform/osx/sdk/NSBundle+MGLAdditions.m b/platform/osx/sdk/NSBundle+MGLAdditions.m
deleted file mode 100644
index a53802c343..0000000000
--- a/platform/osx/sdk/NSBundle+MGLAdditions.m
+++ /dev/null
@@ -1,22 +0,0 @@
-#import "NSBundle+MGLAdditions.h"
-
-#import "MGLAccountManager.h"
-
-void mgl_linkBundleCategory() {}
-
-@implementation NSBundle (MGLAdditions)
-
-+ (instancetype)mgl_resourceBundle {
- return [self bundleWithPath:[self mgl_resourceBundlePath]];
-}
-
-+ (NSString *)mgl_resourceBundlePath {
- NSString *resourceBundlePath = [[self bundleForClass:[MGLAccountManager class]]
- pathForResource:@"Mapbox" ofType:@"bundle"];
- if (!resourceBundlePath) {
- resourceBundlePath = [[self mainBundle] bundlePath];
- }
- return resourceBundlePath;
-}
-
-@end
diff --git a/platform/osx/sdk/NSProcessInfo+MGLAdditions.h b/platform/osx/sdk/NSProcessInfo+MGLAdditions.h
deleted file mode 100644
index 6b34f54756..0000000000
--- a/platform/osx/sdk/NSProcessInfo+MGLAdditions.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#import <Foundation/Foundation.h>
-
-void mgl_linkProcessInfoCategory();
-
-@interface NSProcessInfo (MGLAdditions)
-
-- (BOOL)mgl_isInterfaceBuilderDesignablesAgent;
-
-@end
diff --git a/platform/osx/sdk/NSProcessInfo+MGLAdditions.m b/platform/osx/sdk/NSProcessInfo+MGLAdditions.m
deleted file mode 100644
index 16f869703c..0000000000
--- a/platform/osx/sdk/NSProcessInfo+MGLAdditions.m
+++ /dev/null
@@ -1,11 +0,0 @@
-#import "NSProcessInfo+MGLAdditions.h"
-
-void mgl_linkProcessInfoCategory() {}
-
-@implementation NSProcessInfo (MGLAdditions)
-
-- (BOOL)mgl_isInterfaceBuilderDesignablesAgent {
- return [self.processName isEqualToString:@"IBDesignablesAgent"];
-}
-
-@end
diff --git a/platform/osx/sdk/framework-osx.gypi b/platform/osx/sdk/framework-osx.gypi
new file mode 100644
index 0000000000..0c7c89d3ec
--- /dev/null
+++ b/platform/osx/sdk/framework-osx.gypi
@@ -0,0 +1,46 @@
+{
+ 'includes': [
+ '../../../gyp/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'osxsdk',
+ 'product_name': 'Mapbox',
+ 'type': 'shared_library',
+ 'mac_bundle': 1,
+
+ 'dependencies': [
+ 'mbgl.gyp:core',
+ 'mbgl.gyp:platform-<(platform_lib)',
+ 'mbgl.gyp:http-<(http_lib)',
+ 'mbgl.gyp:asset-<(asset_lib)',
+ 'mbgl.gyp:cache-<(cache_lib)',
+ ],
+
+ 'xcode_settings': {
+ 'SDKROOT': 'macosx',
+ 'SUPPORTED_PLATFORMS':'macosx',
+ 'OTHER_LDFLAGS': [ '-stdlib=libc++', '-lstdc++' ],
+ 'INSTALL_PATH': '@executable_path/../Frameworks',
+ 'INFOPLIST_FILE': '../platform/osx/sdk/Info.plist',
+ 'CLANG_ENABLE_OBJC_ARC': 'YES',
+ 'PRODUCT_BUNDLE_IDENTIFIER': 'com.mapbox.MapboxGL',
+ },
+
+ 'mac_framework_headers': [
+ '<!@(find ../include/mbgl/{darwin,osx} -type f \! -name \'.*\')',
+ ],
+
+ 'sources': [
+ './Mapbox.m',
+ ],
+
+ 'direct_dependent_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework',
+ '$(SDKROOT)/System/Library/Frameworks/CoreLocation.framework',
+ ],
+ },
+ },
+ ]
+}
diff --git a/platform/osx/sdk/resources/MGLAnnotationCallout.xib b/platform/osx/sdk/resources/MGLAnnotationCallout.xib
deleted file mode 100644
index edf84a26a7..0000000000
--- a/platform/osx/sdk/resources/MGLAnnotationCallout.xib
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
- <dependencies>
- <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
- </dependencies>
- <objects>
- <customObject id="-2" userLabel="File's Owner" customClass="NSViewController">
- <connections>
- <outlet property="view" destination="c22-O7-iKe" id="QAM-0O-WIj"/>
- </connections>
- </customObject>
- <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
- <customObject id="-3" userLabel="Application" customClass="NSObject"/>
- <customView id="c22-O7-iKe">
- <rect key="frame" x="0.0" y="0.0" width="270" height="50"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <subviews>
- <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="k5x-ao-Pz3">
- <rect key="frame" x="18" y="25" width="234" height="17"/>
- <textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" title="Title" id="nVE-Zi-KcG">
- <font key="font" metaFont="system"/>
- <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- <connections>
- <binding destination="-2" name="value" keyPath="representedObject.title" id="3nD-YS-gzq"/>
- </connections>
- </textField>
- <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e9C-Ve-ccw">
- <rect key="frame" x="18" y="8" width="234" height="14"/>
- <textFieldCell key="cell" controlSize="small" selectable="YES" sendsActionOnEndEditing="YES" title="Subtitle" id="eKw-tQ-dw8">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- <connections>
- <binding destination="-2" name="value" keyPath="representedObject.subtitle" id="RQf-48-DyH"/>
- </connections>
- </textField>
- </subviews>
- <constraints>
- <constraint firstItem="e9C-Ve-ccw" firstAttribute="leading" secondItem="k5x-ao-Pz3" secondAttribute="leading" id="ApT-ew-CYb"/>
- <constraint firstAttribute="bottom" secondItem="e9C-Ve-ccw" secondAttribute="bottom" constant="8" id="CWV-Dd-8oi"/>
- <constraint firstItem="k5x-ao-Pz3" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="20" id="UUL-GB-Jtv"/>
- <constraint firstItem="e9C-Ve-ccw" firstAttribute="top" secondItem="k5x-ao-Pz3" secondAttribute="bottom" constant="3" id="Urc-wn-m8X"/>
- <constraint firstItem="e9C-Ve-ccw" firstAttribute="trailing" secondItem="k5x-ao-Pz3" secondAttribute="trailing" id="gss-6G-9GF"/>
- <constraint firstAttribute="trailing" secondItem="k5x-ao-Pz3" secondAttribute="trailing" constant="20" id="xCZ-s9-HaP"/>
- <constraint firstItem="k5x-ao-Pz3" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" constant="8" id="xcm-oY-jjy"/>
- </constraints>
- <point key="canvasLocation" x="257" y="355"/>
- </customView>
- </objects>
-</document>
diff --git a/platform/osx/sdk/resources/default_marker.pdf b/platform/osx/sdk/resources/default_marker.pdf
deleted file mode 100644
index 4e2e332301..0000000000
--- a/platform/osx/sdk/resources/default_marker.pdf
+++ /dev/null
Binary files differ
diff --git a/platform/osx/sdk/resources/mapbox.pdf b/platform/osx/sdk/resources/mapbox.pdf
deleted file mode 100644
index c08a0e3135..0000000000
--- a/platform/osx/sdk/resources/mapbox.pdf
+++ /dev/null
Binary files differ