diff --git a/iphone/Maps/Bookmarks/BookmarksVC.mm b/iphone/Maps/Bookmarks/BookmarksVC.mm index 27f7602dab..049e2393ff 100644 --- a/iphone/Maps/Bookmarks/BookmarksVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksVC.mm @@ -237,8 +237,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica { [Statistics logEvent:kStatEventName(kStatBookmarks, kStatShowOnMap)]; // Same as "Close". - MapViewController * mapVC = self.navigationController.viewControllers.firstObject; - mapVC.controlsManager.searchHidden = YES; + [MWMSearchManager manager].state = MWMSearchManagerStateHidden; f.ShowBookmark({static_cast(indexPath.row), m_categoryIndex}); [self.navigationController popToRootViewControllerAnimated:YES]; } diff --git a/iphone/Maps/Bridging-Header.h b/iphone/Maps/Bridging-Header.h index d6da7daae6..986dafe32c 100644 --- a/iphone/Maps/Bridging-Header.h +++ b/iphone/Maps/Bridging-Header.h @@ -10,12 +10,15 @@ #import "MoPub-Bridging-Header.h" #import "MPNativeAd.h" #import "MPNativeAd+MWM.h" +#import "MWMTypes.h" +#import "UIKitCategories.h" #import "private.h" #import "AppInfo.h" #import "MWMAvailableAreaAffectDirection.h" #import "MWMBanner.h" +#import "MWMBottomMenuViewController.h" #import "MWMCollectionViewController.h" #import "MWMConsts.h" #import "MWMController.h" @@ -23,25 +26,30 @@ #import "MWMKeyboard.h" #import "MWMLocationManager.h" #import "MWMMapWidgetsHelper.h" +#import "MWMNavigationDashboardEntity.h" +#import "MWMNavigationDashboardManager.h" #import "MWMNoMapsViewController.h" #import "MWMPlacePageButtonsProtocol.h" #import "MWMPlacePageCellUpdateProtocol.h" #import "MWMPlacePageManagerHelper.h" #import "MWMPlacePageTaxiProvider.h" #import "MWMPushNotifications.h" +#import "MWMRoutePreviewTaxiCellType.h" #import "MWMRouter.h" #import "MWMSearchItemType.h" #import "MWMSearchNoResults.h" #import "MWMSettings.h" #import "MWMSideButtons.h" #import "MWMTableViewCell.h" +#import "MWMTextToSpeech.h" +#import "MWMTextToSpeechObserver.h" #import "MWMTextView.h" #import "MWMTrafficButtonViewController.h" -#import "MWMTypes.h" +#import "MWMTrafficManager.h" + #import "MWMViewController.h" #import "Statistics.h" #import "UIButton+RuntimeAttributes.h" #import "UIColor+MapsMeColor.h" #import "UIFont+MapsMeFonts.h" -#import "UIKitCategories.h" #import "UIViewController+Navigation.h" diff --git a/iphone/Maps/Categories/String+Format.swift b/iphone/Maps/Categories/String+Format.swift new file mode 100644 index 0000000000..2f06abe0ba --- /dev/null +++ b/iphone/Maps/Categories/String+Format.swift @@ -0,0 +1,6 @@ +extension String { + init(coreFormat: String, arguments: [CVarArg]) { + let format = coreFormat.replacingOccurrences(of: "%s", with: "%@") + self.init(format: format, arguments: arguments) + } +} diff --git a/iphone/Maps/Classes/Components/DimBackground.swift b/iphone/Maps/Classes/Components/DimBackground.swift new file mode 100644 index 0000000000..a6b98cc113 --- /dev/null +++ b/iphone/Maps/Classes/Components/DimBackground.swift @@ -0,0 +1,43 @@ +@objc(MWMDimBackground) +final class DimBackground: SolidTouchView { + private let mainView: UIView + private var tapAction: (() -> Void)! + + init(mainView: UIView) { + self.mainView = mainView + super.init(frame: mainView.superview!.bounds) + backgroundColor = UIColor.fadeBackground() + autoresizingMask = [.flexibleWidth, .flexibleHeight]; + addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTap))) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc + func setVisible(_ visible: Bool, tapAction: @escaping () -> Void) { + self.tapAction = tapAction + + if visible { + let sv = mainView.superview! + frame = sv.bounds + sv.insertSubview(self, belowSubview: mainView) + alpha = 0 + } else { + alpha = 0.8 + } + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { self.alpha = visible ? 0.8 : 0 }, + completion: { _ in + if !visible { + self.removeFromSuperview() + } + }) + } + + @objc + private func onTap() { + tapAction() + } +} diff --git a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.h b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.h index b201dfe7cb..5d05bc079a 100644 --- a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.h +++ b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.h @@ -1,17 +1,9 @@ #import "MWMButton.h" +#import "MWMCircularProgressState.h" #import "UIImageView+Coloring.h" #include "std/vector.hpp" -typedef NS_ENUM(NSInteger, MWMCircularProgressState) { - MWMCircularProgressStateNormal, - MWMCircularProgressStateSelected, - MWMCircularProgressStateProgress, - MWMCircularProgressStateSpinner, - MWMCircularProgressStateFailed, - MWMCircularProgressStateCompleted -}; - using MWMCircularProgressStateVec = vector; @class MWMCircularProgress; diff --git a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressState.h b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressState.h new file mode 100644 index 0000000000..8d0302e06b --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressState.h @@ -0,0 +1,8 @@ +typedef NS_ENUM(NSInteger, MWMCircularProgressState) { + MWMCircularProgressStateNormal, + MWMCircularProgressStateSelected, + MWMCircularProgressStateProgress, + MWMCircularProgressStateSpinner, + MWMCircularProgressStateFailed, + MWMCircularProgressStateCompleted +}; diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h index 4523f122a3..f41f52de20 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h @@ -2,7 +2,7 @@ #import "MWMNavigationDashboardManager.h" #import "MWMSearchManager.h" -#include "map/user_mark.hpp" +#include "map/place_page_info.hpp" @class MapViewController; @protocol MWMFeatureHolder; @@ -18,8 +18,6 @@ @property(nonatomic) BOOL trafficButtonHidden; @property(nonatomic) MWMBottomMenuState menuState; @property(nonatomic) MWMBottomMenuState menuRestoreState; -@property(nonatomic, readonly) MWMNavigationDashboardState navigationState; -@property(nonatomic) BOOL searchHidden; @property(nonatomic) BOOL isDirectionViewHidden; - (instancetype)init __attribute__((unavailable("init is not available"))); @@ -52,9 +50,7 @@ #pragma mark - MWMSearchManager -- (void)searchViewDidEnterState:(MWMSearchManagerState)state; - (void)actionDownloadMaps:(mwm::DownloaderMode)mode; -- (void)searchFrameUpdated:(CGRect)frame; - (BOOL)searchText:(NSString *)text forInputLocale:(NSString *)locale; - (void)searchTextOnMap:(NSString *)text forInputLocale:(NSString *)locale; diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm index 22228b4fc2..19f6a44d21 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm @@ -5,6 +5,7 @@ #import "MWMAlertViewController.h" #import "MWMAlertViewController.h" #import "MWMAuthorizationCommon.h" +#import "MWMBottomMenuControllerProtocol.h" #import "MWMBottomMenuViewController.h" #import "MWMButton.h" #import "MWMCommon.h" @@ -12,11 +13,9 @@ #import "MWMNetworkPolicy.h" #import "MWMObjectsCategorySelectorController.h" #import "MWMPlacePageManager.h" -#import "MWMRoutePreview.h" #import "MWMRouter.h" #import "MWMSearchManager.h" #import "MWMSideButtons.h" -#import "MWMTaxiPreviewDataSource.h" #import "MWMToast.h" #import "MWMTrafficButtonViewController.h" #import "MapViewController.h" @@ -40,8 +39,7 @@ NSString * const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue"; extern NSString * const kAlohalyticsTapEventKey; -@interface MWMMapViewControlsManager () +@interface MWMMapViewControlsManager () @property(nonatomic) MWMSideButtons * sideButtons; @property(nonatomic) MWMTrafficButtonViewController * trafficButton; @@ -54,9 +52,6 @@ extern NSString * const kAlohalyticsTapEventKey; @property(nonatomic) BOOL disableStandbyOnRouteFollowing; -@property(nonatomic) CGFloat topBound; -@property(nonatomic) CGFloat leftBound; - @end @implementation MWMMapViewControlsManager @@ -74,7 +69,6 @@ extern NSString * const kAlohalyticsTapEventKey; self.sideButtonsHidden = NO; self.trafficButtonHidden = NO; self.isDirectionViewHidden = YES; - self.menuState = MWMBottomMenuStateInactive; self.menuRestoreState = MWMBottomMenuStateInactive; return self; } @@ -84,12 +78,11 @@ extern NSString * const kAlohalyticsTapEventKey; if ([MWMToast affectsStatusBar]) return [MWMToast preferredStatusBarStyle]; - BOOL const isSearchUnderStatusBar = !self.searchHidden; + BOOL const isSearchUnderStatusBar = (self.searchManager.state != MWMSearchManagerStateHidden); BOOL const isNavigationUnderStatusBar = self.navigationManager.state != MWMNavigationDashboardStateHidden && self.navigationManager.state != MWMNavigationDashboardStateNavigation; - BOOL const isMenuViewUnderStatusBar = self.menuState == MWMBottomMenuStateActive || - self.menuState == MWMBottomMenuStateRoutingExpanded; + BOOL const isMenuViewUnderStatusBar = self.menuState == MWMBottomMenuStateActive; BOOL const isDirectionViewUnderStatusBar = !self.isDirectionViewHidden; BOOL const isAddPlaceUnderStatusBar = [self.ownerController.view hasSubviewWithViewClass:[MWMAddPlaceNavigationBar class]]; @@ -123,11 +116,6 @@ extern NSString * const kAlohalyticsTapEventKey; [self.trafficButton viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [self.menuController viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [self.searchManager viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - [coordinator animateAlongsideTransition:^( - id _Nonnull context) { - self.navigationManager.leftBound = self.leftBound; - } - completion:nil]; } #pragma mark - MWMPlacePageViewManager @@ -158,30 +146,6 @@ extern NSString * const kAlohalyticsTapEventKey; } } -- (void)searchViewDidEnterState:(MWMSearchManagerState)state -{ - if (state == MWMSearchManagerStateMapSearch) - { - [self.navigationManager setMapSearch]; - } - if (state == MWMSearchManagerStateHidden) - { - if (!IPAD) - { - self.hidden = NO; - self.leftBound = self.topBound = 0.0; - } - } - [self.ownerController setNeedsStatusBarAppearanceUpdate]; -} - -- (void)searchFrameUpdated:(CGRect)frame -{ - CGSize const s = frame.size; - self.leftBound = s.width; - self.topBound = s.height; -} - - (void)searchTextOnMap:(NSString *)text forInputLocale:(NSString *)locale { if (![self searchText:text forInputLocale:locale]) @@ -226,23 +190,6 @@ extern NSString * const kAlohalyticsTapEventKey; } } -- (void)closeInfoScreens -{ - if (IPAD) - { - if (!self.searchHidden) - self.searchManager.state = MWMSearchManagerStateHidden; - else - [MWMRouter stopRouting]; - } - else - { - CGSize const ownerViewSize = self.ownerController.view.size; - if (ownerViewSize.width > ownerViewSize.height) - [self dismissPlacePage]; - } -} - - (void)didFinishAddingPlace { self.trafficButtonHidden = NO; @@ -280,12 +227,6 @@ extern NSString * const kAlohalyticsTapEventKey; #pragma mark - MWMNavigationDashboardManager -- (void)routePreviewDidChangeFrame:(CGRect)newFrame -{ - if (IPAD) - self.navigationManager.leftBound = newFrame.origin.x + newFrame.size.width; -} - - (void)setDisableStandbyOnRouteFollowing:(BOOL)disableStandbyOnRouteFollowing { if (_disableStandbyOnRouteFollowing == disableStandbyOnRouteFollowing) @@ -297,9 +238,13 @@ extern NSString * const kAlohalyticsTapEventKey; [[MapsAppDelegate theApp] enableStandby]; } -- (MWMTaxiCollectionView *)taxiCollectionView +#pragma mark - MWMSearchManagerObserver + +- (void)onSearchManagerStateChanged { - return self.menuController.taxiCollectionView; + auto state = [MWMSearchManager manager].state; + if (!IPAD && state == MWMSearchManagerStateHidden) + self.hidden = NO; } #pragma mark - Routing @@ -307,7 +252,6 @@ extern NSString * const kAlohalyticsTapEventKey; - (void)onRoutePrepare { self.navigationManager.state = MWMNavigationDashboardStatePrepare; - self.menuController.p2pButton.selected = YES; [self onRoutePointsUpdated]; } @@ -321,7 +265,11 @@ extern NSString * const kAlohalyticsTapEventKey; - (void)onRouteError { - self.navigationManager.state = MWMNavigationDashboardStateError; + if ([MWMRouter isTaxi]) + return; + auto nm = self.navigationManager; + nm.errorMessage = L(@"routing_planning_error"); + nm.state = MWMNavigationDashboardStateError; } - (void)onRouteReady @@ -331,10 +279,10 @@ extern NSString * const kAlohalyticsTapEventKey; { dispatch_async(dispatch_get_main_queue(), ^{ [MWMRouter disableFollowMode]; - [self.navigationManager updateDashboard]; }); } - if (self.navigationManager.state != MWMNavigationDashboardStateNavigation) + [MWMSearchManager manager].state = MWMSearchManagerStateHidden; + if (self.navigationManager.state != MWMNavigationDashboardStateNavigation && ![MWMRouter isTaxi]) self.navigationManager.state = MWMNavigationDashboardStateReady; } @@ -354,7 +302,6 @@ extern NSString * const kAlohalyticsTapEventKey; self.navigationManager.state = MWMNavigationDashboardStateHidden; self.disableStandbyOnRouteFollowing = NO; self.trafficButtonHidden = NO; - self.menuState = MWMBottomMenuStateInactive; } - (void)onRoutePointsUpdated { [self.navigationManager onRoutePointsUpdated]; } @@ -393,19 +340,18 @@ extern NSString * const kAlohalyticsTapEventKey; - (MWMNavigationDashboardManager *)navigationManager { if (!_navigationManager) - { _navigationManager = - [[MWMNavigationDashboardManager alloc] initWithParentView:self.ownerController.view - delegate:self]; - [_navigationManager addInfoDisplay:self.menuController]; - } + [[MWMNavigationDashboardManager alloc] initWithParentView:self.ownerController.view]; return _navigationManager; } - (MWMSearchManager *)searchManager { if (!_searchManager) + { _searchManager = [[MWMSearchManager alloc] init]; + [MWMSearchManager addObserver:self]; + } return _searchManager; } @@ -446,11 +392,6 @@ extern NSString * const kAlohalyticsTapEventKey; self.menuController.state = self.hidden ? MWMBottomMenuStateHidden : menuState; } -- (void)setRoutingErrorMessage:(NSString *)message -{ - [self.menuController setRoutingErrorMessage:message]; -} - - (MWMBottomMenuState)menuState { MWMBottomMenuState const state = self.menuController.state; @@ -459,36 +400,6 @@ extern NSString * const kAlohalyticsTapEventKey; return _menuState; } -- (MWMNavigationDashboardState)navigationState { return self.navigationManager.state; } -- (void)setTopBound:(CGFloat)topBound -{ - if (IPAD) - return; - _topBound = topBound; - self.navigationManager.topBound = topBound; -} - -- (void)setLeftBound:(CGFloat)leftBound -{ - if (!IPAD) - return; - if ([MWMRouter isRoutingActive]) - return; - _leftBound = self.navigationManager.leftBound = self.menuController.leftBound = leftBound; -} - -- (BOOL)searchHidden -{ - if (!_searchManager) - return YES; - return self.searchManager.state == MWMSearchManagerStateHidden; -} -- (void)setSearchHidden:(BOOL)searchHidden -{ - self.searchManager.state = - searchHidden ? MWMSearchManagerStateHidden : MWMSearchManagerStateDefault; -} - #pragma mark - MWMFeatureHolder - (id)featureHolder { return self.placePageManager; } diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm index 044ee3905c..7cc9084b6a 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm @@ -123,43 +123,37 @@ NSArray * imagesWithName(NSString * name) [iv stopAnimating]; switch ([MWMTrafficManager state]) { - case TrafficManager::TrafficState::Disabled: - btn.imageName = @"btn_traffic_off"; - break; - case TrafficManager::TrafficState::Enabled: - btn.imageName = @"btn_traffic_on"; - break; - case TrafficManager::TrafficState::WaitingData: + case MWMTrafficManagerStateDisabled: btn.imageName = @"btn_traffic_off"; break; + case MWMTrafficManagerStateEnabled: btn.imageName = @"btn_traffic_on"; break; + case MWMTrafficManagerStateWaitingData: iv.animationImages = imagesWithName(@"btn_traffic_update"); iv.animationDuration = 0.8; [iv startAnimating]; break; - case TrafficManager::TrafficState::Outdated: - btn.imageName = @"btn_traffic_outdated"; - break; - case TrafficManager::TrafficState::NoData: + case MWMTrafficManagerStateOutdated: btn.imageName = @"btn_traffic_outdated"; break; + case MWMTrafficManagerStateNoData: btn.imageName = @"btn_traffic_on"; [MWMToast showWithText:L(@"traffic_data_unavailable")]; break; - case TrafficManager::TrafficState::NetworkError: + case MWMTrafficManagerStateNetworkError: btn.imageName = @"btn_traffic_off"; [MWMTrafficManager enableTraffic:NO]; [[MWMAlertViewController activeAlertController] presentNoConnectionAlert]; break; - case TrafficManager::TrafficState::ExpiredApp: - btn.imageName = @"btn_traffic_on"; - [MWMToast showWithText:L(@"traffic_update_app_message")]; - break; - case TrafficManager::TrafficState::ExpiredData: + case MWMTrafficManagerStateExpiredData: btn.imageName = @"btn_traffic_on"; [MWMToast showWithText:L(@"traffic_update_maps_text")]; break; + case MWMTrafficManagerStateExpiredApp: + btn.imageName = @"btn_traffic_on"; + [MWMToast showWithText:L(@"traffic_update_app_message")]; + break; } } - (IBAction)buttonTouchUpInside { - if ([MWMTrafficManager state] == TrafficManager::TrafficState::Disabled) + if ([MWMTrafficManager state] == MWMTrafficManagerStateDisabled) [MWMTrafficManager enableTraffic:YES]; else [MWMTrafficManager enableTraffic:NO]; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.h index 2a50c96464..afa0ef5cf0 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.h @@ -1,10 +1,6 @@ -#include "platform/location.hpp" - -#include "geometry/latlon.hpp" - @interface MWMNavigationDashboardEntity : NSObject -@property(nonatomic, readonly) ms::LatLon pedestrianDirectionPosition; +@property(nonatomic, readonly) CLLocation * pedestrianDirectionPosition; @property(nonatomic, readonly) BOOL isValid; @property(nonatomic, readonly) NSString * speed; @property(nonatomic, readonly) NSString * speedUnits; @@ -16,14 +12,13 @@ @property(nonatomic, readonly) UIImage * turnImage; @property(nonatomic, readonly) UIImage * nextTurnImage; @property(nonatomic, readonly) NSUInteger roundExitNumber; -@property(nonatomic, readonly) NSUInteger timeToTarget; +@property(nonatomic, readonly) NSString * eta; +@property(nonatomic, readonly) NSString * arrival; @property(nonatomic, readonly) CGFloat progress; //@property (nonatomic, readonly) vector lanes; @property(nonatomic, readonly) BOOL isPedestrian; @property(nonatomic, readonly) NSAttributedString * estimate; -- (void)updateFollowingInfo:(location::FollowingInfo const &)info; - + (instancetype) new __attribute__((unavailable("init is not available"))); @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm index 6246792152..0d69ddb1f4 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm @@ -1,111 +1,32 @@ #import "MWMNavigationDashboardEntity.h" -#import "MWMCommon.h" #import "MWMCoreUnits.h" #import "MWMLocationManager.h" #import "MWMSettings.h" -#import "MapsAppDelegate.h" #import "SwiftBridge.h" -#include "Framework.h" -#include "geometry/distance_on_sphere.hpp" #include "platform/measurement_utils.hpp" -using namespace routing::turns; +@interface MWMNavigationDashboardEntity () + +@property(nonatomic, readwrite) CLLocation * pedestrianDirectionPosition; +@property(nonatomic, readwrite) BOOL isValid; +@property(nonatomic, readwrite) NSString * targetDistance; +@property(nonatomic, readwrite) NSString * targetUnits; +@property(nonatomic, readwrite) NSString * distanceToTurn; +@property(nonatomic, readwrite) NSString * turnUnits; +@property(nonatomic, readwrite) NSString * streetName; +@property(nonatomic, readwrite) UIImage * turnImage; +@property(nonatomic, readwrite) UIImage * nextTurnImage; +@property(nonatomic, readwrite) NSUInteger roundExitNumber; +@property(nonatomic, readwrite) NSUInteger timeToTarget; +@property(nonatomic, readwrite) CGFloat progress; +@property(nonatomic, readwrite) BOOL isPedestrian; +@property(nonatomic, readwrite) NSAttributedString * estimate; + +@end @implementation MWMNavigationDashboardEntity -- (void)updateFollowingInfo:(location::FollowingInfo const &)info -{ - _isValid = info.IsValid(); - _timeToTarget = info.m_time; - _targetDistance = @(info.m_distToTarget.c_str()); - _targetUnits = @(info.m_targetUnitsSuffix.c_str()); - _progress = info.m_completionPercent; - CLLocation * lastLocation = [MWMLocationManager lastLocation]; - if (lastLocation && [MWMRouter type] == MWMRouterTypePedestrian) - { - _isPedestrian = YES; - string distance; - CLLocationCoordinate2D const & coordinate = lastLocation.coordinate; - _pedestrianDirectionPosition = info.m_pedestrianDirectionPos; - // TODO: Not the best solution, but this solution is temporary and will be replaced in future - measurement_utils::FormatDistance( - ms::DistanceOnEarth(coordinate.latitude, coordinate.longitude, - _pedestrianDirectionPosition.lat, _pedestrianDirectionPosition.lon), - distance); - istringstream is(distance); - string dist; - string units; - is >> dist; - is >> units; - _nextTurnImage = nil; - _distanceToTurn = @(dist.c_str()); - _turnUnits = @(units.c_str()); - _streetName = @""; - } - else - { - _isPedestrian = NO; - _distanceToTurn = @(info.m_distToTurn.c_str()); - _turnUnits = @(info.m_turnUnitsSuffix.c_str()); - _streetName = @(info.m_targetName.c_str()); - _nextTurnImage = image(info.m_nextTurn, true); - } - - NSDictionary * etaAttributes = @{ - NSForegroundColorAttributeName : UIColor.blackPrimaryText, - NSFontAttributeName : UIFont.medium17 - }; - NSString * eta = [NSDateComponentsFormatter etaStringFrom:_timeToTarget]; - NSString * resultString = - [NSString stringWithFormat:@"%@ • %@ %@", eta, _targetDistance, _targetUnits]; - NSMutableAttributedString * result = - [[NSMutableAttributedString alloc] initWithString:resultString]; - [result addAttributes:etaAttributes range:NSMakeRange(0, resultString.length)]; - _estimate = [result copy]; - - CarDirection const turn = info.m_turn; - _turnImage = image(turn, false); - BOOL const isRound = turn == CarDirection::EnterRoundAbout || - turn == CarDirection::StayOnRoundAbout || - turn == CarDirection::LeaveRoundAbout; - if (isRound) - _roundExitNumber = info.m_exitNum; - else - _roundExitNumber = 0; -} - -UIImage * image(routing::turns::CarDirection t, bool isNextTurn) -{ - if ([MWMRouter type] == MWMRouterTypePedestrian) - return [UIImage imageNamed:@"ic_direction"]; - - NSString * imageName; - switch (t) - { - case CarDirection::TurnSlightRight: imageName = @"slight_right"; break; - case CarDirection::TurnRight: imageName = @"simple_right"; break; - case CarDirection::TurnSharpRight: imageName = @"sharp_right"; break; - case CarDirection::TurnSlightLeft: imageName = @"slight_left"; break; - case CarDirection::TurnLeft: imageName = @"simple_left"; break; - case CarDirection::TurnSharpLeft: imageName = @"sharp_left"; break; - case CarDirection::UTurnLeft: imageName = @"uturn_left"; break; - case CarDirection::UTurnRight: imageName = @"uturn_right"; break; - case CarDirection::ReachedYourDestination: imageName = @"finish_point"; break; - case CarDirection::LeaveRoundAbout: - case CarDirection::EnterRoundAbout: imageName = @"round"; break; - case CarDirection::GoStraight: imageName = @"straight"; break; - case CarDirection::StartAtEndOfStreet: - case CarDirection::StayOnRoundAbout: - case CarDirection::TakeTheExit: - case CarDirection::Count: - case CarDirection::None: imageName = isNextTurn ? nil : @"straight"; break; - } - if (!imageName) - return nil; - return [UIImage imageNamed:isNextTurn ? [imageName stringByAppendingString:@"_then"] : imageName]; -} - - (NSString *)speed { CLLocation * lastLocation = [MWMLocationManager lastLocation]; @@ -121,4 +42,13 @@ UIImage * image(routing::turns::CarDirection t, bool isNextTurn) return @(measurement_utils::FormatSpeedUnits(units).c_str()); } +- (NSString *)eta { return [NSDateComponentsFormatter etaStringFrom:self.timeToTarget]; } +- (NSString *)arrival +{ + auto arrivalDate = [[NSDate date] dateByAddingTimeInterval:self.timeToTarget]; + return [NSDateFormatter localizedStringFromDate:arrivalDate + dateStyle:NSDateFormatterNoStyle + timeStyle:NSDateFormatterShortStyle]; +} + @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardInfoProtocol.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardInfoProtocol.h deleted file mode 100644 index ab73ebe27a..0000000000 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardInfoProtocol.h +++ /dev/null @@ -1,7 +0,0 @@ -#import "MWMNavigationDashboardEntity.h" - -@protocol MWMNavigationDashboardInfoProtocol - -- (void)updateNavigationInfo:(MWMNavigationDashboardEntity *)info; - -@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager+Entity.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager+Entity.h new file mode 100644 index 0000000000..9cb7bccb44 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager+Entity.h @@ -0,0 +1,9 @@ +#import "MWMNavigationDashboardManager.h" + +#include "platform/location.hpp" + +@interface MWMNavigationDashboardManager (Entity) + +- (void)updateFollowingInfo:(location::FollowingInfo const &)info; + +@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager+Entity.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager+Entity.mm new file mode 100644 index 0000000000..2106bb7ad0 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager+Entity.mm @@ -0,0 +1,149 @@ +#import "MWMLocationManager.h" +#import "MWMNavigationDashboardEntity.h" +#import "MWMNavigationDashboardManager+Entity.h" +#import "MWMRouter.h" +#import "SwiftBridge.h" + +#include "geometry/distance_on_sphere.hpp" +#include "routing/turns.hpp" + +namespace +{ +UIImage * image(routing::turns::CarDirection t, bool isNextTurn) +{ + if ([MWMRouter type] == MWMRouterTypePedestrian) + return [UIImage imageNamed:@"ic_direction"]; + + using namespace routing::turns; + NSString * imageName; + switch (t) + { + case CarDirection::TurnSlightRight: imageName = @"slight_right"; break; + case CarDirection::TurnRight: imageName = @"simple_right"; break; + case CarDirection::TurnSharpRight: imageName = @"sharp_right"; break; + case CarDirection::TurnSlightLeft: imageName = @"slight_left"; break; + case CarDirection::TurnLeft: imageName = @"simple_left"; break; + case CarDirection::TurnSharpLeft: imageName = @"sharp_left"; break; + case CarDirection::UTurnLeft: imageName = @"uturn_left"; break; + case CarDirection::UTurnRight: imageName = @"uturn_right"; break; + case CarDirection::ReachedYourDestination: imageName = @"finish_point"; break; + case CarDirection::LeaveRoundAbout: + case CarDirection::EnterRoundAbout: imageName = @"round"; break; + case CarDirection::GoStraight: imageName = @"straight"; break; + case CarDirection::StartAtEndOfStreet: + case CarDirection::StayOnRoundAbout: + case CarDirection::TakeTheExit: + case CarDirection::Count: + case CarDirection::None: imageName = isNextTurn ? nil : @"straight"; break; + } + if (!imageName) + return nil; + return [UIImage imageNamed:isNextTurn ? [imageName stringByAppendingString:@"_then"] : imageName]; +} +} // namespace + +@interface MWMNavigationDashboardEntity () + +@property(nonatomic, readwrite) CLLocation * pedestrianDirectionPosition; +@property(nonatomic, readwrite) BOOL isValid; +@property(nonatomic, readwrite) NSString * targetDistance; +@property(nonatomic, readwrite) NSString * targetUnits; +@property(nonatomic, readwrite) NSString * distanceToTurn; +@property(nonatomic, readwrite) NSString * turnUnits; +@property(nonatomic, readwrite) NSString * streetName; +@property(nonatomic, readwrite) UIImage * turnImage; +@property(nonatomic, readwrite) UIImage * nextTurnImage; +@property(nonatomic, readwrite) NSUInteger roundExitNumber; +@property(nonatomic, readwrite) NSUInteger timeToTarget; +@property(nonatomic, readwrite) CGFloat progress; +@property(nonatomic, readwrite) BOOL isPedestrian; +@property(nonatomic, readwrite) NSAttributedString * estimate; + +@end + +@interface MWMNavigationDashboardManager () + +@property(nonatomic) MWMNavigationDashboardEntity * entity; + +- (void)onNavigationInfoUpdated; + +@end + +@implementation MWMNavigationDashboardManager (Entity) + +- (void)updateFollowingInfo:(location::FollowingInfo const &)info +{ + if ([MWMRouter isRouteFinished]) + { + [MWMRouter stopRouting]; + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); + return; + } + + if (auto entity = self.entity) + { + entity.isValid = info.IsValid(); + entity.timeToTarget = info.m_time; + entity.targetDistance = @(info.m_distToTarget.c_str()); + entity.targetUnits = @(info.m_targetUnitsSuffix.c_str()); + entity.progress = info.m_completionPercent; + CLLocation * lastLocation = [MWMLocationManager lastLocation]; + if (lastLocation && [MWMRouter type] == MWMRouterTypePedestrian) + { + entity.isPedestrian = YES; + string distance; + CLLocationCoordinate2D const & coordinate = lastLocation.coordinate; + + auto const lat = info.m_pedestrianDirectionPos.lat; + auto const lon = info.m_pedestrianDirectionPos.lon; + entity.pedestrianDirectionPosition = [[CLLocation alloc] initWithLatitude:lat longitude:lon]; + // TODO: Not the best solution, but this solution is temporary and will be replaced in future + measurement_utils::FormatDistance( + ms::DistanceOnEarth(coordinate.latitude, coordinate.longitude, lat, lon), distance); + istringstream is(distance); + string dist; + string units; + is >> dist; + is >> units; + entity.nextTurnImage = nil; + entity.distanceToTurn = @(dist.c_str()); + entity.turnUnits = @(units.c_str()); + entity.streetName = @""; + } + else + { + entity.isPedestrian = NO; + entity.distanceToTurn = @(info.m_distToTurn.c_str()); + entity.turnUnits = @(info.m_turnUnitsSuffix.c_str()); + entity.streetName = @(info.m_targetName.c_str()); + entity.nextTurnImage = image(info.m_nextTurn, true); + } + + NSDictionary * etaAttributes = @{ + NSForegroundColorAttributeName : UIColor.blackPrimaryText, + NSFontAttributeName : UIFont.medium17 + }; + NSString * eta = [NSDateComponentsFormatter etaStringFrom:entity.timeToTarget]; + NSString * resultString = + [NSString stringWithFormat:@"%@ • %@ %@", eta, entity.targetDistance, entity.targetUnits]; + NSMutableAttributedString * result = + [[NSMutableAttributedString alloc] initWithString:resultString]; + [result addAttributes:etaAttributes range:NSMakeRange(0, resultString.length)]; + entity.estimate = [result copy]; + + using namespace routing::turns; + CarDirection const turn = info.m_turn; + entity.turnImage = image(turn, false); + BOOL const isRound = turn == CarDirection::EnterRoundAbout || + turn == CarDirection::StayOnRoundAbout || + turn == CarDirection::LeaveRoundAbout; + if (isRound) + entity.roundExitNumber = info.m_exitNum; + else + entity.roundExitNumber = 0; + } + + [self onNavigationInfoUpdated]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h index de5cb97b5e..5697a338ab 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h @@ -1,15 +1,7 @@ #import "MWMBottomMenuView.h" -#import "MWMCircularProgress.h" - -#import "MWMNavigationDashboardEntity.h" -#import "MWMNavigationDashboardInfoProtocol.h" -#import "MWMNavigationViewProtocol.h" -#import "MWMRoutePreview.h" +#import "MWMNavigationDashboardObserver.h" #import "MWMTaxiPreviewDataSource.h" -#include "Framework.h" -#include "platform/location.hpp" - typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) { MWMNavigationDashboardStateHidden, MWMNavigationDashboardStatePrepare, @@ -19,40 +11,23 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) { MWMNavigationDashboardStateNavigation }; -@protocol MWMNavigationDashboardManagerProtocol - -- (void)setMenuState:(MWMBottomMenuState)menuState; -- (void)setMenuRestoreState:(MWMBottomMenuState)menuState; -- (void)setRoutingErrorMessage:(NSString *)errorMessage; -- (MWMTaxiCollectionView *)taxiCollectionView; - -@end - @interface MWMNavigationDashboardManager : NSObject + (MWMNavigationDashboardManager *)manager; ++ (void)addObserver:(id)observer; ++ (void)removeObserver:(id)observer; -@property(nonatomic, readonly) MWMNavigationDashboardEntity * entity; -@property(nonatomic, readonly) MWMRoutePreview * routePreview; @property(nonatomic) MWMNavigationDashboardState state; -@property(nonatomic) MWMTaxiPreviewDataSource * taxiDataSource; -@property(weak, nonatomic, readonly) id delegate; -@property(nonatomic) CGFloat topBound; -@property(nonatomic) CGFloat leftBound; +@property(nonatomic, readonly) MWMTaxiPreviewDataSource * taxiDataSource; +@property(nonatomic) NSString * errorMessage; - (instancetype)init __attribute__((unavailable("init is not available"))); -- (instancetype)initWithParentView:(UIView *)view - delegate:(id)delegate; -- (void)updateFollowingInfo:(location::FollowingInfo const &)info; -- (void)updateDashboard; +- (instancetype)initWithParentView:(UIView *)view; - (void)setRouteBuilderProgress:(CGFloat)progress; - (void)mwm_refreshUI; -- (void)setMapSearch; - -- (void)addInfoDisplay:(id)infoDisplay; - -- (void)updateStartButtonTitle:(UIButton *)startButton; - (void)onRoutePointsUpdated; ++ (void)updateNavigationInfoAvailableArea:(CGRect)frame; + @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm index ab8985eebd..d7f04237de 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm @@ -4,26 +4,32 @@ #import "MWMCommon.h" #import "MWMLocationHelpers.h" #import "MWMMapViewControlsManager.h" +#import "MWMNavigationDashboardEntity.h" #import "MWMNavigationInfoView.h" #import "MWMRoutePoint+CPP.h" #import "MWMRoutePreview.h" #import "MWMRouter.h" -#import "MWMTaxiPreviewDataSource.h" +#import "MWMSearchManager.h" #import "MWMTextToSpeech.h" +#import "MWMTrafficManager.h" #import "MapViewController.h" #import "MapsAppDelegate.h" #import "Statistics.h" +#import "SwiftBridge.h" #include "platform/platform.hpp" +extern NSString * const kAlohalyticsTapEventKey; + namespace { -NSString * const kRoutePreviewXibName = @"MWMRoutePreview"; NSString * const kRoutePreviewIPADXibName = @"MWMiPadRoutePreview"; +NSString * const kRoutePreviewIPhoneXibName = @"MWMiPhoneRoutePreview"; NSString * const kNavigationInfoViewXibName = @"MWMNavigationInfoView"; +NSString * const kNavigationControlViewXibName = @"NavigationControlView"; -using TInfoDisplay = id; -using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; +using TObserver = id; +using TObservers = NSHashTable<__kindof TObserver>; } // namespace @interface MWMMapViewControlsManager () @@ -32,16 +38,18 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; @end -@interface MWMNavigationDashboardManager () +@interface MWMNavigationDashboardManager () -@property(nonatomic, readwrite) IBOutlet MWMRoutePreview * routePreview; +@property(nonatomic) IBOutlet MWMNavigationControlView * navigationControlView; @property(nonatomic) IBOutlet MWMNavigationInfoView * navigationInfoView; - -@property(nonatomic) TInfoDisplays * infoDisplays; - -@property(weak, nonatomic) UIView * ownerView; - +@property(nonatomic) IBOutlet MWMRoutePreview * routePreview; +@property(nonatomic) IBOutlet MWMRoutePreviewStatus * statusBox; +@property(nonatomic) IBOutlet MWMRouteStartButton * goButton; @property(nonatomic) MWMNavigationDashboardEntity * entity; +@property(nonatomic) TObservers * observers; +@property(nonatomic, readwrite) MWMTaxiPreviewDataSource * taxiDataSource; +@property(weak, nonatomic) IBOutlet MWMTaxiCollectionView * taxiCollectionView; +@property(weak, nonatomic) UIView * ownerView; @end @@ -53,46 +61,22 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; } - (instancetype)initWithParentView:(UIView *)view - delegate:(id)delegate { self = [super init]; if (self) { _ownerView = view; - _delegate = delegate; - _infoDisplays = [TInfoDisplays weakObjectsHashTable]; + _observers = [TObservers weakObjectsHashTable]; } return self; } -- (void)updateFollowingInfo:(location::FollowingInfo const &)info +- (void)loadPreviewWithStatusBox { - if ([MWMRouter isRouteFinished]) - { - [MWMRouter stopRouting]; - AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); - return; - } - - [self.entity updateFollowingInfo:info]; - [self updateDashboard]; -} - -- (void)handleError -{ - if ([MWMRouter isTaxi]) - return; - - [self.routePreview stateError]; - [self.routePreview router:[MWMRouter type] setState:MWMCircularProgressStateFailed]; -} - -- (void)updateDashboard -{ - if (!self.entity.isValid) - return; - for (TInfoDisplay infoDisplay in self.infoDisplays) - [infoDisplay updateNavigationInfo:self.entity]; + [NSBundle.mainBundle loadNibNamed:IPAD ? kRoutePreviewIPADXibName : kRoutePreviewIPhoneXibName + owner:self + options:nil]; + _statusBox.ownerView = self.ownerView; } #pragma mark - MWMRoutePreview @@ -102,63 +86,81 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; [self.routePreview router:[MWMRouter type] setProgress:progress / 100.]; } -#pragma mark - MWMNavigationDashboard - -- (IBAction)routingStopTouchUpInside -{ - if (IPAD && self.state != MWMNavigationDashboardStateNavigation) - [self.delegate routePreviewDidChangeFrame:{}]; - [MWMRouter stopRouting]; -} - -#pragma mark - MWMTaxiDataSource - -- (MWMTaxiPreviewDataSource *)taxiDataSource -{ - if (!_taxiDataSource) - { - _taxiDataSource = [[MWMTaxiPreviewDataSource alloc] initWithCollectionView:IPAD ? - self.routePreview.taxiCollectionView : self.delegate.taxiCollectionView]; - } - return _taxiDataSource; -} - #pragma mark - MWMNavigationGo - (IBAction)routingStartTouchUpInside { [MWMRouter startRouting]; } +- (void)updateGoButtonTitle +{ + NSString * title = nil; + if ([MWMRouter isTaxi]) + title = self.taxiDataSource.isTaxiInstalled ? L(@"taxi_order") : L(@"install_app"); + else + title = L(@"p2p_start"); + + [self.goButton setTitle:title forState:UIControlStateNormal]; +} + +- (void)onRoutePointsUpdated { [self.navigationInfoView updateToastView]; } +- (void)mwm_refreshUI +{ + [_routePreview mwm_refreshUI]; + [_navigationInfoView mwm_refreshUI]; + [_navigationControlView mwm_refreshUI]; + [_statusBox mwm_refreshUI]; +} + +- (void)onNavigationInfoUpdated +{ + auto entity = self.entity; + if (!entity.isValid) + return; + [_navigationInfoView onNavigationInfoUpdated:entity]; + [_statusBox onNavigationInfoUpdated:entity]; + [_navigationControlView onNavigationInfoUpdated:entity]; +} #pragma mark - State changes -- (void)hideState +- (void)stateHidden { + self.taxiDataSource = nil; [self.routePreview remove]; self.routePreview = nil; self.navigationInfoView.state = MWMNavigationInfoViewStateHidden; self.navigationInfoView = nil; + self.navigationControlView.isVisible = NO; + self.navigationControlView = nil; + [self.statusBox stateNavigation]; + self.statusBox = nil; } -- (void)showStatePrepare +- (void)statePrepare { self.navigationInfoView.state = MWMNavigationInfoViewStatePrepare; - [self.routePreview addToView:self.ownerView]; - [self.routePreview statePrepare]; - [self.routePreview selectRouter:[MWMRouter type]]; - [self setMenuState:MWMBottomMenuStateHidden]; + auto routePreview = self.routePreview; + [routePreview addToView:self.ownerView]; + [routePreview statePrepare]; + [routePreview selectRouter:[MWMRouter type]]; + [self updateGoButtonTitle]; + [self.goButton statePrepare]; + [self.statusBox statePrepare]; } -- (void)showStatePlanning +- (void)statePlanning { - [self showStatePrepare]; + [self statePrepare]; [self.routePreview router:[MWMRouter type] setState:MWMCircularProgressStateSpinner]; [self setRouteBuilderProgress:0.]; if (![MWMRouter isTaxi]) return; - auto showError = ^(NSString * errorMessage) - { - [self.routePreview stateError]; - [self.routePreview router:MWMRouterTypeTaxi setState:MWMCircularProgressStateFailed]; - [self setMenuErrorStateWithErrorMessage:errorMessage]; + __weak auto wSelf = self; + auto showError = ^(NSString * errorMessage) { + __strong auto self = wSelf; + if (!self) + return; + self.errorMessage = errorMessage; + self.state = MWMNavigationDashboardStateError; }; auto pFrom = [MWMRouter startPoint]; @@ -172,131 +174,151 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; return; } [self.taxiDataSource requestTaxiFrom:pFrom - to:pTo - completion:^{ - [self setMenuState:MWMBottomMenuStateGo]; - [self.routePreview stateReady]; - [self setRouteBuilderProgress:100.]; - } - failure:^(NSString * errorMessage) { - showError(errorMessage); - }]; + to:pTo + completion:^{ + wSelf.state = MWMNavigationDashboardStateReady; + } + failure:^(NSString * errorMessage) { + showError(errorMessage); + }]; } -- (void)showStateReady +- (void)stateError { - if ([MWMRouter isTaxi]) - return; - - [self setMenuState:MWMBottomMenuStateGo]; - [self.routePreview stateReady]; + NSAssert(_state == MWMNavigationDashboardStatePlanning, @"Invalid state change (error)"); + auto routePreview = self.routePreview; + [routePreview router:[MWMRouter type] setState:MWMCircularProgressStateFailed]; + [self updateGoButtonTitle]; + [self.goButton stateError]; + [self.statusBox stateErrorWithMessage:self.errorMessage]; } -- (void)showStateNavigation +- (void)stateReady +{ + NSAssert(_state == MWMNavigationDashboardStatePlanning, @"Invalid state change (ready)"); + [self setRouteBuilderProgress:100.]; + [self updateGoButtonTitle]; + [self.goButton stateReady]; + [self.statusBox stateReady]; +} + +- (void)stateNavigation { - [self setMenuState:MWMBottomMenuStateRouting]; [self.routePreview remove]; self.routePreview = nil; self.navigationInfoView.state = MWMNavigationInfoViewStateNavigation; + self.navigationControlView.isVisible = YES; + [self.statusBox stateNavigation]; + self.statusBox = nil; } -- (void)updateStartButtonTitle:(UIButton *)startButton +#pragma mark - MWMNavigationControlView + +- (IBAction)ttsButtonAction { - auto t = self.startButtonTitle; - [startButton setTitle:t forState:UIControlStateNormal]; - [startButton setTitle:t forState:UIControlStateDisabled]; + BOOL const isEnabled = [MWMTextToSpeech tts].active; + [Statistics logEvent:kStatMenu withParameters:@{kStatTTS : isEnabled ? kStatOn : kStatOff}]; + [MWMTextToSpeech tts].active = !isEnabled; } -- (void)onRoutePointsUpdated { [self.navigationInfoView updateToastView]; } -- (void)setMenuErrorStateWithErrorMessage:(NSString *)message +- (IBAction)trafficButtonAction { - [self.delegate setRoutingErrorMessage:message]; - [self setMenuState:MWMBottomMenuStateRoutingError]; + BOOL const switchOn = ([MWMTrafficManager state] == MWMTrafficManagerStateDisabled); + [Statistics logEvent:kStatMenu withParameters:@{kStatTraffic : switchOn ? kStatOn : kStatOff}]; + [MWMTrafficManager enableTraffic:switchOn]; } -- (void)setMenuState:(MWMBottomMenuState)menuState +- (IBAction)settingsButtonAction { - id delegate = self.delegate; - [delegate setMenuState:menuState]; - [delegate setMenuRestoreState:menuState]; + [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatSettings}]; + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"settingsAndMore"]; + [[MapViewController controller] performSegueWithIdentifier:@"Map2Settings" sender:nil]; } -- (void)mwm_refreshUI +- (IBAction)stopRoutingButtonAction { [MWMRouter stopRouting]; } +#pragma mark - Add/Remove Observers + ++ (void)addObserver:(id)observer { - if (_routePreview) - [self.routePreview mwm_refreshUI]; - if (_navigationInfoView) - [self.navigationInfoView mwm_refreshUI]; + [[MWMNavigationDashboardManager manager].observers addObject:observer]; } ++ (void)removeObserver:(id)observer +{ + [[MWMNavigationDashboardManager manager].observers removeObject:observer]; +} + +#pragma mark - MWMNavigationDashboardObserver + +- (void)onNavigationDashboardStateChanged +{ + for (TObserver observer in self.observers) + [observer onNavigationDashboardStateChanged]; +} + +#pragma mark - MWMSearchManagerObserver + +- (void)onSearchManagerStateChanged +{ + auto state = [MWMSearchManager manager].state; + if (state == MWMSearchManagerStateMapSearch) + [self setMapSearch]; +} + +#pragma mark - Available area + ++ (void)updateNavigationInfoAvailableArea:(CGRect)frame +{ + [[MWMNavigationDashboardManager manager] updateNavigationInfoAvailableArea:frame]; +} + +- (void)updateNavigationInfoAvailableArea:(CGRect)frame { _navigationInfoView.frame = frame; } #pragma mark - Properties - (void)setState:(MWMNavigationDashboardState)state { + if (_state == state) + return; + if (state == MWMNavigationDashboardStateHidden) + [MWMSearchManager removeObserver:self]; + else + [MWMSearchManager addObserver:self]; switch (state) { - case MWMNavigationDashboardStateHidden: [self hideState]; break; - case MWMNavigationDashboardStatePrepare: [self showStatePrepare]; break; - case MWMNavigationDashboardStatePlanning: [self showStatePlanning]; break; - case MWMNavigationDashboardStateError: - NSAssert( - _state == MWMNavigationDashboardStatePlanning || _state == MWMNavigationDashboardStateReady, - @"Invalid state change (error)"); - [self handleError]; - break; - case MWMNavigationDashboardStateReady: - NSAssert(_state == MWMNavigationDashboardStatePlanning, @"Invalid state change (ready)"); - [self showStateReady]; - break; - case MWMNavigationDashboardStateNavigation: [self showStateNavigation]; break; + case MWMNavigationDashboardStateHidden: [self stateHidden]; break; + case MWMNavigationDashboardStatePrepare: [self statePrepare]; break; + case MWMNavigationDashboardStatePlanning: [self statePlanning]; break; + case MWMNavigationDashboardStateError: [self stateError]; break; + case MWMNavigationDashboardStateReady: [self stateReady]; break; + case MWMNavigationDashboardStateNavigation: [self stateNavigation]; break; } _state = state; [[MapViewController controller] updateStatusBarStyle]; - [self updateDashboard]; + [self onNavigationDashboardStateChanged]; } -- (void)setTopBound:(CGFloat)topBound +- (MWMTaxiPreviewDataSource *)taxiDataSource { - _topBound = topBound; - if (_routePreview) - self.routePreview.topBound = topBound; - if (_navigationInfoView) - self.navigationInfoView.topBound = topBound; + if (!_taxiDataSource) + _taxiDataSource = + [[MWMTaxiPreviewDataSource alloc] initWithCollectionView:self.taxiCollectionView]; + return _taxiDataSource; } -- (void)setLeftBound:(CGFloat)leftBound -{ - _leftBound = leftBound; - if (_routePreview && IPAD) - self.routePreview.leftBound = leftBound; - if (_navigationInfoView) - self.navigationInfoView.leftBound = leftBound; -} - -- (void)addInfoDisplay:(TInfoDisplay)infoDisplay { [self.infoDisplays addObject:infoDisplay]; } -- (NSString *)startButtonTitle -{ - if (![MWMRouter isTaxi]) - return L(@"p2p_start"); - return self.taxiDataSource.isTaxiInstalled ? L(@"taxi_order") : L(@"install_app"); -} - -#pragma mark - Properties - - (MWMRoutePreview *)routePreview { if (!_routePreview) - { - [NSBundle.mainBundle loadNibNamed:IPAD ? kRoutePreviewIPADXibName : kRoutePreviewXibName - owner:self - options:nil]; - _routePreview.dashboardManager = self; - _routePreview.delegate = self.delegate; - [self addInfoDisplay:_routePreview]; - } + [self loadPreviewWithStatusBox]; return _routePreview; } +- (MWMRoutePreviewStatus *)statusBox +{ + if (!_statusBox) + [self loadPreviewWithStatusBox]; + return _statusBox; +} + - (MWMNavigationInfoView *)navigationInfoView { if (!_navigationInfoView) @@ -304,11 +326,20 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; [NSBundle.mainBundle loadNibNamed:kNavigationInfoViewXibName owner:self options:nil]; _navigationInfoView.state = MWMNavigationInfoViewStateHidden; _navigationInfoView.ownerView = self.ownerView; - [self addInfoDisplay:_navigationInfoView]; } return _navigationInfoView; } +- (MWMNavigationControlView *)navigationControlView +{ + if (!_navigationControlView) + { + [NSBundle.mainBundle loadNibNamed:kNavigationControlViewXibName owner:self options:nil]; + _navigationControlView.ownerView = self.ownerView; + } + return _navigationControlView; +} + - (MWMNavigationDashboardEntity *)entity { if (!_entity) @@ -318,8 +349,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; - (void)setMapSearch { - if (_navigationInfoView) - [self.navigationInfoView setMapSearch]; + [_navigationInfoView setMapSearch]; } @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardObserver.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardObserver.h new file mode 100644 index 0000000000..2db38612c0 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardObserver.h @@ -0,0 +1,5 @@ +@protocol MWMNavigationDashboardObserver + +- (void)onNavigationDashboardStateChanged; + +@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h index 026b329f46..48e5feef75 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.h @@ -1,5 +1,3 @@ -#import "MWMNavigationDashboardInfoProtocol.h" - enum class NavigationSearchState { Maximized, @@ -18,14 +16,16 @@ typedef NS_ENUM(NSUInteger, MWMNavigationInfoViewState) { MWMNavigationInfoViewStateNavigation }; -@interface MWMNavigationInfoView : UIView +@class MWMNavigationDashboardEntity; + +@interface MWMNavigationInfoView : UIView -@property(nonatomic) CGFloat topBound; -@property(nonatomic) CGFloat leftBound; @property(nonatomic, readonly) NavigationSearchState searchState; @property(nonatomic) MWMNavigationInfoViewState state; @property(weak, nonatomic) UIView * ownerView; +- (void)onNavigationInfoUpdated:(MWMNavigationDashboardEntity *)info; + - (void)setMapSearch; - (void)updateToastView; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm index 428c095897..e245cfa157 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.mm @@ -8,6 +8,7 @@ #import "MWMLocationObserver.h" #import "MWMMapViewControlsManager.h" #import "MWMMapWidgets.h" +#import "MWMNavigationDashboardEntity.h" #import "MWMRouter.h" #import "MWMSearch.h" #import "MapViewController.h" @@ -77,6 +78,7 @@ BOOL defaultOrientation(CGSize const & size) @property(weak, nonatomic) IBOutlet NSLayoutConstraint * searchButtonsViewHeight; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * searchButtonsViewWidth; @property(nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray * searchLandscapeConstraints; +@property(weak, nonatomic) IBOutlet NSLayoutConstraint * searchButtonsToastOffset; @property(nonatomic) IBOutletCollection(UIButton) NSArray * searchButtons; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * searchButtonsSideSize; @property(weak, nonatomic) IBOutlet MWMButton * searchGasButton; @@ -96,20 +98,12 @@ BOOL defaultOrientation(CGSize const & size) @property(nonatomic) BOOL hasLocation; +@property(nonatomic) CGRect availableArea; + @end @implementation MWMNavigationInfoView -- (void)layoutSubviews -{ - [super layoutSubviews]; - if (!CGRectEqualToRect(self.frame, self.defaultFrame)) - { - self.frame = self.defaultFrame; - [self setNeedsLayout]; - } -} - - (void)setMapSearch { [self setSearchState:NavigationSearchState::MinimizedSearch animated:YES]; } - (void)updateToastView { @@ -159,7 +153,7 @@ BOOL defaultOrientation(CGSize const & size) BOOL const isStart = ([MWMRouter startPoint] == nil); auto const type = isStart ? kStatRoutingPointTypeStart : kStatRoutingPointTypeFinish; [Statistics logEvent:kStatRoutingTooltipClicked withParameters:@{kStatRoutingPointType : type}]; - [MWMMapViewControlsManager manager].searchHidden = NO; + [MWMSearchManager manager].state = MWMSearchManagerStateDefault; } - (IBAction)addLocationRoutePoint @@ -187,14 +181,14 @@ BOOL defaultOrientation(CGSize const & size) switch (self.searchState) { case NavigationSearchState::Maximized: - [MWMMapViewControlsManager manager].searchHidden = NO; + [MWMSearchManager manager].state = MWMSearchManagerStateDefault; [self setSearchState:NavigationSearchState::MinimizedNormal animated:YES]; [Statistics logEvent:kStatRoutingSearchClicked withParameters:@{ kStatRoutingMode : kStatRoutingModeOnRoute }]; break; case NavigationSearchState::MinimizedNormal: if (self.state == MWMNavigationInfoViewStatePrepare) { - [MWMMapViewControlsManager manager].searchHidden = NO; + [MWMSearchManager manager].state = MWMSearchManagerStateDefault; [Statistics logEvent:kStatRoutingSearchClicked withParameters:@{ kStatRoutingMode : kStatRoutingModePlanning }]; } else @@ -209,7 +203,7 @@ BOOL defaultOrientation(CGSize const & size) case NavigationSearchState::MinimizedShop: case NavigationSearchState::MinimizedATM: [MWMSearch clear]; - [MWMMapViewControlsManager manager].searchHidden = YES; + [MWMSearchManager manager].state = MWMSearchManagerStateHidden; [self setSearchState:NavigationSearchState::MinimizedNormal animated:YES]; break; } @@ -252,9 +246,38 @@ BOOL defaultOrientation(CGSize const & size) [self setSearchState:NavigationSearchState::MinimizedNormal animated:YES]; } -#pragma mark - MWMNavigationDashboardInfoProtocol +- (void)layoutSearch +{ + BOOL const defaultView = defaultOrientation(self.frame.size); + CGFloat alpha = 1; + CGFloat searchButtonsSideSize = kSearchButtonsSideSize; + if (self.searchState == NavigationSearchState::Maximized) + { + self.searchButtonsViewWidth.constant = + defaultView ? kSearchButtonsViewWidthPortrait : kSearchButtonsViewWidthLandscape; + self.searchButtonsViewHeight.constant = + defaultView ? kSearchButtonsViewHeightPortrait : kSearchButtonsViewHeightLandscape; + } + else + { + self.searchButtonsViewWidth.constant = 0; + self.searchButtonsViewHeight.constant = 0; + alpha = 0; + searchButtonsSideSize = 0; + } + for (UIButton * searchButton in self.searchButtons) + searchButton.alpha = alpha; + UILayoutPriority const priority = + defaultView ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh; + for (NSLayoutConstraint * constraint in self.searchLandscapeConstraints) + constraint.priority = priority; + self.searchButtonsToastOffset.priority = priority + UILayoutPriorityFittingSizeLevel; + self.searchButtonsSideSize.constant = searchButtonsSideSize; +} -- (void)updateNavigationInfo:(MWMNavigationDashboardEntity *)info +#pragma mark - MWMNavigationDashboardManager + +- (void)onNavigationInfoUpdated:(MWMNavigationDashboardEntity *)info { self.navigationInfo = info; if (self.state != MWMNavigationInfoViewStateNavigation) @@ -320,34 +343,6 @@ BOOL defaultOrientation(CGSize const & size) [self setNeedsLayout]; } -- (void)layoutSearch -{ - BOOL const defaultView = defaultOrientation(self.frame.size); - CGFloat alpha = 1; - CGFloat searchButtonsSideSize = kSearchButtonsSideSize; - if (self.searchState == NavigationSearchState::Maximized) - { - self.searchButtonsViewWidth.constant = - defaultView ? kSearchButtonsViewWidthPortrait : kSearchButtonsViewWidthLandscape; - self.searchButtonsViewHeight.constant = - defaultView ? kSearchButtonsViewHeightPortrait : kSearchButtonsViewHeightLandscape; - } - else - { - self.searchButtonsViewWidth.constant = 0; - self.searchButtonsViewHeight.constant = 0; - alpha = 0; - searchButtonsSideSize = 0; - } - for (UIButton * searchButton in self.searchButtons) - searchButton.alpha = alpha; - UILayoutPriority const priority = - defaultView ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh; - for (NSLayoutConstraint * constraint in self.searchLandscapeConstraints) - constraint.priority = priority; - self.searchButtonsSideSize.constant = searchButtonsSideSize; -} - #pragma mark - MWMLocationObserver - (void)onLocationUpdate:(location::GpsInfo const &)gpsInfo @@ -364,10 +359,9 @@ BOOL defaultOrientation(CGSize const & size) if (lastLocation && self.state == MWMNavigationInfoViewStateNavigation && [MWMRouter type] == MWMRouterTypePedestrian) { - auto const mercator = - location_helpers::ToMercator(self.navigationInfo.pedestrianDirectionPosition); - auto const angle = ang::AngleTo(lastLocation.mercator, mercator) + info.m_bearing; - transform = CATransform3DMakeRotation(M_PI_2 - angle, 0, 0, 1); + auto const angle = ang::AngleTo(lastLocation.mercator, + self.navigationInfo.pedestrianDirectionPosition.mercator); + transform = CATransform3DMakeRotation(M_PI_2 - angle + info.m_bearing, 0, 0, 1); } self.nextTurnImageView.layer.transform = transform; } @@ -408,14 +402,10 @@ BOOL defaultOrientation(CGSize const & size) - (void)setFrame:(CGRect)frame { - CGSize const & oldSize = self.frame.size; - CGSize const & size = frame.size; - if (CGRectEqualToRect(self.frame, frame) || (equalScreenDimensions(oldSize.width, size.width) && - equalScreenDimensions(oldSize.height, size.height))) - return; super.frame = frame; - [self layoutIfNeeded]; + [self setNeedsLayout]; [self layoutSearch]; + self.turnsTopOffset.constant = self.minY > 0 ? kShiftedTurnsTopOffset : kBaseTurnsTopOffset; [UIView animateWithDuration:kDefaultAnimationDuration animations:^{ self.searchButtonsView.layer.cornerRadius = @@ -463,11 +453,14 @@ BOOL defaultOrientation(CGSize const & size) - (void)setState:(MWMNavigationInfoViewState)state { + if (_state == state) + return; _state = state; switch (state) { case MWMNavigationInfoViewStateHidden: self.isVisible = NO; + [self setToastViewHidden:YES]; [MWMLocationManager removeObserver:self]; break; case MWMNavigationInfoViewStateNavigation: @@ -502,10 +495,10 @@ BOOL defaultOrientation(CGSize const & size) - (void)setIsVisible:(BOOL)isVisible { - [self setNeedsLayout]; if (_isVisible == isVisible) return; _isVisible = isVisible; + [self setNeedsLayout]; if (isVisible) { self.bookmarksButton.imageName = @"ic_routing_bookmark"; @@ -517,29 +510,14 @@ BOOL defaultOrientation(CGSize const & size) return; [sv insertSubview:self atIndex:0]; } - else - { - [self removeFromSuperview]; - } -} - -- (CGRect)defaultFrame -{ - return {{self.leftBound, self.topBound}, - {self.superview.width - self.leftBound, self.superview.height - self.topBound}}; -} - -- (void)setTopBound:(CGFloat)topBound -{ - _topBound = MAX(topBound, 0.0); - self.turnsTopOffset.constant = topBound > 0 ? kShiftedTurnsTopOffset : kBaseTurnsTopOffset; - [self setNeedsLayout]; -} - -- (void)setLeftBound:(CGFloat)leftBound -{ - _leftBound = MAX(leftBound, 0.0); - [self setNeedsLayout]; + [UIView animateWithDuration:kDefaultAnimationDuration + animations:^{ + [self layoutIfNeeded]; + } + completion:^(BOOL finished) { + if (!isVisible) + [self removeFromSuperview]; + }]; } - (void)setToastViewHidden:(BOOL)hidden @@ -548,14 +526,15 @@ BOOL defaultOrientation(CGSize const & size) self.toastView.hidden = NO; [self setNeedsLayout]; self.toastViewHideOffset.priority = - hidden ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow; + (hidden ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow) + 20; [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - [self layoutIfNeeded]; - } completion:^(BOOL finished) { - if (hidden) - self.toastView.hidden = YES; - }]; + animations:^{ + [self layoutIfNeeded]; + } + completion:^(BOOL finished) { + if (hidden) + self.toastView.hidden = YES; + }]; } @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib index 4f24748a4a..8717ed0426 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationInfoView.xib @@ -1,5 +1,5 @@ - + @@ -367,7 +367,7 @@ - + @@ -378,14 +378,14 @@ - + - + - + @@ -430,7 +430,6 @@ - diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h deleted file mode 100644 index 4de53b4bc7..0000000000 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h +++ /dev/null @@ -1,17 +0,0 @@ -#import "MWMNavigationViewProtocol.h" - -@interface MWMNavigationView : SolidTouchView - -@property (nonatomic) CGFloat topBound; -@property (nonatomic) CGFloat leftBound; -@property (nonatomic) CGFloat defaultHeight; -@property (nonatomic, readonly) BOOL isVisible; -@property (nonatomic) UIView * statusbarBackground; -@property (weak, nonatomic) id delegate; -@property (weak, nonatomic, readonly) IBOutlet UIView * contentView; - -- (void)addToView:(UIView *)superview; -- (void)remove; -- (CGRect)defaultFrame; - -@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.mm deleted file mode 100644 index 305e1f2a98..0000000000 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.mm +++ /dev/null @@ -1,87 +0,0 @@ -#import "MWMNavigationView.h" -#import "MWMCommon.h" - -@interface MWMNavigationView () - -@property(nonatomic) BOOL isVisible; - -@property(weak, nonatomic, readwrite) IBOutlet UIView * contentView; - -@end - -@implementation MWMNavigationView - -- (void)awakeFromNib -{ - [super awakeFromNib]; - self.statusbarBackground = [[UIView alloc] initWithFrame:CGRectZero]; - self.statusbarBackground.backgroundColor = self.contentView.backgroundColor; - self.defaultHeight = self.height; - self.topBound = 0.0; - self.leftBound = 0.0; -} - -- (void)addToView:(UIView *)superview -{ - self.frame = self.defaultFrame; - self.isVisible = YES; - NSAssert(superview != nil, @"Superview can't be nil"); - if ([superview.subviews containsObject:self]) - return; - [superview addSubview:self]; -} - -- (void)remove { self.isVisible = NO; } -- (void)layoutSubviews -{ - [super layoutSubviews]; - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - if (!CGRectEqualToRect(self.frame, self.defaultFrame)) - self.frame = self.defaultFrame; - CGFloat const sbHeight = statusBarHeight(); - self.statusbarBackground.frame = CGRectMake(0.0, -sbHeight, self.width, sbHeight); - } - completion:^(BOOL finished) { - if (!self.isVisible) - [self removeFromSuperview]; - }]; -} - -#pragma mark - Properties - -- (CGRect)defaultFrame -{ - return CGRectMake(self.leftBound, self.isVisible ? self.topBound : -self.defaultHeight, - self.superview.width, self.defaultHeight); -} - -- (void)setTopBound:(CGFloat)topBound -{ - CGFloat const sbHeight = statusBarHeight(); - _topBound = MAX(topBound, sbHeight); - if (_topBound <= sbHeight) - { - if (![self.statusbarBackground.superview isEqual:self]) - [self addSubview:self.statusbarBackground]; - } - else - { - [self.statusbarBackground removeFromSuperview]; - } - [self setNeedsLayout]; -} - -- (void)setLeftBound:(CGFloat)leftBound -{ - _leftBound = MAX(leftBound, 0.0); - [self setNeedsLayout]; -} - -- (void)setIsVisible:(BOOL)isVisible -{ - _isVisible = isVisible; - [self setNeedsLayout]; -} - -@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationViewProtocol.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationViewProtocol.h deleted file mode 100644 index 03794cff3e..0000000000 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationViewProtocol.h +++ /dev/null @@ -1,5 +0,0 @@ -@protocol MWMNavigationViewProtocol - -- (void)routePreviewDidChangeFrame:(CGRect)newFrame; - -@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/NavigationControlView.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/NavigationControlView.swift new file mode 100644 index 0000000000..0b93527153 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/NavigationControlView.swift @@ -0,0 +1,252 @@ +@objc(MWMNavigationControlView) +final class NavigationControlView: SolidTouchView, MWMTextToSpeechObserver, MWMTrafficManagerObserver { + @IBOutlet private weak var distanceLabel: UILabel! + @IBOutlet private weak var distanceLegendLabel: UILabel! + @IBOutlet private weak var distanceWithLegendLabel: UILabel! + @IBOutlet private weak var progressView: UIView! + @IBOutlet private weak var routingProgress: NSLayoutConstraint! + @IBOutlet private weak var speedLabel: UILabel! + @IBOutlet private weak var speedLegendLabel: UILabel! + @IBOutlet private weak var speedWithLegendLabel: UILabel! + @IBOutlet private weak var timeLabel: UILabel! + @IBOutlet private weak var timePageControl: UIPageControl! + + @IBOutlet private weak var extendButton: UIButton! { + didSet { + setExtendButtonImage() + } + } + + @IBOutlet private weak var ttsButton: UIButton! { + didSet { + ttsButton.setImage(#imageLiteral(resourceName: "ic_voice_off"), for: .normal) + ttsButton.setImage(#imageLiteral(resourceName: "ic_voice_on"), for: .selected) + ttsButton.setImage(#imageLiteral(resourceName: "ic_voice_on"), for: [.selected, .highlighted]) + onTTSStatusUpdated() + } + } + + @IBOutlet private weak var trafficButton: UIButton! { + didSet { + trafficButton.setImage(#imageLiteral(resourceName: "ic_setting_traffic_off"), for: .normal) + trafficButton.setImage(#imageLiteral(resourceName: "ic_setting_traffic_on"), for: .selected) + trafficButton.setImage(#imageLiteral(resourceName: "ic_setting_traffic_on"), for: [.selected, .highlighted]) + onTrafficStateUpdated() + } + } + + private lazy var dimBackground: DimBackground = { + DimBackground(mainView: self) + }() + weak var ownerView: UIView! + + private weak var navigationInfo: MWMNavigationDashboardEntity? + + private var hiddenConstraint: NSLayoutConstraint! + private var extendedConstraint: NSLayoutConstraint! + var isVisible = false { + didSet { + guard isVisible != oldValue else { return } + if isVisible { + addView() + } else { + dimBackground.setVisible(false) {} + } + DispatchQueue.main.async { + self.superview?.setNeedsLayout() + self.hiddenConstraint.isActive = !self.isVisible + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { self.superview?.layoutIfNeeded() }, + completion: { _ in + if (!self.isVisible) { + self.removeFromSuperview() + } + }) + } + } + } + + private var isExtended = false { + willSet { + guard isExtended != newValue else { return } + morphExtendButton() + } + didSet { + guard isVisible && superview != nil else { return } + guard isExtended != oldValue else { return } + + superview?.setNeedsLayout() + extendedConstraint.isActive = isExtended + UIView.animate(withDuration: kDefaultAnimationDuration) { self.superview?.layoutIfNeeded() } + + dimBackground.setVisible(isExtended) { [weak self] in + self?.diminish() + } + } + } + + private func addView() { + guard superview != ownerView else { return } + ownerView.addSubview(self) + + NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: ownerView, attribute: .left, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: ownerView, attribute: .right, multiplier: 1, constant: 0).isActive = true + + hiddenConstraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0) + hiddenConstraint.priority = UILayoutPriorityDefaultHigh + hiddenConstraint.isActive = true + + let visibleConstraint = NSLayoutConstraint(item: progressView, attribute: .bottom, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0) + visibleConstraint.priority = UILayoutPriorityDefaultLow + visibleConstraint.isActive = true + + extendedConstraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0) + extendedConstraint.priority = UILayoutPriorityDefaultHigh - 1 + } + + override func mwm_refreshUI() { + if isVisible { + super.mwm_refreshUI() + } + } + + override func awakeFromNib() { + super.awakeFromNib() + translatesAutoresizingMaskIntoConstraints = false + + MWMTextToSpeech.add(self) + MWMTrafficManager.add(self) + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + let isCompact = traitCollection.verticalSizeClass == .compact + distanceLabel.isHidden = isCompact + distanceLegendLabel.isHidden = isCompact + distanceWithLegendLabel.isHidden = !isCompact + speedLabel.isHidden = isCompact + speedLegendLabel.isHidden = isCompact + speedWithLegendLabel.isHidden = !isCompact + + let pgScale: CGFloat = isCompact ? 0.7 : 1 + timePageControl.transform = CGAffineTransform(scaleX: pgScale, y: pgScale) + } + + func onNavigationInfoUpdated(_ info: MWMNavigationDashboardEntity) { + navigationInfo = info + guard !MWMRouter.isTaxi() else { return } + + let routingNumberAttributes: [String : Any] = + [NSForegroundColorAttributeName : UIColor.blackPrimaryText(), NSFontAttributeName : UIFont.bold24()] + let routingLegendAttributes: [String : Any] = + [NSForegroundColorAttributeName : UIColor.blackSecondaryText(), NSFontAttributeName : UIFont.bold14()] + + if timePageControl.currentPage == 0 { + timeLabel.text = info.eta + } else { + timeLabel.text = info.arrival + } + + var distanceWithLegend: NSMutableAttributedString? + if let targetDistance = info.targetDistance { + distanceLabel.text = targetDistance + distanceWithLegend = NSMutableAttributedString(string: targetDistance, attributes: routingNumberAttributes) + } + + if let targetUnits = info.targetUnits { + distanceLegendLabel.text = targetUnits + if let distanceWithLegend = distanceWithLegend { + distanceWithLegend.append(NSAttributedString(string: targetUnits, attributes: routingLegendAttributes)) + distanceWithLegendLabel.attributedText = distanceWithLegend + } + } + + let speed = info.speed ?? "0" + speedLabel.text = speed + speedLegendLabel.text = info.speedUnits + let speedWithLegend = NSMutableAttributedString(string: speed, attributes: routingNumberAttributes) + speedWithLegend.append(NSAttributedString(string: info.speedUnits, attributes: routingLegendAttributes)) + speedWithLegendLabel.attributedText = speedWithLegend + + progressView.setNeedsLayout() + routingProgress.constant = progressView.width * info.progress / 100 + UIView.animate(withDuration: kDefaultAnimationDuration) { [progressView] in + progressView?.layoutIfNeeded() + } + } + + @IBAction + private func toggleInfoAction() { + if let navigationInfo = navigationInfo { + timePageControl.currentPage = (timePageControl.currentPage + 1) % timePageControl.numberOfPages + onNavigationInfoUpdated(navigationInfo) + } + refreshDiminishTimer() + } + + @IBAction + private func extendAction() { + isExtended = !isExtended + refreshDiminishTimer() + } + + private func morphExtendButton() { + guard let imageView = extendButton.imageView else { return } + let morphImagesCount = 6 + let startValue = isExtended ? morphImagesCount : 1 + let endValue = isExtended ? 0 : morphImagesCount + 1 + let stepValue = isExtended ? -1 : 1 + var morphImages: [UIImage] = [] + let nightMode = UIColor.isNightMode() ? "dark" : "light" + for i in stride(from: startValue, to: endValue, by: stepValue) { + let imageName = "ic_menu_\(i)_\(nightMode)" + morphImages.append(UIImage(named: imageName)!) + } + imageView.animationImages = morphImages + imageView.animationRepeatCount = 1 + imageView.image = morphImages.last + imageView.startAnimating() + setExtendButtonImage() + } + + private func setExtendButtonImage() { + DispatchQueue.main.async { + guard let imageView = self.extendButton.imageView else { return } + if imageView.isAnimating { + self.setExtendButtonImage() + } else { + self.extendButton.setImage(self.isExtended ? #imageLiteral(resourceName: "ic_menu_down") : #imageLiteral(resourceName: "ic_menu"), for: .normal) + } + } + } + + private func refreshDiminishTimer() { + let sel = #selector(diminish) + NSObject.cancelPreviousPerformRequests(withTarget: self, selector: sel, object: self) + perform(sel, with: self, afterDelay: 5) + } + + @objc + private func diminish() { + isExtended = false + } + + func onTTSStatusUpdated() { + guard MWMRouter.isRoutingActive() else { return } + let isPedestrianRouting = MWMRouter.type() == .pedestrian + ttsButton.isHidden = isPedestrianRouting || !MWMTextToSpeech.isTTSEnabled() + if !ttsButton.isHidden { + ttsButton.isSelected = MWMTextToSpeech.tts().active + } + refreshDiminishTimer() + } + + func onTrafficStateUpdated() { + trafficButton.isSelected = MWMTrafficManager.state() != .disabled + refreshDiminishTimer() + } + + override var sideButtonsAreaAffectDirections: MWMAvailableAreaAffectDirections { + return .bottom + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/NavigationControlView.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/NavigationControlView.xib new file mode 100644 index 0000000000..5265c89014 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/NavigationControlView.xib @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.h index 2b83dc946c..5c784f4124 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.h @@ -1,21 +1,19 @@ -#import "MWMCircularProgress.h" -#import "MWMNavigationDashboardInfoProtocol.h" -#import "MWMNavigationView.h" +#import "MWMCircularProgressState.h" @class MWMNavigationDashboardEntity; @class MWMNavigationDashboardManager; @class MWMTaxiCollectionView; -@interface MWMRoutePreview : MWMNavigationView +@interface MWMRoutePreview : UIView -@property(weak, nonatomic, readonly) IBOutlet MWMTaxiCollectionView * taxiCollectionView; -@property(weak, nonatomic) MWMNavigationDashboardManager * dashboardManager; +- (void)addToView:(UIView *)superview; +- (void)remove; - (void)statePrepare; -- (void)stateError; -- (void)stateReady; - (void)selectRouter:(MWMRouterType)routerType; - (void)router:(MWMRouterType)routerType setState:(MWMCircularProgressState)state; - (void)router:(MWMRouterType)routerType setProgress:(CGFloat)progress; +- (CGRect)defaultFrame; + @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm index e82cadda00..9d6ba117c6 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm @@ -2,6 +2,7 @@ #import "MWMCircularProgress.h" #import "MWMCommon.h" #import "MWMLocationManager.h" +#import "MWMNavigationDashboardEntity.h" #import "MWMNavigationDashboardManager.h" #import "MWMRouter.h" #import "MWMTaxiPreviewDataSource.h" @@ -12,41 +13,15 @@ #include "platform/platform.hpp" -namespace -{ -CGFloat constexpr kAdditionalHeight = 20.; -} // namespace - @interface MWMRoutePreview () +@property(nonatomic) BOOL isVisible; @property(weak, nonatomic) IBOutlet UIButton * backButton; -@property(weak, nonatomic) IBOutlet UIView * pedestrian; -@property(weak, nonatomic) IBOutlet UIView * vehicle; @property(weak, nonatomic) IBOutlet UIView * bicycle; +@property(weak, nonatomic) IBOutlet UIView * contentView; +@property(weak, nonatomic) IBOutlet UIView * pedestrian; @property(weak, nonatomic) IBOutlet UIView * taxi; -@property(weak, nonatomic) IBOutlet UIButton * goButton; -@property(weak, nonatomic) IBOutlet UIView * statusBox; -@property(weak, nonatomic) IBOutlet UIView * planningBox; -@property(weak, nonatomic) IBOutlet UIView * resultsBox; -@property(weak, nonatomic) IBOutlet UIView * heightBox; -@property(weak, nonatomic) IBOutlet UIView * taxiBox; -@property(weak, nonatomic) IBOutlet UIView * errorBox; -@property(weak, nonatomic) IBOutlet UILabel * errorLabel; -@property(weak, nonatomic) IBOutlet UILabel * resultLabel; -@property(weak, nonatomic) IBOutlet UILabel * arriveLabel; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * statusBoxHeight; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * resultsBoxHeight; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * heightBoxHeight; -@property(weak, nonatomic) IBOutlet UIImageView * heightProfileImage; -@property(weak, nonatomic) IBOutlet UIView * heightProfileElevation; -@property(weak, nonatomic) IBOutlet UIImageView * elevationImage; -@property(weak, nonatomic) IBOutlet UILabel * elevationHeight; -@property(weak, nonatomic) IBOutlet MWMTaxiCollectionView * taxiCollectionView; - -@property(nonatomic) UIImageView * movingCellImage; - -@property(nonatomic) BOOL isNeedToMove; -@property(nonatomic) NSIndexPath * indexPathOfMovingCell; +@property(weak, nonatomic) IBOutlet UIView * vehicle; @end @@ -58,14 +33,10 @@ CGFloat constexpr kAdditionalHeight = 20.; - (void)awakeFromNib { [super awakeFromNib]; - self.autoresizingMask = UIViewAutoresizingFlexibleWidth; - self.layer.shouldRasterize = YES; - self.layer.rasterizationScale = UIScreen.mainScreen.scale; + [self setupProgresses]; [self.backButton matchInterfaceOrientation]; - - self.elevationImage.mwm_coloring = MWMImageColoringBlue; } - (void)setupProgresses @@ -101,117 +72,15 @@ CGFloat constexpr kAdditionalHeight = 20.; m_progresses[routerType] = progress; } -- (void)didMoveToSuperview { [self setupActualHeight]; } - (void)statePrepare { - [[MWMNavigationDashboardManager manager] updateStartButtonTitle:self.goButton]; for (auto const & progress : m_progresses) progress.second.state = MWMCircularProgressStateNormal; - self.goButton.hidden = NO; - self.goButton.enabled = NO; - [self setupActualHeight]; - self.statusBox.hidden = YES; - self.resultsBox.hidden = YES; - self.heightBox.hidden = YES; - self.heightProfileElevation.hidden = YES; - self.planningBox.hidden = YES; - self.errorBox.hidden = YES; - self.taxiBox.hidden = YES; - if (!MWMLocationManager.lastLocation || !Platform::IsConnected()) [self.taxi removeFromSuperview]; } -- (void)stateError -{ - [[MWMNavigationDashboardManager manager] updateStartButtonTitle:self.goButton]; - self.goButton.hidden = NO; - self.goButton.enabled = NO; - self.statusBox.hidden = NO; - self.planningBox.hidden = YES; - self.resultsBox.hidden = YES; - self.heightBox.hidden = YES; - self.taxiBox.hidden = YES; - self.heightProfileElevation.hidden = YES; - self.errorBox.hidden = NO; - if (IPAD) - [self iPadNotReady]; -} - -- (void)stateReady -{ - [[MWMNavigationDashboardManager manager] updateStartButtonTitle:self.goButton]; - self.goButton.hidden = NO; - self.goButton.enabled = YES; - self.statusBox.hidden = NO; - self.planningBox.hidden = YES; - self.errorBox.hidden = YES; - self.resultsBox.hidden = NO; - BOOL const hasAltitude = [MWMRouter hasRouteAltitude]; - self.heightBox.hidden = !hasAltitude; - self.heightProfileElevation.hidden = !hasAltitude; - if (IPAD) - [self iPadReady]; -} - -- (void)iPadReady -{ - [self layoutIfNeeded]; - if ([MWMRouter isTaxi]) - { - self.statusBoxHeight.constant = self.taxiBox.height; - self.taxiBox.hidden = NO; - } - else - { - self.statusBoxHeight.constant = - self.resultsBoxHeight.constant + - ([MWMRouter hasRouteAltitude] ? self.heightBoxHeight.constant : 0); - [UIView animateWithDuration:kDefaultAnimationDuration animations:^ - { - [self layoutIfNeeded]; - } - completion:^(BOOL finished) - { - [UIView animateWithDuration:kDefaultAnimationDuration animations:^ - { - self.arriveLabel.alpha = 1.; - } - completion:^(BOOL finished) - { - [self updateHeightProfile]; - }]; - }]; - } -} - -- (void)updateHeightProfile -{ - if (![MWMRouter hasRouteAltitude]) - return; - dispatch_async(dispatch_get_main_queue(), ^{ - [MWMRouter routeAltitudeImageForSize:self.heightProfileImage.frame.size - completion:^(UIImage * image, NSString * altitudeElevation) { - self.heightProfileImage.image = image; - self.elevationHeight.text = altitudeElevation; - }]; - }); -} - -- (void)iPadNotReady -{ - self.taxiBox.hidden = YES; - self.errorLabel.text = [MWMRouter isTaxi] ? L(@"taxi_not_found") : L(@"routing_planning_error"); - self.arriveLabel.alpha = 0.; - [self layoutIfNeeded]; - self.statusBoxHeight.constant = self.resultsBoxHeight.constant; - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - [self layoutIfNeeded]; - }]; -} - - (void)selectRouter:(MWMRouterType)routerType { for (auto const & progress : m_progresses) @@ -219,13 +88,6 @@ CGFloat constexpr kAdditionalHeight = 20.; m_progresses[routerType].state = MWMCircularProgressStateSelected; } -- (void)layoutSubviews -{ - [super layoutSubviews]; - [self setupActualHeight]; - [self.delegate routePreviewDidChangeFrame:self.frame]; -} - - (void)router:(MWMRouterType)routerType setState:(MWMCircularProgressState)state { m_progresses[routerType].state = state; @@ -254,96 +116,51 @@ CGFloat constexpr kAdditionalHeight = 20.; [self selectRouter:routerType]; [MWMRouter setType:routerType]; [MWMRouter rebuildWithBestRouter:NO]; + NSString * routerTypeString = nil; switch (routerType) { - case MWMRouterTypeVehicle: - [Statistics logEvent:kStatPointToPoint - withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : kStatVehicle}]; - break; - case MWMRouterTypePedestrian: - [Statistics logEvent:kStatPointToPoint - withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : kStatPedestrian}]; - break; - case MWMRouterTypeBicycle: - [Statistics logEvent:kStatPointToPoint - withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : kStatBicycle}]; - break; - case MWMRouterTypeTaxi: - [Statistics logEvent:kStatPointToPoint - withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : kStatTaxi}]; - break; + case MWMRouterTypeVehicle: routerTypeString = kStatVehicle; break; + case MWMRouterTypePedestrian: routerTypeString = kStatPedestrian; break; + case MWMRouterTypeBicycle: routerTypeString = kStatBicycle; break; + case MWMRouterTypeTaxi: routerTypeString = kStatTaxi; break; } + [Statistics logEvent:kStatPointToPoint + withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : routerTypeString}]; } } +- (void)addToView:(UIView *)superview +{ + NSAssert(superview != nil, @"Superview can't be nil"); + if ([superview.subviews containsObject:self]) + return; + [superview addSubview:self]; + self.frame = self.defaultFrame; + self.isVisible = YES; +} + +- (void)remove { self.isVisible = NO; } +- (void)layoutSubviews +{ + [UIView animateWithDuration:kDefaultAnimationDuration + animations:^{ + if (!CGRectEqualToRect(self.frame, self.defaultFrame)) + self.frame = self.defaultFrame; + } + completion:^(BOOL finished) { + if (!self.isVisible) + [self removeFromSuperview]; + }]; + [super layoutSubviews]; +} + #pragma mark - Properties -- (CGRect)defaultFrame +- (CGRect)defaultFrame { return CGRectNull; } +- (void)setIsVisible:(BOOL)isVisible { - if (!IPAD) - return super.defaultFrame; - CGFloat const width = 320.; - CGFloat const origin = self.isVisible ? 0. : -width; - return {{origin, self.topBound}, {width, self.superview.height - kAdditionalHeight}}; -} - -- (void)setupActualHeight -{ - if (!self.superview) - return; - CGFloat const selfHeight = IPAD ? self.superview.height - kAdditionalHeight : 44; - self.defaultHeight = selfHeight; - self.height = selfHeight; -} - -#pragma mark - MWMNavigationDashboardInfoProtocol - -- (void)updateNavigationInfo:(MWMNavigationDashboardEntity *)info -{ - self.resultLabel.attributedText = info.estimate; - if (!IPAD) - return; - - NSString * arriveStr = [NSDateFormatter - localizedStringFromDate:[[NSDate date] dateByAddingTimeInterval:info.timeToTarget] - dateStyle:NSDateFormatterNoStyle - timeStyle:NSDateFormatterShortStyle]; - self.arriveLabel.text = [NSString stringWithFormat:L(@"routing_arrive"), arriveStr.UTF8String]; -} - -#pragma mark - AvailableArea / VisibleArea - -- (MWMAvailableAreaAffectDirections)visibleAreaAffectDirections -{ - return IPAD ? MWMAvailableAreaAffectDirectionsLeft : MWMAvailableAreaAffectDirectionsTop; -} - -#pragma mark - AvailableArea / PlacePageArea - -- (MWMAvailableAreaAffectDirections)placePageAreaAffectDirections -{ - return IPAD ? MWMAvailableAreaAffectDirectionsLeft : MWMAvailableAreaAffectDirectionsNone; -} - -#pragma mark - AvailableArea / WidgetsArea - -- (MWMAvailableAreaAffectDirections)widgetsAreaAffectDirections -{ - return IPAD ? MWMAvailableAreaAffectDirectionsLeft : MWMAvailableAreaAffectDirectionsNone; -} - -#pragma mark - AvailableArea / SideButtonsArea - -- (MWMAvailableAreaAffectDirections)sideButtonsAreaAffectDirections -{ - return IPAD ? MWMAvailableAreaAffectDirectionsLeft : MWMAvailableAreaAffectDirectionsTop; -} - -#pragma mark - AvailableArea / TrafficButtonArea - -- (MWMAvailableAreaAffectDirections)trafficButtonAreaAffectDirections -{ - return IPAD ? MWMAvailableAreaAffectDirectionsLeft : MWMAvailableAreaAffectDirectionsTop; + _isVisible = isVisible; + [self setNeedsLayout]; } @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.xib deleted file mode 100644 index 47db805e51..0000000000 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.xib +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreviewTaxiCellType.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreviewTaxiCellType.h new file mode 100644 index 0000000000..d9b91ad392 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreviewTaxiCellType.h @@ -0,0 +1,5 @@ +typedef NS_ENUM(NSInteger, MWMRoutePreviewTaxiCellType) { + MWMRoutePreviewTaxiCellTypeTaxi, + MWMRoutePreviewTaxiCellTypeUber, + MWMRoutePreviewTaxiCellTypeYandex +}; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.h index 1f3a6e22fc..7003547b05 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.h @@ -1,4 +1,4 @@ -#import "SwiftBridge.h" +#import "MWMRoutePreviewTaxiCellType.h" @class MWMRoutePoint; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.mm index 3380b04968..a2085dc634 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMTaxiPreviewDataSource.mm @@ -1,14 +1,16 @@ #import "MWMTaxiPreviewDataSource.h" #import "MWMCommon.h" #import "MWMNetworkPolicy.h" +#import "MWMRoutePoint.h" #import "Statistics.h" +#import "SwiftBridge.h" #include "Framework.h" -#include "geometry/mercator.hpp" - #include "partners_api/taxi_provider.hpp" +#include "geometry/mercator.hpp" + @interface MWMTaxiCollectionView () @property(nonatomic) UIPageControl * pageControl; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.h new file mode 100644 index 0000000000..06623a8c5b --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.h @@ -0,0 +1,5 @@ +#import "MWMRoutePreview.h" + +@interface MWMiPadRoutePreview : MWMRoutePreview + +@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.mm new file mode 100644 index 0000000000..2052354f62 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.mm @@ -0,0 +1,67 @@ +#import "MWMiPadRoutePreview.h" +#import "MWMRouter.h" +#import "SwiftBridge.h" + +@interface MWMRoutePreview () + +@property(nonatomic) BOOL isVisible; + +@end + +@implementation MWMiPadRoutePreview + +- (CGRect)defaultFrame +{ + CGFloat const width = 320; + return {{self.isVisible ? 0 : -width, 0}, {width, self.superview.height}}; +} + +#pragma mark - SolidTouchView + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {} +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {} +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {} +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {} +#pragma mark - AvailableArea / VisibleArea + +- (MWMAvailableAreaAffectDirections)visibleAreaAffectDirections +{ + return MWMAvailableAreaAffectDirectionsLeft; +} + +#pragma mark - AvailableArea / PlacePageArea + +- (MWMAvailableAreaAffectDirections)placePageAreaAffectDirections +{ + return MWMAvailableAreaAffectDirectionsLeft; +} + +#pragma mark - AvailableArea / WidgetsArea + +- (MWMAvailableAreaAffectDirections)widgetsAreaAffectDirections +{ + return MWMAvailableAreaAffectDirectionsLeft; +} + +#pragma mark - AvailableArea / SideButtonsArea + +- (MWMAvailableAreaAffectDirections)sideButtonsAreaAffectDirections +{ + return MWMAvailableAreaAffectDirectionsLeft; +} + +#pragma mark - AvailableArea / TrafficButtonArea + +- (MWMAvailableAreaAffectDirections)trafficButtonAreaAffectDirections +{ + return MWMAvailableAreaAffectDirectionsLeft; +} + +#pragma mark - AvailableArea / NavigationInfoArea + +- (MWMAvailableAreaAffectDirections)navigationInfoAreaAffectDirections +{ + return MWMAvailableAreaAffectDirectionsLeft; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib index 395a67cbd3..ea8a900845 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMiPadRoutePreview.xib @@ -1,5 +1,5 @@ - + @@ -17,16 +17,29 @@ + + + - - - + + + + + + + + + + + + + - + - + @@ -108,35 +121,14 @@ - - + + - - - - - - - - - - - - + + - + + + + + + + + + + + + + + + - + @@ -185,6 +192,9 @@ + + + - - - - - - - - - - - - - - - - - - + - + @@ -250,14 +243,11 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/NavigationRoutePreviewStatusView.xib b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/NavigationRoutePreviewStatusView.xib new file mode 100644 index 0000000000..b46d04935f --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/NavigationRoutePreviewStatusView.xib @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewStatus.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewStatus.swift new file mode 100644 index 0000000000..21c2c3659e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewStatus.swift @@ -0,0 +1,130 @@ +@objc(MWMRoutePreviewStatus) +final class RoutePreviewStatus: SolidTouchView { + @IBOutlet private weak var errorBox: UIView! + @IBOutlet private weak var resultsBox: UIView! + @IBOutlet private weak var heightBox: UIView! + @IBOutlet private weak var taxiBox: UIView! + @IBOutlet private weak var errorLabel: UILabel! + @IBOutlet private weak var resultLabel: UILabel! + @IBOutlet private weak var arriveLabel: UILabel? + @IBOutlet private weak var heightProfileImage: UIImageView! + @IBOutlet private weak var heightProfileElevationHeight: UILabel? + + @IBOutlet private var errorBoxBottom: NSLayoutConstraint! + @IBOutlet private var resultsBoxBottom: NSLayoutConstraint! + @IBOutlet private var heightBoxBottom: NSLayoutConstraint! + @IBOutlet private var taxiBoxBottom: NSLayoutConstraint! + + private var hiddenConstraint: NSLayoutConstraint! + weak var ownerView: UIView! + + var isVisible = false { + didSet { + alternative(iPhone: { + guard self.isVisible != oldValue else { return } + if self.isVisible { + self.addView() + } + DispatchQueue.main.async { + guard let sv = self.superview else { return } + sv.setNeedsLayout() + self.hiddenConstraint.isActive = !self.isVisible + UIView.animate(withDuration: kDefaultAnimationDuration, + animations: { sv.layoutIfNeeded() }, + completion: { _ in + if (!self.isVisible) { + self.removeFromSuperview() + } + }) + } + }, + iPad: { self.isHidden = !self.isVisible })() + } + } + + private func addView() { + guard superview != ownerView else { return } + ownerView.addSubview(self) + + NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: ownerView, attribute: .left, multiplier: 1, constant: 0).isActive = true + NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: ownerView, attribute: .right, multiplier: 1, constant: 0).isActive = true + + hiddenConstraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0) + hiddenConstraint.priority = UILayoutPriorityDefaultHigh + hiddenConstraint.isActive = true + + let visibleConstraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0) + visibleConstraint.priority = UILayoutPriorityDefaultLow + visibleConstraint.isActive = true + } + + private func updateHeight() { + DispatchQueue.main.async { + self.setNeedsLayout() + self.errorBoxBottom.isActive = !self.errorBox.isHidden + self.resultsBoxBottom.isActive = !self.resultsBox.isHidden + self.heightBoxBottom.isActive = !self.heightBox.isHidden + self.taxiBoxBottom.isActive = !self.taxiBox.isHidden + UIView.animate(withDuration: kDefaultAnimationDuration) { self.layoutIfNeeded() } + } + } + + func stateHidden() { + isVisible = false + } + + func statePrepare() { + isVisible = false + } + + func stateError(message: String) { + isVisible = true + errorBox.isHidden = false + resultsBox.isHidden = true + heightBox.isHidden = true + taxiBox.isHidden = true + + errorLabel.text = message + + updateHeight() + } + + func stateReady() { + isVisible = true + errorBox.isHidden = true + + if MWMRouter.isTaxi() { + taxiBox.isHidden = false + resultsBox.isHidden = true + heightBox.isHidden = true + } else { + taxiBox.isHidden = true + resultsBox.isHidden = false + if MWMRouter.hasRouteAltitude() { + heightBox.isHidden = false + MWMRouter.routeAltitudeImage(for: heightProfileImage.frame.size, + completion: { (image, elevation) in + self.heightProfileImage.image = image + self.heightProfileElevationHeight?.text = elevation + }) + } else { + heightBox.isHidden = true + } + } + + updateHeight() + } + + func stateNavigation() { + isVisible = false + } + + func onNavigationInfoUpdated(_ info: MWMNavigationDashboardEntity) { + resultLabel.attributedText = info.estimate + arriveLabel?.text = String(coreFormat: L("routing_arrive"), arguments: [info.arrival]) + } + + override var sideButtonsAreaAffectDirections: MWMAvailableAreaAffectDirections { + return alternative(iPhone: .bottom, iPad: []) + } +} diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewTaxiCell.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewTaxiCell.swift index b3462fb03d..0cc4b5f469 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewTaxiCell.swift +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RoutePreviewTaxiCell.swift @@ -1,10 +1,3 @@ -@objc(MWMRoutePreviewTaxiCellType) -enum RoutePreviewTaxiCellType: Int { - case taxi - case uber - case yandex -} - @objc(MWMRoutePreviewTaxiCell) final class RoutePreviewTaxiCell: UICollectionViewCell { @@ -22,7 +15,7 @@ final class RoutePreviewTaxiCell: UICollectionViewCell { } } - func config(type: RoutePreviewTaxiCellType, title: String, eta: String, price: String, currency: String) { + func config(type: MWMRoutePreviewTaxiCellType, title: String, eta: String, price: String, currency: String) { let iconImage = { () -> UIImage in switch type { case .taxi: return #imageLiteral(resourceName: "icTaxiTaxi") diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteStartButton.swift b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteStartButton.swift new file mode 100644 index 0000000000..b14f4e77b5 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/RouteStartButton.swift @@ -0,0 +1,23 @@ +@objc(MWMRouteStartButton) +final class RouteStartButton: UIButton { + func statePrepare() { + isHidden = false + isEnabled = false + } + + func stateError() { + isHidden = alternative(iPhone: true, iPad: false) + isEnabled = false + } + + func stateReady() { + isHidden = false + isEnabled = true + } + + override func mwm_refreshUI() { + super.mwm_refreshUI() + setBackgroundColor(UIColor.linkBlue(), for: .normal) + setBackgroundColor(UIColor.linkBlueHighlighted(), for: .highlighted) + } +} diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 419e641b3c..b5a97e1625 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -134,8 +134,10 @@ BOOL gIsFirstMyPositionMode = YES; if ([MapsAppDelegate theApp].hasApiURL) return; - MWMMapViewControlsManager * cm = self.controlsManager; - if (cm.searchHidden && cm.navigationState == MWMNavigationDashboardStateHidden) + BOOL const isSearchHidden = ([MWMSearchManager manager].state == MWMSearchManagerStateHidden); + BOOL const isNavigationDashboardHidden = + ([MWMNavigationDashboardManager manager].state == MWMNavigationDashboardStateHidden); + if (isSearchHidden && isNavigationDashboardHidden) self.controlsManager.hidden = !self.controlsManager.hidden; } @@ -262,7 +264,8 @@ BOOL gIsFirstMyPositionMode = YES; name:UIDeviceOrientationDidChangeNotification object:nil]; - self.controlsManager.menuState = self.controlsManager.menuRestoreState; + if (![MWMRouter isRoutingActive]) + self.controlsManager.menuState = self.controlsManager.menuRestoreState; [self updateStatusBarStyle]; GetFramework().InvalidateRendering(); @@ -516,15 +519,15 @@ BOOL gIsFirstMyPositionMode = YES; [self.navigationController popToRootViewControllerAnimated:NO]; if (self.isViewLoaded) { - BOOL isSearchHidden = YES; + auto searchState = MWMSearchManagerStateHidden; [MWMRouter stopRouting]; if ([action isEqualToString:@"me.maps.3daction.bookmarks"]) [self openBookmarks]; else if ([action isEqualToString:@"me.maps.3daction.search"]) - isSearchHidden = NO; + searchState = MWMSearchManagerStateDefault; else if ([action isEqualToString:@"me.maps.3daction.route"]) [self.controlsManager onRoutePrepare]; - self.controlsManager.searchHidden = isSearchHidden; + [MWMSearchManager manager].state = MWMSearchManagerStateHidden; } else { diff --git a/iphone/Maps/Core/Routing/MWMRouter.mm b/iphone/Maps/Core/Routing/MWMRouter.mm index f6ead432a4..5f62a0ef7f 100644 --- a/iphone/Maps/Core/Routing/MWMRouter.mm +++ b/iphone/Maps/Core/Routing/MWMRouter.mm @@ -10,7 +10,7 @@ #import "MWMLocationManager.h" #import "MWMLocationObserver.h" #import "MWMMapViewControlsManager.h" -#import "MWMNavigationDashboardManager.h" +#import "MWMNavigationDashboardManager+Entity.h" #import "MWMRoutePoint+CPP.h" #import "MWMSearch.h" #import "MWMSettings.h" @@ -115,7 +115,6 @@ char const * kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeI + (void)stopRouting { [self stop]; - [MWMNavigationDashboardManager manager].taxiDataSource = nil; } + (BOOL)isRoutingActive { return GetFramework().GetRoutingManager().IsRoutingActive(); } @@ -440,23 +439,23 @@ char const * kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeI + (void)doStop:(BOOL)removeRoutePoints { + auto & rm = GetFramework().GetRoutingManager(); // Don't save taxi routing type as default. - if ([[self class] isTaxi]) - GetFramework().GetRoutingManager().SetRouter(routing::RouterType::Vehicle); + if ([MWMRouter isTaxi]) + rm.SetRouter(routing::RouterType::Vehicle); [self clearAltitudeImagesData]; - GetFramework().GetRoutingManager().CloseRouting(removeRoutePoints); + rm.CloseRouting(removeRoutePoints); [MWMThemeManager setAutoUpdates:NO]; [MapsAppDelegate.theApp showAlertIfRequired]; } - (void)updateFollowingInfo { - auto const & f = GetFramework(); - if (!f.GetRoutingManager().IsRoutingActive()) + if (![MWMRouter isRoutingActive]) return; location::FollowingInfo info; - f.GetRoutingManager().GetRouteFollowingInfo(info); + GetFramework().GetRoutingManager().GetRouteFollowingInfo(info); if (info.IsValid()) [[MWMNavigationDashboardManager manager] updateFollowingInfo:info]; } @@ -544,10 +543,6 @@ char const * kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeI f.DeactivateMapSelection(true); [mapViewControlsManager onRouteReady]; [self updateFollowingInfo]; - if (![MWMRouter isTaxi]) - [[MWMNavigationDashboardManager manager] setRouteBuilderProgress:100]; - - mapViewControlsManager.searchHidden = YES; break; } case routing::IRouter::RouteFileNotExist: diff --git a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h new file mode 100644 index 0000000000..b5637da20f --- /dev/null +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h @@ -0,0 +1,18 @@ +#import "MWMTextToSpeech.h" + +#include "std/string.hpp" +#include "std/vector.hpp" + +@interface MWMTextToSpeech (CPP) + +// Returns a list of available languages in the following format: +// * name in bcp47; +// * localized name; +- (vector>)availableLanguages; + +@end + +namespace tts +{ +string translatedTwine(string const & twine); +} // namespace tts diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.h b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.h similarity index 69% rename from iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.h rename to iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.h index f56299335b..ac9398773c 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.h +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.h @@ -1,5 +1,4 @@ -#include "std/string.hpp" -#include "std/vector.hpp" +#import "MWMTextToSpeechObserver.h" @interface MWMTextToSpeech : NSObject @@ -8,13 +7,10 @@ + (void)setTTSEnabled:(BOOL)enabled; + (NSString *)savedLanguage; -+ (NSString *)ttsStatusNotificationKey; ++ (void)addObserver:(id)observer; ++ (void)removeObserver:(id)observer; @property(nonatomic) BOOL active; -// Returns a list of available languages in the following format: -// * name in bcp47; -// * localized name; -- (vector>)availableLanguages; - (void)setNotificationsLocale:(NSString *)locale; - (void)playTurnNotifications; @@ -27,9 +23,3 @@ + (instancetype) new __attribute__((unavailable("call tts instead"))); @end - -namespace tts -{ -string translatedTwine(string const & twine); - -} // namespace tts diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm similarity index 89% rename from iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm rename to iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm index 4f7af918b7..9ebfe0926c 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm @@ -1,7 +1,7 @@ -#import "MWMTextToSpeech.h" #import #import "MWMCommon.h" #import "MWMRouter.h" +#import "MWMTextToSpeech+CPP.h" #import "Statistics.h" #include "LocaleTranslator.h" @@ -40,6 +40,9 @@ vector> availableLanguages() } return result; } + +using TObserver = id; +using TObservers = NSHashTable<__kindof TObserver>; } // namespace @interface MWMTextToSpeech () @@ -52,6 +55,8 @@ vector> availableLanguages() @property(nonatomic) float speechRate; @property(nonatomic) AVAudioSession * audioSession; +@property(nonatomic) TObservers * observers; + @end @implementation MWMTextToSpeech @@ -72,6 +77,7 @@ vector> availableLanguages() if (self) { _availableLanguages = availableLanguages(); + _observers = [TObservers weakObjectsHashTable]; NSString * saved = [[self class] savedLanguage]; NSString * preferedLanguageBcp47; @@ -112,12 +118,7 @@ vector> availableLanguages() return self; } -- (void)dealloc -{ - self.speechSynthesizer.delegate = nil; -} - -+ (NSString *)ttsStatusNotificationKey { return @"TTFStatusWasChangedFromSettingsNotification"; } +- (void)dealloc { self.speechSynthesizer.delegate = nil; } - (vector>)availableLanguages { return _availableLanguages; } - (void)setNotificationsLocale:(NSString *)locale { @@ -140,11 +141,11 @@ vector> availableLanguages() NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setBool:enabled forKey:kIsTTSEnabled]; [ud synchronize]; - [[NSNotificationCenter defaultCenter] postNotificationName:[self ttsStatusNotificationKey] - object:nil - userInfo:nil]; + + auto tts = [MWMTextToSpeech tts]; + [tts onTTSStatusUpdated]; if (enabled) - [[self tts] setActive:YES]; + [tts setActive:YES]; } - (void)setActive:(BOOL)active @@ -156,18 +157,11 @@ vector> availableLanguages() [self setAudioSessionActive:active]; [MWMRouter enableTurnNotifications:active]; runAsyncOnMainQueue(^{ - [[NSNotificationCenter defaultCenter] - postNotificationName:[[self class] ttsStatusNotificationKey] - object:nil - userInfo:nil]; + [self onTTSStatusUpdated]; }); } -- (BOOL)active -{ - return [[self class] isTTSEnabled] && [MWMRouter areTurnNotificationsEnabled]; -} - +- (BOOL)active { return [[self class] isTTSEnabled] && [MWMRouter areTurnNotificationsEnabled]; } + (NSString *)savedLanguage { return [[NSUserDefaults standardUserDefaults] stringForKey:kUserDefaultsTTSLanguageBcp47]; @@ -265,6 +259,26 @@ vector> availableLanguages() return YES; } +#pragma mark - MWMNavigationDashboardObserver + +- (void)onTTSStatusUpdated +{ + for (TObserver observer in self.observers) + [observer onTTSStatusUpdated]; +} + +#pragma mark - Add/Remove Observers + ++ (void)addObserver:(id)observer +{ + [[MWMTextToSpeech tts].observers addObject:observer]; +} + ++ (void)removeObserver:(id)observer +{ + [[MWMTextToSpeech tts].observers removeObject:observer]; +} + @end namespace tts diff --git a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeechObserver.h b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeechObserver.h new file mode 100644 index 0000000000..95a3e195d0 --- /dev/null +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeechObserver.h @@ -0,0 +1,5 @@ +@protocol MWMTextToSpeechObserver + +- (void)onTTSStatusUpdated; + +@end diff --git a/iphone/Maps/Core/Traffic/MWMTrafficManager.h b/iphone/Maps/Core/Traffic/MWMTrafficManager.h index f36ec68392..7c6fbe317f 100644 --- a/iphone/Maps/Core/Traffic/MWMTrafficManager.h +++ b/iphone/Maps/Core/Traffic/MWMTrafficManager.h @@ -1,13 +1,12 @@ #import "MWMTrafficManagerObserver.h" - -#include "map/traffic_manager.hpp" +#import "MWMTrafficManagerState.h" @interface MWMTrafficManager : NSObject + (void)addObserver:(id)observer; + (void)removeObserver:(id)observer; -+ (TrafficManager::TrafficState)state; ++ (MWMTrafficManagerState)state; + (void)enableTraffic:(BOOL)enable; diff --git a/iphone/Maps/Core/Traffic/MWMTrafficManager.mm b/iphone/Maps/Core/Traffic/MWMTrafficManager.mm index 3bbfe0299d..3d249a9761 100644 --- a/iphone/Maps/Core/Traffic/MWMTrafficManager.mm +++ b/iphone/Maps/Core/Traffic/MWMTrafficManager.mm @@ -3,6 +3,8 @@ #include "Framework.h" +#include "map/traffic_manager.hpp" + namespace { using TObserver = id; @@ -39,11 +41,9 @@ using TObservers = NSHashTable<__kindof TObserver>; _observers = [TObservers weakObjectsHashTable]; auto & m = GetFramework().GetTrafficManager(); m.SetStateListener([self](TrafficManager::TrafficState state) { - runAsyncOnMainQueue(^{ - self.state = state; - for (TObserver observer in self.observers) - [observer onTrafficStateUpdated]; - }); + self.state = state; + for (TObserver observer in self.observers) + [observer onTrafficStateUpdated]; }); } return self; @@ -61,7 +61,21 @@ using TObservers = NSHashTable<__kindof TObserver>; [[MWMTrafficManager manager].observers removeObject:observer]; } -+ (TrafficManager::TrafficState)state { return [MWMTrafficManager manager].state; } ++ (MWMTrafficManagerState)state +{ + switch ([MWMTrafficManager manager].state) + { + case TrafficManager::TrafficState::Disabled: return MWMTrafficManagerStateDisabled; + case TrafficManager::TrafficState::Enabled: return MWMTrafficManagerStateEnabled; + case TrafficManager::TrafficState::WaitingData: return MWMTrafficManagerStateWaitingData; + case TrafficManager::TrafficState::Outdated: return MWMTrafficManagerStateOutdated; + case TrafficManager::TrafficState::NoData: return MWMTrafficManagerStateNoData; + case TrafficManager::TrafficState::NetworkError: return MWMTrafficManagerStateNetworkError; + case TrafficManager::TrafficState::ExpiredData: return MWMTrafficManagerStateExpiredData; + case TrafficManager::TrafficState::ExpiredApp: return MWMTrafficManagerStateExpiredApp; + } +} + + (void)enableTraffic:(BOOL)enable { auto & f = GetFramework(); diff --git a/iphone/Maps/Core/Traffic/MWMTrafficManagerState.h b/iphone/Maps/Core/Traffic/MWMTrafficManagerState.h new file mode 100644 index 0000000000..63c01713d0 --- /dev/null +++ b/iphone/Maps/Core/Traffic/MWMTrafficManagerState.h @@ -0,0 +1,10 @@ +typedef NS_ENUM(NSUInteger, MWMTrafficManagerState) { + MWMTrafficManagerStateDisabled, + MWMTrafficManagerStateEnabled, + MWMTrafficManagerStateWaitingData, + MWMTrafficManagerStateOutdated, + MWMTrafficManagerStateNoData, + MWMTrafficManagerStateNetworkError, + MWMTrafficManagerStateExpiredData, + MWMTrafficManagerStateExpiredApp +}; diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 7fd8a382fc..09d9645e39 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -112,6 +112,42 @@ 3406FA161C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3406FA141C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm */; }; 3406FA181C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3406FA171C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib */; }; 3406FA191C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3406FA171C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib */; }; + 340708431F28ED2D00029ECC /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708421F28ED2D00029ECC /* MWMRoutePreview.mm */; }; + 3407084C1F28EDD100029ECC /* MWMiPadRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340708441F28EDD100029ECC /* MWMiPadRoutePreview.xib */; }; + 3407084E1F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708481F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm */; }; + 3407084F1F28EDD100029ECC /* RoutePreviewTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708491F28EDD100029ECC /* RoutePreviewTaxiCell.swift */; }; + 340708501F28EDD100029ECC /* MWMTaxiCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3407084B1F28EDD100029ECC /* MWMTaxiCollectionLayout.mm */; }; + 340708521F28F1DD00029ECC /* MWMiPadRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340708441F28EDD100029ECC /* MWMiPadRoutePreview.xib */; }; + 340708531F28F1DE00029ECC /* MWMiPadRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 340708441F28EDD100029ECC /* MWMiPadRoutePreview.xib */; }; + 340708561F28F1E900029ECC /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708421F28ED2D00029ECC /* MWMRoutePreview.mm */; }; + 340708571F28F1EA00029ECC /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708421F28ED2D00029ECC /* MWMRoutePreview.mm */; }; + 340708581F28F1F000029ECC /* MWMTaxiCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3407084B1F28EDD100029ECC /* MWMTaxiCollectionLayout.mm */; }; + 340708591F28F1F000029ECC /* MWMTaxiCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3407084B1F28EDD100029ECC /* MWMTaxiCollectionLayout.mm */; }; + 3407085A1F28F1F400029ECC /* MWMTaxiPreviewDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708481F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm */; }; + 3407085B1F28F1F400029ECC /* MWMTaxiPreviewDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708481F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm */; }; + 3407085C1F28F27100029ECC /* RoutePreviewTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708491F28EDD100029ECC /* RoutePreviewTaxiCell.swift */; }; + 3407085D1F28F27200029ECC /* RoutePreviewTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708491F28EDD100029ECC /* RoutePreviewTaxiCell.swift */; }; + 340708601F28FE2800029ECC /* MWMiPadRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3407085F1F28FE2800029ECC /* MWMiPadRoutePreview.mm */; }; + 340708611F28FE2800029ECC /* MWMiPadRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3407085F1F28FE2800029ECC /* MWMiPadRoutePreview.mm */; }; + 340708621F28FE2800029ECC /* MWMiPadRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3407085F1F28FE2800029ECC /* MWMiPadRoutePreview.mm */; }; + 340708641F2905A500029ECC /* NavigationInfoArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708631F2905A500029ECC /* NavigationInfoArea.swift */; }; + 340708651F2905A500029ECC /* NavigationInfoArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708631F2905A500029ECC /* NavigationInfoArea.swift */; }; + 340708661F2905A500029ECC /* NavigationInfoArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708631F2905A500029ECC /* NavigationInfoArea.swift */; }; + 3407086D1F2B427400029ECC /* RoutePreviewTaxiCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3407086C1F2B427400029ECC /* RoutePreviewTaxiCell.xib */; }; + 3407086E1F2B427400029ECC /* RoutePreviewTaxiCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3407086C1F2B427400029ECC /* RoutePreviewTaxiCell.xib */; }; + 3407086F1F2B427400029ECC /* RoutePreviewTaxiCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3407086C1F2B427400029ECC /* RoutePreviewTaxiCell.xib */; }; + 340708771F2B5D6C00029ECC /* DimBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708761F2B5D6C00029ECC /* DimBackground.swift */; }; + 340708781F2B5D6C00029ECC /* DimBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708761F2B5D6C00029ECC /* DimBackground.swift */; }; + 340708791F2B5D6C00029ECC /* DimBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340708761F2B5D6C00029ECC /* DimBackground.swift */; }; + 3407087B1F2B6F5200029ECC /* NavigationControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3407087A1F2B6F5200029ECC /* NavigationControlView.swift */; }; + 3407087C1F2B6F5200029ECC /* NavigationControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3407087A1F2B6F5200029ECC /* NavigationControlView.swift */; }; + 3407087D1F2B6F5200029ECC /* NavigationControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3407087A1F2B6F5200029ECC /* NavigationControlView.swift */; }; + 3407087F1F2B6F7000029ECC /* NavigationControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3407087E1F2B6F7000029ECC /* NavigationControlView.xib */; }; + 340708801F2B6F7000029ECC /* NavigationControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3407087E1F2B6F7000029ECC /* NavigationControlView.xib */; }; + 340708811F2B6F7000029ECC /* NavigationControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3407087E1F2B6F7000029ECC /* NavigationControlView.xib */; }; + 340708841F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708831F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm */; }; + 340708851F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708831F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm */; }; + 340708861F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340708831F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm */; }; 340837131B7243CE00B5C185 /* MWMActivityViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340837121B7243CE00B5C185 /* MWMActivityViewController.mm */; }; 340837161B72451A00B5C185 /* MWMShareActivityItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340837151B72451A00B5C185 /* MWMShareActivityItem.mm */; }; 340E1EEB1E2F614400CE49BF /* Authorization.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 340E1EE41E2F614400CE49BF /* Authorization.storyboard */; }; @@ -176,9 +212,6 @@ 3451F4ED1F026DAF00A981F2 /* PlacePageTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3451F4EC1F026DAF00A981F2 /* PlacePageTaxiCell.swift */; }; 3451F4EE1F026DAF00A981F2 /* PlacePageTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3451F4EC1F026DAF00A981F2 /* PlacePageTaxiCell.swift */; }; 3451F4EF1F026DAF00A981F2 /* PlacePageTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3451F4EC1F026DAF00A981F2 /* PlacePageTaxiCell.swift */; }; - 3451F4F11F02935300A981F2 /* RoutePreviewTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3451F4F01F02935300A981F2 /* RoutePreviewTaxiCell.swift */; }; - 3451F4F21F02935300A981F2 /* RoutePreviewTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3451F4F01F02935300A981F2 /* RoutePreviewTaxiCell.swift */; }; - 3451F4F31F02935300A981F2 /* RoutePreviewTaxiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3451F4F01F02935300A981F2 /* RoutePreviewTaxiCell.swift */; }; 3454D7B81E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3454D79A1E07F045004AF2AD /* CALayer+RuntimeAttributes.mm */; }; 3454D7B91E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3454D79A1E07F045004AF2AD /* CALayer+RuntimeAttributes.mm */; }; 3454D7BA1E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3454D79A1E07F045004AF2AD /* CALayer+RuntimeAttributes.mm */; }; @@ -270,6 +303,27 @@ 3470402F1EA6470700038379 /* BorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470402E1EA6470700038379 /* BorderedButton.swift */; }; 347040301EA6470700038379 /* BorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470402E1EA6470700038379 /* BorderedButton.swift */; }; 347040311EA6470700038379 /* BorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470402E1EA6470700038379 /* BorderedButton.swift */; }; + 34763EE61F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */; }; + 34763EE71F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */; }; + 34763EE81F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */; }; + 34763EED1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34763EEC1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib */; }; + 34763EEE1F2F5F2F00F4D2D3 /* MWMiPhoneRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34763EEC1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib */; }; + 34763EEF1F2F5F2F00F4D2D3 /* MWMiPhoneRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34763EEC1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib */; }; + 34763EF21F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EF11F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm */; }; + 34763EF31F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EF11F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm */; }; + 34763EF41F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34763EF11F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm */; }; + 34763EFA1F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34763EF91F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib */; }; + 34763EFB1F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34763EF91F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib */; }; + 34763EFC1F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34763EF91F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib */; }; + 34763EFE1F3069BB00F4D2D3 /* RouteStartButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763EFD1F3069BB00F4D2D3 /* RouteStartButton.swift */; }; + 34763EFF1F3069BB00F4D2D3 /* RouteStartButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763EFD1F3069BB00F4D2D3 /* RouteStartButton.swift */; }; + 34763F001F3069BB00F4D2D3 /* RouteStartButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763EFD1F3069BB00F4D2D3 /* RouteStartButton.swift */; }; + 34763F021F30749000F4D2D3 /* RoutePreviewStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763F011F30749000F4D2D3 /* RoutePreviewStatus.swift */; }; + 34763F031F30749000F4D2D3 /* RoutePreviewStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763F011F30749000F4D2D3 /* RoutePreviewStatus.swift */; }; + 34763F041F30749000F4D2D3 /* RoutePreviewStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763F011F30749000F4D2D3 /* RoutePreviewStatus.swift */; }; + 34763F061F3092E700F4D2D3 /* String+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763F051F3092E700F4D2D3 /* String+Format.swift */; }; + 34763F071F3092E700F4D2D3 /* String+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763F051F3092E700F4D2D3 /* String+Format.swift */; }; + 34763F081F3092E700F4D2D3 /* String+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34763F051F3092E700F4D2D3 /* String+Format.swift */; }; 3476B8DC1BFDD30B00874594 /* tts-how-to-set-up-voice.html in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8D51BFDD30B00874594 /* tts-how-to-set-up-voice.html */; }; 3476B8DD1BFDD30B00874594 /* tts-how-to-set-up-voice.html in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8D51BFDD30B00874594 /* tts-how-to-set-up-voice.html */; }; 3476B8E01BFDD33A00874594 /* tts-how-to-set-up-voice-img in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */; }; @@ -290,6 +344,9 @@ 347E1A991F1F7404002BF7A8 /* CianElement.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A951F1F7404002BF7A8 /* CianElement.xib */; }; 347E1A9A1F1F7404002BF7A8 /* CianElement.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A951F1F7404002BF7A8 /* CianElement.xib */; }; 347E1A9B1F1F7404002BF7A8 /* CianElement.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A951F1F7404002BF7A8 /* CianElement.xib */; }; + 347BFA8F1F27909200E5531F /* MenuArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347BFA8E1F27909200E5531F /* MenuArea.swift */; }; + 347BFA901F27909200E5531F /* MenuArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347BFA8E1F27909200E5531F /* MenuArea.swift */; }; + 347BFA911F27909200E5531F /* MenuArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347BFA8E1F27909200E5531F /* MenuArea.swift */; }; 34845DAE1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; }; 34845DAF1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; }; 34845DB01E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; }; @@ -616,7 +673,6 @@ 4A7D89C71B2EBF3B00AC843E /* resources-xhdpi_dark in Resources */ = {isa = PBXBuildFile; fileRef = 4A7D89C31B2EBF3B00AC843E /* resources-xhdpi_dark */; }; 4A7D89C81B2EBF3B00AC843E /* resources-xxhdpi_dark in Resources */ = {isa = PBXBuildFile; fileRef = 4A7D89C41B2EBF3B00AC843E /* resources-xxhdpi_dark */; }; 5605022F1B6211E100169CAD /* sound-strings in Resources */ = {isa = PBXBuildFile; fileRef = 5605022E1B6211E100169CAD /* sound-strings */; }; - 560634F21B78806100F3D670 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 560634F11B78806100F3D670 /* MWMTextToSpeech.mm */; }; 56C74C391C74A3BC00B71B9F /* MWMInputEmailValidator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ABA62F1C2D58F300FE1BEC /* MWMInputEmailValidator.mm */; }; 671182E11C7F0DD400CB8177 /* countries_obsolete.txt in Resources */ = {isa = PBXBuildFile; fileRef = 671182DE1C7F0DD400CB8177 /* countries_obsolete.txt */; }; 671182E21C7F0DD400CB8177 /* packed_polygons_obsolete.bin in Resources */ = {isa = PBXBuildFile; fileRef = 671182DF1C7F0DD400CB8177 /* packed_polygons_obsolete.bin */; }; @@ -650,8 +706,6 @@ 6741A9681BF340DE002C974C /* faq.html in Resources */ = {isa = PBXBuildFile; fileRef = 978D4A30199A11E600D72CA7 /* faq.html */; }; 6741A96C1BF340DE002C974C /* MWMDownloadTransitMapAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F64F19981AB81A00006EAF7E /* MWMDownloadTransitMapAlert.xib */; }; 6741A96D1BF340DE002C974C /* MWMLocationAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BBF2C71B4FFB8C000CF8E2 /* MWMLocationAlert.xib */; }; - 6741A96E1BF340DE002C974C /* MWMRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BB6CBD1BB15A5E00DF1DF2 /* MWMRoutePreview.xib */; }; - 6741A9701BF340DE002C974C /* MWMiPadRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6172FA41BBD5A3E0081D325 /* MWMiPadRoutePreview.xib */; }; 6741A9711BF340DE002C974C /* copyright.html in Resources */ = {isa = PBXBuildFile; fileRef = 97A5967E19B9CD47007A963F /* copyright.html */; }; 6741A9741BF340DE002C974C /* resources-6plus_dark in Resources */ = {isa = PBXBuildFile; fileRef = 4A7D89C11B2EBF3B00AC843E /* resources-6plus_dark */; }; 6741A9751BF340DE002C974C /* WorldCoasts.mwm in Resources */ = {isa = PBXBuildFile; fileRef = FA459EB314327AF700B5BB3C /* WorldCoasts.mwm */; }; @@ -676,14 +730,12 @@ 6741A9A91BF340DE002C974C /* MWMDefaultAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F198B1AB81A00006EAF7E /* MWMDefaultAlert.mm */; }; 6741A9B01BF340DE002C974C /* MapsAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MapsAppDelegate.mm */; }; 6741A9B11BF340DE002C974C /* MWMAPIBarView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 341522BE1B666A550077AA8F /* MWMAPIBarView.mm */; }; - 6741A9B61BF340DE002C974C /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 560634F11B78806100F3D670 /* MWMTextToSpeech.mm */; }; 6741A9B71BF340DE002C974C /* EAGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46F26CD710F623BA00ECCA39 /* EAGLView.mm */; }; 6741A9B81BF340DE002C974C /* MapViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = EED10A4411F78D120095FAD4 /* MapViewController.mm */; }; 6741A9B91BF340DE002C974C /* MWMRateAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F61579331AC2CE9A0032D8E9 /* MWMRateAlert.mm */; }; 6741A9C01BF340DE002C974C /* MWMTextView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6588E2B1B15C26700EE1E58 /* MWMTextView.mm */; }; 6741A9CF1BF340DE002C974C /* MWMLocationAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BBF2C51B4FFB72000CF8E2 /* MWMLocationAlert.mm */; }; 6741A9D41BF340DE002C974C /* MWMAlertViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F19821AB81A00006EAF7E /* MWMAlertViewController.mm */; }; - 6741A9DB1BF340DE002C974C /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD337E1B62403B00F2CE18 /* MWMRoutePreview.mm */; }; 6741A9E01BF340DE002C974C /* MWMDownloaderDialogHeader.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F4B731B4A45FD0081A24A /* MWMDownloaderDialogHeader.mm */; }; 6741A9E71BF340DE002C974C /* MWMCircularProgressView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 349A35791B53D4C9009677EE /* MWMCircularProgressView.mm */; }; 6741A9E81BF340DE002C974C /* MWMAPIBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3465E7D71B6658C000854C4D /* MWMAPIBar.mm */; }; @@ -700,7 +752,6 @@ 6741AA191BF340DE002C974C /* MWMDownloaderDialogCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F4B6C1B46A51F0081A24A /* MWMDownloaderDialogCell.mm */; }; 6741AA1C1BF340DE002C974C /* MWMRoutingDisclaimerAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F63774E91B59376F00BCF54D /* MWMRoutingDisclaimerAlert.mm */; }; 6741AA1D1BF340DE002C974C /* MWMDownloadTransitMapAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F19971AB81A00006EAF7E /* MWMDownloadTransitMapAlert.mm */; }; - 6741AA221BF340DE002C974C /* MWMNavigationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */; }; 6741AA281BF340DE002C974C /* MWMAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F19861AB81A00006EAF7E /* MWMAlert.mm */; }; 6741AA291BF340DE002C974C /* ColorPickerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED48BBB417C267F5003E7E92 /* ColorPickerView.mm */; }; 6741AA2B1BF340DE002C974C /* CircleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED48BBB917C2B1E2003E7E92 /* CircleView.mm */; }; @@ -773,7 +824,6 @@ 849CF5F61DE842290024A8A5 /* resources-6plus_clear in Resources */ = {isa = PBXBuildFile; fileRef = 4A23D1571B8B4DD700D4EB6F /* resources-6plus_clear */; }; 849CF5F81DE842290024A8A5 /* unicode_blocks.txt in Resources */ = {isa = PBXBuildFile; fileRef = EE583CBA12F773F00042CBE3 /* unicode_blocks.txt */; }; 849CF5F91DE842290024A8A5 /* fonts_blacklist.txt in Resources */ = {isa = PBXBuildFile; fileRef = EEFE7C1212F8C9E1006AF8C3 /* fonts_blacklist.txt */; }; - 849CF5FA1DE842290024A8A5 /* RoutePreviewTaxiCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F68FCB891DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib */; }; 849CF5FC1DE842290024A8A5 /* resources-xxhdpi_clear in Resources */ = {isa = PBXBuildFile; fileRef = 4A23D15A1B8B4DD700D4EB6F /* resources-xxhdpi_clear */; }; 849CF5FE1DE842290024A8A5 /* MWMDefaultAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F64F198C1AB81A00006EAF7E /* MWMDefaultAlert.xib */; }; 849CF5FF1DE842290024A8A5 /* fonts_whitelist.txt in Resources */ = {isa = PBXBuildFile; fileRef = EEFE7C1312F8C9E1006AF8C3 /* fonts_whitelist.txt */; }; @@ -800,8 +850,6 @@ 849CF6291DE842290024A8A5 /* faq.html in Resources */ = {isa = PBXBuildFile; fileRef = 978D4A30199A11E600D72CA7 /* faq.html */; }; 849CF62F1DE842290024A8A5 /* MWMDownloadTransitMapAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F64F19981AB81A00006EAF7E /* MWMDownloadTransitMapAlert.xib */; }; 849CF6301DE842290024A8A5 /* MWMLocationAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BBF2C71B4FFB8C000CF8E2 /* MWMLocationAlert.xib */; }; - 849CF6311DE842290024A8A5 /* MWMRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BB6CBD1BB15A5E00DF1DF2 /* MWMRoutePreview.xib */; }; - 849CF6381DE842290024A8A5 /* MWMiPadRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6172FA41BBD5A3E0081D325 /* MWMiPadRoutePreview.xib */; }; 849CF6391DE842290024A8A5 /* copyright.html in Resources */ = {isa = PBXBuildFile; fileRef = 97A5967E19B9CD47007A963F /* copyright.html */; }; 849CF63D1DE842290024A8A5 /* WorldCoasts_obsolete.mwm in Resources */ = {isa = PBXBuildFile; fileRef = 671182E01C7F0DD400CB8177 /* WorldCoasts_obsolete.mwm */; }; 849CF63F1DE842290024A8A5 /* resources-6plus_dark in Resources */ = {isa = PBXBuildFile; fileRef = 4A7D89C11B2EBF3B00AC843E /* resources-6plus_dark */; }; @@ -839,7 +887,6 @@ 849CF6971DE842290024A8A5 /* MapsAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MapsAppDelegate.mm */; }; 849CF6981DE842290024A8A5 /* MWMAPIBarView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 341522BE1B666A550077AA8F /* MWMAPIBarView.mm */; }; 849CF69D1DE842290024A8A5 /* MWMInputLoginValidator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ABA6271C2D567B00FE1BEC /* MWMInputLoginValidator.mm */; }; - 849CF69E1DE842290024A8A5 /* MWMTextToSpeech.mm in Sources */ = {isa = PBXBuildFile; fileRef = 560634F11B78806100F3D670 /* MWMTextToSpeech.mm */; }; 849CF69F1DE842290024A8A5 /* MWMStartButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6791B121C43DEA7007A8A6E /* MWMStartButton.mm */; }; 849CF6A01DE842290024A8A5 /* EAGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46F26CD710F623BA00ECCA39 /* EAGLView.mm */; }; 849CF6A21DE842290024A8A5 /* MapViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = EED10A4411F78D120095FAD4 /* MapViewController.mm */; }; @@ -857,7 +904,6 @@ 849CF6D31DE842290024A8A5 /* MWMMapDownloadDialog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3406FA141C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm */; }; 849CF6D51DE842290024A8A5 /* MWMTableViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34C9BCFF1C6DB693000DC38D /* MWMTableViewController.mm */; }; 849CF6D81DE842290024A8A5 /* MWMSegue.mm in Sources */ = {isa = PBXBuildFile; fileRef = F607C18D1C047FDC00B53A87 /* MWMSegue.mm */; }; - 849CF6DC1DE842290024A8A5 /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD337E1B62403B00F2CE18 /* MWMRoutePreview.mm */; }; 849CF6DF1DE842290024A8A5 /* MWMAuthorizationCommon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */; }; 849CF6E11DE842290024A8A5 /* MWMDownloaderDialogHeader.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F4B731B4A45FD0081A24A /* MWMDownloaderDialogHeader.mm */; }; 849CF6E71DE842290024A8A5 /* MWMSearchNoResultsAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3462258D1DDC5DBA001E8752 /* MWMSearchNoResultsAlert.mm */; }; @@ -870,7 +916,6 @@ 849CF6FB1DE842290024A8A5 /* BookmarksVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA36B80615403A4F004560CC /* BookmarksVC.mm */; }; 849CF6FC1DE842290024A8A5 /* MWMSideButtonsView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3490D2DC1CE9DD2500D0B838 /* MWMSideButtonsView.mm */; }; 849CF7071DE842290024A8A5 /* LocaleTranslator.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6381BF41CD12045004CA943 /* LocaleTranslator.mm */; }; - 849CF70A1DE842290024A8A5 /* MWMTaxiPreviewDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = F68FCB841DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm */; }; 849CF70D1DE842290024A8A5 /* MWMAddPlaceNavigationBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = F653CE151C71F60200A453F1 /* MWMAddPlaceNavigationBar.mm */; }; 849CF7121DE842290024A8A5 /* SelectSetVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA054611155C465E001F4E37 /* SelectSetVC.mm */; }; 849CF7141DE842290024A8A5 /* AddSetVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAA614B7155F16950031C345 /* AddSetVC.mm */; }; @@ -884,7 +929,6 @@ 849CF72B1DE842290024A8A5 /* MWMBookmarkNameCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6B97B251CD0CA990009B612 /* MWMBookmarkNameCell.mm */; }; 849CF72F1DE842290024A8A5 /* MWMInputValidator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ABA61F1C2D517500FE1BEC /* MWMInputValidator.mm */; }; 849CF7331DE842290024A8A5 /* MWMInputValidatorFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ABA6231C2D551900FE1BEC /* MWMInputValidatorFactory.mm */; }; - 849CF7371DE842290024A8A5 /* MWMTaxiCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6F778791DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm */; }; 849CF73C1DE842290024A8A5 /* MWMMultilineLabel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346EDADA1B9F0E35004F8DB5 /* MWMMultilineLabel.mm */; }; 849CF73D1DE842290024A8A5 /* MWMViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34C9BD011C6DB693000DC38D /* MWMViewController.mm */; }; 849CF7461DE842290024A8A5 /* MWMTableViewCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F626D52D1C3E6CAA00C17D15 /* MWMTableViewCell.mm */; }; @@ -892,7 +936,6 @@ 849CF74C1DE842290024A8A5 /* MWMLocationNotFoundAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346B42AA1DD5E3D20094EBEE /* MWMLocationNotFoundAlert.mm */; }; 849CF7561DE842290024A8A5 /* MWMRoutingDisclaimerAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F63774E91B59376F00BCF54D /* MWMRoutingDisclaimerAlert.mm */; }; 849CF7581DE842290024A8A5 /* MWMDownloadTransitMapAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F19971AB81A00006EAF7E /* MWMDownloadTransitMapAlert.mm */; }; - 849CF75C1DE842290024A8A5 /* MWMNavigationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */; }; 849CF7601DE842290024A8A5 /* MWMStopButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34AB39C01D2BD8310021857D /* MWMStopButton.mm */; }; 849CF7611DE842290024A8A5 /* MWMMailViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B924411DC8A29C0008D971 /* MWMMailViewController.mm */; }; 849CF7631DE842290024A8A5 /* MWMAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64F19861AB81A00006EAF7E /* MWMAlert.mm */; }; @@ -953,7 +996,6 @@ F6150E561EFA7352000B955D /* MWUGCCommentsController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6150E501EFA7352000B955D /* MWUGCCommentsController.xib */; }; F61579341AC2CE9A0032D8E9 /* MWMRateAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F61579331AC2CE9A0032D8E9 /* MWMRateAlert.mm */; }; F61579361AC2CEB60032D8E9 /* MWMRateAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F61579351AC2CEB60032D8E9 /* MWMRateAlert.xib */; }; - F6172FA51BBD5A3E0081D325 /* MWMiPadRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6172FA41BBD5A3E0081D325 /* MWMiPadRoutePreview.xib */; }; F623DA6B1C9C2731006A3436 /* opening_hours_how_to_edit.html in Resources */ = {isa = PBXBuildFile; fileRef = F623DA6A1C9C2731006A3436 /* opening_hours_how_to_edit.html */; }; F623DA6C1C9C2731006A3436 /* opening_hours_how_to_edit.html in Resources */ = {isa = PBXBuildFile; fileRef = F623DA6A1C9C2731006A3436 /* opening_hours_how_to_edit.html */; }; F623DA6F1C9C2E62006A3436 /* MWMAddPlaceNavigationBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = F653CE171C71F62400A453F1 /* MWMAddPlaceNavigationBar.xib */; }; @@ -1033,7 +1075,6 @@ F6664C171E645A4100E703C2 /* MWMPPReviewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6664C111E645A4100E703C2 /* MWMPPReviewCell.xib */; }; F6791B131C43DEA7007A8A6E /* MWMStartButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6791B121C43DEA7007A8A6E /* MWMStartButton.mm */; }; F6791B141C43DF0B007A8A6E /* MWMStartButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6791B121C43DEA7007A8A6E /* MWMStartButton.mm */; }; - F67E751E1DB76DFC00D6741F /* MWMTaxiCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6F778791DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm */; }; F682249A1E5B104600BC1C18 /* PPHotelDescriptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68224991E5B104600BC1C18 /* PPHotelDescriptionCell.swift */; }; F682249B1E5B104600BC1C18 /* PPHotelDescriptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68224991E5B104600BC1C18 /* PPHotelDescriptionCell.swift */; }; F682249C1E5B104600BC1C18 /* PPHotelDescriptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68224991E5B104600BC1C18 /* PPHotelDescriptionCell.swift */; }; @@ -1046,10 +1087,6 @@ F68BDF1B1EF80DE90009BB81 /* MWMUGCCommentCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F68BDF1A1EF80DE90009BB81 /* MWMUGCCommentCell.mm */; }; F68BDF1C1EF80DE90009BB81 /* MWMUGCCommentCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F68BDF1A1EF80DE90009BB81 /* MWMUGCCommentCell.mm */; }; F68BDF1D1EF80DE90009BB81 /* MWMUGCCommentCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F68BDF1A1EF80DE90009BB81 /* MWMUGCCommentCell.mm */; }; - F68FCB851DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = F68FCB841DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm */; }; - F68FCB861DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = F68FCB841DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm */; }; - F68FCB8C1DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F68FCB891DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib */; }; - F68FCB8D1DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F68FCB891DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib */; }; F69018B81E9E601400B3C10B /* MWMAutoupdateController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F69018B71E9E601400B3C10B /* MWMAutoupdateController.mm */; }; F69018BC1E9F7CB600B3C10B /* MWMAutoupdateController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F69018BB1E9F7CB600B3C10B /* MWMAutoupdateController.xib */; }; F69018BD1E9F7CB600B3C10B /* MWMAutoupdateController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F69018BB1E9F7CB600B3C10B /* MWMAutoupdateController.xib */; }; @@ -1071,7 +1108,6 @@ F6B97B271CD0CA990009B612 /* MWMBookmarkNameCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6B97B251CD0CA990009B612 /* MWMBookmarkNameCell.mm */; }; F6B97B291CD0CB170009B612 /* MWMBookmarkNameCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6B97B281CD0CB170009B612 /* MWMBookmarkNameCell.xib */; }; F6B97B2A1CD0CB170009B612 /* MWMBookmarkNameCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6B97B281CD0CB170009B612 /* MWMBookmarkNameCell.xib */; }; - F6BB6CBE1BB15A5E00DF1DF2 /* MWMRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BB6CBD1BB15A5E00DF1DF2 /* MWMRoutePreview.xib */; }; F6BBF2C61B4FFB72000CF8E2 /* MWMLocationAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BBF2C51B4FFB72000CF8E2 /* MWMLocationAlert.mm */; }; F6BBF2C81B4FFB8C000CF8E2 /* MWMLocationAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BBF2C71B4FFB8C000CF8E2 /* MWMLocationAlert.xib */; }; F6BC1E521ACBF98600EF0360 /* MWMFacebookAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BC1E511ACBF98600EF0360 /* MWMFacebookAlert.mm */; }; @@ -1080,8 +1116,6 @@ F6BD1D211CA412920047B8E8 /* MWMOsmAuthAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD1D1F1CA412920047B8E8 /* MWMOsmAuthAlert.mm */; }; F6BD1D231CA412E30047B8E8 /* MWMOsmAuthAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BD1D221CA412E30047B8E8 /* MWMOsmAuthAlert.xib */; }; F6BD1D241CA412E40047B8E8 /* MWMOsmAuthAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BD1D221CA412E30047B8E8 /* MWMOsmAuthAlert.xib */; }; - F6BD33811B62403B00F2CE18 /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD337E1B62403B00F2CE18 /* MWMRoutePreview.mm */; }; - F6BD33841B6240F200F2CE18 /* MWMNavigationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */; }; F6BD33871B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33861B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm */; }; F6C0E62D1EF80F9000A4EFAA /* MWMUGCCommentCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6C0E62C1EF80F9000A4EFAA /* MWMUGCCommentCell.xib */; }; F6C269F61F14D76F00EB6519 /* ugc_types.csv in Resources */ = {isa = PBXBuildFile; fileRef = F642D1221F0F9D1D005E3C25 /* ugc_types.csv */; }; @@ -1269,9 +1303,6 @@ F6E2FE3C1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC8E1E097B9F0083EBEC /* MWMMigrationViewController.mm */; }; F6E2FE3D1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC8E1E097B9F0083EBEC /* MWMMigrationViewController.mm */; }; F6E2FE3E1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC8E1E097B9F0083EBEC /* MWMMigrationViewController.mm */; }; - F6E2FE3F1E097BA00083EBEC /* MWMPlacePageEntity.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC921E097B9F0083EBEC /* MWMPlacePageEntity.mm */; }; - F6E2FE401E097BA00083EBEC /* MWMPlacePageEntity.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC921E097B9F0083EBEC /* MWMPlacePageEntity.mm */; }; - F6E2FE411E097BA00083EBEC /* MWMPlacePageEntity.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC921E097B9F0083EBEC /* MWMPlacePageEntity.mm */; }; F6E2FE421E097BA00083EBEC /* MWMDirectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC951E097B9F0083EBEC /* MWMDirectionView.mm */; }; F6E2FE431E097BA00083EBEC /* MWMDirectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC951E097B9F0083EBEC /* MWMDirectionView.mm */; }; F6E2FE441E097BA00083EBEC /* MWMDirectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC951E097B9F0083EBEC /* MWMDirectionView.mm */; }; @@ -1542,7 +1573,6 @@ F6E2FF681E097BA00083EBEC /* MWMUnitsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FD4D1E097BA00083EBEC /* MWMUnitsController.mm */; }; F6E2FF691E097BA00083EBEC /* MWMUnitsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FD4D1E097BA00083EBEC /* MWMUnitsController.mm */; }; F6E2FF6A1E097BA00083EBEC /* MWMUnitsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FD4D1E097BA00083EBEC /* MWMUnitsController.mm */; }; - F6F7787A1DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6F778791DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm */; }; F6F8E3C51EF8469700F2DE8F /* libugc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6F8E3C41EF8469700F2DE8F /* libugc.a */; }; F6FE3C381CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6FE3C371CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.mm */; }; F6FE3C391CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6FE3C371CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.mm */; }; @@ -1730,6 +1760,25 @@ 3406FA131C6E0C3300E9FAD2 /* MWMMapDownloadDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMMapDownloadDialog.h; sourceTree = ""; }; 3406FA141C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMMapDownloadDialog.mm; sourceTree = ""; }; 3406FA171C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMMapDownloadDialog.xib; sourceTree = ""; }; + 340708411F28ED2D00029ECC /* MWMRoutePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMRoutePreview.h; sourceTree = ""; }; + 340708421F28ED2D00029ECC /* MWMRoutePreview.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMRoutePreview.mm; sourceTree = ""; }; + 340708441F28EDD100029ECC /* MWMiPadRoutePreview.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMiPadRoutePreview.xib; sourceTree = ""; }; + 340708471F28EDD100029ECC /* MWMTaxiPreviewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTaxiPreviewDataSource.h; sourceTree = ""; }; + 340708481F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTaxiPreviewDataSource.mm; sourceTree = ""; }; + 340708491F28EDD100029ECC /* RoutePreviewTaxiCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoutePreviewTaxiCell.swift; sourceTree = ""; }; + 3407084A1F28EDD100029ECC /* MWMTaxiCollectionLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTaxiCollectionLayout.h; sourceTree = ""; }; + 3407084B1F28EDD100029ECC /* MWMTaxiCollectionLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTaxiCollectionLayout.mm; sourceTree = ""; }; + 3407085E1F28FE2800029ECC /* MWMiPadRoutePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMiPadRoutePreview.h; sourceTree = ""; }; + 3407085F1F28FE2800029ECC /* MWMiPadRoutePreview.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMiPadRoutePreview.mm; sourceTree = ""; }; + 340708631F2905A500029ECC /* NavigationInfoArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationInfoArea.swift; sourceTree = ""; }; + 3407086C1F2B427400029ECC /* RoutePreviewTaxiCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoutePreviewTaxiCell.xib; sourceTree = ""; }; + 340708761F2B5D6C00029ECC /* DimBackground.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DimBackground.swift; sourceTree = ""; }; + 3407087A1F2B6F5200029ECC /* NavigationControlView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationControlView.swift; sourceTree = ""; }; + 3407087E1F2B6F7000029ECC /* NavigationControlView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NavigationControlView.xib; sourceTree = ""; }; + 340708831F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "MWMNavigationDashboardManager+Entity.mm"; sourceTree = ""; }; + 340708871F2B889400029ECC /* MWMNavigationDashboardManager+Entity.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MWMNavigationDashboardManager+Entity.h"; sourceTree = ""; }; + 340708881F2B8B7900029ECC /* MWMRoutePreviewTaxiCellType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMRoutePreviewTaxiCellType.h; sourceTree = ""; }; + 340708891F2B8CBF00029ECC /* MWMCircularProgressState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMCircularProgressState.h; sourceTree = ""; }; 340837111B7243CE00B5C185 /* MWMActivityViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMActivityViewController.h; sourceTree = ""; }; 340837121B7243CE00B5C185 /* MWMActivityViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMActivityViewController.mm; sourceTree = ""; }; 340837141B72451A00B5C185 /* MWMShareActivityItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMShareActivityItem.h; sourceTree = ""; }; @@ -1766,7 +1815,6 @@ 344D63161E795A2D006F17CB /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 345050211E028B8000A8DC59 /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = ""; }; 3451F4EC1F026DAF00A981F2 /* PlacePageTaxiCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlacePageTaxiCell.swift; sourceTree = ""; }; - 3451F4F01F02935300A981F2 /* RoutePreviewTaxiCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoutePreviewTaxiCell.swift; sourceTree = ""; }; 3454D7991E07F045004AF2AD /* CALayer+RuntimeAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CALayer+RuntimeAttributes.h"; sourceTree = ""; }; 3454D79A1E07F045004AF2AD /* CALayer+RuntimeAttributes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "CALayer+RuntimeAttributes.mm"; sourceTree = ""; }; 3454D79B1E07F045004AF2AD /* CLLocation+Mercator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CLLocation+Mercator.h"; sourceTree = ""; }; @@ -1824,6 +1872,19 @@ 3470402E1EA6470700038379 /* BorderedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BorderedButton.swift; sourceTree = ""; }; 347526FA1DC0B00F00918CF5 /* common-debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-debug.xcconfig"; path = "../../xcode/common-debug.xcconfig"; sourceTree = ""; }; 347526FB1DC0B00F00918CF5 /* common-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-release.xcconfig"; path = "../../xcode/common-release.xcconfig"; sourceTree = ""; }; + 34763EE41F2F392300F4D2D3 /* MWMTextToSpeech.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTextToSpeech.h; sourceTree = ""; }; + 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTextToSpeech.mm; sourceTree = ""; }; + 34763EE91F2F394D00F4D2D3 /* MWMTextToSpeech+CPP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MWMTextToSpeech+CPP.h"; sourceTree = ""; }; + 34763EEA1F2F3AD700F4D2D3 /* MWMTextToSpeechObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMTextToSpeechObserver.h; sourceTree = ""; }; + 34763EEB1F2F420B00F4D2D3 /* MWMTrafficManagerState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMTrafficManagerState.h; sourceTree = ""; }; + 34763EEC1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMiPhoneRoutePreview.xib; sourceTree = ""; }; + 34763EF01F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMiPhoneRoutePreview.h; sourceTree = ""; }; + 34763EF11F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMiPhoneRoutePreview.mm; sourceTree = ""; }; + 34763EF91F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NavigationRoutePreviewStatusView.xib; sourceTree = ""; }; + 34763EFD1F3069BB00F4D2D3 /* RouteStartButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteStartButton.swift; sourceTree = ""; }; + 34763F011F30749000F4D2D3 /* RoutePreviewStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoutePreviewStatus.swift; sourceTree = ""; }; + 34763F051F3092E700F4D2D3 /* String+Format.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Format.swift"; sourceTree = ""; }; + 34763F0B1F30CCAC00F4D2D3 /* MWMEditorCellType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMEditorCellType.h; sourceTree = ""; }; 3476B8D51BFDD30B00874594 /* tts-how-to-set-up-voice.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "tts-how-to-set-up-voice.html"; path = "../../data/tts-how-to-set-up-voice.html"; sourceTree = ""; }; 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "tts-how-to-set-up-voice-img"; path = "../../data/tts-how-to-set-up-voice-img"; sourceTree = ""; }; 347E1A871F1F5DD7002BF7A8 /* CianItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CianItemModel.swift; sourceTree = ""; }; @@ -1832,6 +1893,10 @@ 347E1A941F1F7404002BF7A8 /* CianElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CianElement.swift; sourceTree = ""; }; 347E1A951F1F7404002BF7A8 /* CianElement.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CianElement.xib; sourceTree = ""; }; 348320CC1B6A2C52007EC039 /* MWMNavigationViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMNavigationViewProtocol.h; sourceTree = ""; }; + 347AD8081F28B4E6007ACB68 /* MWMSearchManagerObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSearchManagerObserver.h; sourceTree = ""; }; + 347BFA8E1F27909200E5531F /* MenuArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuArea.swift; sourceTree = ""; }; + 347BFA921F27923200E5531F /* MWMBottomMenuControllerProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMBottomMenuControllerProtocol.h; sourceTree = ""; }; + 347BFA931F28842300E5531F /* MWMNavigationDashboardObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMNavigationDashboardObserver.h; sourceTree = ""; }; 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloaderNoResultsEmbedViewController.swift; sourceTree = ""; }; 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchNoResultsViewController.swift; sourceTree = ""; }; 34845DB51E166084003D55B9 /* Common.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = ""; }; @@ -1874,7 +1939,6 @@ 349B926A1DF0518E007779DD /* MWMToast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMToast.h; sourceTree = ""; }; 349B926B1DF0518E007779DD /* MWMToast.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMToast.mm; sourceTree = ""; }; 349B926F1DF0526D007779DD /* MWMToast.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMToast.xib; sourceTree = ""; }; - 349C3AF11D33C6EE002AC7A9 /* MWMNavigationDashboardInfoProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMNavigationDashboardInfoProtocol.h; sourceTree = ""; }; 349D1ABA1E2D05EF004A2006 /* SearchBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = ""; }; 349D1AC31E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMBottomMenuCollectionViewCell.h; sourceTree = ""; }; 349D1AC41E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMBottomMenuCollectionViewCell.mm; sourceTree = ""; }; @@ -2081,8 +2145,6 @@ 4A7D89C31B2EBF3B00AC843E /* resources-xhdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-xhdpi_dark"; path = "../../data/resources-xhdpi_dark"; sourceTree = ""; }; 4A7D89C41B2EBF3B00AC843E /* resources-xxhdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-xxhdpi_dark"; path = "../../data/resources-xxhdpi_dark"; sourceTree = ""; }; 5605022E1B6211E100169CAD /* sound-strings */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "sound-strings"; path = "../../data/sound-strings"; sourceTree = ""; }; - 560634F01B78804C00F3D670 /* MWMTextToSpeech.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTextToSpeech.h; sourceTree = ""; }; - 560634F11B78806100F3D670 /* MWMTextToSpeech.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMTextToSpeech.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 671182DE1C7F0DD400CB8177 /* countries_obsolete.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = countries_obsolete.txt; path = ../../data/countries_obsolete.txt; sourceTree = ""; }; 671182DF1C7F0DD400CB8177 /* packed_polygons_obsolete.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = packed_polygons_obsolete.bin; path = ../../data/packed_polygons_obsolete.bin; sourceTree = ""; }; 671182E01C7F0DD400CB8177 /* WorldCoasts_obsolete.mwm */ = {isa = PBXFileReference; lastKnownFileType = file; name = WorldCoasts_obsolete.mwm; path = ../../data/WorldCoasts_obsolete.mwm; sourceTree = ""; }; @@ -2161,7 +2223,6 @@ F61579321AC2CE9A0032D8E9 /* MWMRateAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMRateAlert.h; sourceTree = ""; }; F61579331AC2CE9A0032D8E9 /* MWMRateAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMRateAlert.mm; sourceTree = ""; }; F61579351AC2CEB60032D8E9 /* MWMRateAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMRateAlert.xib; sourceTree = ""; }; - F6172FA41BBD5A3E0081D325 /* MWMiPadRoutePreview.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMiPadRoutePreview.xib; sourceTree = ""; }; F623DA6A1C9C2731006A3436 /* opening_hours_how_to_edit.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = opening_hours_how_to_edit.html; path = ../../data/opening_hours_how_to_edit.html; sourceTree = ""; }; F626D52C1C3E6CAA00C17D15 /* MWMTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTableViewCell.h; sourceTree = ""; }; F626D52D1C3E6CAA00C17D15 /* MWMTableViewCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTableViewCell.mm; sourceTree = ""; }; @@ -2222,9 +2283,6 @@ F68BDF041EEA9A830009BB81 /* MyTargetSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MyTargetSDK.framework; sourceTree = ""; }; F68BDF191EF80DE90009BB81 /* MWMUGCCommentCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMUGCCommentCell.h; sourceTree = ""; }; F68BDF1A1EF80DE90009BB81 /* MWMUGCCommentCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMUGCCommentCell.mm; sourceTree = ""; }; - F68FCB831DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MWMTaxiPreviewDataSource.h; path = Views/RoutePreview/MWMTaxiPreviewDataSource.h; sourceTree = ""; }; - F68FCB841DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MWMTaxiPreviewDataSource.mm; path = Views/RoutePreview/MWMTaxiPreviewDataSource.mm; sourceTree = ""; }; - F68FCB891DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoutePreviewTaxiCell.xib; sourceTree = ""; }; F69018B61E9E601400B3C10B /* MWMAutoupdateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAutoupdateController.h; sourceTree = ""; }; F69018B71E9E601400B3C10B /* MWMAutoupdateController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAutoupdateController.mm; sourceTree = ""; }; F69018BB1E9F7CB600B3C10B /* MWMAutoupdateController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMAutoupdateController.xib; sourceTree = ""; }; @@ -2236,7 +2294,6 @@ F6B97B241CD0CA990009B612 /* MWMBookmarkNameCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMBookmarkNameCell.h; sourceTree = ""; }; F6B97B251CD0CA990009B612 /* MWMBookmarkNameCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMBookmarkNameCell.mm; sourceTree = ""; }; F6B97B281CD0CB170009B612 /* MWMBookmarkNameCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMBookmarkNameCell.xib; sourceTree = ""; }; - F6BB6CBD1BB15A5E00DF1DF2 /* MWMRoutePreview.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMRoutePreview.xib; sourceTree = ""; }; F6BBF2C41B4FFB72000CF8E2 /* MWMLocationAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMLocationAlert.h; sourceTree = ""; }; F6BBF2C51B4FFB72000CF8E2 /* MWMLocationAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMLocationAlert.mm; sourceTree = ""; }; F6BBF2C71B4FFB8C000CF8E2 /* MWMLocationAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMLocationAlert.xib; sourceTree = ""; }; @@ -2246,10 +2303,6 @@ F6BD1D1E1CA412920047B8E8 /* MWMOsmAuthAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMOsmAuthAlert.h; sourceTree = ""; }; F6BD1D1F1CA412920047B8E8 /* MWMOsmAuthAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMOsmAuthAlert.mm; sourceTree = ""; }; F6BD1D221CA412E30047B8E8 /* MWMOsmAuthAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMOsmAuthAlert.xib; sourceTree = ""; }; - F6BD337D1B62403B00F2CE18 /* MWMRoutePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMRoutePreview.h; sourceTree = ""; }; - F6BD337E1B62403B00F2CE18 /* MWMRoutePreview.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMRoutePreview.mm; sourceTree = ""; }; - F6BD33821B6240F200F2CE18 /* MWMNavigationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMNavigationView.h; sourceTree = ""; }; - F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMNavigationView.mm; sourceTree = ""; }; F6BD33851B62412E00F2CE18 /* MWMNavigationDashboardEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMNavigationDashboardEntity.h; sourceTree = ""; }; F6BD33861B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMNavigationDashboardEntity.mm; sourceTree = ""; }; F6C0E62C1EF80F9000A4EFAA /* MWMUGCCommentCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMUGCCommentCell.xib; sourceTree = ""; }; @@ -2362,8 +2415,6 @@ F6E2FC8C1E097B9F0083EBEC /* MWMMigrationView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMMigrationView.mm; sourceTree = ""; }; F6E2FC8D1E097B9F0083EBEC /* MWMMigrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMMigrationViewController.h; sourceTree = ""; }; F6E2FC8E1E097B9F0083EBEC /* MWMMigrationViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMMigrationViewController.mm; sourceTree = ""; }; - F6E2FC911E097B9F0083EBEC /* MWMPlacePageEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMPlacePageEntity.h; sourceTree = ""; }; - F6E2FC921E097B9F0083EBEC /* MWMPlacePageEntity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMPlacePageEntity.mm; sourceTree = ""; }; F6E2FC941E097B9F0083EBEC /* MWMDirectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMDirectionView.h; sourceTree = ""; }; F6E2FC951E097B9F0083EBEC /* MWMDirectionView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMDirectionView.mm; sourceTree = ""; }; F6E2FC961E097B9F0083EBEC /* MWMDirectionView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMDirectionView.xib; sourceTree = ""; }; @@ -2514,8 +2565,6 @@ F6E2FD4B1E097BA00083EBEC /* MWMTTSSettingsViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTTSSettingsViewController.mm; sourceTree = ""; }; F6E2FD4C1E097BA00083EBEC /* MWMUnitsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMUnitsController.h; sourceTree = ""; }; F6E2FD4D1E097BA00083EBEC /* MWMUnitsController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMUnitsController.mm; sourceTree = ""; }; - F6F778781DABC6D800B603E7 /* MWMTaxiCollectionLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMTaxiCollectionLayout.h; sourceTree = ""; }; - F6F778791DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTaxiCollectionLayout.mm; sourceTree = ""; }; F6F8E3C41EF8469700F2DE8F /* libugc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libugc.a; path = "../../../../Library/Developer/Xcode/DerivedData/omim-fbvotunmmtqmjnezabjibwxwryev/Build/Products/Debug-iphonesimulator/libugc.a"; sourceTree = ""; }; F6FE3C361CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMPlaceDoesntExistAlert.h; sourceTree = ""; }; F6FE3C371CC50FFD00A73196 /* MWMPlaceDoesntExistAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMPlaceDoesntExistAlert.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -2898,6 +2947,7 @@ 340475281E081A4600C92850 /* Core */ = { isa = PBXGroup; children = ( + 34763EE31F2F392300F4D2D3 /* TextToSpeech */, 34F4071C1E9E1AFF00E57AC0 /* Ads */, 3486B50F1E27AD3B0069C126 /* Framework */, 340475291E081A4600C92850 /* Location */, @@ -2989,6 +3039,7 @@ 340475461E081A4600C92850 /* MWMTrafficManager.h */, 340475471E081A4600C92850 /* MWMTrafficManager.mm */, 340475481E081A4600C92850 /* MWMTrafficManagerObserver.h */, + 34763EEB1F2F420B00F4D2D3 /* MWMTrafficManagerState.h */, ); path = Traffic; sourceTree = ""; @@ -3006,6 +3057,31 @@ path = Share; sourceTree = ""; }; + 3409C9B11F28D3870038F2A9 /* RoutePreview */ = { + isa = PBXGroup; + children = ( + 3407085E1F28FE2800029ECC /* MWMiPadRoutePreview.h */, + 3407085F1F28FE2800029ECC /* MWMiPadRoutePreview.mm */, + 340708441F28EDD100029ECC /* MWMiPadRoutePreview.xib */, + 34763EF01F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.h */, + 34763EF11F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm */, + 34763EEC1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib */, + 340708411F28ED2D00029ECC /* MWMRoutePreview.h */, + 340708421F28ED2D00029ECC /* MWMRoutePreview.mm */, + 340708881F2B8B7900029ECC /* MWMRoutePreviewTaxiCellType.h */, + 3407084A1F28EDD100029ECC /* MWMTaxiCollectionLayout.h */, + 3407084B1F28EDD100029ECC /* MWMTaxiCollectionLayout.mm */, + 340708471F28EDD100029ECC /* MWMTaxiPreviewDataSource.h */, + 340708481F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm */, + 34763EF91F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib */, + 340708491F28EDD100029ECC /* RoutePreviewTaxiCell.swift */, + 3407086C1F2B427400029ECC /* RoutePreviewTaxiCell.xib */, + 34763EFD1F3069BB00F4D2D3 /* RouteStartButton.swift */, + 34763F011F30749000F4D2D3 /* RoutePreviewStatus.swift */, + ); + path = RoutePreview; + sourceTree = ""; + }; 340E1EE31E2F614400CE49BF /* Storyboard */ = { isa = PBXGroup; children = ( @@ -3076,6 +3152,7 @@ 349D1CE21E3F836900A878FD /* UIViewController+Hierarchy.swift */, 34F7422F1E0834F400AC1FD6 /* UIViewController+Navigation.h */, 34F742301E0834F400AC1FD6 /* UIViewController+Navigation.mm */, + 34763F051F3092E700F4D2D3 /* String+Format.swift */, ); path = Categories; sourceTree = ""; @@ -3215,6 +3292,7 @@ 343E75951E5B1EE20041226A /* MWMCollectionViewController.h */, 343E75961E5B1EE20041226A /* MWMCollectionViewController.mm */, 3470402E1EA6470700038379 /* BorderedButton.swift */, + 340708761F2B5D6C00029ECC /* DimBackground.swift */, ); path = Components; sourceTree = ""; @@ -3231,6 +3309,17 @@ path = Cian; sourceTree = ""; }; + 34763EE31F2F392300F4D2D3 /* TextToSpeech */ = { + isa = PBXGroup; + children = ( + 34763EE41F2F392300F4D2D3 /* MWMTextToSpeech.h */, + 34763EE51F2F392300F4D2D3 /* MWMTextToSpeech.mm */, + 34763EE91F2F394D00F4D2D3 /* MWMTextToSpeech+CPP.h */, + 34763EEA1F2F3AD700F4D2D3 /* MWMTextToSpeechObserver.h */, + ); + path = TextToSpeech; + sourceTree = ""; + }; 3486B5041E27A4B50069C126 /* Notifications */ = { isa = PBXGroup; children = ( @@ -3272,13 +3361,12 @@ children = ( F6BD33851B62412E00F2CE18 /* MWMNavigationDashboardEntity.h */, F6BD33861B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm */, - F68FCB831DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.h */, - F68FCB841DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm */, 3497A9361B5CF8A900F51E55 /* MWMNavigationDashboardManager.h */, 3497A9371B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm */, - 560634EF1B787EBE00F3D670 /* Sound */, + 340708871F2B889400029ECC /* MWMNavigationDashboardManager+Entity.h */, + 340708831F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm */, + 347BFA931F28842300E5531F /* MWMNavigationDashboardObserver.h */, 34D783C71B5F9D7800E0C0EE /* Views */, - 349C3AF11D33C6EE002AC7A9 /* MWMNavigationDashboardInfoProtocol.h */, ); name = NavigationDashboard; path = ../NavigationDashboard; @@ -3302,6 +3390,7 @@ 349A35771B53D4C9009677EE /* MWMCircularProgress.xib */, 349A35781B53D4C9009677EE /* MWMCircularProgressView.h */, 349A35791B53D4C9009677EE /* MWMCircularProgressView.mm */, + 340708891F2B8CBF00029ECC /* MWMCircularProgressState.h */, ); name = CircularProgress; path = CustomViews/CircularProgress; @@ -3331,6 +3420,7 @@ 349D1ACB1E2E325B004A2006 /* MWMBottomMenuViewController.h */, 349D1ACC1E2E325B004A2006 /* MWMBottomMenuViewController.mm */, 349D1ACD1E2E325B004A2006 /* MWMBottomMenuViewController.xib */, + 347BFA921F27923200E5531F /* MWMBottomMenuControllerProtocol.h */, ); path = BottomMenu; sourceTree = ""; @@ -3420,35 +3510,19 @@ 34D783C71B5F9D7800E0C0EE /* Views */ = { isa = PBXGroup; children = ( + 3409C9B11F28D3870038F2A9 /* RoutePreview */, 34AC8FCA1EFC028600E7F910 /* MWMNavigationInfoView.h */, 34AC8FCB1EFC028600E7F910 /* MWMNavigationInfoView.mm */, 34AC8FCC1EFC028600E7F910 /* MWMNavigationInfoView.xib */, 34AC8FCD1EFC028600E7F910 /* NavigationAddPointToastView.swift */, - 348320CC1B6A2C52007EC039 /* MWMNavigationViewProtocol.h */, - F6BD33821B6240F200F2CE18 /* MWMNavigationView.h */, - F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */, - 34D783CD1B5F9D7800E0C0EE /* RoutePreview */, 34E776251F14FE77003040B3 /* NavigationStreetNameView.swift */, 34E776291F150AFD003040B3 /* NavigationTurnsView.swift */, + 3407087A1F2B6F5200029ECC /* NavigationControlView.swift */, + 3407087E1F2B6F7000029ECC /* NavigationControlView.xib */, ); path = Views; sourceTree = ""; }; - 34D783CD1B5F9D7800E0C0EE /* RoutePreview */ = { - isa = PBXGroup; - children = ( - F6BB6CBD1BB15A5E00DF1DF2 /* MWMRoutePreview.xib */, - F6172FA41BBD5A3E0081D325 /* MWMiPadRoutePreview.xib */, - F6BD337D1B62403B00F2CE18 /* MWMRoutePreview.h */, - F6BD337E1B62403B00F2CE18 /* MWMRoutePreview.mm */, - F6F778781DABC6D800B603E7 /* MWMTaxiCollectionLayout.h */, - F6F778791DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm */, - F68FCB891DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib */, - 3451F4F01F02935300A981F2 /* RoutePreviewTaxiCell.swift */, - ); - path = RoutePreview; - sourceTree = ""; - }; 34E7760D1F14B165003040B3 /* AvailableArea */ = { isa = PBXGroup; children = ( @@ -3459,6 +3533,8 @@ 3444DFCB1F1760B900E73099 /* WidgetsArea.swift */, 3444DFDC1F18A5AF00E73099 /* SideButtonsArea.swift */, 34FE5A6D1F18F30F00BCA729 /* TrafficButtonArea.swift */, + 347BFA8E1F27909200E5531F /* MenuArea.swift */, + 340708631F2905A500029ECC /* NavigationInfoArea.swift */, ); path = AvailableArea; sourceTree = ""; @@ -3548,15 +3624,6 @@ path = Widgets; sourceTree = ""; }; - 560634EF1B787EBE00F3D670 /* Sound */ = { - isa = PBXGroup; - children = ( - 560634F01B78804C00F3D670 /* MWMTextToSpeech.h */, - 560634F11B78806100F3D670 /* MWMTextToSpeech.mm */, - ); - path = Sound; - sourceTree = ""; - }; 97B4E9271851DAB300BEC5D7 /* Custom Views */ = { isa = PBXGroup; children = ( @@ -3938,6 +4005,7 @@ F6E2FC5C1E097B9F0083EBEC /* MWMObjectsCategorySelectorController.mm */, F6E2FC5D1E097B9F0083EBEC /* OpeningHours */, F6E2FC821E097B9F0083EBEC /* Street */, + 34763F0B1F30CCAC00F4D2D3 /* MWMEditorCellType.h */, ); path = Editor; sourceTree = ""; @@ -4036,7 +4104,6 @@ F6E2FC8F1E097B9F0083EBEC /* PlacePage */ = { isa = PBXGroup; children = ( - F6E2FC901E097B9F0083EBEC /* Deprecated */, F6E2FC931E097B9F0083EBEC /* DirectionView */, F6E2FC971E097B9F0083EBEC /* MWMPlacePageData.h */, F6E2FC981E097B9F0083EBEC /* MWMPlacePageData.mm */, @@ -4051,15 +4118,6 @@ path = PlacePage; sourceTree = ""; }; - F6E2FC901E097B9F0083EBEC /* Deprecated */ = { - isa = PBXGroup; - children = ( - F6E2FC911E097B9F0083EBEC /* MWMPlacePageEntity.h */, - F6E2FC921E097B9F0083EBEC /* MWMPlacePageEntity.mm */, - ); - path = Deprecated; - sourceTree = ""; - }; F6E2FC931E097B9F0083EBEC /* DirectionView */ = { isa = PBXGroup; children = ( @@ -4236,6 +4294,7 @@ 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */, 349D1ABA1E2D05EF004A2006 /* SearchBar.swift */, 34B3806B1F1E46E20087D65B /* MWMSearchManagerState.h */, + 347AD8081F28B4E6007ACB68 /* MWMSearchManagerObserver.h */, ); path = Search; sourceTree = ""; @@ -4729,6 +4788,7 @@ 34AC8FCF1EFC028600E7F910 /* MWMNavigationInfoView.xib in Resources */, F652B2EA1C6DE8E500D20C8C /* MWMDropDown.xib in Resources */, 34D3B0231E389D05004100F9 /* MWMEditorAddAdditionalNameTableViewCell.xib in Resources */, + 34763EED1F2F5F2E00F4D2D3 /* MWMiPhoneRoutePreview.xib in Resources */, 34D3B0261E389D05004100F9 /* EditorAdditionalNamePlaceholderTableViewCell.xib in Resources */, F6E2FDB81E097BA00083EBEC /* MWMEditorAdditionalNamesHeader.xib in Resources */, 34D3B02C1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.xib in Resources */, @@ -4742,7 +4802,6 @@ F6664C151E645A4100E703C2 /* MWMPPReviewCell.xib in Resources */, F6BC1E541ACBF9AB00EF0360 /* MWMFacebookAlert.xib in Resources */, F643247E1EF82B21009296F9 /* UGCSelectImpressionCell.xib in Resources */, - F6172FA51BBD5A3E0081D325 /* MWMiPadRoutePreview.xib in Resources */, F6BBF2C81B4FFB8C000CF8E2 /* MWMLocationAlert.xib in Resources */, 3406FA181C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib in Resources */, F6E2FD521E097BA00083EBEC /* MWMMapDownloaderAdsTableViewCell.xib in Resources */, @@ -4757,6 +4816,7 @@ 34D3B04A1E389D05004100F9 /* MWMNoteCell.xib in Resources */, F6E2FDEE1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.xib in Resources */, F6E2FDF41E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.xib in Resources */, + 3407084C1F28EDD100029ECC /* MWMiPadRoutePreview.xib in Resources */, F6E2FDFA1E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.xib in Resources */, F6E2FE751E097BA00083EBEC /* MWMOpeningHoursCell.xib in Resources */, F6E2FE001E097BA00083EBEC /* MWMOpeningHoursClosedSpanTableViewCell.xib in Resources */, @@ -4776,7 +4836,6 @@ F6E2FEA51E097BA00083EBEC /* MWMPPView.xib in Resources */, F69CE8D91E5C5088002B5881 /* PPHotelCarouselCell.xib in Resources */, F61579361AC2CEB60032D8E9 /* MWMRateAlert.xib in Resources */, - F6BB6CBE1BB15A5E00DF1DF2 /* MWMRoutePreview.xib in Resources */, F63774E71B59375E00BCF54D /* MWMRoutingDisclaimerAlert.xib in Resources */, F6E2FEFF1E097BA00083EBEC /* MWMSearchCategoryCell.xib in Resources */, F69CE8DD1E5C51AB002B5881 /* CarouselElement.xib in Resources */, @@ -4799,13 +4858,13 @@ 3490D2E21CE9DD2500D0B838 /* MWMSideButtonsView.xib in Resources */, 346DB82A1E5C4F6700E3123E /* GalleryCell.xib in Resources */, F6E2FE2D1E097BA00083EBEC /* MWMStreetEditorEditTableViewCell.xib in Resources */, - F68FCB8C1DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib in Resources */, 349B92701DF0526D007779DD /* MWMToast.xib in Resources */, 3463BA681DE81DB90082417F /* MWMTrafficButtonViewController.xib in Resources */, F623DA6B1C9C2731006A3436 /* opening_hours_how_to_edit.html in Resources */, FA85F633145DDDC20090E1A0 /* packed_polygons.bin in Resources */, 671182E21C7F0DD400CB8177 /* packed_polygons_obsolete.bin in Resources */, 4519503A1B7A3E070085DA05 /* patterns.txt in Resources */, + 34763EFA1F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib in Resources */, 4A23D15C1B8B4DD700D4EB6F /* resources-6plus_clear in Resources */, 4A7D89C51B2EBF3B00AC843E /* resources-6plus_dark in Resources */, A367C93B1B17334800E2B6E7 /* resources-default in Resources */, @@ -4817,6 +4876,7 @@ 4A23D15E1B8B4DD700D4EB6F /* resources-xhdpi_clear in Resources */, 4A7D89C71B2EBF3B00AC843E /* resources-xhdpi_dark in Resources */, 4A23D15F1B8B4DD700D4EB6F /* resources-xxhdpi_clear in Resources */, + 3407086D1F2B427400029ECC /* RoutePreviewTaxiCell.xib in Resources */, 4A7D89C81B2EBF3B00AC843E /* resources-xxhdpi_dark in Resources */, 340E1EF41E2F614400CE49BF /* SearchFilters.storyboard in Resources */, 347E1A991F1F7404002BF7A8 /* CianElement.xib in Resources */, @@ -4832,6 +4892,7 @@ EE583CBB12F773F00042CBE3 /* unicode_blocks.txt in Resources */, 340E1EFD1E2F614400CE49BF /* Welcome.storyboard in Resources */, FAFF422A1347F101009BBB14 /* World.mwm in Resources */, + 3407087F1F2B6F7000029ECC /* NavigationControlView.xib in Resources */, FA459EB414327AF700B5BB3C /* WorldCoasts.mwm in Resources */, 671182E31C7F0DD400CB8177 /* WorldCoasts_obsolete.mwm in Resources */, 346DB8361E5C4F6700E3123E /* GalleryViewController.xib in Resources */, @@ -4909,6 +4970,7 @@ 34AC8FD51EFC02D100E7F910 /* MWMNavigationInfoView.xib in Resources */, 34D3B0241E389D05004100F9 /* MWMEditorAddAdditionalNameTableViewCell.xib in Resources */, 34D3B0271E389D05004100F9 /* EditorAdditionalNamePlaceholderTableViewCell.xib in Resources */, + 34763EEE1F2F5F2F00F4D2D3 /* MWMiPhoneRoutePreview.xib in Resources */, F6E2FDB91E097BA00083EBEC /* MWMEditorAdditionalNamesHeader.xib in Resources */, 34D3B02D1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.xib in Resources */, 34D3B0331E389D05004100F9 /* MWMEditorCategoryCell.xib in Resources */, @@ -4919,7 +4981,6 @@ F64D9CA31C899C760063FA30 /* MWMEditorViralAlert.xib in Resources */, 346DB8311E5C4F6700E3123E /* GalleryItemViewController.xib in Resources */, 6741A9911BF340DE002C974C /* MWMFacebookAlert.xib in Resources */, - 6741A9701BF340DE002C974C /* MWMiPadRoutePreview.xib in Resources */, 6741A96D1BF340DE002C974C /* MWMLocationAlert.xib in Resources */, F643247F1EF82B21009296F9 /* UGCSelectImpressionCell.xib in Resources */, 3406FA191C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib in Resources */, @@ -4937,6 +4998,7 @@ F6E2FDF51E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.xib in Resources */, F6E2FDFB1E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.xib in Resources */, 342639361EA0E60A0025EB89 /* local_ads_symbols.txt in Resources */, + 340708521F28F1DD00029ECC /* MWMiPadRoutePreview.xib in Resources */, 4554B6EC1E55F0EF0084017F /* drules_proto_vehicle_clear.bin in Resources */, F6E2FE761E097BA00083EBEC /* MWMOpeningHoursCell.xib in Resources */, F6E2FE011E097BA00083EBEC /* MWMOpeningHoursClosedSpanTableViewCell.xib in Resources */, @@ -4955,7 +5017,6 @@ F6E2FE941E097BA00083EBEC /* PlacePageTaxiCell.xib in Resources */, F6E2FEA61E097BA00083EBEC /* MWMPPView.xib in Resources */, 6741A9811BF340DE002C974C /* MWMRateAlert.xib in Resources */, - 6741A96E1BF340DE002C974C /* MWMRoutePreview.xib in Resources */, 6741A9601BF340DE002C974C /* MWMRoutingDisclaimerAlert.xib in Resources */, F6E2FF001E097BA00083EBEC /* MWMSearchCategoryCell.xib in Resources */, F6E2FF331E097BA00083EBEC /* MWMSearchCommonCell.xib in Resources */, @@ -4977,7 +5038,6 @@ 347E1A921F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */, 346DB82B1E5C4F6700E3123E /* GalleryCell.xib in Resources */, F6E2FE2E1E097BA00083EBEC /* MWMStreetEditorEditTableViewCell.xib in Resources */, - F68FCB8D1DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib in Resources */, 349B92711DF0526D007779DD /* MWMToast.xib in Resources */, 3463BA691DE81DB90082417F /* MWMTrafficButtonViewController.xib in Resources */, F623DA6C1C9C2731006A3436 /* opening_hours_how_to_edit.html in Resources */, @@ -4986,6 +5046,7 @@ 676507601C10559800830BB3 /* patterns.txt in Resources */, 6741A94A1BF340DE002C974C /* resources-6plus_clear in Resources */, 6741A9741BF340DE002C974C /* resources-6plus_dark in Resources */, + 34763EFB1F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib in Resources */, 677A2DE21C0DD50900635A00 /* resources-default in Resources */, F607C1881C032A8800B53A87 /* resources-hdpi_clear in Resources */, F607C18A1C032A8800B53A87 /* resources-hdpi_dark in Resources */, @@ -4997,6 +5058,7 @@ 6741A9981BF340DE002C974C /* resources-xhdpi_clear in Resources */, 6741A9611BF340DE002C974C /* resources-xhdpi_dark in Resources */, 6741A94D1BF340DE002C974C /* resources-xxhdpi_clear in Resources */, + 3407086E1F2B427400029ECC /* RoutePreviewTaxiCell.xib in Resources */, 6741A9551BF340DE002C974C /* resources-xxhdpi_dark in Resources */, 340E1EF51E2F614400CE49BF /* SearchFilters.storyboard in Resources */, 347E1A9A1F1F7404002BF7A8 /* CianElement.xib in Resources */, @@ -5012,6 +5074,7 @@ 6741A94B1BF340DE002C974C /* unicode_blocks.txt in Resources */, 340E1EFE1E2F614400CE49BF /* Welcome.storyboard in Resources */, 6741A9521BF340DE002C974C /* World.mwm in Resources */, + 340708801F2B6F7000029ECC /* NavigationControlView.xib in Resources */, 6741A9751BF340DE002C974C /* WorldCoasts.mwm in Resources */, 671182E41C7F0DD800CB8177 /* WorldCoasts_obsolete.mwm in Resources */, 346DB8371E5C4F6700E3123E /* GalleryViewController.xib in Resources */, @@ -5089,6 +5152,7 @@ 34AC8FD61EFC02D100E7F910 /* MWMNavigationInfoView.xib in Resources */, 34D3B0251E389D05004100F9 /* MWMEditorAddAdditionalNameTableViewCell.xib in Resources */, 34D3B0281E389D05004100F9 /* EditorAdditionalNamePlaceholderTableViewCell.xib in Resources */, + 34763EEF1F2F5F2F00F4D2D3 /* MWMiPhoneRoutePreview.xib in Resources */, F6E2FDBA1E097BA00083EBEC /* MWMEditorAdditionalNamesHeader.xib in Resources */, 34D3B02E1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.xib in Resources */, 34D3B0341E389D05004100F9 /* MWMEditorCategoryCell.xib in Resources */, @@ -5100,7 +5164,6 @@ 346DB8321E5C4F6700E3123E /* GalleryItemViewController.xib in Resources */, F6664C171E645A4100E703C2 /* MWMPPReviewCell.xib in Resources */, 849CF66F1DE842290024A8A5 /* MWMFacebookAlert.xib in Resources */, - 849CF6381DE842290024A8A5 /* MWMiPadRoutePreview.xib in Resources */, F64324801EF82B21009296F9 /* UGCSelectImpressionCell.xib in Resources */, 849CF6301DE842290024A8A5 /* MWMLocationAlert.xib in Resources */, 849CF60D1DE842290024A8A5 /* MWMMapDownloadDialog.xib in Resources */, @@ -5117,6 +5180,7 @@ F6E2FDF61E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.xib in Resources */, F6E2FDFC1E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.xib in Resources */, 342639381EA0E60B0025EB89 /* local_ads_symbols.txt in Resources */, + 340708531F28F1DE00029ECC /* MWMiPadRoutePreview.xib in Resources */, F6E2FE771E097BA00083EBEC /* MWMOpeningHoursCell.xib in Resources */, 4554B6ED1E55F0F00084017F /* drules_proto_vehicle_clear.bin in Resources */, F6E2FE021E097BA00083EBEC /* MWMOpeningHoursClosedSpanTableViewCell.xib in Resources */, @@ -5135,7 +5199,6 @@ F6E2FE951E097BA00083EBEC /* PlacePageTaxiCell.xib in Resources */, F6E2FEA71E097BA00083EBEC /* MWMPPView.xib in Resources */, 849CF6511DE842290024A8A5 /* MWMRateAlert.xib in Resources */, - 849CF6311DE842290024A8A5 /* MWMRoutePreview.xib in Resources */, F68224A01E5B105900BC1C18 /* PPHotelDescriptionCell.xib in Resources */, 849CF6191DE842290024A8A5 /* MWMRoutingDisclaimerAlert.xib in Resources */, F6E2FF011E097BA00083EBEC /* MWMSearchCategoryCell.xib in Resources */, @@ -5159,13 +5222,13 @@ 849CF6471DE842290024A8A5 /* MWMSideButtonsView.xib in Resources */, 346DB82C1E5C4F6700E3123E /* GalleryCell.xib in Resources */, F6E2FE2F1E097BA00083EBEC /* MWMStreetEditorEditTableViewCell.xib in Resources */, - 849CF5FA1DE842290024A8A5 /* RoutePreviewTaxiCell.xib in Resources */, 349B92721DF0526D007779DD /* MWMToast.xib in Resources */, 8408BCE21E080DEF00789784 /* MWMTrafficButtonViewController.xib in Resources */, 849CF6611DE842290024A8A5 /* opening_hours_how_to_edit.html in Resources */, 849CF6411DE842290024A8A5 /* packed_polygons.bin in Resources */, 849CF5F51DE842290024A8A5 /* packed_polygons_obsolete.bin in Resources */, 849CF5E61DE842290024A8A5 /* patterns.txt in Resources */, + 34763EFC1F2F74B200F4D2D3 /* NavigationRoutePreviewStatusView.xib in Resources */, 849CF5F61DE842290024A8A5 /* resources-6plus_clear in Resources */, 849CF63F1DE842290024A8A5 /* resources-6plus_dark in Resources */, 849CF6141DE842290024A8A5 /* resources-default in Resources */, @@ -5177,6 +5240,7 @@ F69CE8DB1E5C5088002B5881 /* PPHotelCarouselCell.xib in Resources */, 849CF67A1DE842290024A8A5 /* resources-xhdpi_clear in Resources */, 849CF61A1DE842290024A8A5 /* resources-xhdpi_dark in Resources */, + 3407086F1F2B427400029ECC /* RoutePreviewTaxiCell.xib in Resources */, 849CF5FC1DE842290024A8A5 /* resources-xxhdpi_clear in Resources */, 849CF6061DE842290024A8A5 /* resources-xxhdpi_dark in Resources */, 347E1A9B1F1F7404002BF7A8 /* CianElement.xib in Resources */, @@ -5192,6 +5256,7 @@ 849CF5F81DE842290024A8A5 /* unicode_blocks.txt in Resources */, 340E1EFF1E2F614400CE49BF /* Welcome.storyboard in Resources */, 849CF6021DE842290024A8A5 /* World.mwm in Resources */, + 340708811F2B6F7000029ECC /* NavigationControlView.xib in Resources */, 849CF6401DE842290024A8A5 /* WorldCoasts.mwm in Resources */, 849CF63D1DE842290024A8A5 /* WorldCoasts_obsolete.mwm in Resources */, 346DB8381E5C4F6700E3123E /* GalleryViewController.xib in Resources */, @@ -5344,8 +5409,10 @@ 34D3AFF51E37A36A004100F9 /* UICollectionView+Cells.swift in Sources */, F6E2FEC01E097BA00083EBEC /* MWMConsole.mm in Sources */, 3490D2DE1CE9DD2500D0B838 /* MWMSideButtons.mm in Sources */, + 340708771F2B5D6C00029ECC /* DimBackground.swift in Sources */, F6E2FDF71E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.mm in Sources */, 1D3623260D0F684500981E51 /* MapsAppDelegate.mm in Sources */, + 34763EF21F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm in Sources */, F6E2FE181E097BA00083EBEC /* MWMOpeningHoursTimeSpanTableViewCell.mm in Sources */, F6E2FDEB1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.mm in Sources */, F6150E511EFA7352000B955D /* MWUGCCommentsController.mm in Sources */, @@ -5371,6 +5438,7 @@ F6E2FF081E097BA00083EBEC /* MWMSearchHistoryManager.mm in Sources */, F63AF50A1EA6213F00A1DB98 /* FilterRatingCell.swift in Sources */, F6E2FD8E1E097BA00083EBEC /* MWMNoMapsViewController.mm in Sources */, + 340708641F2905A500029ECC /* NavigationInfoArea.swift in Sources */, 34D3B0411E389D05004100F9 /* MWMEditorTextTableViewCell.mm in Sources */, 3404163B1E7BDFE000E2B6D6 /* PhotosViewController.swift in Sources */, F6E2FE601E097BA00083EBEC /* MWMBookmarkCell.mm in Sources */, @@ -5392,6 +5460,7 @@ F6588E2C1B15C26700EE1E58 /* MWMTextView.mm in Sources */, 3454D7E51E07F045004AF2AD /* UIView+RuntimeAttributes.mm in Sources */, 34FE4C451BCC013500066718 /* MWMMapWidgets.mm in Sources */, + 34763F061F3092E700F4D2D3 /* String+Format.swift in Sources */, F6E2FE4B1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */, 346DB8391E5C4F6700E3123E /* GalleryItemModel.swift in Sources */, 3404757D1E081B3300C92850 /* iosOGLContext.mm in Sources */, @@ -5401,6 +5470,7 @@ F6E2FD5B1E097BA00083EBEC /* MWMMapDownloaderCellHeader.mm in Sources */, 340475611E081A4600C92850 /* MWMNetworkPolicy.mm in Sources */, 342EE4111C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm in Sources */, + 3407084F1F28EDD100029ECC /* RoutePreviewTaxiCell.swift in Sources */, F6E2FEE41E097BA00083EBEC /* MWMSearchNoResults.mm in Sources */, F6E2FF621E097BA00083EBEC /* MWMTTSLanguageViewController.mm in Sources */, F64D9C9F1C899C350063FA30 /* MWMEditorViralAlert.mm in Sources */, @@ -5417,6 +5487,7 @@ F64F19991AB81A00006EAF7E /* MWMAlertViewController.mm in Sources */, F6E2FE541E097BA00083EBEC /* MWMPlacePageActionBar.mm in Sources */, 34C9BD091C6DBCDA000DC38D /* MWMNavigationController.mm in Sources */, + 340708431F28ED2D00029ECC /* MWMRoutePreview.mm in Sources */, 34D3B0171E389D05004100F9 /* EditorAdditionalNamePlaceholderTableViewCell.swift in Sources */, 346DB8271E5C4F6700E3123E /* GalleryCell.swift in Sources */, 3406FA151C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm in Sources */, @@ -5437,12 +5508,10 @@ F6E2FF441E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */, F607C18E1C047FDC00B53A87 /* MWMSegue.mm in Sources */, F6E2FE301E097BA00083EBEC /* MWMStreetEditorViewController.mm in Sources */, - F6E2FE3F1E097BA00083EBEC /* MWMPlacePageEntity.mm in Sources */, 340416471E7BF28E00E2B6D6 /* UIView+Snapshot.swift in Sources */, F6E2FE271E097BA00083EBEC /* MWMOpeningHoursSection.mm in Sources */, 34F407341E9E1AFF00E57AC0 /* CoreBanner.swift in Sources */, F6E2FE241E097BA00083EBEC /* MWMOpeningHoursModel.mm in Sources */, - F6BD33811B62403B00F2CE18 /* MWMRoutePreview.mm in Sources */, 34D3B0351E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, F6E2FD8B1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, F6E2FD701E097BA00083EBEC /* MWMMapDownloaderTableViewCell.mm in Sources */, @@ -5453,8 +5522,10 @@ 340475521E081A4600C92850 /* MWMCustomFacebookEvents.mm in Sources */, F6E2FD761E097BA00083EBEC /* MWMMapDownloaderDataSource.mm in Sources */, F64F4B741B4A45FD0081A24A /* MWMDownloaderDialogHeader.mm in Sources */, + 34763F021F30749000F4D2D3 /* RoutePreviewStatus.swift in Sources */, 349D1AD71E2E325C004A2006 /* MWMBottomMenuLayout.mm in Sources */, 3462258E1DDC5DBA001E8752 /* MWMSearchNoResultsAlert.mm in Sources */, + 347BFA8F1F27909200E5531F /* MenuArea.swift in Sources */, F6E2FEBD1E097BA00083EBEC /* MWMPPPreviewLayoutHelper.mm in Sources */, 343E75971E5B1EE20041226A /* MWMCollectionViewController.mm in Sources */, 3454D7DF1E07F045004AF2AD /* UITextField+RuntimeAttributes.mm in Sources */, @@ -5504,14 +5575,15 @@ F6381BF51CD12045004CA943 /* LocaleTranslator.mm in Sources */, 346DB82D1E5C4F6700E3123E /* GalleryItemViewController.swift in Sources */, 34E7761E1F14DB48003040B3 /* PlacePageArea.swift in Sources */, + 34763EFE1F3069BB00F4D2D3 /* RouteStartButton.swift in Sources */, 340475551E081A4600C92850 /* Statistics.mm in Sources */, - F68FCB851DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm in Sources */, F653CE161C71F60200A453F1 /* MWMAddPlaceNavigationBar.mm in Sources */, 3444DFCC1F1760B900E73099 /* WidgetsArea.swift in Sources */, F6E2FE991E097BA00083EBEC /* MWMiPadPlacePageLayoutImpl.mm in Sources */, 34D3B03B1E389D05004100F9 /* MWMEditorSwitchTableViewCell.mm in Sources */, 3454D7CD1E07F045004AF2AD /* UIFont+MapsMeFonts.mm in Sources */, 3454D7DC1E07F045004AF2AD /* UISwitch+RuntimeAttributes.m in Sources */, + 340708501F28EDD100029ECC /* MWMTaxiCollectionLayout.mm in Sources */, F682249A1E5B104600BC1C18 /* PPHotelDescriptionCell.swift in Sources */, F6E2FEC91E097BA00083EBEC /* MWMSearchFilterTransitioning.mm in Sources */, FA054612155C465E001F4E37 /* SelectSetVC.mm in Sources */, @@ -5540,12 +5612,14 @@ F6E2FF4D1E097BA00083EBEC /* MWMAboutController.mm in Sources */, 34F5E0D31E3F254800B1C415 /* UIView+Hierarchy.swift in Sources */, 34F407371E9E1AFF00E57AC0 /* FacebookBanner.swift in Sources */, + 340708601F28FE2800029ECC /* MWMiPadRoutePreview.mm in Sources */, F6150E291EF95234000B955D /* MWMUGCReviewController.mm in Sources */, 3497A93A1B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm in Sources */, F6E2FED81E097BA00083EBEC /* MWMSearchContentView.mm in Sources */, F6E2FD881E097BA00083EBEC /* MWMMapDownloaderViewController.mm in Sources */, 34BC72241B0DECAE0012A34B /* MWMMapViewControlsManager.mm in Sources */, F6E2FF4A1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, + 3407087B1F2B6F5200029ECC /* NavigationControlView.swift in Sources */, 3470402F1EA6470700038379 /* BorderedButton.swift in Sources */, F6E2FE781E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */, F6BD1D201CA412920047B8E8 /* MWMOsmAuthAlert.mm in Sources */, @@ -5559,6 +5633,7 @@ F6E2FE9F1E097BA00083EBEC /* MWMPlacePageLayout.mm in Sources */, F6E2FEC31E097BA00083EBEC /* MWMSearchFilterPresentationController.mm in Sources */, 340475731E081A4600C92850 /* MWMStorage.mm in Sources */, + 34763EE61F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */, 340416531E7C09C200E2B6D6 /* PhotoScalingView.swift in Sources */, F6E2FD851E097BA00083EBEC /* MWMBaseMapDownloaderViewController.mm in Sources */, 34ABA6241C2D551900FE1BEC /* MWMInputValidatorFactory.mm in Sources */, @@ -5569,7 +5644,6 @@ 3404164B1E7BF42E00E2B6D6 /* UIView+Coordinates.swift in Sources */, 349D1ADA1E2E325C004A2006 /* MWMBottomMenuView.mm in Sources */, F6E2FD911E097BA00083EBEC /* MWMBookmarkColorViewController.mm in Sources */, - F6F7787A1DABC6D800B603E7 /* MWMTaxiCollectionLayout.mm in Sources */, F643247A1EF82AD9009296F9 /* UGCSelectImpressionCell.swift in Sources */, F63AF5051EA6162400A1DB98 /* FilterTypeCell.swift in Sources */, F6E2FDA31E097BA00083EBEC /* MWMCuisineEditorViewController.mm in Sources */, @@ -5595,12 +5669,10 @@ 346B42AB1DD5E3D20094EBEE /* MWMLocationNotFoundAlert.mm in Sources */, F6E2FF021E097BA00083EBEC /* MWMSearchHistoryClearCell.mm in Sources */, F63774EA1B59376F00BCF54D /* MWMRoutingDisclaimerAlert.mm in Sources */, - 3451F4F11F02935300A981F2 /* RoutePreviewTaxiCell.swift in Sources */, 340475081E08199E00C92850 /* MWMMyTarget.mm in Sources */, 3404164F1E7C085F00E2B6D6 /* PhotoViewController.swift in Sources */, F64F19A31AB81A00006EAF7E /* MWMDownloadTransitMapAlert.mm in Sources */, 3404754C1E081A4600C92850 /* MWMKeyboard.mm in Sources */, - F6BD33841B6240F200F2CE18 /* MWMNavigationView.mm in Sources */, F6E2FE721E097BA00083EBEC /* MWMOpeningHours.mm in Sources */, 34AB39C11D2BD8310021857D /* MWMStopButton.mm in Sources */, F69CE8D51E5C49B4002B5881 /* PPHotelCarouselCell.swift in Sources */, @@ -5619,6 +5691,7 @@ ED48BBB517C267F5003E7E92 /* ColorPickerView.mm in Sources */, F6E2FF561E097BA00083EBEC /* MWMMobileInternetViewController.mm in Sources */, 340416431E7BED3900E2B6D6 /* PhotosTransitionAnimator.swift in Sources */, + 3407084E1F28EDD100029ECC /* MWMTaxiPreviewDataSource.mm in Sources */, ED48BBBA17C2B1E2003E7E92 /* CircleView.mm in Sources */, F6E2FEEA1E097BA00083EBEC /* MWMSearchTextField.mm in Sources */, F6664C121E645A4100E703C2 /* MWMPPReviewCell.mm in Sources */, @@ -5629,6 +5702,7 @@ F6E2FD9D1E097BA00083EBEC /* MWMEditBookmarkController.mm in Sources */, F6E2FE091E097BA00083EBEC /* MWMOpeningHoursDeleteScheduleTableViewCell.mm in Sources */, 3454D7E21E07F045004AF2AD /* UITextView+RuntimeAttributes.mm in Sources */, + 340708841F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm in Sources */, 34D15BA81BD8F93C00C8BCBE /* AddSetTableViewCell.mm in Sources */, F6E2FED51E097BA00083EBEC /* MWMSearchChangeModeView.mm in Sources */, F6A218491CA3F26800BE2CC6 /* MWMEditorViralActivityItem.mm in Sources */, @@ -5643,9 +5717,9 @@ 34845DB71E166084003D55B9 /* Common.swift in Sources */, 6741A9A31BF340DE002C974C /* main.mm in Sources */, 34D3B04F1E38A20C004100F9 /* Bundle+Init.swift in Sources */, - F67E751E1DB76DFC00D6741F /* MWMTaxiCollectionLayout.mm in Sources */, F6E2FF541E097BA00083EBEC /* MWMHelpController.mm in Sources */, F6E2FF5A1E097BA00083EBEC /* MWMNightModeController.mm in Sources */, + 340708581F28F1F000029ECC /* MWMTaxiCollectionLayout.mm in Sources */, 6741A9A51BF340DE002C974C /* MWMShareActivityItem.mm in Sources */, F6E2FE1F1E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */, 3454D7B91E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */, @@ -5661,8 +5735,10 @@ 34D3AFF61E37A36A004100F9 /* UICollectionView+Cells.swift in Sources */, 6741A9A91BF340DE002C974C /* MWMDefaultAlert.mm in Sources */, F6E2FEC11E097BA00083EBEC /* MWMConsole.mm in Sources */, + 340708781F2B5D6C00029ECC /* DimBackground.swift in Sources */, 3490D2DF1CE9DD2500D0B838 /* MWMSideButtons.mm in Sources */, F6E2FDF81E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.mm in Sources */, + 34763EF31F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm in Sources */, F6E2FE191E097BA00083EBEC /* MWMOpeningHoursTimeSpanTableViewCell.mm in Sources */, F6E2FDEC1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.mm in Sources */, F6150E521EFA7352000B955D /* MWUGCCommentsController.mm in Sources */, @@ -5677,7 +5753,6 @@ F6E2FE491E097BA00083EBEC /* MWMPlacePageData.mm in Sources */, 340475501E081A4600C92850 /* fabric_logging_ios.mm in Sources */, 34F4073E1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */, - 6741A9B61BF340DE002C974C /* MWMTextToSpeech.mm in Sources */, F6E2FED01E097BA00083EBEC /* MWMSearchFilterViewController.mm in Sources */, 347E1A971F1F7404002BF7A8 /* CianElement.swift in Sources */, 34D4FA671E265749003F53EF /* WhatsNewController.swift in Sources */, @@ -5688,6 +5763,7 @@ F6E2FD8F1E097BA00083EBEC /* MWMNoMapsViewController.mm in Sources */, F63AF50B1EA6213F00A1DB98 /* FilterRatingCell.swift in Sources */, 34D3B0421E389D05004100F9 /* MWMEditorTextTableViewCell.mm in Sources */, + 340708651F2905A500029ECC /* NavigationInfoArea.swift in Sources */, 3404163C1E7BDFE000E2B6D6 /* PhotosViewController.swift in Sources */, F6E2FE611E097BA00083EBEC /* MWMBookmarkCell.mm in Sources */, F6E2FEA31E097BA00083EBEC /* MWMPPView.mm in Sources */, @@ -5709,6 +5785,7 @@ 3454D7E61E07F045004AF2AD /* UIView+RuntimeAttributes.mm in Sources */, F6E2FE4C1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */, 3404757E1E081B3300C92850 /* iosOGLContext.mm in Sources */, + 34763F071F3092E700F4D2D3 /* String+Format.swift in Sources */, 346DB83A1E5C4F6700E3123E /* GalleryItemModel.swift in Sources */, F6E2FD5C1E097BA00083EBEC /* MWMMapDownloaderCellHeader.mm in Sources */, 34D3AFF21E37945B004100F9 /* UITableView+Cells.swift in Sources */, @@ -5751,7 +5828,6 @@ F6E2FF451E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */, 34C9BD0A1C6DBCDA000DC38D /* MWMNavigationController.mm in Sources */, F6E2FE311E097BA00083EBEC /* MWMStreetEditorViewController.mm in Sources */, - F6E2FE401E097BA00083EBEC /* MWMPlacePageEntity.mm in Sources */, F6E2FE281E097BA00083EBEC /* MWMOpeningHoursSection.mm in Sources */, 3406FA161C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm in Sources */, 340416481E7BF28E00E2B6D6 /* UIView+Snapshot.swift in Sources */, @@ -5760,7 +5836,6 @@ 34C9BD031C6DB693000DC38D /* MWMTableViewController.mm in Sources */, F6E2FD8C1E097BA00083EBEC /* MWMNoMapsView.mm in Sources */, 34D3B0361E389D05004100F9 /* MWMEditorSelectTableViewCell.mm in Sources */, - 6741A9DB1BF340DE002C974C /* MWMRoutePreview.mm in Sources */, F6E2FD711E097BA00083EBEC /* MWMMapDownloaderTableViewCell.mm in Sources */, F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.mm in Sources */, 340475531E081A4600C92850 /* MWMCustomFacebookEvents.mm in Sources */, @@ -5772,7 +5847,9 @@ 6741A9E01BF340DE002C974C /* MWMDownloaderDialogHeader.mm in Sources */, 349D1AD81E2E325C004A2006 /* MWMBottomMenuLayout.mm in Sources */, F6E2FEBE1E097BA00083EBEC /* MWMPPPreviewLayoutHelper.mm in Sources */, + 34763F031F30749000F4D2D3 /* RoutePreviewStatus.swift in Sources */, 3454D7E01E07F045004AF2AD /* UITextField+RuntimeAttributes.mm in Sources */, + 347BFA901F27909200E5531F /* MenuArea.swift in Sources */, 343E75981E5B1EE20041226A /* MWMCollectionViewController.mm in Sources */, F6E2FEFA1E097BA00083EBEC /* MWMSearchCategoriesManager.mm in Sources */, 34E776141F14B17F003040B3 /* AvailableArea.swift in Sources */, @@ -5794,6 +5871,7 @@ 3444DFD21F17620C00E73099 /* MWMMapWidgetsHelper.mm in Sources */, F6E2FE3D1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */, F6150E481EFA5C94000B955D /* UGCTextReviewCell.swift in Sources */, + 340708561F28F1E900029ECC /* MWMRoutePreview.mm in Sources */, F6E2FD501E097BA00083EBEC /* MWMMapDownloaderAdsTableViewCell.mm in Sources */, F6E2FE881E097BA00083EBEC /* MWMPlacePageRegularCell.mm in Sources */, F6E2FD801E097BA00083EBEC /* MWMMapDownloaderExtendedDataSourceWithAds.mm in Sources */, @@ -5809,6 +5887,7 @@ F660DEE51EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */, F6E2FDF21E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.mm in Sources */, F6E2FD831E097BA00083EBEC /* MWMMapDownloaderSearchDataSource.mm in Sources */, + 3407085C1F28F27100029ECC /* RoutePreviewTaxiCell.swift in Sources */, 3490D2E11CE9DD2500D0B838 /* MWMSideButtonsView.mm in Sources */, F6664C021E6459DA00E703C2 /* PPReviewHeaderCell.swift in Sources */, F6E2FE7C1E097BA00083EBEC /* MWMPlacePageOpeningHoursCell.mm in Sources */, @@ -5821,11 +5900,11 @@ 3454D7C21E07F045004AF2AD /* NSString+Categories.mm in Sources */, 6741A9FE1BF340DE002C974C /* SelectSetVC.mm in Sources */, 34E7761F1F14DB48003040B3 /* PlacePageArea.swift in Sources */, + 34763EFF1F3069BB00F4D2D3 /* RouteStartButton.swift in Sources */, 346DB82E1E5C4F6700E3123E /* GalleryItemViewController.swift in Sources */, 340475561E081A4600C92850 /* Statistics.mm in Sources */, F6381BF61CD12045004CA943 /* LocaleTranslator.mm in Sources */, 3444DFCD1F1760B900E73099 /* WidgetsArea.swift in Sources */, - F68FCB861DA7BBA6007CC7D7 /* MWMTaxiPreviewDataSource.mm in Sources */, F6E2FE9A1E097BA00083EBEC /* MWMiPadPlacePageLayoutImpl.mm in Sources */, 34D3B03C1E389D05004100F9 /* MWMEditorSwitchTableViewCell.mm in Sources */, 6741A9FF1BF340DE002C974C /* AddSetVC.mm in Sources */, @@ -5858,12 +5937,14 @@ F6E2FF4E1E097BA00083EBEC /* MWMAboutController.mm in Sources */, 34F407381E9E1AFF00E57AC0 /* FacebookBanner.swift in Sources */, F6150E2A1EF95234000B955D /* MWMUGCReviewController.mm in Sources */, + 340708611F28FE2800029ECC /* MWMiPadRoutePreview.mm in Sources */, 34F5E0D41E3F254800B1C415 /* UIView+Hierarchy.swift in Sources */, 6741AA0B1BF340DE002C974C /* MWMMapViewControlsManager.mm in Sources */, F6E2FED91E097BA00083EBEC /* MWMSearchContentView.mm in Sources */, F6E2FD891E097BA00083EBEC /* MWMMapDownloaderViewController.mm in Sources */, F6BD1D211CA412920047B8E8 /* MWMOsmAuthAlert.mm in Sources */, 347040301EA6470700038379 /* BorderedButton.swift in Sources */, + 3407087C1F2B6F5200029ECC /* NavigationControlView.swift in Sources */, F6E2FF4B1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, F6E2FE791E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */, F6B97B271CD0CA990009B612 /* MWMBookmarkNameCell.mm in Sources */, @@ -5877,6 +5958,7 @@ F6E2FEA01E097BA00083EBEC /* MWMPlacePageLayout.mm in Sources */, F6E2FEC41E097BA00083EBEC /* MWMSearchFilterPresentationController.mm in Sources */, 340416541E7C09C200E2B6D6 /* PhotoScalingView.swift in Sources */, + 34763EE71F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */, 34ABA6251C2D551900FE1BEC /* MWMInputValidatorFactory.mm in Sources */, F6E2FD861E097BA00083EBEC /* MWMBaseMapDownloaderViewController.mm in Sources */, F6E2FEE21E097BA00083EBEC /* MWMSearchManager.mm in Sources */, @@ -5886,6 +5968,7 @@ 3404164C1E7BF42E00E2B6D6 /* UIView+Coordinates.swift in Sources */, 6741AA141BF340DE002C974C /* MWMMultilineLabel.mm in Sources */, 349D1ADB1E2E325C004A2006 /* MWMBottomMenuView.mm in Sources */, + 3407085A1F28F1F400029ECC /* MWMTaxiPreviewDataSource.mm in Sources */, F6E2FD921E097BA00083EBEC /* MWMBookmarkColorViewController.mm in Sources */, F643247B1EF82AD9009296F9 /* UGCSelectImpressionCell.swift in Sources */, F63AF5061EA6162400A1DB98 /* FilterTypeCell.swift in Sources */, @@ -5910,9 +5993,7 @@ 6741AA1D1BF340DE002C974C /* MWMDownloadTransitMapAlert.mm in Sources */, 340475771E081A4600C92850 /* MWMTrafficManager.mm in Sources */, 346B42AC1DD5E3D20094EBEE /* MWMLocationNotFoundAlert.mm in Sources */, - 6741AA221BF340DE002C974C /* MWMNavigationView.mm in Sources */, F6E2FF031E097BA00083EBEC /* MWMSearchHistoryClearCell.mm in Sources */, - 3451F4F21F02935300A981F2 /* RoutePreviewTaxiCell.swift in Sources */, 340475091E08199E00C92850 /* MWMMyTarget.mm in Sources */, 340416501E7C086000E2B6D6 /* PhotoViewController.swift in Sources */, 674A7E301C0DB10B003D48E1 /* MWMMapWidgets.mm in Sources */, @@ -5946,6 +6027,7 @@ F6E2FE0A1E097BA00083EBEC /* MWMOpeningHoursDeleteScheduleTableViewCell.mm in Sources */, 3454D7DA1E07F045004AF2AD /* UILabel+RuntimeAttributes.mm in Sources */, 3454D7E31E07F045004AF2AD /* UITextView+RuntimeAttributes.mm in Sources */, + 340708851F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm in Sources */, F6A2184A1CA3F26800BE2CC6 /* MWMEditorViralActivityItem.mm in Sources */, F6E2FED61E097BA00083EBEC /* MWMSearchChangeModeView.mm in Sources */, 6741AA2D1BF340DE002C974C /* AddSetTableViewCell.mm in Sources */, @@ -5962,6 +6044,7 @@ 34D3B0501E38A20C004100F9 /* Bundle+Init.swift in Sources */, 3454D7D51E07F045004AF2AD /* UIImageView+Coloring.mm in Sources */, F6E2FF551E097BA00083EBEC /* MWMHelpController.mm in Sources */, + 340708591F28F1F000029ECC /* MWMTaxiCollectionLayout.mm in Sources */, F6E2FF5B1E097BA00083EBEC /* MWMNightModeController.mm in Sources */, 849CF6841DE842290024A8A5 /* MWMShareActivityItem.mm in Sources */, F6E2FE201E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */, @@ -5977,8 +6060,10 @@ F63AF5101EA6215100A1DB98 /* FilterPriceCategoryCell.swift in Sources */, 34D3AFF71E37A36A004100F9 /* UICollectionView+Cells.swift in Sources */, 340475601E081A4600C92850 /* MWMLocationPredictor.mm in Sources */, + 340708791F2B5D6C00029ECC /* DimBackground.swift in Sources */, F6E2FEC21E097BA00083EBEC /* MWMConsole.mm in Sources */, 845E4B1C1DEC839800D6BED8 /* MWMTrafficButtonViewController.mm in Sources */, + 34763EF41F2F5F6400F4D2D3 /* MWMiPhoneRoutePreview.mm in Sources */, F6E2FDF91E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.mm in Sources */, F6E2FE1A1E097BA00083EBEC /* MWMOpeningHoursTimeSpanTableViewCell.mm in Sources */, F6E2FDED1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.mm in Sources */, @@ -6000,10 +6085,10 @@ 34D4FA681E265749003F53EF /* WhatsNewController.swift in Sources */, 34D3B01C1E389D05004100F9 /* MWMButtonCell.mm in Sources */, 3486B5171E27AD3B0069C126 /* Framework.cpp in Sources */, - 849CF69E1DE842290024A8A5 /* MWMTextToSpeech.mm in Sources */, F6E2FF0A1E097BA00083EBEC /* MWMSearchHistoryManager.mm in Sources */, F6E2FD901E097BA00083EBEC /* MWMNoMapsViewController.mm in Sources */, F63AF50C1EA6213F00A1DB98 /* FilterRatingCell.swift in Sources */, + 340708661F2905A500029ECC /* NavigationInfoArea.swift in Sources */, 34D3B0431E389D05004100F9 /* MWMEditorTextTableViewCell.mm in Sources */, 3404163D1E7BDFE000E2B6D6 /* PhotosViewController.swift in Sources */, F6E2FE621E097BA00083EBEC /* MWMBookmarkCell.mm in Sources */, @@ -6025,6 +6110,7 @@ F6E2FF2E1E097BA00083EBEC /* MWMSearchCell.mm in Sources */, 340475661E081A4600C92850 /* MWMRouter.mm in Sources */, 849CF6AF1DE842290024A8A5 /* MWMTextView.mm in Sources */, + 34763F081F3092E700F4D2D3 /* String+Format.swift in Sources */, 849CF6B11DE842290024A8A5 /* MWMMapWidgets.mm in Sources */, F6E2FE4D1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */, 346DB83B1E5C4F6700E3123E /* GalleryItemModel.swift in Sources */, @@ -6071,7 +6157,6 @@ F6E2FF461E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */, 3404756C1E081A4600C92850 /* MWMSearch+CoreSpotlight.mm in Sources */, F6E2FE321E097BA00083EBEC /* MWMStreetEditorViewController.mm in Sources */, - F6E2FE411E097BA00083EBEC /* MWMPlacePageEntity.mm in Sources */, 340416491E7BF28E00E2B6D6 /* UIView+Snapshot.swift in Sources */, F6E2FE291E097BA00083EBEC /* MWMOpeningHoursSection.mm in Sources */, 34F407361E9E1AFF00E57AC0 /* CoreBanner.swift in Sources */, @@ -6086,9 +6171,10 @@ 349D1CE51E3F836900A878FD /* UIViewController+Hierarchy.swift in Sources */, F692F3841EA0FAF5001E82EB /* MWMAutoupdateController.mm in Sources */, 34574A681E3B85F80061E839 /* ThemeManager.swift in Sources */, - 849CF6DC1DE842290024A8A5 /* MWMRoutePreview.mm in Sources */, F6E2FD781E097BA00083EBEC /* MWMMapDownloaderDataSource.mm in Sources */, + 34763F041F30749000F4D2D3 /* RoutePreviewStatus.swift in Sources */, 349D1AD91E2E325C004A2006 /* MWMBottomMenuLayout.mm in Sources */, + 347BFA911F27909200E5531F /* MenuArea.swift in Sources */, 849CF6DF1DE842290024A8A5 /* MWMAuthorizationCommon.mm in Sources */, F6E2FEBF1E097BA00083EBEC /* MWMPPPreviewLayoutHelper.mm in Sources */, 343E75991E5B1EE20041226A /* MWMCollectionViewController.mm in Sources */, @@ -6110,6 +6196,7 @@ 34F407421E9E1AFF00E57AC0 /* RBBanner.swift in Sources */, 3444DFD31F17620C00E73099 /* MWMMapWidgetsHelper.mm in Sources */, F6E2FE3E1E097BA00083EBEC /* MWMMigrationViewController.mm in Sources */, + 340708571F28F1EA00029ECC /* MWMRoutePreview.mm in Sources */, F6150E491EFA5C94000B955D /* UGCTextReviewCell.swift in Sources */, F6E2FD511E097BA00083EBEC /* MWMMapDownloaderAdsTableViewCell.mm in Sources */, F6E2FE891E097BA00083EBEC /* MWMPlacePageRegularCell.mm in Sources */, @@ -6125,6 +6212,7 @@ 34F4072D1E9E1AFF00E57AC0 /* Banner.swift in Sources */, F660DEE61EAF4F59004DC056 /* MWMLocationManager+SpeedAndAltitude.swift in Sources */, F6E2FDF31E097BA00083EBEC /* MWMOpeningHoursAddScheduleTableViewCell.mm in Sources */, + 3407085D1F28F27200029ECC /* RoutePreviewTaxiCell.swift in Sources */, F6E2FD841E097BA00083EBEC /* MWMMapDownloaderSearchDataSource.mm in Sources */, F6664C031E6459DA00E703C2 /* PPReviewHeaderCell.swift in Sources */, 849CF6F61DE842290024A8A5 /* MWMNavigationDashboardEntity.mm in Sources */, @@ -6137,6 +6225,7 @@ F6E2FF671E097BA00083EBEC /* MWMTTSSettingsViewController.mm in Sources */, 3454D7D81E07F045004AF2AD /* UIKitCategories.mm in Sources */, 346DB82F1E5C4F6700E3123E /* GalleryItemViewController.swift in Sources */, + 34763F001F3069BB00F4D2D3 /* RouteStartButton.swift in Sources */, 34E776201F14DB48003040B3 /* PlacePageArea.swift in Sources */, 849CF6FB1DE842290024A8A5 /* BookmarksVC.mm in Sources */, 849CF6FC1DE842290024A8A5 /* MWMSideButtonsView.mm in Sources */, @@ -6146,7 +6235,6 @@ 34D3B03D1E389D05004100F9 /* MWMEditorSwitchTableViewCell.mm in Sources */, 849CF7071DE842290024A8A5 /* LocaleTranslator.mm in Sources */, 340475821E081B3300C92850 /* iosOGLContextFactory.mm in Sources */, - 849CF70A1DE842290024A8A5 /* MWMTaxiPreviewDataSource.mm in Sources */, F682249C1E5B104600BC1C18 /* PPHotelDescriptionCell.swift in Sources */, F6E2FECB1E097BA00083EBEC /* MWMSearchFilterTransitioning.mm in Sources */, 849CF70D1DE842290024A8A5 /* MWMAddPlaceNavigationBar.mm in Sources */, @@ -6174,12 +6262,14 @@ F6E2FF4F1E097BA00083EBEC /* MWMAboutController.mm in Sources */, 34F5E0D51E3F254800B1C415 /* UIView+Hierarchy.swift in Sources */, 34F407391E9E1AFF00E57AC0 /* FacebookBanner.swift in Sources */, + 340708621F28FE2800029ECC /* MWMiPadRoutePreview.mm in Sources */, F6150E2B1EF95234000B955D /* MWMUGCReviewController.mm in Sources */, 849CF71D1DE842290024A8A5 /* MWMNavigationDashboardManager.mm in Sources */, 3454D7C91E07F045004AF2AD /* UIButton+RuntimeAttributes.mm in Sources */, F6E2FEDA1E097BA00083EBEC /* MWMSearchContentView.mm in Sources */, F6E2FD8A1E097BA00083EBEC /* MWMMapDownloaderViewController.mm in Sources */, F6E2FF4C1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */, + 3407087D1F2B6F5200029ECC /* NavigationControlView.swift in Sources */, 347040311EA6470700038379 /* BorderedButton.swift in Sources */, F6E2FE7A1E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */, 849CF7251DE842290024A8A5 /* MWMMapViewControlsManager.mm in Sources */, @@ -6193,6 +6283,7 @@ F6E2FEA11E097BA00083EBEC /* MWMPlacePageLayout.mm in Sources */, F6E2FEC51E097BA00083EBEC /* MWMSearchFilterPresentationController.mm in Sources */, F6E2FD871E097BA00083EBEC /* MWMBaseMapDownloaderViewController.mm in Sources */, + 34763EE81F2F392300F4D2D3 /* MWMTextToSpeech.mm in Sources */, 340416551E7C09C200E2B6D6 /* PhotoScalingView.swift in Sources */, F6E2FEE31E097BA00083EBEC /* MWMSearchManager.mm in Sources */, 34943BBC1E2626B200B14F84 /* WelcomePageController.swift in Sources */, @@ -6202,6 +6293,7 @@ 349D1ADC1E2E325C004A2006 /* MWMBottomMenuView.mm in Sources */, 3404164D1E7BF42E00E2B6D6 /* UIView+Coordinates.swift in Sources */, F6E2FD931E097BA00083EBEC /* MWMBookmarkColorViewController.mm in Sources */, + 3407085B1F28F1F400029ECC /* MWMTaxiPreviewDataSource.mm in Sources */, 849CF7331DE842290024A8A5 /* MWMInputValidatorFactory.mm in Sources */, F6E2FDA51E097BA00083EBEC /* MWMCuisineEditorViewController.mm in Sources */, F643247C1EF82AD9009296F9 /* UGCSelectImpressionCell.swift in Sources */, @@ -6211,7 +6303,6 @@ 34D3B02B1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.mm in Sources */, 34E776281F14FE77003040B3 /* NavigationStreetNameView.swift in Sources */, 34926BE81EA4C2A700DCF14C /* SearchBanners.swift in Sources */, - 849CF7371DE842290024A8A5 /* MWMTaxiCollectionLayout.mm in Sources */, 3454D7C61E07F045004AF2AD /* UIButton+Orientation.mm in Sources */, 3404165D1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */, 340475571E081A4600C92850 /* Statistics.mm in Sources */, @@ -6229,7 +6320,6 @@ 3404756F1E081A4600C92850 /* MWMSearch.mm in Sources */, 849CF74C1DE842290024A8A5 /* MWMLocationNotFoundAlert.mm in Sources */, F6E2FF041E097BA00083EBEC /* MWMSearchHistoryClearCell.mm in Sources */, - 3451F4F31F02935300A981F2 /* RoutePreviewTaxiCell.swift in Sources */, 340475541E081A4600C92850 /* MWMCustomFacebookEvents.mm in Sources */, 340416511E7C086000E2B6D6 /* PhotoViewController.swift in Sources */, 3404750A1E08199E00C92850 /* MWMMyTarget.mm in Sources */, @@ -6241,7 +6331,6 @@ F6E2FF611E097BA00083EBEC /* MWMSettingsViewController.mm in Sources */, F6E2FE2C1E097BA00083EBEC /* MWMStreetEditorEditTableViewCell.mm in Sources */, 34EE259F1EFA682D00F870AB /* PPViatorCarouselCell.swift in Sources */, - 849CF75C1DE842290024A8A5 /* MWMNavigationView.mm in Sources */, 849CF7601DE842290024A8A5 /* MWMStopButton.mm in Sources */, 346DB83E1E5C4F6700E3123E /* GalleryModel.swift in Sources */, 849CF7611DE842290024A8A5 /* MWMMailViewController.mm in Sources */, @@ -6263,6 +6352,7 @@ 849CF7671DE842290024A8A5 /* CircleView.mm in Sources */, F6E2FD9F1E097BA00083EBEC /* MWMEditBookmarkController.mm in Sources */, F6E2FE0B1E097BA00083EBEC /* MWMOpeningHoursDeleteScheduleTableViewCell.mm in Sources */, + 340708861F2B863500029ECC /* MWMNavigationDashboardManager+Entity.mm in Sources */, 849CF76D1DE842290024A8A5 /* AddSetTableViewCell.mm in Sources */, F6E2FED71E097BA00083EBEC /* MWMSearchChangeModeView.mm in Sources */, 849CF76E1DE842290024A8A5 /* MWMEditorViralActivityItem.mm in Sources */, diff --git a/iphone/Maps/UI/AvailableArea/MenuArea.swift b/iphone/Maps/UI/AvailableArea/MenuArea.swift new file mode 100644 index 0000000000..b9dab4425e --- /dev/null +++ b/iphone/Maps/UI/AvailableArea/MenuArea.swift @@ -0,0 +1,21 @@ +final class MenuArea: AvailableArea { + override func isAreaAffectingView(_ other: UIView) -> Bool { + return !other.menuAreaAffectDirections.isEmpty + } + + override func addAffectingView(_ other: UIView) { + let ov = other.menuAreaAffectView + let directions = ov.menuAreaAffectDirections + addConstraints(otherView: ov, directions: directions) + } + + override func notifyObserver() { + MWMBottomMenuViewController.updateAvailableArea(frame) + } +} + +extension UIView { + var menuAreaAffectDirections: MWMAvailableAreaAffectDirections { return [] } + + var menuAreaAffectView: UIView { return self } +} diff --git a/iphone/Maps/UI/AvailableArea/NavigationInfoArea.swift b/iphone/Maps/UI/AvailableArea/NavigationInfoArea.swift new file mode 100644 index 0000000000..da57a6813b --- /dev/null +++ b/iphone/Maps/UI/AvailableArea/NavigationInfoArea.swift @@ -0,0 +1,21 @@ +final class NavigationInfoArea: AvailableArea { + override func isAreaAffectingView(_ other: UIView) -> Bool { + return !other.navigationInfoAreaAffectDirections.isEmpty + } + + override func addAffectingView(_ other: UIView) { + let ov = other.navigationInfoAreaAffectView + let directions = ov.navigationInfoAreaAffectDirections + addConstraints(otherView: ov, directions: directions) + } + + override func notifyObserver() { + MWMNavigationDashboardManager.updateNavigationInfoAvailableArea(frame) + } +} + +extension UIView { + var navigationInfoAreaAffectDirections: MWMAvailableAreaAffectDirections { return [] } + + var navigationInfoAreaAffectView: UIView { return self } +} diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuControllerProtocol.h b/iphone/Maps/UI/BottomMenu/MWMBottomMenuControllerProtocol.h new file mode 100644 index 0000000000..d5a24c4ac2 --- /dev/null +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuControllerProtocol.h @@ -0,0 +1,11 @@ +#import "MWMMapDownloaderTypes.h" + +#include "platform/location.hpp" + +@protocol MWMBottomMenuControllerProtocol + +- (void)actionDownloadMaps:(mwm::DownloaderMode)mode; +- (void)addPlace:(BOOL)isBusiness hasPoint:(BOOL)hasPoint point:(m2::PointD const &)point; +- (void)didFinishAddingPlace; + +@end diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.h b/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.h index b3ac0bac3b..88663fe7f3 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.h +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.h @@ -1,28 +1,18 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuState) { MWMBottomMenuStateHidden, MWMBottomMenuStateInactive, - MWMBottomMenuStateActive, - MWMBottomMenuStateCompact, - MWMBottomMenuStateGo, - MWMBottomMenuStateRoutingError, - MWMBottomMenuStateRouting, - MWMBottomMenuStateRoutingExpanded + MWMBottomMenuStateActive }; -@class MWMTaxiCollectionView; - @interface MWMBottomMenuView : SolidTouchView @property(nonatomic) MWMBottomMenuState state; -@property(nonatomic) MWMBottomMenuState restoreState; -@property(nonatomic) CGFloat leftBound; @property(nonatomic) CGFloat layoutThreshold; -@property(weak, nonatomic, readonly) IBOutlet MWMTaxiCollectionView * taxiCollectionView; - -@property(nonatomic) BOOL searchIsActive; - - (void)refreshLayout; +- (void)updateAvailableArea:(CGRect)frame; +- (BOOL)isCompact; + @end diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.mm b/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.mm index 30bb4aeb49..fbe16dd027 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.mm +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuView.mm @@ -1,5 +1,6 @@ #import "MWMBottomMenuView.h" #import "EAGLView.h" +#import "MWMAvailableAreaAffectDirection.h" #import "MWMBottomMenuViewController.h" #import "MWMButton.h" #import "MWMCommon.h" @@ -18,39 +19,12 @@ namespace { CGFloat constexpr kAdditionalHeight = 64; CGFloat constexpr kDefaultMainButtonsHeight = 48; -CGFloat constexpr kBicyclePlanningMainButtonsHeightLandscape = 62; -CGFloat constexpr kBicyclePlanningMainButtonsHeightRegular = 94; -CGFloat constexpr kTaxiPreviewMainButtonHeight = 68.; CGFloat constexpr kDefaultMenuButtonWidth = 60; -CGFloat constexpr kRoutingAdditionalButtonsOffsetCompact = 0; -CGFloat constexpr kRoutingAdditionalButtonsOffsetRegular = 48; -CGFloat constexpr kRoutingMainButtonsHeightCompact = 52; -CGFloat constexpr kRoutingMainButtonsHeightRegular = 56; -CGFloat constexpr kRoutingMainButtonsHeightLandscape = 40; -CGFloat constexpr kRoutingMenuButtonWidthCompact = 40; -CGFloat constexpr kRoutingMenuButtonWidthRegular = 56; -CGFloat constexpr kSpeedDistanceOffsetCompact = 0; -CGFloat constexpr kSpeedDistanceOffsetRegular = 16; -CGFloat constexpr kSpeedDistanceWidthCompact = 72; -CGFloat constexpr kSpeedDistanceWidthLandscape = 128; -CGFloat constexpr kSpeedDistanceWidthRegular = 88; -CGFloat constexpr kGoButtonWidthLandscape = 128; -CGFloat constexpr kGoButtonWidthRegular = 80; -CGFloat constexpr kPageControlTopOffsetRegular = 0; -CGFloat constexpr kPageControlTopOffsetLandscape = -8; -CGFloat constexpr kPageControlScaleLandscape = 0.7; -CGFloat constexpr kThresholdCompact = 321; -CGFloat constexpr kThresholdRegular = 415; -CGFloat constexpr kTimeWidthCompact = 112; -CGFloat constexpr kTimeWidthRegular = 128; } // namespace @interface MWMBottomMenuView () -@property(weak, nonatomic) IBOutlet UIView * mainButtons; -@property(weak, nonatomic) IBOutlet UIView * separator; @property(weak, nonatomic) IBOutlet UICollectionView * additionalButtons; -@property(weak, nonatomic) IBOutlet MWMTaxiCollectionView * taxiCollectionView; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * mainButtonsHeight; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * additionalButtonsHeight; @@ -58,55 +32,17 @@ CGFloat constexpr kTimeWidthRegular = 128; @property(weak, nonatomic) IBOutlet UIView * downloadBadge; -@property(weak, nonatomic) IBOutlet MWMButton * p2pButton; @property(weak, nonatomic) IBOutlet MWMButton * searchButton; -@property(weak, nonatomic) IBOutlet MWMButton * bookmarksButton; @property(weak, nonatomic) IBOutlet MWMButton * menuButton; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * menuButtonWidth; -@property(weak, nonatomic) IBOutlet UIView * routingView; -@property(weak, nonatomic) IBOutlet UIButton * goButton; -@property(weak, nonatomic) IBOutlet UIButton * toggleInfoButton; -@property(weak, nonatomic) IBOutlet UIView * speedView; -@property(weak, nonatomic) IBOutlet UIView * timeView; -@property(weak, nonatomic) IBOutlet UIView * distanceView; -@property(weak, nonatomic) IBOutlet UIView * progressView; -@property(weak, nonatomic) IBOutlet UIView * routingAdditionalView; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * routingAdditionalViewHeight; -@property(nonatomic) IBOutletCollection(NSLayoutConstraint) - NSArray * routingAdditionalButtonsOffset; -@property(nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray * speedDistanceOffset; -@property(weak, nonatomic) IBOutlet UILabel * speedLabel; -@property(weak, nonatomic) IBOutlet UILabel * timeLabel; -@property(weak, nonatomic) IBOutlet UILabel * distanceLabel; -@property(weak, nonatomic) IBOutlet UILabel * speedLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * distanceLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * speedWithLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * distanceWithLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * estimateLabel; -@property(weak, nonatomic) IBOutlet UIView * heightProfileContainer; -@property(weak, nonatomic) IBOutlet UIView * taxiContainer; -@property(weak, nonatomic) IBOutlet UIImageView * heightProfileImage; -@property(weak, nonatomic) IBOutlet UIView * heightProfileElevation; -@property(weak, nonatomic) IBOutlet UIImageView * elevationImage; -@property(weak, nonatomic) IBOutlet UILabel * elevationHeight; - -@property(weak, nonatomic) IBOutlet UIPageControl * pageControl; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * pageControlTopOffset; - -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * speedDistanceWidth; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * timeWidth; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * goButtonWidth; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * estimateLabelTopOffset; -@property(nonatomic) IBOutletCollection(NSLayoutConstraint) - NSArray * heightProfileContainerVerticalOrientation; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * routingViewManuButtonPffset; @property(nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray * mainButtonConstraintsLeftToRight; -@property(nonatomic) CGFloat layoutDuration; - @property(weak, nonatomic) IBOutlet MWMBottomMenuViewController * owner; +@property(nonatomic) CGFloat layoutDuration; +@property(nonatomic) CGRect availableArea; + @end @implementation MWMBottomMenuView @@ -116,22 +52,6 @@ CGFloat constexpr kTimeWidthRegular = 128; [super awakeFromNib]; self.additionalButtons.hidden = YES; self.downloadBadge.hidden = YES; - self.goButton.hidden = YES; - self.estimateLabel.hidden = YES; - self.heightProfileContainer.hidden = YES; - self.heightProfileElevation.hidden = YES; - self.toggleInfoButton.hidden = YES; - self.speedView.hidden = YES; - self.timeView.hidden = YES; - self.distanceView.hidden = YES; - self.progressView.hidden = YES; - self.routingView.hidden = YES; - self.routingAdditionalView.hidden = YES; - self.restoreState = MWMBottomMenuStateInactive; - [self.goButton setBackgroundColor:[UIColor linkBlue] forState:UIControlStateNormal]; - [self.goButton setBackgroundColor:[UIColor linkBlueHighlighted] - forState:UIControlStateHighlighted]; - self.elevationImage.mwm_coloring = MWMImageColoringBlue; if (isInterfaceRightToLeft()) { @@ -140,36 +60,41 @@ CGFloat constexpr kTimeWidthRegular = 128; } } +- (void)didMoveToSuperview +{ + [super didMoveToSuperview]; + self.minY = self.superview.height; + self.width = self.superview.width; +} + - (void)layoutSubviews { - [self refreshOnOrientationChange]; if (self.layoutDuration > 0.0) { CGFloat const duration = self.layoutDuration; self.layoutDuration = 0.0; - [self layoutIfNeeded]; + if (self.state != MWMBottomMenuStateHidden) + self.hidden = NO; + [self setNeedsLayout]; [UIView animateWithDuration:duration - animations:^{ - [self layoutGeometry]; - [self layoutIfNeeded]; - }]; + animations:^{ + [self updateAppearance]; + [self layoutIfNeeded]; + } + completion:^(BOOL finished) { + if (self.state == MWMBottomMenuStateHidden) + self.hidden = YES; + }]; } - else - { - [self layoutGeometry]; - } - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - [self updateAlphaAndColor]; - } - completion:^(BOOL finished) { - [self updateVisibility]; - }]; - [self updateFonts]; - [self updateHeightProfile]; [super layoutSubviews]; } +- (void)updateAppearance +{ + [self updateAlphaAndColor]; + [self updateGeometry]; +} + - (void)updateAlphaAndColor { switch (self.state) @@ -177,233 +102,30 @@ CGFloat constexpr kTimeWidthRegular = 128; case MWMBottomMenuStateHidden: break; case MWMBottomMenuStateInactive: self.backgroundColor = [UIColor menuBackground]; - self.menuButton.alpha = 1.0; - self.bookmarksButton.alpha = 1.0; - self.downloadBadge.alpha = 1.0; - self.routingView.alpha = 0.0; - self.routingAdditionalView.alpha = 0.0; - self.p2pButton.alpha = 1.0; - self.searchButton.alpha = 1.0; + self.downloadBadge.alpha = [self isCompact] ? 0.0 : 1.0; + self.additionalButtons.alpha = 0.0; break; case MWMBottomMenuStateActive: self.backgroundColor = [UIColor white]; - self.menuButton.alpha = 1.0; - self.bookmarksButton.alpha = 1.0; self.downloadBadge.alpha = 0.0; - self.routingView.alpha = 0.0; - self.routingAdditionalView.alpha = 0.0; - self.p2pButton.alpha = 1.0; - self.searchButton.alpha = 1.0; - break; - case MWMBottomMenuStateCompact: - self.backgroundColor = [UIColor menuBackground]; - if (!IPAD) - { - self.bookmarksButton.alpha = 0.0; - self.p2pButton.alpha = 0.0; - self.searchButton.alpha = 0.0; - } - self.menuButton.alpha = 1.0; - self.downloadBadge.alpha = 0.0; - self.routingView.alpha = 0.0; - self.routingAdditionalView.alpha = 0.0; - break; - case MWMBottomMenuStateGo: - self.backgroundColor = [UIColor white]; - self.menuButton.alpha = 0.0; - self.downloadBadge.alpha = 1.0; - self.bookmarksButton.alpha = 0.0; - self.routingView.alpha = 1.0; - self.goButton.alpha = 1.0; - self.estimateLabel.alpha = 1.0; - self.heightProfileContainer.alpha = 1.0; - self.speedView.alpha = 0.0; - self.timeView.alpha = 0.0; - self.distanceView.alpha = 0.0; - self.progressView.alpha = 0.0; - self.routingAdditionalView.alpha = 0.0; - self.p2pButton.alpha = 0.0; - self.searchButton.alpha = 0.0; - break; - case MWMBottomMenuStateRoutingError: - self.backgroundColor = [UIColor white]; - self.menuButton.alpha = 0.0; - self.downloadBadge.alpha = 1.0; - self.bookmarksButton.alpha = 0.0; - self.routingView.alpha = 1.0; - self.goButton.alpha = 0.0; - self.estimateLabel.alpha = 1.0; - self.heightProfileContainer.alpha = 0.0; - self.speedView.alpha = 0.0; - self.timeView.alpha = 0.0; - self.distanceView.alpha = 0.0; - self.progressView.alpha = 0.0; - self.routingAdditionalView.alpha = 0.0; - self.p2pButton.alpha = 0.0; - self.searchButton.alpha = 0.0; - break; - case MWMBottomMenuStateRouting: - case MWMBottomMenuStateRoutingExpanded: - self.backgroundColor = [UIColor white]; - self.menuButton.alpha = 1.0; - self.downloadBadge.alpha = 0.0; - self.bookmarksButton.alpha = 0.0; - self.routingView.alpha = 1.0; - self.goButton.alpha = 0.0; - self.estimateLabel.alpha = 0.0; - self.heightProfileContainer.alpha = 0.0; - self.speedView.alpha = 1.0; - self.timeView.alpha = 1.0; - self.distanceView.alpha = 1.0; - self.progressView.alpha = 1.0; - self.routingAdditionalView.alpha = 1.0; - self.p2pButton.alpha = 0.0; - self.searchButton.alpha = 0.0; + self.additionalButtons.alpha = 1.0; break; } } -- (void)updateFonts +- (void)updateGeometry { - if (self.state != MWMBottomMenuStateRouting && self.state != MWMBottomMenuStateRoutingExpanded) + auto const availableArea = self.availableArea; + if (CGRectEqualToRect(availableArea, CGRectZero)) return; - UIFont * numberFont = - (IPAD || self.width > kThresholdRegular) ? [UIFont bold24] : [UIFont bold22]; - UIFont * legendFont = [UIFont bold12]; - self.speedLabel.font = numberFont; - self.timeLabel.font = numberFont; - self.distanceLabel.font = numberFont; - self.speedLegendLabel.font = legendFont; - self.distanceLegendLabel.font = legendFont; -} - -- (void)updateHeightProfile -{ - if (self.heightProfileContainer.hidden || ![MWMRouter hasRouteAltitude]) - return; - dispatch_async(dispatch_get_main_queue(), ^{ - [MWMRouter routeAltitudeImageForSize:self.heightProfileImage.frame.size - completion:^(UIImage * image, NSString * altitudeElevation) { - self.heightProfileImage.image = image; - self.elevationHeight.text = altitudeElevation; - }]; - }); -} - -- (void)updateVisibility -{ - switch (self.state) - { - case MWMBottomMenuStateHidden: break; - case MWMBottomMenuStateInactive: - self.additionalButtons.hidden = YES; - self.routingView.hidden = YES; - self.routingAdditionalView.hidden = YES; - self.taxiContainer.hidden = YES; - self.estimateLabel.hidden = YES; - break; - case MWMBottomMenuStateActive: - self.downloadBadge.hidden = YES; - self.routingView.hidden = YES; - self.routingAdditionalView.hidden = YES; - self.taxiContainer.hidden = YES; - self.estimateLabel.hidden = YES; - break; - case MWMBottomMenuStateCompact: - if (!IPAD) - { - self.bookmarksButton.hidden = YES; - self.p2pButton.hidden = YES; - self.searchButton.hidden = YES; - } - self.downloadBadge.hidden = YES; - self.routingView.hidden = YES; - self.routingAdditionalView.hidden = YES; - self.taxiContainer.hidden = YES; - self.estimateLabel.hidden = YES; - break; - case MWMBottomMenuStateGo: - { - self.downloadBadge.hidden = YES; - self.menuButton.hidden = YES; - self.bookmarksButton.hidden = YES; - self.p2pButton.hidden = YES; - self.searchButton.hidden = YES; - self.routingAdditionalView.hidden = YES; - BOOL const isNeedToShowTaxi = [MWMRouter isTaxi] || IPAD; - self.estimateLabel.hidden = isNeedToShowTaxi; - self.taxiContainer.hidden = !isNeedToShowTaxi; - break; - } - case MWMBottomMenuStateRoutingError: - self.downloadBadge.hidden = YES; - self.menuButton.hidden = YES; - self.bookmarksButton.hidden = YES; - self.p2pButton.hidden = YES; - self.searchButton.hidden = YES; - self.routingAdditionalView.hidden = YES; - self.estimateLabel.hidden = NO; - self.taxiContainer.hidden = YES; - break; - case MWMBottomMenuStateRouting: - case MWMBottomMenuStateRoutingExpanded: - self.downloadBadge.hidden = YES; - self.bookmarksButton.hidden = YES; - self.routingView.hidden = NO; - self.routingAdditionalView.hidden = NO; - self.p2pButton.hidden = YES; - self.searchButton.hidden = YES; - self.taxiContainer.hidden = YES; - break; - } -} - -- (void)layoutGeometry -{ self.separatorHeight.constant = 0.0; self.additionalButtonsHeight.constant = 0.0; self.menuButtonWidth.constant = kDefaultMenuButtonWidth; self.mainButtonsHeight.constant = kDefaultMainButtonsHeight; - self.routingViewManuButtonPffset.priority = UILayoutPriorityDefaultHigh; - self.routingAdditionalViewHeight.constant = 0.0; switch (self.state) { case MWMBottomMenuStateHidden: self.minY = self.superview.height; return; case MWMBottomMenuStateInactive: break; - case MWMBottomMenuStateGo: - { - [[MWMNavigationDashboardManager manager] updateStartButtonTitle:self.goButton]; - [self layoutGoGeometry]; - if ([MWMRouter hasRouteAltitude]) - { - BOOL const isLandscape = self.width > self.layoutThreshold; - if (isLandscape) - { - self.mainButtonsHeight.constant = kBicyclePlanningMainButtonsHeightLandscape; - self.estimateLabelTopOffset.priority = UILayoutPriorityDefaultHigh; - } - else - { - self.estimateLabelTopOffset.priority = UILayoutPriorityDefaultHigh; - for (NSLayoutConstraint * constraint in self.heightProfileContainerVerticalOrientation) - constraint.priority = UILayoutPriorityDefaultHigh; - self.mainButtonsHeight.constant = kBicyclePlanningMainButtonsHeightRegular; - } - } - else if ([MWMRouter isTaxi]) - { - self.mainButtonsHeight.constant = kTaxiPreviewMainButtonHeight; - } - break; - } - case MWMBottomMenuStateRoutingError: - self.mainButtonsHeight.constant = kDefaultMainButtonsHeight; - break; - case MWMBottomMenuStateCompact: - if (self.restoreState == MWMBottomMenuStateRouting && !IPAD && - UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) - self.mainButtonsHeight.constant = kRoutingMainButtonsHeightLandscape; - break; case MWMBottomMenuStateActive: { self.separatorHeight.constant = 1.0; @@ -420,104 +142,16 @@ CGFloat constexpr kTimeWidthRegular = 128; } } break; - case MWMBottomMenuStateRouting: [self layoutRoutingGeometry]; break; - case MWMBottomMenuStateRoutingExpanded: - self.routingAdditionalViewHeight.constant = kAdditionalHeight; - [self layoutRoutingGeometry]; - break; } - CGFloat const width = MIN(self.superview.width - self.leftBound, self.superview.width); - CGFloat const additionalHeight = - MAX(self.additionalButtonsHeight.constant, self.routingAdditionalViewHeight.constant); - CGFloat const height = + auto const additionalHeight = self.additionalButtonsHeight.constant; + auto const height = self.mainButtonsHeight.constant + self.separatorHeight.constant + additionalHeight; - self.frame = {{self.superview.width - width, self.superview.height - height}, {width, height}}; + self.frame = {{availableArea.origin.x, availableArea.size.height - height}, + {availableArea.size.width, height}}; } -- (void)layoutGoGeometry +- (void)morphMenuButtonTemplate:(NSString *)morphTemplate direct:(BOOL)direct { - BOOL const isLandscape = self.width > self.layoutThreshold; - self.estimateLabelTopOffset.priority = UILayoutPriorityDefaultLow; - self.routingViewManuButtonPffset.priority = UILayoutPriorityDefaultLow; - for (NSLayoutConstraint * constraint in self.heightProfileContainerVerticalOrientation) - constraint.priority = UILayoutPriorityDefaultLow; - self.goButtonWidth.constant = isLandscape ? kGoButtonWidthLandscape : kGoButtonWidthRegular; -} - -- (void)layoutRoutingGeometry -{ - auto layoutAdditionalButtonsOffset = ^(CGFloat offset) { - for (NSLayoutConstraint * constraint in self.routingAdditionalButtonsOffset) - constraint.constant = offset; - }; - auto layoutSpeedDistanceOffset = ^(CGFloat offset) { - for (NSLayoutConstraint * constraint in self.speedDistanceOffset) - constraint.constant = offset; - }; - self.pageControlTopOffset.constant = kPageControlTopOffsetRegular; - self.pageControl.transform = CGAffineTransformIdentity; - self.speedLabel.hidden = NO; - self.distanceLabel.hidden = NO; - self.speedLegendLabel.hidden = NO; - self.distanceLegendLabel.hidden = NO; - self.speedWithLegendLabel.hidden = YES; - self.distanceWithLegendLabel.hidden = YES; - if (IPAD) - { - self.speedDistanceWidth.constant = kSpeedDistanceWidthRegular; - self.timeWidth.constant = kTimeWidthRegular; - self.mainButtonsHeight.constant = kRoutingMainButtonsHeightRegular; - self.menuButtonWidth.constant = kDefaultMenuButtonWidth; - layoutAdditionalButtonsOffset(kRoutingAdditionalButtonsOffsetRegular); - layoutSpeedDistanceOffset(kSpeedDistanceOffsetRegular); - } - else - { - self.timeWidth.constant = kTimeWidthRegular; - self.mainButtonsHeight.constant = kRoutingMainButtonsHeightCompact; - self.menuButtonWidth.constant = kRoutingMenuButtonWidthCompact; - layoutAdditionalButtonsOffset(kRoutingAdditionalButtonsOffsetCompact); - layoutSpeedDistanceOffset(kSpeedDistanceOffsetCompact); - if (self.width <= kThresholdCompact) - { - self.speedDistanceWidth.constant = kSpeedDistanceWidthCompact; - self.timeWidth.constant = kTimeWidthCompact; - } - else if (self.width <= kThresholdRegular) - { - self.speedDistanceWidth.constant = kSpeedDistanceWidthRegular; - } - else - { - self.pageControlTopOffset.constant = kPageControlTopOffsetLandscape; - self.pageControl.transform = - CGAffineTransformMakeScale(kPageControlScaleLandscape, kPageControlScaleLandscape); - self.speedDistanceWidth.constant = kSpeedDistanceWidthLandscape; - self.mainButtonsHeight.constant = kRoutingMainButtonsHeightLandscape; - self.menuButtonWidth.constant = kRoutingMenuButtonWidthRegular; - layoutAdditionalButtonsOffset(kRoutingAdditionalButtonsOffsetRegular); - self.speedLabel.hidden = YES; - self.distanceLabel.hidden = YES; - self.speedLegendLabel.hidden = YES; - self.distanceLegendLabel.hidden = YES; - self.speedWithLegendLabel.hidden = NO; - self.distanceWithLegendLabel.hidden = NO; - } - } -} - -- (void)updateMenuButtonFromState:(MWMBottomMenuState)fromState toState:(MWMBottomMenuState)toState -{ - if (fromState == MWMBottomMenuStateActive || toState == MWMBottomMenuStateActive) - [self morphMenuButtonTemplate:@"ic_menu_" toState:toState]; - else if (fromState == MWMBottomMenuStateCompact || toState == MWMBottomMenuStateCompact) - [self morphMenuButtonTemplate:@"ic_menu_rotate_" toState:toState]; - [self refreshMenuButtonState]; -} - -- (void)morphMenuButtonTemplate:(NSString *)morphTemplate toState:(MWMBottomMenuState)toState -{ - BOOL const direct = toState == MWMBottomMenuStateActive || toState == MWMBottomMenuStateCompact; UIButton * btn = self.menuButton; NSUInteger const morphImagesCount = 6; NSUInteger const startValue = direct ? 1 : morphImagesCount; @@ -535,6 +169,7 @@ CGFloat constexpr kTimeWidthRegular = 128; btn.imageView.animationRepeatCount = 1; btn.imageView.image = morphImages.lastObject; [btn.imageView startAnimating]; + [self refreshMenuButtonState]; } - (void)refreshMenuButtonState @@ -546,64 +181,28 @@ CGFloat constexpr kTimeWidthRegular = 128; } else { - UIButton * btn = self.menuButton; NSString * name = nil; switch (self.state) { - case MWMBottomMenuStateHidden: + case MWMBottomMenuStateHidden: name = @"ic_menu"; break; case MWMBottomMenuStateInactive: - case MWMBottomMenuStateRoutingError: - case MWMBottomMenuStateGo: name = @"ic_menu"; break; - case MWMBottomMenuStateActive: - case MWMBottomMenuStateRouting: - case MWMBottomMenuStateRoutingExpanded: name = @"ic_menu_down"; break; - case MWMBottomMenuStateCompact: name = @"ic_menu_left"; break; - } - UIImage * image = [UIImage imageNamed:name]; - [btn setImage:image forState:UIControlStateNormal]; - if (self.state == MWMBottomMenuStateInactive) - { - btn.transform = CGAffineTransformIdentity; - } - else - { - BOOL const rotate = (self.state == MWMBottomMenuStateRouting); - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - btn.transform = rotate ? CGAffineTransformMakeRotation(M_PI) - : CGAffineTransformIdentity; - }]; + name = [self isCompact] ? @"ic_menu_left" : @"ic_menu"; + break; + case MWMBottomMenuStateActive: name = @"ic_menu_down"; break; } + [self.menuButton setImage:[UIImage imageNamed:name] forState:UIControlStateNormal]; } }); } -- (void)refreshOnOrientationChange -{ - if (IPAD || self.state != MWMBottomMenuStateCompact) - return; - BOOL const isPortrait = self.superview.width < self.superview.height; - if (isPortrait) - self.owner.leftBound = 0.0; -} - - (void)refreshLayout { self.layoutDuration = kDefaultAnimationDuration; [self setNeedsLayout]; - if (self.state == MWMBottomMenuStateInactive) - [self updateBadge]; } - (void)updateBadge { - auto state = self.state; - if (state == MWMBottomMenuStateRouting || state == MWMBottomMenuStateRoutingExpanded || - state == MWMBottomMenuStateGo) - { - self.downloadBadge.hidden = YES; - return; - } auto & s = GetFramework().GetStorage(); storage::Storage::UpdateInfo updateInfo{}; s.GetUpdateInfo(s.GetRootId(), updateInfo); @@ -613,124 +212,32 @@ CGFloat constexpr kTimeWidthRegular = 128; #pragma mark - Properties -- (void)setFrame:(CGRect)frame -{ - frame.size.width = MAX(self.menuButtonWidth.constant, frame.size.width); - super.frame = frame; -} - - (void)setState:(MWMBottomMenuState)state { if (_state == state) return; - [self refreshLayout]; - BOOL updateMenuButton = YES; - switch (state) - { - case MWMBottomMenuStateHidden: updateMenuButton = NO; break; - case MWMBottomMenuStateInactive: - { - if (![MWMRouter isRoutingActive]) - _leftBound = 0.0; - self.p2pButton.hidden = self.searchButton.hidden = self.bookmarksButton.hidden = NO; - self.menuButton.hidden = NO; - self.layoutDuration = - (_state == MWMBottomMenuStateCompact && !IPAD) ? 0.0 : kDefaultAnimationDuration; - break; - } - case MWMBottomMenuStateActive: - self.restoreState = _state; - [self updateMenuButtonFromState:_state toState:state]; - self.menuButton.hidden = NO; - self.additionalButtons.hidden = NO; - self.bookmarksButton.hidden = NO; - self.p2pButton.hidden = NO; - self.searchButton.hidden = NO; - break; - case MWMBottomMenuStateCompact: - if (_state == MWMBottomMenuStateGo) - self.restoreState = _state; - self.layoutDuration = IPAD ? kDefaultAnimationDuration : 0.0; - self.menuButton.hidden = NO; - break; - case MWMBottomMenuStateGo: - { - self.goButton.enabled = YES; - self.goButton.hidden = NO; - self.estimateLabel.hidden = NO; - BOOL const hasAltitude = [MWMRouter hasRouteAltitude]; - self.heightProfileContainer.hidden = !hasAltitude; - self.heightProfileElevation.hidden = !hasAltitude; - self.toggleInfoButton.hidden = YES; - self.speedView.hidden = YES; - self.timeView.hidden = YES; - self.distanceView.hidden = YES; - self.progressView.hidden = YES; - self.routingView.hidden = NO; - self.routingAdditionalView.hidden = YES; - break; - } - case MWMBottomMenuStateRoutingError: - self.goButton.hidden = YES; - self.estimateLabel.hidden = NO; - self.heightProfileContainer.hidden = YES; - self.heightProfileElevation.hidden = YES; - self.toggleInfoButton.hidden = YES; - self.speedView.hidden = YES; - self.timeView.hidden = YES; - self.distanceView.hidden = YES; - self.progressView.hidden = YES; - self.routingView.hidden = NO; - self.routingAdditionalView.hidden = YES; - break; - case MWMBottomMenuStateRouting: - self.menuButton.hidden = NO; - self.goButton.hidden = YES; - self.estimateLabel.hidden = YES; - self.heightProfileContainer.hidden = YES; - self.heightProfileElevation.hidden = YES; - self.toggleInfoButton.hidden = NO; - self.speedView.hidden = NO; - self.timeView.hidden = NO; - self.distanceView.hidden = NO; - self.progressView.hidden = NO; - self.routingView.hidden = NO; - self.routingAdditionalView.hidden = YES; - break; - case MWMBottomMenuStateRoutingExpanded: - self.menuButton.hidden = NO; - self.goButton.hidden = YES; - self.estimateLabel.hidden = YES; - self.heightProfileContainer.hidden = YES; - self.heightProfileElevation.hidden = YES; - self.toggleInfoButton.hidden = NO; - self.speedView.hidden = NO; - self.timeView.hidden = NO; - self.distanceView.hidden = NO; - self.progressView.hidden = NO; - self.routingView.hidden = NO; - self.routingAdditionalView.hidden = NO; - break; - } - if (updateMenuButton) - [self updateMenuButtonFromState:_state toState:state]; + BOOL const isActive = (state == MWMBottomMenuStateActive); + self.additionalButtons.hidden = !isActive; + if (_state == MWMBottomMenuStateActive || isActive) + [self morphMenuButtonTemplate:@"ic_menu_" direct:isActive]; _state = state; + [self refreshLayout]; [self updateBadge]; } -- (void)setLeftBound:(CGFloat)leftBound +- (void)updateAvailableArea:(CGRect)frame { - _leftBound = MAX(leftBound, 0.0); - if ([MWMNavigationDashboardManager manager].state != MWMNavigationDashboardStatePrepare) - self.state = _leftBound > 1.0 ? MWMBottomMenuStateCompact : self.restoreState; - [self setNeedsLayout]; -} - -- (void)setSearchIsActive:(BOOL)searchIsActive -{ - _searchIsActive = self.searchButton.selected = searchIsActive; + if (CGRectEqualToRect(self.availableArea, frame)) + return; + BOOL const wasCompact = [self isCompact]; + self.availableArea = frame; + BOOL const isCompact = [self isCompact]; + if (wasCompact || isCompact) + [self morphMenuButtonTemplate:@"ic_menu_rotate_" direct:isCompact]; + [self refreshLayout]; } +- (BOOL)isCompact { return self.availableArea.origin.x > 0; } #pragma mark - AvailableArea / PlacePageArea - (MWMAvailableAreaAffectDirections)placePageAreaAffectDirections diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.h b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.h index b81ab802dd..e3c13ff4f2 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.h +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.h @@ -1,33 +1,19 @@ #import "MWMBottomMenuView.h" -#import "MWMMapDownloaderTypes.h" -#import "MWMNavigationDashboardManager.h" -#include "platform/location.hpp" +@class MapViewController, MWMButton; +@protocol MWMBottomMenuControllerProtocol; -@class MapViewController, MWMButton, MWMTaxiCollectionView; - -@protocol MWMBottomMenuControllerProtocol - -- (void)actionDownloadMaps:(mwm::DownloaderMode)mode; -- (void)closeInfoScreens; -- (void)addPlace:(BOOL)isBusiness hasPoint:(BOOL)hasPoint point:(m2::PointD const &)point; -- (void)didFinishAddingPlace; - -@end - -@interface MWMBottomMenuViewController : UIViewController +@interface MWMBottomMenuViewController : UIViewController + (MWMBottomMenuViewController *)controller; @property(nonatomic) MWMBottomMenuState state; -@property(weak, nonatomic) IBOutlet MWMButton * p2pButton; -@property(nonatomic) CGFloat leftBound; - (instancetype)initWithParentController:(MapViewController *)controller delegate:(id)delegate; - (void)mwm_refreshUI; -- (MWMTaxiCollectionView *)taxiCollectionView; -- (void)setRoutingErrorMessage:(NSString *)routingErrorMessage; + ++ (void)updateAvailableArea:(CGRect)frame; @end diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm index 3b54c20d78..ca325154bb 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm @@ -3,6 +3,7 @@ #import "EAGLView.h" #import "MWMActivityViewController.h" #import "MWMBottomMenuCollectionViewCell.h" +#import "MWMBottomMenuControllerProtocol.h" #import "MWMBottomMenuLayout.h" #import "MWMBottomMenuView.h" #import "MWMButton.h" @@ -15,7 +16,6 @@ #import "MWMSearchManager.h" #import "MWMSettingsViewController.h" #import "MWMTextToSpeech.h" -#import "MWMTrafficManager.h" #import "MapViewController.h" #import "MapsAppDelegate.h" #import "Statistics.h" @@ -30,13 +30,11 @@ #include "platform/mwm_version.hpp" extern NSString * const kAlohalyticsTapEventKey; -extern NSString * const kSearchStateWillChangeNotification; extern NSString * const kSearchStateKey; namespace { CGFloat constexpr kLayoutThreshold = 420.0; -NSTimeInterval constexpr kRoutingDiminishInterval = 5.0; } // namespace typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { @@ -54,43 +52,16 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { @end @interface MWMBottomMenuViewController () - -@property(weak, nonatomic) MapViewController * controller; -@property(weak, nonatomic) IBOutlet UICollectionView * buttonsCollectionView; - -@property(weak, nonatomic) IBOutlet UICollectionView * additionalButtons; - -@property(weak, nonatomic) id delegate; - -@property(nonatomic) BOOL searchIsActive; - -@property(nonatomic) SolidTouchView * dimBackground; + MWMNavigationDashboardObserver, MWMSearchManagerObserver> @property(nonatomic) MWMBottomMenuState restoreState; - +@property(nonatomic) MWMDimBackground * dimBackground; @property(nonatomic, readonly) NSUInteger additionalButtonsCount; - -@property(weak, nonatomic) MWMNavigationDashboardEntity * navigationInfo; - -@property(copy, nonatomic) NSString * routingErrorMessage; - -@property(weak, nonatomic) IBOutlet UILabel * speedLabel; -@property(weak, nonatomic) IBOutlet UILabel * timeLabel; -@property(weak, nonatomic) IBOutlet UILabel * distanceLabel; -@property(weak, nonatomic) IBOutlet UILabel * speedLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * distanceLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * speedWithLegendLabel; -@property(weak, nonatomic) IBOutlet UILabel * distanceWithLegendLabel; -@property(weak, nonatomic) IBOutlet UIPageControl * routingInfoPageControl; -@property(weak, nonatomic) IBOutlet UILabel * estimateLabel; - -@property(weak, nonatomic) IBOutlet UIView * progressView; -@property(weak, nonatomic) IBOutlet NSLayoutConstraint * routingProgress; -@property(weak, nonatomic) IBOutlet MWMButton * ttsSoundButton; -@property(weak, nonatomic) IBOutlet MWMButton * trafficButton; - +@property(weak, nonatomic) IBOutlet MWMButton * searchButton; @property(weak, nonatomic) IBOutlet NSLayoutConstraint * mainButtonsHeight; +@property(weak, nonatomic) IBOutlet UICollectionView * additionalButtons; +@property(weak, nonatomic) MapViewController * controller; +@property(weak, nonatomic) id delegate; @end @@ -101,6 +72,12 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { return [MWMMapViewControlsManager manager].menuController; } ++ (void)updateAvailableArea:(CGRect)frame +{ + auto view = static_cast([self controller].view); + [view updateAvailableArea:frame]; +} + - (instancetype)initWithParentController:(MapViewController *)controller delegate:(id)delegate { @@ -110,9 +87,7 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { _controller = controller; _delegate = delegate; [controller addChildViewController:self]; - MWMBottomMenuView * view = (MWMBottomMenuView *)self.view; - [controller.view addSubview:view]; - view.maxY = controller.view.height; + [controller.view addSubview:self.view]; } return self; } @@ -121,24 +96,16 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { - (void)viewDidLoad { [super viewDidLoad]; - UICollectionView * bcv = self.buttonsCollectionView; + UICollectionView * bcv = self.additionalButtons; [bcv registerWithCellClass:[MWMBottomMenuCollectionViewPortraitCell class]]; [bcv registerWithCellClass:[MWMBottomMenuCollectionViewLandscapeCell class]]; MWMBottomMenuLayout * cvLayout = - (MWMBottomMenuLayout *)self.buttonsCollectionView.collectionViewLayout; + (MWMBottomMenuLayout *)self.additionalButtons.collectionViewLayout; cvLayout.layoutThreshold = kLayoutThreshold; - ((MWMBottomMenuView *)self.view).layoutThreshold = kLayoutThreshold; + self.menuView.layoutThreshold = kLayoutThreshold; - NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self - selector:@selector(searchStateWillChange:) - name:kSearchStateWillChangeNotification - object:nil]; - [nc addObserver:self - selector:@selector(ttsButtonStatusChanged:) - name:[MWMTextToSpeech ttsStatusNotificationKey] - object:nil]; - [MWMTrafficManager addObserver:self]; + [MWMSearchManager addObserver:self]; + [MWMNavigationDashboardManager addObserver:self]; } - (void)viewWillAppear:(BOOL)animated @@ -148,124 +115,16 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { } - (void)mwm_refreshUI { [self.view mwm_refreshUI]; } -#pragma mark - MWMNavigationDashboardInfoProtocol - -- (void)updateNavigationInfo:(MWMNavigationDashboardEntity *)info -{ - if ([MWMRouter isTaxi]) - return; - - self.navigationInfo = info; - if (!info) - return; - - NSDictionary * routingNumberAttributes = @{ - NSForegroundColorAttributeName : [UIColor blackPrimaryText], - NSFontAttributeName : [UIFont bold24] - }; - NSDictionary * routingLegendAttributes = @{ - NSForegroundColorAttributeName : [UIColor blackSecondaryText], - NSFontAttributeName : [UIFont bold14] - }; - - self.estimateLabel.attributedText = info.estimate; - if (self.routingInfoPageControl.currentPage == 0) - { - self.timeLabel.text = [NSDateComponentsFormatter etaStringFrom:info.timeToTarget]; - } - else - { - NSDate * arrivalDate = [[NSDate date] dateByAddingTimeInterval:info.timeToTarget]; - self.timeLabel.text = [NSDateFormatter localizedStringFromDate:arrivalDate - dateStyle:NSDateFormatterNoStyle - timeStyle:NSDateFormatterShortStyle]; - } - NSString * targetDistance = info.targetDistance; - NSMutableAttributedString * distance; - if (targetDistance) - { - self.distanceLabel.text = targetDistance; - distance = [[NSMutableAttributedString alloc] initWithString:targetDistance - attributes:routingNumberAttributes]; - } - - NSString * targetUnits = info.targetUnits; - if (targetUnits) - { - self.distanceLegendLabel.text = targetUnits; - if (distance) - { - [distance appendAttributedString:[[NSAttributedString alloc] initWithString:targetUnits - attributes:routingLegendAttributes]]; - self.distanceWithLegendLabel.attributedText = distance; - } - } - - NSString * currentSpeed = info.speed ?: @"0"; - self.speedLabel.text = currentSpeed; - self.speedLegendLabel.text = info.speedUnits; - NSMutableAttributedString * speed = - [[NSMutableAttributedString alloc] initWithString:currentSpeed - attributes:routingNumberAttributes]; - [speed - appendAttributedString:[[NSAttributedString alloc] initWithString:info.speedUnits - attributes:routingLegendAttributes]]; - self.speedWithLegendLabel.attributedText = speed; - - [self.progressView layoutIfNeeded]; - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - self.routingProgress.constant = self.progressView.width * info.progress / 100.; - [self.progressView layoutIfNeeded]; - }]; -} - -#pragma mark - Routing - -- (IBAction)toggleInfoTouchUpInside -{ - self.routingInfoPageControl.currentPage = - (self.routingInfoPageControl.currentPage + 1) % self.routingInfoPageControl.numberOfPages; - [self updateNavigationInfo:self.navigationInfo]; - [self refreshRoutingDiminishTimer]; -} - -- (IBAction)routingStartTouchUpInside { [MWMRouter startRouting]; } -- (IBAction)routingStopTouchUpInside { [MWMRouter stopRouting]; } -- (IBAction)soundTouchUpInside:(MWMButton *)sender -{ - BOOL const isEnabled = sender.selected; - [Statistics logEvent:kStatMenu withParameters:@{kStatTTS : isEnabled ? kStatOn : kStatOff}]; - [MWMTextToSpeech tts].active = !isEnabled; - [self refreshRoutingDiminishTimer]; -} - -#pragma mark - MWMTrafficManagerObserver - -- (void)onTrafficStateUpdated -{ - MWMButton * tb = self.trafficButton; - BOOL const enabled = ([MWMTrafficManager state] != TrafficManager::TrafficState::Disabled); - tb.selected = enabled; -} - -- (IBAction)trafficTouchUpInside:(MWMButton *)sender -{ - BOOL const switchOn = ([MWMTrafficManager state] == TrafficManager::TrafficState::Disabled); - [Statistics logEvent:kStatMenu withParameters:@{kStatTraffic : switchOn ? kStatOn : kStatOff}]; - [MWMTrafficManager enableTraffic:switchOn]; - [self refreshRoutingDiminishTimer]; -} #pragma mark - Refresh Collection View layout - (void)refreshLayout { MWMBottomMenuLayout * cvLayout = - (MWMBottomMenuLayout *)self.buttonsCollectionView.collectionViewLayout; + (MWMBottomMenuLayout *)self.additionalButtons.collectionViewLayout; cvLayout.buttonsCount = [self collectionView:self.additionalButtons numberOfItemsInSection:0]; [self.additionalButtons reloadData]; - [(MWMBottomMenuView *)self.view refreshLayout]; + [self.menuView refreshLayout]; } #pragma mark - Layout @@ -276,24 +135,23 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { [self.additionalButtons reloadData]; } -#pragma mark - Notifications +#pragma mark - MWMNavigationDashboardObserver -- (void)searchStateWillChange:(NSNotification *)notification +- (void)onNavigationDashboardStateChanged { - MWMSearchManagerState state = - MWMSearchManagerState([[notification userInfo][kSearchStateKey] unsignedIntegerValue]); - self.searchIsActive = state != MWMSearchManagerStateHidden; + auto const navigationState = [MWMNavigationDashboardManager manager].state; + if (navigationState == MWMNavigationDashboardStateHidden) + self.state = MWMBottomMenuStateInactive; + else + self.state = MWMBottomMenuStateHidden; } -- (void)ttsButtonStatusChanged:(NSNotification *)notification +#pragma mark - MWMSearchManagerObserver + +- (void)onSearchManagerStateChanged { - if (![MWMRouter isRoutingActive]) - return; - BOOL const isPedestrianRouting = [MWMRouter type] == MWMRouterTypePedestrian; - MWMButton * ttsButton = self.ttsSoundButton; - ttsButton.hidden = isPedestrianRouting || ![MWMTextToSpeech isTTSEnabled]; - if (!ttsButton.hidden) - ttsButton.selected = [MWMTextToSpeech tts].active; + auto state = [MWMSearchManager manager].state; + self.searchButton.selected = (state != MWMSearchManagerStateHidden); } #pragma mark - UICollectionViewDataSource @@ -320,7 +178,7 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { case MWMBottomMenuViewCellAddPlace: { BOOL const isEnabled = - self.controller.controlsManager.navigationState == MWMNavigationDashboardStateHidden && + [MWMNavigationDashboardManager manager].state == MWMNavigationDashboardStateHidden && GetFramework().CanEditMap(); [cell configureWithImageName:@"ic_add_place" label:L(@"placepage_add_place_button") @@ -386,7 +244,7 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { - (void)menuActionDownloadMaps { [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatDownloadMaps}]; - self.state = self.restoreState; + self.state = MWMBottomMenuStateInactive; [self.delegate actionDownloadMaps:mwm::DownloaderMode::Downloaded]; } @@ -424,9 +282,7 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { - (IBAction)point2PointButtonTouchUpInside:(UIButton *)sender { [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatPointToPoint}]; - self.state = self.restoreState; BOOL const isSelected = !sender.isSelected; - sender.selected = isSelected; if (isSelected) [[MWMMapViewControlsManager manager] onRoutePrepare]; else @@ -437,16 +293,19 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { { [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatSearch}]; [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"search"]; - self.state = self.restoreState; - self.controller.controlsManager.searchHidden = self.searchIsActive; + self.state = MWMBottomMenuStateInactive; + auto searchManager = [MWMSearchManager manager]; + if (searchManager.state == MWMSearchManagerStateHidden) + searchManager.state = MWMSearchManagerStateDefault; + else + searchManager.state = MWMSearchManagerStateHidden; } - (IBAction)bookmarksButtonTouchUpInside { [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatBookmarks}]; [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"bookmarks"]; - self.state = self.restoreState; - [self.delegate closeInfoScreens]; + self.state = MWMBottomMenuStateInactive; [self.controller openBookmarks]; } @@ -456,161 +315,64 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { { case MWMBottomMenuStateHidden: NSAssert(false, @"Incorrect state"); break; case MWMBottomMenuStateInactive: - case MWMBottomMenuStateGo: - case MWMBottomMenuStateRoutingError: - [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatExpand}]; - self.state = MWMBottomMenuStateActive; + if ([self.menuView isCompact]) + { + [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatRegular}]; + if (IPAD) + { + [MWMSearchManager manager].state = MWMSearchManagerStateHidden; + [MWMRouter stopRouting]; + } + } + else + { + [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatExpand}]; + self.state = MWMBottomMenuStateActive; + } break; case MWMBottomMenuStateActive: - case MWMBottomMenuStateRoutingExpanded: [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatCollapse}]; - self.state = self.restoreState; + self.state = MWMBottomMenuStateInactive; break; - case MWMBottomMenuStateCompact: - [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatRegular}]; - [self.delegate closeInfoScreens]; - break; - case MWMBottomMenuStateRouting: self.state = MWMBottomMenuStateRoutingExpanded; break; } } -- (void)dimBackgroundTap -{ - // In case when there are 2 touch events (dimBackgroundTap & menuButtonTouchUpInside) - // if dimBackgroundTap is processed first then menuButtonTouchUpInside behaves as if menu is - // inactive this is wrong case, so we postpone dimBackgroundTap to make sure - // menuButtonTouchUpInside processed first - dispatch_async(dispatch_get_main_queue(), ^{ - self.state = self.restoreState; - }); -} - -- (void)toggleDimBackgroundVisible:(BOOL)visible -{ - if (visible) - [self.controller.view insertSubview:self.dimBackground belowSubview:self.view]; - self.dimBackground.alpha = visible ? 0.0 : 0.8; - [UIView animateWithDuration:kDefaultAnimationDuration - animations:^{ - self.dimBackground.alpha = visible ? 0.8 : 0.0; - } - completion:^(BOOL finished) { - if (!visible) - { - [self.dimBackground removeFromSuperview]; - self.dimBackground = nil; - } - }]; -} - -- (void)refreshRoutingDiminishTimer -{ - SEL const diminishFunction = @selector(diminishRoutingState); - [NSObject cancelPreviousPerformRequestsWithTarget:self selector:diminishFunction object:self]; - runAsyncOnMainQueue(^{ - if (self.state == MWMBottomMenuStateRoutingExpanded) - [self performSelector:diminishFunction withObject:self afterDelay:kRoutingDiminishInterval]; - }); -} - -- (void)diminishRoutingState { self.state = MWMBottomMenuStateRouting; } #pragma mark - Properties -- (SolidTouchView *)dimBackground +- (MWMBottomMenuView *)menuView { return (MWMBottomMenuView *)self.view; } +- (MWMDimBackground *)dimBackground { if (!_dimBackground) - { - _dimBackground = [[SolidTouchView alloc] initWithFrame:self.controller.view.bounds]; - _dimBackground.backgroundColor = [UIColor fadeBackground]; - _dimBackground.autoresizingMask = - UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - UITapGestureRecognizer * tap = - [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dimBackgroundTap)]; - [_dimBackground addGestureRecognizer:tap]; - } + _dimBackground = [[MWMDimBackground alloc] initWithMainView:self.view]; return _dimBackground; } -- (MWMTaxiCollectionView *)taxiCollectionView -{ - return static_cast(self.view).taxiCollectionView; -} - - (void)setState:(MWMBottomMenuState)state { runAsyncOnMainQueue(^{ [self.controller setNeedsStatusBarAppearanceUpdate]; }); - [self refreshRoutingDiminishTimer]; - MWMBottomMenuView * view = (MWMBottomMenuView *)self.view; - BOOL const menuActive = - (state == MWMBottomMenuStateActive || state == MWMBottomMenuStateRoutingExpanded); + MWMBottomMenuView * view = self.menuView; + BOOL const menuActive = (state == MWMBottomMenuStateActive); if (menuActive) [self.controller.view bringSubviewToFront:view]; - [self toggleDimBackgroundVisible:menuActive]; - if (state == MWMBottomMenuStateRoutingExpanded) - [self ttsButtonStatusChanged:nil]; - - if (state == MWMBottomMenuStateInactive || state == MWMBottomMenuStateRouting) - { - dispatch_async(dispatch_get_main_queue(), ^{ - self.p2pButton.selected = - ([MWMNavigationDashboardManager manager].state == MWMNavigationDashboardStatePrepare); - }); - view.state = self.restoreState = state; - return; - } - if (IPAD && state == MWMBottomMenuStateGo) - return; - if (view.state == MWMBottomMenuStateCompact && - (state == MWMBottomMenuStateGo || state == MWMBottomMenuStateRouting)) - self.restoreState = state; - else - view.state = state; - - if (state == MWMBottomMenuStateRoutingError) - self.estimateLabel.text = self.routingErrorMessage; -} - -- (MWMBottomMenuState)state { return ((MWMBottomMenuView *)self.view).state; } -- (void)setRestoreState:(MWMBottomMenuState)restoreState -{ - ((MWMBottomMenuView *)self.view).restoreState = restoreState; -} - -- (MWMBottomMenuState)restoreState { return ((MWMBottomMenuView *)self.view).restoreState; } -- (void)setLeftBound:(CGFloat)leftBound -{ - ((MWMBottomMenuView *)self.view).leftBound = leftBound; -} - -- (CGFloat)leftBound { return ((MWMBottomMenuView *)self.view).leftBound; } -- (void)setSearchIsActive:(BOOL)searchIsActive -{ - ((MWMBottomMenuView *)self.view).searchIsActive = searchIsActive; -} - -- (BOOL)searchIsActive { return ((MWMBottomMenuView *)self.view).searchIsActive; } -- (void)setTtsSoundButton:(MWMButton *)ttsSoundButton -{ - _ttsSoundButton = ttsSoundButton; - [ttsSoundButton setImage:[UIImage imageNamed:@"ic_voice_off"] forState:UIControlStateNormal]; - [ttsSoundButton setImage:[UIImage imageNamed:@"ic_voice_on"] forState:UIControlStateSelected]; - [ttsSoundButton setImage:[UIImage imageNamed:@"ic_voice_on"] - forState:UIControlStateSelected | UIControlStateHighlighted]; - [self ttsButtonStatusChanged:nil]; -} - -- (void)setTrafficButton:(MWMButton *)trafficButton -{ - _trafficButton = trafficButton; - [trafficButton setImage:[UIImage imageNamed:@"ic_setting_traffic_off"] - forState:UIControlStateNormal]; - [trafficButton setImage:[UIImage imageNamed:@"ic_setting_traffic_on"] - forState:UIControlStateSelected]; - [trafficButton setImage:[UIImage imageNamed:@"ic_setting_traffic_on"] - forState:UIControlStateSelected | UIControlStateHighlighted]; + __weak auto wSelf = self; + [self.dimBackground setVisible:menuActive + tapAction:^{ + // In case when there are 2 touch events (dimBackgroundTap & + // menuButtonTouchUpInside) + // if dimBackgroundTap is processed first then menuButtonTouchUpInside + // behaves as if menu is + // inactive this is wrong case, so we postpone dimBackgroundTap to make + // sure + // menuButtonTouchUpInside processed first + dispatch_async(dispatch_get_main_queue(), ^{ + wSelf.state = MWMBottomMenuStateInactive; + }); + }]; + view.state = state; } +- (MWMBottomMenuState)state { return self.menuView.state; } @end diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.xib b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.xib index 426804f243..53d03e2af7 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.xib +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.xib @@ -1,5 +1,5 @@ - + @@ -13,22 +13,8 @@ - - - - - - - - - - - - - - - + @@ -85,293 +71,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -565,54 +164,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -620,15 +178,9 @@ - - - - - - diff --git a/iphone/Maps/UI/Editor/MWMEditorCellType.h b/iphone/Maps/UI/Editor/MWMEditorCellType.h new file mode 100644 index 0000000000..0aa4b82dc3 --- /dev/null +++ b/iphone/Maps/UI/Editor/MWMEditorCellType.h @@ -0,0 +1,29 @@ +typedef NS_ENUM(NSUInteger, MWMEditorCellType) { + MWMEditorCellTypePostcode = feature::Metadata::EType::FMD_COUNT, + MWMEditorCellTypePhoneNumber, + MWMEditorCellTypeWebsite, + MWMEditorCellTypeURL, + MWMEditorCellTypeEmail, + MWMEditorCellTypeOperator, + MWMEditorCellTypeOpenHours, + MWMEditorCellTypeWiFi, + MWMEditorCellTypeCoordinate, + MWMEditorCellTypeBookmark, + MWMEditorCellTypeEditButton, + MWMEditorCellTypeAddBusinessButton, + MWMEditorCellTypeAddPlaceButton, + MWMEditorCellTypeReportButton, + MWMEditorCellTypeCategory, + MWMEditorCellTypeName, + MWMEditorCellTypeAdditionalName, + MWMEditorCellTypeAddAdditionalName, + MWMEditorCellTypeAddAdditionalNamePlaceholder, + MWMEditorCellTypeStreet, + MWMEditorCellTypeBuilding, + MWMEditorCellTypeZipCode, + MWMEditorCellTypeBuildingLevels, + MWMEditorCellTypeCuisine, + MWMEditorCellTypeNote, + MWMEditorCellTypeBookingMore, + MWMEditorCellTypeCount +}; diff --git a/iphone/Maps/UI/Editor/MWMEditorViewController.mm b/iphone/Maps/UI/Editor/MWMEditorViewController.mm index c471a7541c..4f35b15097 100644 --- a/iphone/Maps/UI/Editor/MWMEditorViewController.mm +++ b/iphone/Maps/UI/Editor/MWMEditorViewController.mm @@ -9,6 +9,7 @@ #import "MWMEditorAdditionalNamesHeader.h" #import "MWMEditorAdditionalNamesTableViewController.h" #import "MWMEditorCategoryCell.h" +#import "MWMEditorCellType.h" #import "MWMEditorCommon.h" #import "MWMEditorNotesFooter.h" #import "MWMEditorSelectTableViewCell.h" @@ -17,7 +18,6 @@ #import "MWMNoteCell.h" #import "MWMObjectsCategorySelectorController.h" #import "MWMOpeningHoursEditorViewController.h" -#import "MWMPlacePageEntity.h" #import "MWMPlacePageOpeningHoursCell.h" #import "MWMStreetEditorViewController.h" #import "MapViewController.h" @@ -25,6 +25,10 @@ #import "SwiftBridge.h" #import "UIViewController+Navigation.h" +#include "Framework.h" + +#include "indexer/osm_editor.hpp" + #include "std/algorithm.hpp" namespace @@ -49,35 +53,35 @@ typedef NS_ENUM(NSUInteger, MWMEditorSection) { MWMEditorSectionButton }; -vector const kSectionCategoryCellTypes{MWMPlacePageCellTypeCategory}; -vector const kSectionAddressCellTypes{ - MWMPlacePageCellTypeStreet, MWMPlacePageCellTypeBuilding, MWMPlacePageCellTypeZipCode}; +vector const kSectionCategoryCellTypes{MWMEditorCellTypeCategory}; +vector const kSectionAddressCellTypes{ + MWMEditorCellTypeStreet, MWMEditorCellTypeBuilding, MWMEditorCellTypeZipCode}; -vector const kSectionNoteCellTypes{MWMPlacePageCellTypeNote}; -vector const kSectionButtonCellTypes{MWMPlacePageCellTypeReportButton}; +vector const kSectionNoteCellTypes{MWMEditorCellTypeNote}; +vector const kSectionButtonCellTypes{MWMEditorCellTypeReportButton}; -using MWMPlacePageCellTypeClassMap = map; -MWMPlacePageCellTypeClassMap const kCellType2Class{ - {MWMPlacePageCellTypeCategory, [MWMEditorCategoryCell class]}, - {MWMPlacePageCellTypeAdditionalName, [MWMEditorAdditionalNameTableViewCell class]}, - {MWMPlacePageCellTypeAddAdditionalName, [MWMEditorAddAdditionalNameTableViewCell class]}, - {MWMPlacePageCellTypeAddAdditionalNamePlaceholder, +using MWMEditorCellTypeClassMap = map; +MWMEditorCellTypeClassMap const kCellType2Class{ + {MWMEditorCellTypeCategory, [MWMEditorCategoryCell class]}, + {MWMEditorCellTypeAdditionalName, [MWMEditorAdditionalNameTableViewCell class]}, + {MWMEditorCellTypeAddAdditionalName, [MWMEditorAddAdditionalNameTableViewCell class]}, + {MWMEditorCellTypeAddAdditionalNamePlaceholder, [MWMEditorAdditionalNamePlaceholderTableViewCell class]}, - {MWMPlacePageCellTypeStreet, [MWMEditorSelectTableViewCell class]}, - {MWMPlacePageCellTypeBuilding, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeZipCode, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeBuildingLevels, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeOpenHours, [MWMPlacePageOpeningHoursCell class]}, - {MWMPlacePageCellTypePhoneNumber, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeWebsite, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeEmail, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeOperator, [MWMEditorTextTableViewCell class]}, - {MWMPlacePageCellTypeCuisine, [MWMEditorSelectTableViewCell class]}, - {MWMPlacePageCellTypeWiFi, [MWMEditorSwitchTableViewCell class]}, - {MWMPlacePageCellTypeNote, [MWMNoteCell class]}, - {MWMPlacePageCellTypeReportButton, [MWMButtonCell class]}}; + {MWMEditorCellTypeStreet, [MWMEditorSelectTableViewCell class]}, + {MWMEditorCellTypeBuilding, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeZipCode, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeBuildingLevels, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeOpenHours, [MWMPlacePageOpeningHoursCell class]}, + {MWMEditorCellTypePhoneNumber, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeWebsite, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeEmail, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeOperator, [MWMEditorTextTableViewCell class]}, + {MWMEditorCellTypeCuisine, [MWMEditorSelectTableViewCell class]}, + {MWMEditorCellTypeWiFi, [MWMEditorSwitchTableViewCell class]}, + {MWMEditorCellTypeNote, [MWMNoteCell class]}, + {MWMEditorCellTypeReportButton, [MWMButtonCell class]}}; -Class cellClass(MWMPlacePageCellType cellType) +Class cellClass(MWMEditorCellType cellType) { auto const it = kCellType2Class.find(cellType); ASSERT(it != kCellType2Class.end(), ()); @@ -98,45 +102,45 @@ void cleanupAdditionalLanguages(vector const & names, newAdditionalLanguages.end()); } -vector cellsForAdditionalNames( - osm::NamesDataSource const & ds, vector const & newAdditionalLanguages, - BOOL showAdditionalNames) +vector cellsForAdditionalNames(osm::NamesDataSource const & ds, + vector const & newAdditionalLanguages, + BOOL showAdditionalNames) { - vector res; + vector res; auto const allNamesSize = ds.names.size() + newAdditionalLanguages.size(); if (allNamesSize != 0) { if (showAdditionalNames) { - res.insert(res.begin(), allNamesSize, MWMPlacePageCellTypeAdditionalName); + res.insert(res.begin(), allNamesSize, MWMEditorCellTypeAdditionalName); } else { auto const mandatoryNamesCount = ds.mandatoryNamesCount; - res.insert(res.begin(), mandatoryNamesCount, MWMPlacePageCellTypeAdditionalName); + res.insert(res.begin(), mandatoryNamesCount, MWMEditorCellTypeAdditionalName); if (allNamesSize > mandatoryNamesCount) - res.push_back(MWMPlacePageCellTypeAddAdditionalNamePlaceholder); + res.push_back(MWMEditorCellTypeAddAdditionalNamePlaceholder); } } - res.push_back(MWMPlacePageCellTypeAddAdditionalName); + res.push_back(MWMEditorCellTypeAddAdditionalName); return res; } -vector cellsForProperties(vector const & props) +vector cellsForProperties(vector const & props) { using namespace osm; - vector res; + vector res; for (auto const p : props) { switch (p) { - case Props::OpeningHours: res.push_back(MWMPlacePageCellTypeOpenHours); break; - case Props::Phone: res.push_back(MWMPlacePageCellTypePhoneNumber); break; - case Props::Website: res.push_back(MWMPlacePageCellTypeWebsite); break; - case Props::Email: res.push_back(MWMPlacePageCellTypeEmail); break; - case Props::Cuisine: res.push_back(MWMPlacePageCellTypeCuisine); break; - case Props::Operator: res.push_back(MWMPlacePageCellTypeOperator); break; - case Props::Internet: res.push_back(MWMPlacePageCellTypeWiFi); break; + case Props::OpeningHours: res.push_back(MWMEditorCellTypeOpenHours); break; + case Props::Phone: res.push_back(MWMEditorCellTypePhoneNumber); break; + case Props::Website: res.push_back(MWMEditorCellTypeWebsite); break; + case Props::Email: res.push_back(MWMEditorCellTypeEmail); break; + case Props::Cuisine: res.push_back(MWMEditorCellTypeCuisine); break; + case Props::Operator: res.push_back(MWMEditorCellTypeOperator); break; + case Props::Internet: res.push_back(MWMEditorCellTypeWiFi); break; case Props::Wikipedia: case Props::Fax: case Props::Stars: @@ -148,7 +152,7 @@ vector cellsForProperties(vector const & props return res; } -void registerCellsForTableView(vector const & cells, UITableView * tv) +void registerCellsForTableView(vector const & cells, UITableView * tv) { for (auto const c : cells) [tv registerWithCellClass:cellClass(c)]; @@ -176,7 +180,7 @@ void registerCellsForTableView(vector const & cells, UITab @implementation MWMEditorViewController { vector m_sections; - map> m_cells; + map> m_cells; osm::EditableMapObject m_mapObject; vector m_newAdditionalLanguages; } @@ -411,7 +415,7 @@ void registerCellsForTableView(vector const & cells, UITab m_sections.push_back(MWMEditorSectionAddress); m_cells[MWMEditorSectionAddress] = kSectionAddressCellTypes; if (m_mapObject.IsBuilding() && !m_mapObject.IsPointType()) - m_cells[MWMEditorSectionAddress].push_back(MWMPlacePageCellTypeBuildingLevels); + m_cells[MWMEditorSectionAddress].push_back(MWMEditorCellTypeBuildingLevels); registerCellsForTableView(kSectionAddressCellTypes, self.tableView); } @@ -441,7 +445,7 @@ void registerCellsForTableView(vector const & cells, UITab registerCellsForTableView(kSectionButtonCellTypes, self.tableView); } -- (MWMPlacePageCellType)cellTypeForIndexPath:(NSIndexPath *)indexPath +- (MWMEditorCellType)cellTypeForIndexPath:(NSIndexPath *)indexPath { return m_cells[m_sections[indexPath.section]][indexPath.row]; } @@ -458,7 +462,7 @@ void registerCellsForTableView(vector const & cells, UITab BOOL const isValid = ![self.invalidCells containsObject:indexPath]; switch ([self cellTypeForIndexPath:indexPath]) { - case MWMPlacePageCellTypeCategory: + case MWMEditorCellTypeCategory: { MWMEditorCategoryCell * cCell = static_cast(cell); [cCell configureWithDelegate:self @@ -466,7 +470,7 @@ void registerCellsForTableView(vector const & cells, UITab isCreating:self.isCreating]; break; } - case MWMPlacePageCellTypePhoneNumber: + case MWMEditorCellTypePhoneNumber: { MWMEditorTextTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -479,7 +483,7 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeNone]; break; } - case MWMPlacePageCellTypeWebsite: + case MWMEditorCellTypeWebsite: { MWMEditorTextTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -492,7 +496,7 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeNone]; break; } - case MWMPlacePageCellTypeEmail: + case MWMEditorCellTypeEmail: { MWMEditorTextTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -505,7 +509,7 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeNone]; break; } - case MWMPlacePageCellTypeOperator: + case MWMEditorCellTypeOperator: { MWMEditorTextTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -516,14 +520,14 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeSentences]; break; } - case MWMPlacePageCellTypeOpenHours: + case MWMEditorCellTypeOpenHours: { MWMPlacePageOpeningHoursCell * tCell = static_cast(cell); NSString * text = @(m_mapObject.GetOpeningHours().c_str()); [tCell configWithDelegate:self info:(text.length ? text : L(@"add_opening_hours"))]; break; } - case MWMPlacePageCellTypeWiFi: + case MWMEditorCellTypeWiFi: { MWMEditorSwitchTableViewCell * tCell = static_cast(cell); // TODO(Vlad, IgorTomko): Support all other possible Internet statuses. @@ -533,7 +537,7 @@ void registerCellsForTableView(vector const & cells, UITab on:m_mapObject.GetInternet() == osm::Internet::Wlan]; break; } - case MWMPlacePageCellTypeAdditionalName: + case MWMEditorCellTypeAdditionalName: { MWMEditorAdditionalNameTableViewCell * tCell = static_cast(cell); @@ -574,15 +578,15 @@ void registerCellsForTableView(vector const & cells, UITab } break; } - case MWMPlacePageCellTypeAddAdditionalName: + case MWMEditorCellTypeAddAdditionalName: { MWMEditorAddAdditionalNameTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self]; break; } - case MWMPlacePageCellTypeAddAdditionalNamePlaceholder: break; - case MWMPlacePageCellTypeStreet: + case MWMEditorCellTypeAddAdditionalNamePlaceholder: break; + case MWMEditorCellTypeStreet: { MWMEditorSelectTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -591,7 +595,7 @@ void registerCellsForTableView(vector const & cells, UITab placeholder:L(@"add_street")]; break; } - case MWMPlacePageCellTypeBuilding: + case MWMEditorCellTypeBuilding: { MWMEditorTextTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -604,7 +608,7 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeNone]; break; } - case MWMPlacePageCellTypeZipCode: + case MWMEditorCellTypeZipCode: { MWMEditorTextTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -617,7 +621,7 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeAllCharacters]; break; } - case MWMPlacePageCellTypeBuildingLevels: + case MWMEditorCellTypeBuildingLevels: { NSString * placeholder = [NSString stringWithFormat:L(@"editor_storey_number"), @@ -636,7 +640,7 @@ void registerCellsForTableView(vector const & cells, UITab capitalization:UITextAutocapitalizationTypeNone]; break; } - case MWMPlacePageCellTypeCuisine: + case MWMEditorCellTypeCuisine: { MWMEditorSelectTableViewCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -645,7 +649,7 @@ void registerCellsForTableView(vector const & cells, UITab placeholder:L(@"select_cuisine")]; break; } - case MWMPlacePageCellTypeNote: + case MWMEditorCellTypeNote: { MWMNoteCell * tCell = static_cast(cell); [tCell configWithDelegate:self @@ -653,7 +657,7 @@ void registerCellsForTableView(vector const & cells, UITab placeholder:L(@"editor_detailed_description_hint")]; break; } - case MWMPlacePageCellTypeReportButton: + case MWMEditorCellTypeReportButton: { MWMButtonCell * tCell = static_cast(cell); @@ -710,13 +714,13 @@ void registerCellsForTableView(vector const & cells, UITab Class cls = [self cellClassForIndexPath:indexPath]; auto cell = [self offscreenCellForClass:cls]; [self fillCell:cell atIndexPath:indexPath]; - MWMPlacePageCellType const cellType = [self cellTypeForIndexPath:indexPath]; + MWMEditorCellType const cellType = [self cellTypeForIndexPath:indexPath]; switch (cellType) { - case MWMPlacePageCellTypeOpenHours: return ((MWMPlacePageOpeningHoursCell *)cell).cellHeight; - case MWMPlacePageCellTypeCategory: - case MWMPlacePageCellTypeReportButton: return self.tableView.rowHeight; - case MWMPlacePageCellTypeNote: return static_cast(cell).cellHeight; + case MWMEditorCellTypeOpenHours: return ((MWMPlacePageOpeningHoursCell *)cell).cellHeight; + case MWMEditorCellTypeCategory: + case MWMEditorCellTypeReportButton: return self.tableView.rowHeight; + case MWMEditorCellTypeNote: return static_cast(cell).cellHeight; default: { [cell setNeedsUpdateConstraints]; @@ -819,7 +823,7 @@ void registerCellsForTableView(vector const & cells, UITab - (void)cellShouldChangeSize:(MWMNoteCell *)cell text:(NSString *)text { - self.offscreenCells[cellClass(MWMPlacePageCellTypeNote)] = cell; + self.offscreenCells[cellClass(MWMEditorCellTypeNote)] = cell; self.note = text; [self.tableView refresh]; NSIndexPath * ip = [self.tableView indexPathForCell:cell]; @@ -868,42 +872,42 @@ void registerCellsForTableView(vector const & cells, UITab { NSAssert(changeText != nil, @"String can't be nil!"); NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint:cell.center]; - MWMPlacePageCellType const cellType = [self cellTypeForIndexPath:indexPath]; + MWMEditorCellType const cellType = [self cellTypeForIndexPath:indexPath]; string const val = changeText.UTF8String; switch (cellType) { - case MWMPlacePageCellTypePhoneNumber: + case MWMEditorCellTypePhoneNumber: m_mapObject.SetPhone(val); if (!osm::EditableMapObject::ValidatePhone(val)) [self markCellAsInvalid:indexPath]; break; - case MWMPlacePageCellTypeWebsite: + case MWMEditorCellTypeWebsite: m_mapObject.SetWebsite(val); if (!osm::EditableMapObject::ValidateWebsite(val)) [self markCellAsInvalid:indexPath]; break; - case MWMPlacePageCellTypeEmail: + case MWMEditorCellTypeEmail: m_mapObject.SetEmail(val); if (!osm::EditableMapObject::ValidateEmail(val)) [self markCellAsInvalid:indexPath]; break; - case MWMPlacePageCellTypeOperator: m_mapObject.SetOperator(val); break; - case MWMPlacePageCellTypeBuilding: + case MWMEditorCellTypeOperator: m_mapObject.SetOperator(val); break; + case MWMEditorCellTypeBuilding: m_mapObject.SetHouseNumber(val); if (!osm::EditableMapObject::ValidateHouseNumber(val)) [self markCellAsInvalid:indexPath]; break; - case MWMPlacePageCellTypeZipCode: + case MWMEditorCellTypeZipCode: m_mapObject.SetPostcode(val); if (!osm::EditableMapObject::ValidatePostCode(val)) [self markCellAsInvalid:indexPath]; break; - case MWMPlacePageCellTypeBuildingLevels: + case MWMEditorCellTypeBuildingLevels: m_mapObject.SetBuildingLevels(val); if (!osm::EditableMapObject::ValidateBuildingLevels(val)) [self markCellAsInvalid:indexPath]; break; - case MWMPlacePageCellTypeAdditionalName: + case MWMEditorCellTypeAdditionalName: { MWMEditorAdditionalNameTableViewCell * tCell = static_cast(cell); @@ -917,10 +921,10 @@ void registerCellsForTableView(vector const & cells, UITab - (void)cell:(UITableViewCell *)cell changeSwitch:(BOOL)changeSwitch { NSIndexPath * indexPath = [self.tableView indexPathForCell:cell]; - MWMPlacePageCellType const cellType = [self cellTypeForIndexPath:indexPath]; + MWMEditorCellType const cellType = [self cellTypeForIndexPath:indexPath]; switch (cellType) { - case MWMPlacePageCellTypeWiFi: + case MWMEditorCellTypeWiFi: m_mapObject.SetInternet(changeSwitch ? osm::Internet::Wlan : osm::Internet::Unknown); break; default: NSAssert(false, @"Invalid field for changeSwitch"); break; @@ -932,19 +936,19 @@ void registerCellsForTableView(vector const & cells, UITab - (void)cellSelect:(UITableViewCell *)cell { NSIndexPath * indexPath = [self.tableView indexPathForCell:cell]; - MWMPlacePageCellType const cellType = [self cellTypeForIndexPath:indexPath]; + MWMEditorCellType const cellType = [self cellTypeForIndexPath:indexPath]; switch (cellType) { - case MWMPlacePageCellTypeStreet: + case MWMEditorCellTypeStreet: [self performSegueWithIdentifier:kStreetEditorSegue sender:nil]; break; - case MWMPlacePageCellTypeCuisine: + case MWMEditorCellTypeCuisine: [self performSegueWithIdentifier:kCuisineEditorSegue sender:nil]; break; - case MWMPlacePageCellTypeCategory: + case MWMEditorCellTypeCategory: [self performSegueWithIdentifier:kCategoryEditorSegue sender:nil]; break; - case MWMPlacePageCellTypeReportButton: [self tapOnButtonCell:cell]; break; + case MWMEditorCellTypeReportButton: [self tapOnButtonCell:cell]; break; default: NSAssert(false, @"Invalid field for cellSelect"); break; } } diff --git a/iphone/Maps/UI/PlacePage/Deprecated/MWMPlacePageEntity.h b/iphone/Maps/UI/PlacePage/Deprecated/MWMPlacePageEntity.h deleted file mode 100644 index 4842de29e6..0000000000 --- a/iphone/Maps/UI/PlacePage/Deprecated/MWMPlacePageEntity.h +++ /dev/null @@ -1,84 +0,0 @@ -#include "Framework.h" - -#include "indexer/feature_meta.hpp" - -#include "storage/index.hpp" - -typedef NS_ENUM(NSUInteger, MWMPlacePageCellType) -{ - MWMPlacePageCellTypePostcode = feature::Metadata::EType::FMD_COUNT, - MWMPlacePageCellTypePhoneNumber, - MWMPlacePageCellTypeWebsite, - MWMPlacePageCellTypeURL, - MWMPlacePageCellTypeEmail, - MWMPlacePageCellTypeOperator, - MWMPlacePageCellTypeOpenHours, - MWMPlacePageCellTypeWiFi, - MWMPlacePageCellTypeCoordinate, - MWMPlacePageCellTypeBookmark, - MWMPlacePageCellTypeEditButton, - MWMPlacePageCellTypeAddBusinessButton, - MWMPlacePageCellTypeAddPlaceButton, - MWMPlacePageCellTypeReportButton, - MWMPlacePageCellTypeCategory, - MWMPlacePageCellTypeName, - MWMPlacePageCellTypeAdditionalName, - MWMPlacePageCellTypeAddAdditionalName, - MWMPlacePageCellTypeAddAdditionalNamePlaceholder, - MWMPlacePageCellTypeStreet, - MWMPlacePageCellTypeBuilding, - MWMPlacePageCellTypeZipCode, - MWMPlacePageCellTypeBuildingLevels, - MWMPlacePageCellTypeCuisine, - MWMPlacePageCellTypeNote, - MWMPlacePageCellTypeBookingMore, - MWMPlacePageCellTypeCount -}; - -using MWMPlacePageCellTypeValueMap = map; - -@class MWMPlacePageViewManager; - -@interface MWMPlacePageEntity : NSObject - -@property (copy, nonatomic) NSString * title; -@property (copy, nonatomic) NSString * subtitle; -@property (copy, nonatomic) NSString * address; -@property (copy, nonatomic) NSString * bookmarkTitle; -@property (copy, nonatomic) NSString * bookmarkCategory; -@property (copy, nonatomic) NSString * bookmarkDescription; -@property (nonatomic, readonly) BOOL isHTMLDescription; -@property (copy, nonatomic) NSString * bookmarkColor; -@property (copy, nonatomic) NSString * bookingRating; -@property (copy, nonatomic) NSString * bookingPrice; -@property (copy, nonatomic) NSString * bookingOnlinePrice; - -@property (nonatomic) BookmarkAndCategory bac; -@property (weak, nonatomic) MWMPlacePageViewManager * manager; - -- (FeatureID const &)featureID; -- (BOOL)isMyPosition; -- (BOOL)isBookmark; -- (BOOL)isApi; -- (BOOL)isBooking; -- (BOOL)isOpentable; -- (ms::LatLon)latLon; -- (m2::PointD const &)mercator; -- (NSString *)apiURL; -- (NSURL *)sponsoredURL; -- (NSURL *)sponsoredDescriptionURL; -- (NSString *)sponsoredId; -- (NSString *)phoneNumber; -- (string)titleForNewBookmark; - -- (instancetype)initWithInfo:(place_page::Info const &)info; -- (void)synchronize; -- (void)onlinePricingWithCompletionBlock:(MWMVoidBlock)completion failure:(MWMVoidBlock)failure; - -- (void)toggleCoordinateSystem; - -- (NSString *)getCellValue:(MWMPlacePageCellType)cellType; -- (place_page::Info const &)info; -- (storage::TCountryId const &)countryId; - -@end diff --git a/iphone/Maps/UI/PlacePage/Deprecated/MWMPlacePageEntity.mm b/iphone/Maps/UI/PlacePage/Deprecated/MWMPlacePageEntity.mm deleted file mode 100644 index 6a724b048a..0000000000 --- a/iphone/Maps/UI/PlacePage/Deprecated/MWMPlacePageEntity.mm +++ /dev/null @@ -1,330 +0,0 @@ -#import "MWMPlacePageEntity.h" -#import "MWMMapViewControlsManager.h" -#import "MWMNetworkPolicy.h" -#import "MapViewController.h" -#import "MapsAppDelegate.h" - -#include "Framework.h" - -#include "indexer/osm_editor.hpp" - -#include "platform/measurement_utils.hpp" -#include "platform/mwm_version.hpp" -#include "platform/platform.hpp" - -using feature::Metadata; - -static NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS"; - -namespace -{ -NSUInteger gMetaFieldsMap[MWMPlacePageCellTypeCount] = {}; - -void putFields(NSUInteger eTypeValue, NSUInteger ppValue) -{ - gMetaFieldsMap[eTypeValue] = ppValue; - gMetaFieldsMap[ppValue] = eTypeValue; -} - -void initFieldsMap() -{ - putFields(Metadata::FMD_URL, MWMPlacePageCellTypeURL); - putFields(Metadata::FMD_WEBSITE, MWMPlacePageCellTypeWebsite); - putFields(Metadata::FMD_PHONE_NUMBER, MWMPlacePageCellTypePhoneNumber); - putFields(Metadata::FMD_OPEN_HOURS, MWMPlacePageCellTypeOpenHours); - putFields(Metadata::FMD_EMAIL, MWMPlacePageCellTypeEmail); - putFields(Metadata::FMD_POSTCODE, MWMPlacePageCellTypePostcode); - putFields(Metadata::FMD_INTERNET, MWMPlacePageCellTypeWiFi); - putFields(Metadata::FMD_CUISINE, MWMPlacePageCellTypeCuisine); - - ASSERT_EQUAL(gMetaFieldsMap[Metadata::FMD_URL], MWMPlacePageCellTypeURL, ()); - ASSERT_EQUAL(gMetaFieldsMap[MWMPlacePageCellTypeURL], Metadata::FMD_URL, ()); - ASSERT_EQUAL(gMetaFieldsMap[Metadata::FMD_WEBSITE], MWMPlacePageCellTypeWebsite, ()); - ASSERT_EQUAL(gMetaFieldsMap[MWMPlacePageCellTypeWebsite], Metadata::FMD_WEBSITE, ()); - ASSERT_EQUAL(gMetaFieldsMap[Metadata::FMD_POSTCODE], MWMPlacePageCellTypePostcode, ()); - ASSERT_EQUAL(gMetaFieldsMap[MWMPlacePageCellTypePostcode], Metadata::FMD_POSTCODE, ()); - ASSERT_EQUAL(gMetaFieldsMap[Metadata::FMD_MAXSPEED], 0, ()); -} -} // namespace - -@implementation MWMPlacePageEntity -{ - MWMPlacePageCellTypeValueMap m_values; - place_page::Info m_info; -} - -- (instancetype)initWithInfo:(const place_page::Info &)info -{ - self = [super init]; - if (self) - { - m_info = info; - initFieldsMap(); - [self config]; - } - return self; -} - -- (void)config -{ - [self configureDefault]; - - if (m_info.IsFeature()) - [self configureFeature]; - if (m_info.IsBookmark()) - [self configureBookmark]; -} - -- (void)setMetaField:(NSUInteger)key value:(string const &)value -{ - NSAssert(key >= Metadata::FMD_COUNT, @"Incorrect enum value"); - MWMPlacePageCellType const cellType = static_cast(key); - if (value.empty()) - m_values.erase(cellType); - else - m_values[cellType] = value; -} - -- (void)configureDefault -{ - self.title = @(m_info.GetTitle().c_str()); - self.address = @(m_info.GetAddress().c_str()); - self.subtitle = @(m_info.GetSubtitle().c_str()); - self.bookingRating = @(m_info.GetRatingFormatted().c_str()); - self.bookingPrice = @(m_info.GetApproximatePricing().c_str()); -} - -- (void)configureFeature -{ - // Category can also be custom-formatted, please check m_info getters. - // TODO(Vlad): Refactor using osm::Props instead of direct Metadata access. - feature::Metadata const & md = m_info.GetMetadata(); - auto const types = md.GetPresentTypes(); - for (auto const type : types) - { - switch (type) - { - case Metadata::FMD_URL: - case Metadata::FMD_WEBSITE: - case Metadata::FMD_PHONE_NUMBER: - case Metadata::FMD_OPEN_HOURS: - case Metadata::FMD_EMAIL: - case Metadata::FMD_POSTCODE: [self setMetaField:gMetaFieldsMap[type] value:md.Get(type)]; break; - case Metadata::FMD_INTERNET: - [self setMetaField:gMetaFieldsMap[type] value:L(@"WiFi_available").UTF8String]; - break; - default: break; - } - } -} - -- (void)onlinePricingWithCompletionBlock:(MWMVoidBlock)completion failure:(MWMVoidBlock)failure -{ - if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE || !self.isBooking) - { - failure(); - return; - } - - NSNumberFormatter * currencyFormatter = [[NSNumberFormatter alloc] init]; - if (currencyFormatter.currencyCode.length != 3) - currencyFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle; - currencyFormatter.maximumFractionDigits = 0; - string const currency = currencyFormatter.currencyCode.UTF8String; - network_policy::CallPartnersApi([self, completion, failure, currency, currencyFormatter]( - platform::NetworkPolicy const & canUseNetwork) { - auto const api = GetFramework().GetBookingApi(canUseNetwork); - if (!api) - { - failure(); - return; - } - auto success = [self, completion, failure, currency, currencyFormatter]( - string const & hotelId, string const & minPrice, string const & priceCurrency) { - if (currency != priceCurrency) - { - failure(); - return; - } - NSNumberFormatter * decimalFormatter = [[NSNumberFormatter alloc] init]; - decimalFormatter.numberStyle = NSNumberFormatterDecimalStyle; - NSNumber * currencyNumber = [decimalFormatter - numberFromString:[@(minPrice.c_str()) - stringByReplacingOccurrencesOfString:@"." - withString:decimalFormatter - .decimalSeparator]]; - NSString * currencyString = [currencyFormatter stringFromNumber:currencyNumber]; - NSString * currencyPattern = - [L(@"place_page_starting_from") stringByReplacingOccurrencesOfString:@"%s" - withString:@"%@"]; - self.bookingOnlinePrice = [NSString stringWithFormat:currencyPattern, currencyString]; - completion(); - }; - api->GetMinPrice(m_info.GetMetadata().Get(Metadata::FMD_SPONSORED_ID), currency, success); - }); -} - -- (void)configureBookmark -{ - auto const bac = m_info.GetBookmarkAndCategory(); - BookmarkCategory * cat = GetFramework().GetBmCategory(bac.m_categoryIndex); - BookmarkData const & data = - static_cast(cat->GetUserMark(bac.m_bookmarkIndex))->GetData(); - - self.bookmarkTitle = @(data.GetName().c_str()); - self.bookmarkCategory = @(m_info.GetBookmarkCategoryName().c_str()); - string const & description = data.GetDescription(); - self.bookmarkDescription = @(description.c_str()); - _isHTMLDescription = strings::IsHTML(description); - self.bookmarkColor = @(data.GetType().c_str()); -} - -- (void)toggleCoordinateSystem -{ - NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; - [ud setBool:![ud boolForKey:kUserDefaultsLatLonAsDMSKey] forKey:kUserDefaultsLatLonAsDMSKey]; - [ud synchronize]; -} - -#pragma mark - Getters - -- (NSString *)getCellValue:(MWMPlacePageCellType)cellType -{ - auto const s = [MapViewController controller].controlsManager.navigationState; - BOOL const navigationIsHidden = s == MWMNavigationDashboardStateHidden; - switch (cellType) - { - case MWMPlacePageCellTypeName: return self.title; - case MWMPlacePageCellTypeCoordinate: return [self coordinate]; - case MWMPlacePageCellTypeAddPlaceButton: - return navigationIsHidden && m_info.ShouldShowAddPlace() ? @"" : nil; - case MWMPlacePageCellTypeBookmark: return m_info.IsBookmark() ? @"" : nil; - case MWMPlacePageCellTypeEditButton: - // TODO(Vlad): It's a really strange way to "display" cell if returned text is not nil. - return navigationIsHidden && m_info.ShouldShowEditPlace() ? @"" : nil; - case MWMPlacePageCellTypeAddBusinessButton: - return navigationIsHidden && m_info.ShouldShowAddBusiness() ? @"" : nil; - case MWMPlacePageCellTypeWebsite: - return self.isBooking ? nil : [self getDefaultField:cellType]; - case MWMPlacePageCellTypeBookingMore: - return self.isBooking ? @(m_info.GetSponsoredDescriptionUrl().c_str()) : nil; - default: return [self getDefaultField:cellType]; - } -} - -- (NSString *)getDefaultField:(MWMPlacePageCellType)cellType -{ - auto const it = m_values.find(cellType); - BOOL const haveField = (it != m_values.end()); - return haveField ? @(it->second.c_str()) : nil; -} - -- (NSURL *)sponsoredURL { return [self sponsoredUrl:NO]; } -- (NSURL *)sponsoredDescriptionURL { return [self sponsoredUrl:YES]; } -- (NSURL *)sponsoredUrl:(BOOL)isDescription -{ - auto const & url = - isDescription ? m_info.GetSponsoredDescriptionUrl() : m_info.GetSponsoredUrl(); - return url.empty() ? nil : [NSURL URLWithString:@(url.c_str())]; -} - -- (place_page::Info const &)info { return m_info; } -- (FeatureID const &)featureID { return m_info.GetID(); } -- (storage::TCountryId const &)countryId { return m_info.GetCountryId(); } -- (BOOL)isMyPosition { return m_info.IsMyPosition(); } -- (BOOL)isBookmark { return m_info.IsBookmark(); } -- (BOOL)isApi { return m_info.HasApiUrl(); } -- (BOOL)isBooking { return m_info.GetSponsoredType() == place_page::SponsoredType::Booking; } -- (BOOL)isOpentable { return m_info.GetSponsoredType() == place_page::SponsoredType::Opentable; } -- (BOOL)isSponsored { return m_info.IsSponsored(); } -- (NSString *)sponsoredId -{ - return self.isSponsored ? @(m_info.GetMetadata().Get(Metadata::FMD_SPONSORED_ID).c_str()) : nil; -} - -- (NSString *)phoneNumber { return [self getCellValue:MWMPlacePageCellTypePhoneNumber]; } -- (ms::LatLon)latLon { return m_info.GetLatLon(); } -- (m2::PointD const &)mercator { return m_info.GetMercator(); } -- (NSString *)apiURL { return @(m_info.GetApiUrl().c_str()); } -- (string)titleForNewBookmark { return m_info.FormatNewBookmarkName(); } -- (NSString *)coordinate -{ - BOOL const useDMSFormat = - [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultsLatLonAsDMSKey]; - ms::LatLon const & latlon = self.latLon; - return @((useDMSFormat ? measurement_utils::FormatLatLon(latlon.lat, latlon.lon) - : measurement_utils::FormatLatLonAsDMS(latlon.lat, latlon.lon, 2)) - .c_str()); -} - -#pragma mark - Bookmark editing - -- (void)setBac:(BookmarkAndCategory)bac { m_info.SetBac(bac); } -- (BookmarkAndCategory)bac { return m_info.GetBookmarkAndCategory(); } -- (NSString *)bookmarkCategory -{ - if (!_bookmarkCategory) - { - Framework & f = GetFramework(); - BookmarkCategory * category = f.GetBmCategory(f.LastEditedBMCategory()); - _bookmarkCategory = @(category->GetName().c_str()); - } - return _bookmarkCategory; -} - -- (NSString *)bookmarkDescription -{ - if (!_bookmarkDescription) - _bookmarkDescription = @""; - return _bookmarkDescription; -} - -- (NSString *)bookmarkColor -{ - if (!_bookmarkColor) - { - Framework & f = GetFramework(); - string type = f.LastEditedBMType(); - _bookmarkColor = @(type.c_str()); - } - return _bookmarkColor; -} - -- (NSString *)bookmarkTitle -{ - if (!_bookmarkTitle) - _bookmarkTitle = self.title; - return _bookmarkTitle; -} - -- (void)synchronize -{ - Framework & f = GetFramework(); - BookmarkCategory * category = f.GetBmCategory(self.bac.m_categoryIndex); - if (!category) - return; - - Bookmark * bookmark = - static_cast(category->GetUserMarkForEdit(self.bac.m_bookmarkIndex)); - if (!bookmark) - return; - - if (self.bookmarkColor) - bookmark->SetType(self.bookmarkColor.UTF8String); - - if (self.bookmarkDescription) - { - string const description(self.bookmarkDescription.UTF8String); - _isHTMLDescription = strings::IsHTML(description); - bookmark->SetDescription(description); - } - - if (self.bookmarkTitle) - bookmark->SetName(self.bookmarkTitle.UTF8String); - - category->SaveToKMLFile(); - category->NotifyChanges(); -} - -@end diff --git a/iphone/Maps/UI/Search/MWMSearchChangeModeView.mm b/iphone/Maps/UI/Search/MWMSearchChangeModeView.mm index e7a038578b..f98c54b353 100644 --- a/iphone/Maps/UI/Search/MWMSearchChangeModeView.mm +++ b/iphone/Maps/UI/Search/MWMSearchChangeModeView.mm @@ -3,7 +3,6 @@ #import "MWMSearch.h" #import "UIButton+RuntimeAttributes.h" -extern NSString * const kSearchStateWillChangeNotification; extern NSString * const kSearchStateKey; @interface MWMSearchChangeModeView () @@ -21,17 +20,12 @@ extern NSString * const kSearchStateKey; - (void)awakeFromNib { [super awakeFromNib]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(searchStateWillChange:) - name:kSearchStateWillChangeNotification - object:nil]; [MWMSearch addObserver:self]; self.changeModeButton.titleLabel.textAlignment = NSTextAlignmentNatural; self.filterButton.titleLabel.textAlignment = NSTextAlignmentNatural; self.filterButtoniPadX.priority = IPAD ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow; } -- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)updateForState:(MWMSearchManagerState)state { UIButton * changeModeButton = self.changeModeButton; @@ -88,13 +82,5 @@ extern NSString * const kSearchStateKey; - (void)onSearchStarted { [self updateFilterButtons:[MWMSearch isHotelResults]]; } - (void)onSearchCompleted { [self updateFilterButtons:[MWMSearch isHotelResults]]; } -#pragma mark - Notifications - -- (void)searchStateWillChange:(NSNotification *)notification -{ - MWMSearchManagerState const state = - MWMSearchManagerState([[notification userInfo][kSearchStateKey] unsignedIntegerValue]); - [self updateForState:state]; -} @end diff --git a/iphone/Maps/UI/Search/MWMSearchManager.h b/iphone/Maps/UI/Search/MWMSearchManager.h index 77b8d5af2c..a902b81c42 100644 --- a/iphone/Maps/UI/Search/MWMSearchManager.h +++ b/iphone/Maps/UI/Search/MWMSearchManager.h @@ -1,10 +1,15 @@ #import "MWMAlertViewController.h" #import "MWMMapDownloaderTypes.h" -#import "MWMSearchTextField.h" +#import "MWMSearchManagerObserver.h" #import "MWMSearchManagerState.h" +#import "MWMSearchTextField.h" @interface MWMSearchManager : NSObject ++ (nonnull MWMSearchManager *)manager; ++ (void)addObserver:(nonnull id)observer; ++ (void)removeObserver:(nonnull id)observer; + @property(nullable, weak, nonatomic) IBOutlet MWMSearchTextField * searchTextField; @property(nonatomic) MWMSearchManagerState state; diff --git a/iphone/Maps/UI/Search/MWMSearchManager.mm b/iphone/Maps/UI/Search/MWMSearchManager.mm index 6e4100503a..72ca7908e3 100644 --- a/iphone/Maps/UI/Search/MWMSearchManager.mm +++ b/iphone/Maps/UI/Search/MWMSearchManager.mm @@ -26,7 +26,6 @@ #include "Framework.h" extern NSString * const kAlohalyticsTapEventKey; -extern NSString * const kSearchStateWillChangeNotification = @"SearchStateWillChangeNotification"; extern NSString * const kSearchStateKey = @"SearchStateKey"; namespace @@ -36,8 +35,17 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { MWMSearchManagerActionBarStateTabBar, MWMSearchManagerActionBarStateModeFilter }; + +using TObserver = id; +using TObservers = NSHashTable<__kindof TObserver>; } // namespace +@interface MWMMapViewControlsManager () + +@property(nonatomic) MWMSearchManager * searchManager; + +@end + @interface MWMSearchManager () @@ -72,10 +80,13 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { @property(nonatomic) MWMSearchFilterTransitioningManager * filterTransitioningManager; +@property(nonatomic) TObservers * observers; + @end @implementation MWMSearchManager ++ (MWMSearchManager *)manager { return [MWMMapViewControlsManager manager].searchManager; } - (nullable instancetype)init { self = [super init]; @@ -84,6 +95,7 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { [NSBundle.mainBundle loadNibNamed:@"MWMSearchView" owner:self options:nil]; self.state = MWMSearchManagerStateHidden; [MWMSearch addObserver:self]; + _observers = [TObservers weakObjectsHashTable]; } return self; } @@ -326,6 +338,26 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { }]; } +#pragma mark - Add/Remove Observers + ++ (void)addObserver:(id)observer +{ + [[MWMSearchManager manager].observers addObject:observer]; +} + ++ (void)removeObserver:(id)observer +{ + [[MWMSearchManager manager].observers removeObject:observer]; +} + +#pragma mark - MWMSearchManagerObserver + +- (void)onSearchManagerStateChanged +{ + for (TObserver observer in self.observers) + [observer onSearchManagerStateChanged]; +} + #pragma mark - Filters - (IBAction)changeMode @@ -410,11 +442,6 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { { if (_state == state) return; - [[NSNotificationCenter defaultCenter] postNotificationName:kSearchStateWillChangeNotification - object:nil - userInfo:@{ - kSearchStateKey : @(state) - }]; if (_state == MWMSearchManagerStateHidden) [self endSearch]; _state = state; @@ -438,7 +465,9 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { [self changeToMapSearchState]; break; } - [[MWMMapViewControlsManager manager] searchViewDidEnterState:state]; + [self onSearchManagerStateChanged]; + [self.changeModeView updateForState:state]; + [[MapViewController controller] updateStatusBarStyle]; } - (void)viewHidden:(BOOL)hidden @@ -448,11 +477,7 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { UIView * contentView = self.contentView; UIView * parentView = self.ownerController.view; - if (hidden) - { - [[MWMMapViewControlsManager manager] searchFrameUpdated:{}]; - } - else + if (!hidden) { if (searchBarView.superview) { @@ -467,7 +492,6 @@ typedef NS_ENUM(NSUInteger, MWMSearchManagerActionBarState) { [self layoutTopViews]; CGRect searchAndStatusBarFrame = self.searchBarView.frame; searchAndStatusBarFrame.size.height += statusBarHeight(); - [[MWMMapViewControlsManager manager] searchFrameUpdated:searchAndStatusBarFrame]; } [UIView animateWithDuration:kDefaultAnimationDuration animations:^{ diff --git a/iphone/Maps/UI/Search/MWMSearchManagerObserver.h b/iphone/Maps/UI/Search/MWMSearchManagerObserver.h new file mode 100644 index 0000000000..e1ef8ab95c --- /dev/null +++ b/iphone/Maps/UI/Search/MWMSearchManagerObserver.h @@ -0,0 +1,5 @@ +@protocol MWMSearchManagerObserver + +- (void)onSearchManagerStateChanged; + +@end diff --git a/iphone/Maps/UI/Search/MWMSearchView.xib b/iphone/Maps/UI/Search/MWMSearchView.xib index cc00af9d19..1ab94adf07 100644 --- a/iphone/Maps/UI/Search/MWMSearchView.xib +++ b/iphone/Maps/UI/Search/MWMSearchView.xib @@ -1,5 +1,5 @@ - + diff --git a/iphone/Maps/UI/Search/SearchBar.swift b/iphone/Maps/UI/Search/SearchBar.swift index 6d6a1ebeb6..8d5a1cd56d 100644 --- a/iphone/Maps/UI/Search/SearchBar.swift +++ b/iphone/Maps/UI/Search/SearchBar.swift @@ -1,6 +1,4 @@ -import UIKit - -class SearchBar: SolidTouchView { +final class SearchBar: SolidTouchView { override var visibleAreaAffectDirections: MWMAvailableAreaAffectDirections { return alternative(iPhone: .top, iPad: .left) } override var placePageAreaAffectDirections: MWMAvailableAreaAffectDirections { return alternative(iPhone: [], iPad: .left) } @@ -8,4 +6,6 @@ class SearchBar: SolidTouchView { override var widgetsAreaAffectDirections: MWMAvailableAreaAffectDirections { return alternative(iPhone: [], iPad: .left) } override var trafficButtonAreaAffectDirections: MWMAvailableAreaAffectDirections { return alternative(iPhone: .top, iPad: .left) } + + override var menuAreaAffectDirections: MWMAvailableAreaAffectDirections { return alternative(iPhone: [], iPad: .left) } } diff --git a/iphone/Maps/UI/Settings/MWMSettingsViewController.mm b/iphone/Maps/UI/Settings/MWMSettingsViewController.mm index e608a99795..c0c02dd508 100644 --- a/iphone/Maps/UI/Settings/MWMSettingsViewController.mm +++ b/iphone/Maps/UI/Settings/MWMSettingsViewController.mm @@ -3,7 +3,7 @@ #import "MWMAuthorizationCommon.h" #import "MWMNetworkPolicy.h" #import "MWMSettings.h" -#import "MWMTextToSpeech.h" +#import "MWMTextToSpeech+CPP.h" #import "Statistics.h" #import "SwiftBridge.h" #import "WebViewController.h" diff --git a/iphone/Maps/UI/Settings/MWMTTSLanguageViewController.mm b/iphone/Maps/UI/Settings/MWMTTSLanguageViewController.mm index dbf3275dcf..46e2e01f71 100644 --- a/iphone/Maps/UI/Settings/MWMTTSLanguageViewController.mm +++ b/iphone/Maps/UI/Settings/MWMTTSLanguageViewController.mm @@ -1,6 +1,6 @@ #import "MWMTTSLanguageViewController.h" #import "MWMTTSSettingsViewController.h" -#import "MWMTextToSpeech.h" +#import "MWMTextToSpeech+CPP.h" #import "SwiftBridge.h" static NSString * const kUnwingSegueIdentifier = @"UnwindToTTSSettings"; diff --git a/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm b/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm index 6cd9c97839..4de4e39b64 100644 --- a/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm +++ b/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm @@ -1,6 +1,6 @@ #import "MWMTTSSettingsViewController.h" #import -#import "MWMTextToSpeech.h" +#import "MWMTextToSpeech+CPP.h" #import "Statistics.h" #import "SwiftBridge.h" #import "WebViewController.h" diff --git a/iphone/Maps/UI/Storyboard/Main.storyboard b/iphone/Maps/UI/Storyboard/Main.storyboard index 3c3badd948..d7df0ceefc 100644 --- a/iphone/Maps/UI/Storyboard/Main.storyboard +++ b/iphone/Maps/UI/Storyboard/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -29,6 +29,14 @@ + +