diff --git a/iphone/Maps/Categories/UIKitCategories.mm b/iphone/Maps/Categories/UIKitCategories.mm index c5e6a71b43..f5691abc26 100644 --- a/iphone/Maps/Categories/UIKitCategories.mm +++ b/iphone/Maps/Categories/UIKitCategories.mm @@ -303,7 +303,6 @@ if (!url) { NSAssert(false, @"URL is nil!"); - auto urlString = url.absoluteString; auto err = [[NSError alloc] initWithDomain:kMapsmeErrorDomain code:0 userInfo:@{ diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h index 18494fa764..4a3ea99d93 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h @@ -49,6 +49,7 @@ - (void)onRouteReady; - (void)onRouteStart; - (void)onRouteStop; +- (void)onRoutePointsUpdated; - (void)processMyPositionStateModeEvent:(location::EMyPositionMode)mode; diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm index b9e3003f78..ac88decc09 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm @@ -178,10 +178,9 @@ extern NSString * const kAlohalyticsTapEventKey; { [self.navigationManager setMapSearch]; } - MWMRoutingPlaneMode const m = MapsAppDelegate.theApp.routingPlaneMode; if (state == MWMSearchManagerStateHidden) { - if (!IPAD || m == MWMRoutingPlaneModeNone) + if (!IPAD) { self.hidden = NO; self.leftBound = self.topBound = 0.0; @@ -190,45 +189,26 @@ extern NSString * const kAlohalyticsTapEventKey; [self.ownerController setNeedsStatusBarAppearanceUpdate]; if (!IPAD || (state != MWMSearchManagerStateDefault && state != MWMSearchManagerStateHidden)) return; - if (m == MWMRoutingPlaneModeSearchSource || m == MWMRoutingPlaneModeSearchDestination) + if (state == MWMSearchManagerStateHidden) { [UIView animateWithDuration:kDefaultAnimationDuration animations:^{ - if (state == MWMSearchManagerStateHidden) - { - self.navigationManager.routePreview.alpha = 1.; - MapsAppDelegate.theApp.routingPlaneMode = MWMRoutingPlaneModePlacePage; - } - else - { - self.navigationManager.routePreview.alpha = 0.; - } + self.navigationManager.routePreview.alpha = 1.; }]; } - else if (m == MWMRoutingPlaneModePlacePage) + else { - if (state == MWMSearchManagerStateHidden) - { - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - self.navigationManager.routePreview.alpha = 1.; - }]; - } - else - { - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - self.navigationManager.routePreview.alpha = 0.; - } - completion:^(BOOL finished) { - MapsAppDelegate.theApp.routingPlaneMode = MWMRoutingPlaneModeNone; - self.navigationManager.routePreview.alpha = 1.; - [self.navigationManager.routePreview removeFromSuperview]; - [MWMRouter stopRouting]; - self.navigationManager.state = MWMNavigationDashboardStateHidden; - self.menuController.p2pButton.selected = NO; - }]; - } + [UIView animateWithDuration:kDefaultAnimationDuration + animations:^{ + self.navigationManager.routePreview.alpha = 0.; + } + completion:^(BOOL finished) { + self.navigationManager.routePreview.alpha = 1.; + [self.navigationManager.routePreview removeFromSuperview]; + [MWMRouter stopRouting]; + self.navigationManager.state = MWMNavigationDashboardStateHidden; + self.menuController.p2pButton.selected = NO; + }]; } } @@ -264,7 +244,7 @@ extern NSString * const kAlohalyticsTapEventKey; MapViewController * ownerController = self.ownerController; if (platform::migrate::NeedMigrate()) { - if (GetFramework().GetRoutingManager().IsRoutingActive()) + if ([MWMRouter isRoutingActive]) { [Statistics logEvent:kStatDownloaderMigrationProhibitedDialogue withParameters:@{kStatFrom : kStatDownloader}]; @@ -341,7 +321,30 @@ extern NSString * const kAlohalyticsTapEventKey; - (void)routePreviewDidChangeFrame:(CGRect)newFrame { - if (!IPAD) + if (IPAD) + { + CGFloat const bound = newFrame.origin.x + newFrame.size.width; + if (self.searchManager.state == MWMSearchManagerStateHidden) + { + CGFloat const leftBound = newFrame.origin.x + newFrame.size.width; + self.navigationManager.leftBound = leftBound; + self.placePageManager.leftBound = leftBound; + self.trafficButton.leftBound = leftBound; + } + else + { + [UIView animateWithDuration:kDefaultAnimationDuration + animations:^{ + CGFloat const alpha = bound > 0 ? 0. : 1.; + for (UIView * view in self.searchManager.topViews) + view.alpha = alpha; + } + completion:^(BOOL finished) { + self.searchManager.state = MWMSearchManagerStateHidden; + }]; + } + } + else { CGFloat const bound = newFrame.origin.y + newFrame.size.height; self.placePageManager.topBound = bound; @@ -349,54 +352,29 @@ extern NSString * const kAlohalyticsTapEventKey; self.trafficButton.topBound = bound; return; } - - CGFloat const bound = newFrame.origin.x + newFrame.size.width; - if (self.searchManager.state == MWMSearchManagerStateHidden) - { - CGFloat const leftBound = newFrame.origin.x + newFrame.size.width; - self.placePageManager.leftBound = leftBound; - self.menuController.leftBound = leftBound; - self.trafficButton.leftBound = leftBound; - } - else - { - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - CGFloat const alpha = bound > 0 ? 0. : 1.; - for (UIView * view in self.searchManager.topViews) - view.alpha = alpha; - } - completion:^(BOOL finished) { - self.searchManager.state = MWMSearchManagerStateHidden; - }]; - } } - (void)navigationDashBoardDidUpdate { + auto nm = self.navigationManager; if (IPAD) { - [self.placePageManager setTopBound:self.topBound + self.navigationManager.leftHeight]; + [self.placePageManager setTopBound:self.topBound + nm.leftTop]; } else { - CGFloat const topBound = self.topBound + self.navigationManager.rightHeight; + auto const topBound = self.topBound + nm.rightTop; + auto const bottomBound = nm.bottom; [self.sideButtons setTopBound:topBound]; + [self.sideButtons setBottomBound:bottomBound]; + [MWMMapWidgets widgetsManager].bottomBound = bottomBound; + [MWMMapWidgets widgetsManager].leftBound = nm.left; BOOL const skipNavDashboardHeight = self.navigationManager.state == MWMNavigationDashboardStateNavigation; [self.placePageManager setTopBound:skipNavDashboardHeight ? self.topBound : topBound]; } } -- (void)didStartEditingRoutePoint:(BOOL)isSource -{ - [Statistics logEvent:kStatEventName(kStatPointToPoint, kStatSearch) - withParameters:@{kStatValue : (isSource ? kStatSource : kStatDestination)}]; - MapsAppDelegate.theApp.routingPlaneMode = - isSource ? MWMRoutingPlaneModeSearchSource : MWMRoutingPlaneModeSearchDestination; - self.searchManager.state = MWMSearchManagerStateDefault; -} - - (void)setDisableStandbyOnRouteFollowing:(BOOL)disableStandbyOnRouteFollowing { if (_disableStandbyOnRouteFollowing == disableStandbyOnRouteFollowing) @@ -418,8 +396,8 @@ extern NSString * const kAlohalyticsTapEventKey; - (void)onRoutePrepare { self.navigationManager.state = MWMNavigationDashboardStatePrepare; - MapsAppDelegate.theApp.routingPlaneMode = MWMRoutingPlaneModePlacePage; self.menuController.p2pButton.selected = YES; + [self onRoutePointsUpdated]; } - (void)onRouteRebuild @@ -433,15 +411,15 @@ extern NSString * const kAlohalyticsTapEventKey; - (void)onRouteError { self.navigationManager.state = MWMNavigationDashboardStateError; - MapsAppDelegate.theApp.routingPlaneMode = MWMRoutingPlaneModePlacePage; } - (void)onRouteReady { - if (![MWMRouter router].startPoint.isMyPosition) + auto startPoint = [MWMRouter startPoint]; + if (!startPoint || !startPoint.isMyPosition) { dispatch_async(dispatch_get_main_queue(), ^{ - GetFramework().GetRoutingManager().DisableFollowMode(); + [MWMRouter disableFollowMode]; [self.navigationManager updateDashboard]; }); } @@ -469,6 +447,7 @@ extern NSString * const kAlohalyticsTapEventKey; [self navigationDashBoardDidUpdate]; } +- (void)onRoutePointsUpdated { [self.navigationManager onRoutePointsUpdated]; } #pragma mark - Properties - (MWMSideButtons *)sideButtons @@ -588,8 +567,7 @@ extern NSString * const kAlohalyticsTapEventKey; { if (!IPAD) return; - MWMRoutingPlaneMode const m = MapsAppDelegate.theApp.routingPlaneMode; - if (m != MWMRoutingPlaneModeNone) + if ([MWMRouter isRoutingActive]) return; _leftBound = self.placePageManager.leftBound = self.navigationManager.leftBound = self.menuController.leftBound = self.trafficButton.leftBound = leftBound; diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm index 34f3dba034..cf9ad93af1 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm @@ -1,7 +1,8 @@ #import "MWMSideButtons.h" -#import "MWMCommon.h" #import "MWMButton.h" +#import "MWMCommon.h" #import "MWMMapViewControlsManager.h" +#import "MWMRouter.h" #import "MWMSettings.h" #import "MWMSideButtonsView.h" #import "Statistics.h" @@ -206,7 +207,7 @@ NSArray * animationImages(NSString * animationTemplate, NSUInteger im - (BOOL)zoomHidden { return self.sideView.zoomHidden; } - (void)setZoomHidden:(BOOL)zoomHidden { - if (GetFramework().GetRoutingManager().IsRoutingActive()) + if ([MWMRouter isRoutingActive]) self.sideView.zoomHidden = NO; else self.sideView.zoomHidden = [MWMSettings zoomButtonsEnabled] ? zoomHidden : YES; diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtonsView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtonsView.mm index a7cf62cbf4..651c41f1e4 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtonsView.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtonsView.mm @@ -89,38 +89,44 @@ CGFloat const kButtonsBottomOffset = 6; }]; } +- (void)doAnimate +{ + [self layoutYPosition]; + + CGFloat const spaceLeft = self.bottomBound - self.topBound - + (equalScreenDimensions(self.topBound, 0.0) ? statusBarHeight() : 0.0); + BOOL const isZoomHidden = self.zoomIn.alpha == 0.0; + BOOL const willZoomHide = (self.location.maxY > spaceLeft); + if (willZoomHide) + { + if (!isZoomHidden) + [self fadeZoomButtonsShow:NO]; + } + else + { + if (isZoomHidden) + [self fadeZoomButtonsShow:YES]; + } + BOOL const isLocationHidden = self.location.alpha == 0.0; + BOOL const willLocationHide = (self.location.height > spaceLeft); + if (willLocationHide) + { + if (!isLocationHidden) + [self fadeLocationButtonShow:NO]; + } + else + { + if (isLocationHidden) + [self fadeLocationButtonShow:YES]; + } + [self setNeedsLayout]; +} + - (void)animate { - runAsyncOnMainQueue(^{ - [self layoutYPosition]; - - CGFloat const spaceLeft = self.bottomBound - self.topBound - - (equalScreenDimensions(self.topBound, 0.0) ? statusBarHeight() : 0.0); - BOOL const isZoomHidden = self.zoomIn.alpha == 0.0; - BOOL const willZoomHide = (self.location.maxY > spaceLeft); - if (willZoomHide) - { - if (!isZoomHidden) - [self fadeZoomButtonsShow:NO]; - } - else - { - if (isZoomHidden) - [self fadeZoomButtonsShow:YES]; - } - BOOL const isLocationHidden = self.location.alpha == 0.0; - BOOL const willLocationHide = (self.location.height > spaceLeft); - if (willLocationHide) - { - if (!isLocationHidden) - [self fadeLocationButtonShow:NO]; - } - else - { - if (isLocationHidden) - [self fadeLocationButtonShow:YES]; - } - }); + auto doAnimate = @selector(doAnimate); + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:doAnimate object:nil]; + [self performSelector:doAnimate withObject:nil afterDelay:0]; } #pragma mark - Properties diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm index f659097189..ebd8ae43f4 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm @@ -23,7 +23,7 @@ using namespace routing::turns; _progress = info.m_completionPercent; auto & f = GetFramework(); CLLocation * lastLocation = [MWMLocationManager lastLocation]; - if (lastLocation && f.GetRoutingManager().GetRouter() == routing::RouterType::Pedestrian) + if (lastLocation && [MWMRouter type] == MWMRouterTypePedestrian) { _isPedestrian = YES; string distance; @@ -78,7 +78,7 @@ using namespace routing::turns; UIImage * image(routing::turns::TurnDirection t, bool isNextTurn) { - if (GetFramework().GetRoutingManager().GetRouter() == routing::RouterType::Pedestrian) + if ([MWMRouter type] == MWMRouterTypePedestrian) return [UIImage imageNamed:@"ic_direction"]; NSString * imageName; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h index 0f424a0d0e..ae12e9deee 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h @@ -21,7 +21,6 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) { @protocol MWMNavigationDashboardManagerProtocol -- (void)didStartEditingRoutePoint:(BOOL)isSource; - (void)setMenuState:(MWMBottomMenuState)menuState; - (void)setMenuRestoreState:(MWMBottomMenuState)menuState; - (void)setRoutingErrorMessage:(NSString *)errorMessage; @@ -40,8 +39,10 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) { @property(weak, nonatomic, readonly) id delegate; @property(nonatomic) CGFloat topBound; @property(nonatomic) CGFloat leftBound; -@property(nonatomic, readonly) CGFloat leftHeight; -@property(nonatomic, readonly) CGFloat rightHeight; +@property(nonatomic, readonly) CGFloat leftTop; +@property(nonatomic, readonly) CGFloat rightTop; +@property(nonatomic, readonly) CGFloat bottom; +@property(nonatomic, readonly) CGFloat left; - (instancetype)init __attribute__((unavailable("init is not available"))); - (instancetype)initWithParentView:(UIView *)view @@ -56,4 +57,6 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) { - (void)updateStartButtonTitle:(UIButton *)startButton; +- (void)onRoutePointsUpdated; + @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm index 982a8310d5..4162ee4cfc 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm @@ -1,9 +1,11 @@ #import "MWMNavigationDashboardManager.h" #import +#import #import "MWMCommon.h" #import "MWMLocationHelpers.h" #import "MWMMapViewControlsManager.h" #import "MWMNavigationInfoView.h" +#import "MWMRoutePoint+CPP.h" #import "MWMRoutePreview.h" #import "MWMRouter.h" #import "MWMTaxiPreviewDataSource.h" @@ -65,7 +67,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; - (void)updateFollowingInfo:(location::FollowingInfo const &)info { - if (GetFramework().GetRoutingManager().IsRouteFinished()) + if ([MWMRouter isRouteFinished]) { [MWMRouter stopRouting]; AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); @@ -82,7 +84,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; return; [self.routePreview stateError]; - [self.routePreview router:[MWMRouter router].type setState:MWMCircularProgressStateFailed]; + [self.routePreview router:[MWMRouter type] setState:MWMCircularProgressStateFailed]; } - (void)updateDashboard @@ -93,11 +95,29 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; [infoDisplay updateNavigationInfo:self.entity]; } +#pragma mark - MWMNavigationInfoView + +- (IBAction)addLocationRoutePoint +{ + if (![MWMRouter startPoint]) + { + [MWMRouter + buildFromPoint:[[MWMRoutePoint alloc] initWithLastLocationAndType:MWMRoutePointTypeStart] + bestRouter:NO]; + } + else if (![MWMRouter finishPoint]) + { + [MWMRouter + buildToPoint:[[MWMRoutePoint alloc] initWithLastLocationAndType:MWMRoutePointTypeFinish] + bestRouter:NO]; + } +} + #pragma mark - MWMRoutePreview - (void)setRouteBuilderProgress:(CGFloat)progress { - [self.routePreview router:[MWMRouter router].type setProgress:progress / 100.]; + [self.routePreview router:[MWMRouter type] setProgress:progress / 100.]; } #pragma mark - MWMNavigationDashboard @@ -131,24 +151,23 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; { [self.routePreview remove]; self.routePreview = nil; - [self.navigationInfoView remove]; + self.navigationInfoView.state = MWMNavigationInfoViewStateHidden; self.navigationInfoView = nil; } - (void)showStatePrepare { - [self.navigationInfoView remove]; - self.navigationInfoView = nil; + self.navigationInfoView.state = MWMNavigationInfoViewStatePrepare; [self.routePreview addToView:self.ownerView]; [self.routePreview statePrepare]; - [self.routePreview selectRouter:[MWMRouter router].type]; + [self.routePreview selectRouter:[MWMRouter type]]; + [self setMenuState:MWMBottomMenuStateHidden]; } - (void)showStatePlanning { [self showStatePrepare]; - [self setMenuState:MWMBottomMenuStatePlanning]; - [self.routePreview router:[MWMRouter router].type setState:MWMCircularProgressStateSpinner]; + [self.routePreview router:[MWMRouter type] setState:MWMCircularProgressStateSpinner]; [self setRouteBuilderProgress:0.]; if (![MWMRouter isTaxi]) return; @@ -160,10 +179,9 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; [self setMenuErrorStateWithErrorMessage:errorMessage]; }; - auto r = [MWMRouter router]; - auto const & start = r.startPoint; - auto const & finish = r.finishPoint; - if (start.isValid && finish.isValid) + auto pFrom = [MWMRouter startPoint]; + auto pTo = [MWMRouter finishPoint]; + if (pFrom && pTo) { if (!Platform::IsConnected()) { @@ -171,16 +189,26 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; showError(L(@"dialog_taxi_offline")); return; } - [self.taxiDataSource requestTaxiFrom:start to:finish completion:^ - { - [self setMenuState:MWMBottomMenuStateGo]; - [self.routePreview stateReady]; - [self setRouteBuilderProgress:100.]; - } - failure:^(NSString * errorMessage) - { - showError(errorMessage); - }]; + [self.taxiDataSource requestTaxiFrom:pFrom + to:pTo + completion:^{ + [self setMenuState:MWMBottomMenuStateGo]; + [self.routePreview stateReady]; + [self setRouteBuilderProgress:100.]; + } + failure:^(NSString * errorMessage) { + showError(errorMessage); + }]; + } + else + { + auto err = [[NSError alloc] initWithDomain:kMapsmeErrorDomain + code:5 + userInfo:@{ + @"Description" : @"Invalid number of taxi route points", + @"Count" : @([MWMRouter pointsCount]) + }]; + [[Crashlytics sharedInstance] recordError:err]; } } @@ -198,7 +226,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; [self setMenuState:MWMBottomMenuStateRouting]; [self.routePreview remove]; self.routePreview = nil; - [self.navigationInfoView addToView:self.ownerView]; + self.navigationInfoView.state = MWMNavigationInfoViewStateNavigation; [MWMMapViewControlsManager manager].searchHidden = YES; } @@ -209,6 +237,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; [startButton setTitle:t forState:UIControlStateDisabled]; } +- (void)onRoutePointsUpdated { [self.navigationInfoView onRoutePointsUpdated]; } - (void)setMenuErrorStateWithErrorMessage:(NSString *)message { [self.delegate setRoutingErrorMessage:message]; @@ -274,7 +303,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; self.navigationInfoView.leftBound = leftBound; } -- (CGFloat)leftHeight +- (CGFloat)leftTop { switch (self.state) { @@ -288,7 +317,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; } } -- (CGFloat)rightHeight +- (CGFloat)rightTop { switch (self.state) { @@ -302,6 +331,35 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; } } +- (CGFloat)bottom +{ + auto ov = self.ownerView; + switch (self.state) + { + case MWMNavigationDashboardStateHidden: return ov.height; + case MWMNavigationDashboardStatePlanning: + case MWMNavigationDashboardStateReady: + case MWMNavigationDashboardStateError: + case MWMNavigationDashboardStatePrepare: + case MWMNavigationDashboardStateNavigation: + return IPAD ? ov.height : self.navigationInfoView.bottom; + } +} + +- (CGFloat)left +{ + switch (self.state) + { + case MWMNavigationDashboardStateHidden: return 0.0; + case MWMNavigationDashboardStatePlanning: + case MWMNavigationDashboardStateReady: + case MWMNavigationDashboardStateError: + case MWMNavigationDashboardStatePrepare: + case MWMNavigationDashboardStateNavigation: + return self.leftBound + (IPAD ? 0 : self.navigationInfoView.left); + } +} + - (void)addInfoDisplay:(TInfoDisplay)infoDisplay { [self.infoDisplays addObject:infoDisplay]; } - (NSString *)startButtonTitle { @@ -309,6 +367,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; return L(@"p2p_start"); return self.taxiDataSource.isTaxiInstalled ? L(@"taxi_order") : L(@"install_app"); } + #pragma mark - Properties - (MWMRoutePreview *)routePreview @@ -330,6 +389,8 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; if (!_navigationInfoView) { [NSBundle.mainBundle loadNibNamed:kNavigationInfoViewXibName owner:self options:nil]; + _navigationInfoView.state = MWMNavigationInfoViewStateHidden; + _navigationInfoView.ownerView = self.ownerView; [self addInfoDisplay:_navigationInfoView]; } return _navigationInfoView; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm index 2b40017448..05374fa2a2 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm @@ -1,6 +1,7 @@ #import "MWMTextToSpeech.h" #import #import "MWMCommon.h" +#import "MWMRouter.h" #import "Statistics.h" #include "LocaleTranslator.h" @@ -153,7 +154,7 @@ vector> availableLanguages() if (active && ![self isValid]) [self createSynthesizer]; [self setAudioSessionActive:active]; - GetFramework().GetRoutingManager().EnableTurnNotifications(active ? true : false); + [MWMRouter enableTurnNotifications:active]; runAsyncOnMainQueue(^{ [[NSNotificationCenter defaultCenter] postNotificationName:[[self class] ttsStatusNotificationKey] @@ -164,10 +165,7 @@ vector> availableLanguages() - (BOOL)active { - return [[self class] isTTSEnabled] && - GetFramework().GetRoutingManager().AreTurnNotificationsEnabled() - ? YES - : NO; + return [[self class] isTTSEnabled] && [MWMRouter areTurnNotificationsEnabled]; } + (NSString *)savedLanguage @@ -225,7 +223,7 @@ vector> availableLanguages() LOG(LERROR, ("Cannot convert UI locale or default locale to twine language. MWMTextToSpeech " "is invalid.")); else - GetFramework().GetRoutingManager().SetTurnNotificationsLocale(twineLang); + [MWMRouter setTurnNotificationsLocale:@(twineLang.c_str())]; } else { @@ -245,18 +243,12 @@ vector> availableLanguages() - (void)playTurnNotifications { - auto & routingManager = GetFramework().GetRoutingManager(); - if (!routingManager.IsRoutingActive()) + if (![MWMRouter isRoutingActive] || ![self isValid]) return; - vector notifications; - routingManager.GenerateTurnNotifications(notifications); - - if (![self isValid]) - return; - - for (auto const & text : notifications) - [self speakOneString:@(text.c_str())]; + NSArray * turnNotifications = [MWMRouter turnNotifications]; + for (NSString * notification in turnNotifications) + [self speakOneString:notification]; } - (BOOL)setAudioSessionActive:(BOOL)audioSessionActive diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h similarity index 59% rename from iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.h rename to iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h index ccbcf450ed..e7b5cb31d6 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h @@ -12,17 +12,26 @@ enum class NavigationSearchState MinimizedATM }; +typedef NS_ENUM(NSUInteger, MWMNavigationInfoViewState) { + MWMNavigationInfoViewStateHidden, + MWMNavigationInfoViewStatePrepare, + MWMNavigationInfoViewStateNavigation +}; + @interface MWMNavigationInfoView : UIView @property(nonatomic) CGFloat topBound; @property(nonatomic) CGFloat leftBound; @property(nonatomic, readonly) CGFloat leftHeight; @property(nonatomic, readonly) CGFloat rightHeight; +@property(nonatomic, readonly) CGFloat bottom; +@property(nonatomic, readonly) CGFloat left; @property(nonatomic, readonly) NavigationSearchState searchState; - -- (void)addToView:(UIView *)superview; -- (void)remove; +@property(nonatomic) MWMNavigationInfoViewState state; +@property(weak, nonatomic) UIView * ownerView; - (void)setMapSearch; +- (void)onRoutePointsUpdated; + @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm similarity index 83% rename from iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.mm rename to iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm index b2a8e8eb1b..a5a20e2e8b 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm @@ -11,6 +11,7 @@ #import "MWMRouter.h" #import "MWMSearch.h" #import "MapViewController.h" +#import "SwiftBridge.h" #import "UIImageView+Coloring.h" #include "geometry/angles.hpp" @@ -69,6 +70,7 @@ BOOL defaultOrientation(CGSize const & size) @property(weak, nonatomic) IBOutlet UIView * searchButtonsView; @property(weak, nonatomic) IBOutlet MWMButton * searchMainButton; +@property(weak, nonatomic) IBOutlet MWMButton * bookmarksButton; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * searchButtonsViewHeight; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * searchButtonsViewWidth; @property(nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray * searchLandscapeConstraints; @@ -81,6 +83,9 @@ BOOL defaultOrientation(CGSize const & size) @property(weak, nonatomic) IBOutlet MWMButton * searchATMButton; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * turnsTopOffset; +@property(weak, nonatomic) IBOutlet MWMNavigationAddPointToastView * toastView; +@property(weak, nonatomic) IBOutlet NSLayoutConstraint * toastViewHideOffset; + @property(nonatomic, readwrite) NavigationSearchState searchState; @property(nonatomic) BOOL isVisible; @@ -90,18 +95,6 @@ BOOL defaultOrientation(CGSize const & size) @implementation MWMNavigationInfoView -- (void)addToView:(UIView *)superview -{ - self.isVisible = YES; - [self setSearchState:NavigationSearchState::MinimizedNormal animated:NO]; - self.turnsWidth.constant = IPAD ? kTurnsiPadWidth : kTurnsiPhoneWidth; - NSAssert(superview != nil, @"Superview can't be nil"); - if ([superview.subviews containsObject:self]) - return; - [superview insertSubview:self atIndex:0]; -} - -- (void)remove { self.isVisible = NO; } - (void)layoutSubviews { [super layoutSubviews]; @@ -111,14 +104,37 @@ BOOL defaultOrientation(CGSize const & size) [[MWMMapViewControlsManager manager] navigationDashBoardDidUpdate]; [self setNeedsLayout]; } - - if (!self.isVisible) - [self removeFromSuperview]; } - (CGFloat)leftHeight { return self.turnsView.maxY; } - (CGFloat)rightHeight { return self.streetNameView.hidden ? 0 : self.streetNameView.maxY; } +- (CGFloat)bottom { return self.toastView.minY; } +- (CGFloat)left +{ + auto sv = self.superview; + BOOL const isLandscape = sv.width > sv.height; + return isLandscape ? self.searchMainButton.maxX : 0; +} + - (void)setMapSearch { [self setSearchState:NavigationSearchState::MinimizedSearch animated:YES]; } +- (void)onRoutePointsUpdated +{ + if (![MWMRouter startPoint]) + { + [self.toastView configWithText:L(@"planning_route_need_start") withActionButton:YES]; + [self setToastViewHidden:NO]; + } + else if (![MWMRouter finishPoint]) + { + [self.toastView configWithText:L(@"planning_route_need_finish") withActionButton:NO]; + [self setToastViewHidden:NO]; + } + else + { + [self setToastViewHidden:YES]; + } +} + #pragma mark - Search - (IBAction)searchMainButtonTouchUpInside @@ -130,7 +146,14 @@ BOOL defaultOrientation(CGSize const & size) [self setSearchState:NavigationSearchState::MinimizedNormal animated:YES]; break; case NavigationSearchState::MinimizedNormal: - [self setSearchState:NavigationSearchState::Maximized animated:YES]; + if (self.state == MWMNavigationInfoViewStatePrepare) + { + [MWMMapViewControlsManager manager].searchHidden = NO; + } + else + { + [self setSearchState:NavigationSearchState::Maximized animated:YES]; + } break; case NavigationSearchState::MinimizedSearch: case NavigationSearchState::MinimizedGas: @@ -167,15 +190,19 @@ BOOL defaultOrientation(CGSize const & size) body(NavigationSearchState::MinimizedATM); } +- (IBAction)bookmarksButtonTouchUpInside { [[MapViewController controller] openBookmarks]; } - (void)collapseSearchOnTimer { [self setSearchState:NavigationSearchState::MinimizedNormal animated:YES]; } + #pragma mark - MWMNavigationDashboardInfoProtocol - (void)updateNavigationInfo:(MWMNavigationDashboardEntity *)info { self.navigationInfo = info; + if (self.state != MWMNavigationInfoViewStateNavigation) + return; if (info.streetName.length != 0) { self.streetNameView.hidden = NO; @@ -374,14 +401,48 @@ BOOL defaultOrientation(CGSize const & size) self.searchMainButton.imageName = kSearchStateButtonImageNames.at(searchState); } +- (void)setState:(MWMNavigationInfoViewState)state +{ + _state = state; + switch (state) + { + case MWMNavigationInfoViewStateHidden: self.isVisible = NO; break; + case MWMNavigationInfoViewStateNavigation: + self.isVisible = YES; + if ([MWMRouter type] == MWMRouterTypePedestrian) + [MWMLocationManager addObserver:self]; + else + [MWMLocationManager removeObserver:self]; + break; + case MWMNavigationInfoViewStatePrepare: + self.isVisible = YES; + self.streetNameView.hidden = YES; + self.turnsView.hidden = YES; + break; + } +} + - (void)setIsVisible:(BOOL)isVisible { - _isVisible = isVisible; [self setNeedsLayout]; - if (isVisible && [MWMRouter router].type == MWMRouterTypePedestrian) - [MWMLocationManager addObserver:self]; + if (_isVisible == isVisible) + return; + _isVisible = isVisible; + if (isVisible) + { + self.bookmarksButton.imageName = @"ic_routing_bookmark"; + [self setSearchState:NavigationSearchState::MinimizedNormal animated:NO]; + self.turnsWidth.constant = IPAD ? kTurnsiPadWidth : kTurnsiPhoneWidth; + UIView * sv = self.ownerView; + NSAssert(sv != nil, @"Superview can't be nil"); + if ([sv.subviews containsObject:self]) + return; + [sv insertSubview:self atIndex:0]; + } else - [MWMLocationManager removeObserver:self]; + { + [self removeFromSuperview]; + } } - (CGRect)defaultFrame @@ -403,4 +464,15 @@ BOOL defaultOrientation(CGSize const & size) [self setNeedsLayout]; } +- (void)setToastViewHidden:(BOOL)hidden +{ + [self setNeedsLayout]; + self.toastViewHideOffset.priority = + hidden ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow; + [UIView animateWithDuration:kDefaultAnimationDuration + animations:^{ + [self layoutIfNeeded]; + }]; +} + @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib similarity index 81% rename from iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.xib rename to iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib index 52f9b4ead3..da668e6443 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationInfoView.xib +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib @@ -1,11 +1,11 @@ - + - + @@ -17,14 +17,62 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - +