From 9a79f348fa4262c557a3b2dac5e54c37efde9fbc Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 14 May 2014 11:42:52 -0700 Subject: move debug app over to use of Cocoa API --- .gitmodules | 3 + ios/MBXViewController.mm | 354 +++++------------------------------------------ ios/MVKMapKit | 1 + ios/llmr-app.gyp | 2 + 4 files changed, 38 insertions(+), 322 deletions(-) create mode 100644 .gitmodules create mode 160000 ios/MVKMapKit diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..37a988d2ba --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ios/MVKMapKit"] + path = ios/MVKMapKit + url = git@github.com:mapbox/MVKMapKit.git diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index 9c4b5d2fe8..6cad26762b 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -1,24 +1,14 @@ #import "MBXViewController.h" +#import "MVKMapView.h" + #import "../common/settings_nsuserdefaults.hpp" -#import "../common/foundation_request.h" -#import -#import -#import #import -#include -#include -#include - -@interface MBXViewController () +@interface MBXViewController () -@property (nonatomic) EAGLContext *context; -@property (nonatomic) CGPoint center; -@property (nonatomic) CGFloat scale; -@property (nonatomic) CGFloat angle; -@property (nonatomic) CGFloat quickZoomStart; +@property (nonatomic) MVKMapView *mapView; @property (nonatomic) BOOL debug; @property (nonatomic) UIView *palette; @property (nonatomic) CLLocationManager *locationManager; @@ -27,12 +17,7 @@ @implementation MBXViewController -class View; - -llmr::Map *map = nullptr; -View *viewObj = nullptr; llmr::Settings_NSUserDefaults *settings = nullptr; -MBXViewController *viewController = nullptr; #pragma mark - Setup @@ -49,110 +34,52 @@ MBXViewController *viewController = nullptr; return self; } -- (void)loadView -{ - [super loadView]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) - { - NSLog(@"Failed to create OpenGL ES context"); - } - - GLKView *view = [[GLKView alloc] initWithFrame:[[UIScreen mainScreen] bounds] context:self.context]; - view.enableSetNeedsDisplay = NO; - view.drawableStencilFormat = GLKViewDrawableStencilFormat8; - view.drawableDepthFormat = GLKViewDrawableDepthFormat16; - [view bindDrawable]; - - self.view = view; -} - - (void)viewDidLoad { [super viewDidLoad]; - [self setupMap]; - [self setupInteraction]; + self.mapView = [[MVKMapView alloc] initWithFrame:self.view.bounds]; + self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.view addSubview:self.mapView]; + + settings = new llmr::Settings_NSUserDefaults(); + [self restoreState]; + [self setupDebugUI]; self.locationManager = [CLLocationManager new]; self.locationManager.delegate = self; - - map->start(); -} - -- (void)setupMap -{ - viewObj = new View(self); - map = new llmr::Map(*viewObj); - - // Load settings - settings = new llmr::Settings_NSUserDefaults(); - [self restoreState]; } - (void)saveState { - if (map && settings) + if (self.mapView && settings) { - map->getLonLatZoom(settings->longitude, settings->latitude, settings->zoom); - settings->angle = map->getAngle(); - settings->debug = map->getDebug(); + settings->longitude = self.mapView.centerCoordinate.longitude; + settings->latitude = self.mapView.centerCoordinate.latitude; + settings->zoom = self.mapView.zoomLevel; + settings->angle = self.mapView.direction; + settings->debug = self.mapView.isDebugActive; settings->save(); } } - (void)restoreState { - if (map && settings) { + if (self.mapView && settings) { settings->load(); - map->setLonLatZoom(settings->longitude, settings->latitude, settings->zoom); - map->setAngle(settings->angle); - map->setDebug(settings->debug); + [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(settings->latitude, settings->longitude) zoomLevel:settings->zoom animated:NO]; + self.mapView.direction = settings->angle; + [self.mapView setDebugActive:settings->debug]; } } -- (void)setupInteraction +- (void)setupDebugUI { - UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; - pan.delegate = self; - [self.view addGestureRecognizer:pan]; - - UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)]; - pinch.delegate = self; - [self.view addGestureRecognizer:pinch]; - - UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotateGesture:)]; - rotate.delegate = self; - [self.view addGestureRecognizer:rotate]; - UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapGesture:)]; singleTap.numberOfTapsRequired = 1; - [self.view addGestureRecognizer:singleTap]; - - UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTapGesture:)]; - doubleTap.numberOfTapsRequired = 2; - [self.view addGestureRecognizer:doubleTap]; - - [singleTap requireGestureRecognizerToFail:doubleTap]; + [self.mapView addGestureRecognizer:singleTap]; - UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTapGesture:)]; - twoFingerTap.numberOfTouchesRequired = 2; - [self.view addGestureRecognizer:twoFingerTap]; - - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) - { - UILongPressGestureRecognizer *quickZoom = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleQuickZoomGesture:)]; - quickZoom.numberOfTapsRequired = 1; - quickZoom.minimumPressDuration = 0.25; - [self.view addGestureRecognizer:quickZoom]; - } -} - -- (void)setupDebugUI -{ NSArray *selectorNames = @[ @"unrotate", @"resetPosition", @"toggleDebug", @"toggleRaster", @"locateUser" ]; CGFloat buttonSize = 40; CGFloat bufferSize = 20; @@ -182,32 +109,19 @@ MBXViewController *viewController = nullptr; - (NSUInteger)supportedInterfaceOrientations { - // We support everything; it's up to the embedding application to limit the orientations. return UIInterfaceOrientationMaskAll; } -#pragma mark - Rendering delegates +#pragma mark - Debugging UI -- (void)swap +- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap { - if (map->needsSwap()) + if (singleTap.state == UIGestureRecognizerStateEnded) { - [(GLKView *)self.view display]; - map->swapped(); + [self togglePalette]; } } -- (void)viewWillLayoutSubviews -{ - [super viewWillLayoutSubviews]; - - GLKView *view = (GLKView *)self.view; - CGRect rect = [view bounds]; - map->resize(rect.size.width, rect.size.height, view.contentScaleFactor, view.drawableWidth, view.drawableHeight); -} - -#pragma mark - Debugging UI - - (void)togglePalette { if (self.palette.alpha < 1) @@ -232,24 +146,24 @@ MBXViewController *viewController = nullptr; - (void)unrotate { - map->resetNorth(); + [self.mapView resetNorth]; } - (void)resetPosition { - map->resetPosition(); + [self.mapView resetPosition]; } - (void)toggleDebug { - map->toggleDebug(); + [self.mapView toggleDebug]; self.debug = ! self.debug; } - (void)toggleRaster { - map->toggleRaster(); + [self.mapView toggleRaster]; } - (void)locateUser @@ -269,197 +183,10 @@ MBXViewController *viewController = nullptr; if (settings) { - // Save settings [self saveState]; delete settings; settings = nullptr; } - - if (map) - { - delete map; - map = nullptr; - } - - if (viewObj) - { - delete viewObj; - viewObj = nullptr; - } - - if ([[EAGLContext currentContext] isEqual:self.context]) - { - [EAGLContext setCurrentContext:nil]; - } -} - -#pragma mark - UI gestures - -- (void)cancelPreviousActions -{ - map->cancelTransitions(); - - [self.locationManager stopUpdatingLocation]; -} - -- (void)handlePanGesture:(UIPanGestureRecognizer *)pan -{ - [self cancelPreviousActions]; - - if (pan.state == UIGestureRecognizerStateBegan) - { - self.center = CGPointMake(0, 0); - } - else if (pan.state == UIGestureRecognizerStateChanged) - { - CGPoint delta = CGPointMake([pan translationInView:pan.view].x - self.center.x, - [pan translationInView:pan.view].y - self.center.y); - - map->moveBy(delta.x, delta.y); - - self.center = CGPointMake(self.center.x + delta.x, self.center.y + delta.y); - } - else if (pan.state == UIGestureRecognizerStateEnded) - { - if ([pan velocityInView:pan.view].x < 50 && [pan velocityInView:pan.view].y < 50) - { - return; - } - - CGPoint finalCenter = CGPointMake(self.center.x + (0.1 * [pan velocityInView:pan.view].x), - self.center.y + (0.1 * [pan velocityInView:pan.view].y)); - - CGFloat duration = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ? 0.3 : 0.5); - - map->moveBy(finalCenter.x - self.center.x, finalCenter.y - self.center.y, duration); - } -} - -- (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch -{ - [self cancelPreviousActions]; - - if (pinch.state == UIGestureRecognizerStateBegan) - { - map->startScaling(); - - self.scale = map->getScale(); - } - else if (pinch.state == UIGestureRecognizerStateChanged) - { - CGFloat tolerance = 2.5; - CGFloat adjustment = 0; - - if (pinch.scale > 1) - { - adjustment = (pinch.scale / tolerance) - (1 / tolerance); - } - else - { - adjustment = (-1 / pinch.scale) / tolerance + (1 / tolerance); - } - - CGFloat newZoom = log2f(self.scale) + adjustment; - - map->scaleBy(powf(2, newZoom) / map->getScale(), [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y); - } - else if (pinch.state == UIGestureRecognizerStateEnded) - { - map->stopScaling(); - - if (fabsf(pinch.velocity) < 20) - { - return; - } - - CGFloat finalZoom = log2f(map->getScale()) + (0.01 * pinch.velocity); - - double scale = map->getScale(); - double new_scale = powf(2, finalZoom); - - CGFloat duration = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ? 0.3 : 0.5); - - map->scaleBy(new_scale / scale, [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y, duration); - } - else if (pinch.state == UIGestureRecognizerStateCancelled) - { - map->stopScaling(); - } -} - -- (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate -{ - [self cancelPreviousActions]; - - if (rotate.state == UIGestureRecognizerStateBegan) - { - map->startRotating(); - - self.angle = map->getAngle(); - } - else if (rotate.state == UIGestureRecognizerStateChanged) - { - map->setAngle(self.angle + rotate.rotation, [rotate locationInView:rotate.view].x, [rotate locationInView:rotate.view].y); - } - else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled) - { - map->stopRotating(); - } -} - -- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap -{ - if (singleTap.state == UIGestureRecognizerStateEnded) - { - [self togglePalette]; - } -} - -- (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap -{ - [self cancelPreviousActions]; - - if (doubleTap.state == UIGestureRecognizerStateEnded) - { - map->scaleBy(2, [doubleTap locationInView:doubleTap.view].x, [doubleTap locationInView:doubleTap.view].y, 0.3); - } -} - -- (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap -{ - [self cancelPreviousActions]; - - if (twoFingerTap.state == UIGestureRecognizerStateEnded) - { - map->scaleBy(0.5, [twoFingerTap locationInView:twoFingerTap.view].x, [twoFingerTap locationInView:twoFingerTap.view].y, 0.3); - } -} - -- (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom -{ - [self cancelPreviousActions]; - - if (quickZoom.state == UIGestureRecognizerStateBegan) - { - self.scale = map->getScale(); - - self.quickZoomStart = [quickZoom locationInView:quickZoom.view].y; - } - else if (quickZoom.state == UIGestureRecognizerStateChanged) - { - CGFloat distance = self.quickZoomStart - [quickZoom locationInView:quickZoom.view].y; - - CGFloat newZoom = log2f(self.scale) + (distance / 100); - - map->scaleBy(powf(2, newZoom) / map->getScale(), self.view.bounds.size.width / 2, self.view.bounds.size.height / 2); - } -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer -{ - NSArray *validSimultaneousGestures = @[ [UIPanGestureRecognizer class], [UIPinchGestureRecognizer class], [UIRotationGestureRecognizer class] ]; - - return ([validSimultaneousGestures containsObject:[gestureRecognizer class]] && [validSimultaneousGestures containsObject:[otherGestureRecognizer class]]); } #pragma mark - User location @@ -468,24 +195,7 @@ MBXViewController *viewController = nullptr; { CLLocation *latestLocation = locations.lastObject; - map->setLonLatZoom(latestLocation.coordinate.longitude, latestLocation.coordinate.latitude, 17, 0.3); + [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(latestLocation.coordinate.latitude, latestLocation.coordinate.longitude) zoomLevel:17 animated:YES]; } -class View : public llmr::View { -public: - View(MBXViewController *controller) : controller(controller) {} - virtual ~View() {} - - void make_active() { - [EAGLContext setCurrentContext:controller.context]; - } - - void swap() { - [controller performSelectorOnMainThread:@selector(swap) withObject:nil waitUntilDone:NO]; - } - -private: - MBXViewController *controller = nullptr; -}; - @end diff --git a/ios/MVKMapKit b/ios/MVKMapKit new file mode 160000 index 0000000000..9c536c3b12 --- /dev/null +++ b/ios/MVKMapKit @@ -0,0 +1 @@ +Subproject commit 9c536c3b12636292ef70bbbc9800858a9d19a1ef diff --git a/ios/llmr-app.gyp b/ios/llmr-app.gyp index c0b40c1cc8..6bd463ab71 100644 --- a/ios/llmr-app.gyp +++ b/ios/llmr-app.gyp @@ -14,6 +14,8 @@ "./MBXAppDelegate.m", "./MBXViewController.h", "./MBXViewController.mm", + "./MVKMapKit/MVKMapKit/MVKMapView.h", + "./MVKMapKit/MVKMapKit/MVKMapView.mm", "../common/settings_nsuserdefaults.hpp", "../common/settings_nsuserdefaults.mm", "../common/foundation_request.h", -- cgit v1.2.1