From 231e5de63ce16b255fa39d99947210476e2f8aba Mon Sep 17 00:00:00 2001 From: Ilya Grechuhin Date: Mon, 14 Sep 2015 17:52:41 +0300 Subject: [PATCH] [ios] Updated search to v2.0. --- iphone/Maps/Bookmarks/BookmarksVC.mm | 7 + .../Classes/Components/MWMMultilineLabel.h | 3 + .../Classes/Components/MWMMultilineLabel.m | 20 + .../CircularProgress/MWMCircularProgress.m | 3 +- .../MWMCircularProgressView.m | 8 +- .../MWMDownloadMapRequest.h | 2 +- .../MWMDownloadMapRequest.mm | 13 +- .../MWMDownloadMapRequestView.h | 2 - .../MWMDownloadMapRequestView.m | 14 +- .../MapViewControls/APIBar/MWMAPIBar.h | 19 +- .../MapViewControls/APIBar/MWMAPIBar.mm | 104 ++- .../MapViewControls/APIBar/MWMAPIBarView.h | 2 - .../MapViewControls/APIBar/MWMAPIBarView.m | 44 - .../MapViewControls/APIBar/MWMAPIBarView.mm | 19 + .../MWMMapViewControlsManager.h | 14 +- .../MWMMapViewControlsManager.mm | 116 ++- .../Search/Console/MWMConsole.h | 5 + .../Search/Console/MWMConsole.mm | 57 ++ .../DownloadView/MWMSearchDownloadView.h | 11 + .../DownloadView/MWMSearchDownloadView.mm | 69 ++ .../MWMSearchDownloadViewController.h | 15 + .../MWMSearchDownloadViewController.mm | 114 +++ .../Search/MWMSearchContentView.h | 3 + .../Search/MWMSearchContentView.mm | 14 + .../MapViewControls/Search/MWMSearchManager.h | 40 + .../Search/MWMSearchManager.mm | 332 +++++++ .../Search/MWMSearchTextField.h | 5 + .../Search/MWMSearchTextField.mm | 41 + .../MapViewControls/Search/MWMSearchView.h | 20 + .../MapViewControls/Search/MWMSearchView.mm | 138 +++ .../TabButtons/MWMSearchTabButtonsView.h | 18 + .../TabButtons/MWMSearchTabButtonsView.mm | 103 ++ .../BookmarksTab/MWMSearchBookmarksCell.h | 10 + .../BookmarksTab/MWMSearchBookmarksCell.mm | 97 ++ .../BookmarksTab/MWMSearchBookmarksManager.h | 10 + .../BookmarksTab/MWMSearchBookmarksManager.mm | 109 +++ .../MWMSearchCategoriesManager.h | 10 + .../MWMSearchCategoriesManager.mm | 61 ++ .../CategoriesTab/MWMSearchCategoryCell.h | 5 + .../CategoriesTab/MWMSearchCategoryCell.mm | 28 + .../HistoryTab/MWMSearchHistoryClearCell.h | 7 + .../HistoryTab/MWMSearchHistoryClearCell.mm | 31 + .../HistoryTab/MWMSearchHistoryManager.h | 10 + .../HistoryTab/MWMSearchHistoryManager.mm | 140 +++ .../HistoryTab/MWMSearchHistoryRequestCell.h | 10 + .../HistoryTab/MWMSearchHistoryRequestCell.mm | 49 + .../MWMSearchTabbedCollectionViewCell.h | 10 + .../MWMSearchTabbedCollectionViewCell.mm | 28 + .../MWMSearchTabbedViewController.h | 14 + .../MWMSearchTabbedViewController.mm | 231 +++++ .../TabbedView/MWMSearchTabbedViewLayout.h | 5 + .../TabbedView/MWMSearchTabbedViewLayout.mm | 36 + .../TabbedView/MWMSearchTabbedViewProtocol.h | 7 + .../Search/TableView/MWMSearchCell.h | 9 + .../Search/TableView/MWMSearchCell.mm | 61 ++ .../Search/TableView/MWMSearchCommonCell.h | 12 + .../Search/TableView/MWMSearchCommonCell.mm | 144 +++ .../Search/TableView/MWMSearchShowOnMapCell.h | 7 + .../TableView/MWMSearchShowOnMapCell.mm | 17 + .../TableView/MWMSearchSuggestionCell.h | 10 + .../TableView/MWMSearchSuggestionCell.mm | 51 + .../Search/TableView/MWMSearchTableView.h | 9 + .../Search/TableView/MWMSearchTableView.mm | 28 + .../TableView/MWMSearchTableViewController.h | 22 + .../TableView/MWMSearchTableViewController.mm | 360 +++++++ .../SideMenu/MWMSideMenuManager.mm | 8 +- .../SideMenu/MWMSideMenuManagerDelegate.h | 1 + .../MWMNavigationDashboardManager.h | 3 + .../MWMNavigationDashboardManager.mm | 23 +- .../Views/Dashboard/MWMNavigationDashboard.mm | 2 +- .../Views/MWMNavigationView.h | 1 + ...MNavigationView.m => MWMNavigationView.mm} | 14 +- .../Views/MWMRouteHelperPanel.mm | 3 +- .../Views/MWMRouteHelperPanelsDrawer.h | 2 +- .../Views/MWMRouteHelperPanelsDrawer.mm | 6 +- .../Views/RoutePreview/MWMRoutePreview.mm | 8 + .../MWMSearchDownloadMapRequest.m | 3 +- ...w.m => MWMSearchDownloadMapRequestView.mm} | 3 +- iphone/Maps/Classes/MWMNavigationDelegate.h | 13 - iphone/Maps/Classes/MWMPlacePage.h | 1 + iphone/Maps/Classes/MWMPlacePageViewManager.h | 6 +- .../Maps/Classes/MWMPlacePageViewManager.mm | 36 +- iphone/Maps/Classes/MWMiPadPlacePage.mm | 19 +- iphone/Maps/Classes/MapViewController.h | 10 +- iphone/Maps/Classes/MapViewController.mm | 246 +---- iphone/Maps/Classes/SearchBar.h | 24 - iphone/Maps/Classes/SearchBar.mm | 158 ---- iphone/Maps/Classes/SearchCategoryCell.h | 10 - iphone/Maps/Classes/SearchCategoryCell.m | 62 -- iphone/Maps/Classes/SearchCell.h | 12 - iphone/Maps/Classes/SearchCell.m | 80 -- iphone/Maps/Classes/SearchResultCell.h | 14 - iphone/Maps/Classes/SearchResultCell.m | 144 --- iphone/Maps/Classes/SearchShowOnMapCell.h | 8 - iphone/Maps/Classes/SearchShowOnMapCell.m | 41 - iphone/Maps/Classes/SearchSuggestCell.h | 11 - iphone/Maps/Classes/SearchSuggestCell.m | 82 -- iphone/Maps/Classes/SearchView.h | 45 - iphone/Maps/Classes/SearchView.mm | 884 ------------------ iphone/Maps/Maps.xcodeproj/project.pbxproj | 358 +++++-- iphone/Maps/Platform/LocationManager.mm | 5 +- .../FrameworkUtils/MWMFrameworkUtils.mm | 2 +- map/framework.cpp | 21 +- map/framework.hpp | 3 +- search/result.hpp | 6 + 105 files changed, 3314 insertions(+), 2077 deletions(-) create mode 100644 iphone/Maps/Classes/Components/MWMMultilineLabel.h create mode 100644 iphone/Maps/Classes/Components/MWMMultilineLabel.m delete mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.m create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewProtocol.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.mm create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.h create mode 100644 iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.mm rename iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/{MWMNavigationView.m => MWMNavigationView.mm} (84%) rename iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/{MWMSearchDownloadMapRequestView.m => MWMSearchDownloadMapRequestView.mm} (94%) delete mode 100644 iphone/Maps/Classes/MWMNavigationDelegate.h delete mode 100644 iphone/Maps/Classes/SearchBar.h delete mode 100644 iphone/Maps/Classes/SearchBar.mm delete mode 100644 iphone/Maps/Classes/SearchCategoryCell.h delete mode 100644 iphone/Maps/Classes/SearchCategoryCell.m delete mode 100644 iphone/Maps/Classes/SearchCell.h delete mode 100644 iphone/Maps/Classes/SearchCell.m delete mode 100644 iphone/Maps/Classes/SearchResultCell.h delete mode 100644 iphone/Maps/Classes/SearchResultCell.m delete mode 100644 iphone/Maps/Classes/SearchShowOnMapCell.h delete mode 100644 iphone/Maps/Classes/SearchShowOnMapCell.m delete mode 100644 iphone/Maps/Classes/SearchSuggestCell.h delete mode 100644 iphone/Maps/Classes/SearchSuggestCell.m delete mode 100644 iphone/Maps/Classes/SearchView.h delete mode 100644 iphone/Maps/Classes/SearchView.mm diff --git a/iphone/Maps/Bookmarks/BookmarksVC.mm b/iphone/Maps/Bookmarks/BookmarksVC.mm index fafd1ce4fc..218602fb2a 100644 --- a/iphone/Maps/Bookmarks/BookmarksVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksVC.mm @@ -5,6 +5,7 @@ #import "Common.h" #import "MapsAppDelegate.h" #import "MapViewController.h" +#import "MWMMapViewControlsManager.h" #import "Statistics.h" #import "UIKitCategories.h" #import @@ -24,6 +25,7 @@ #define EMPTY_SECTION -666 +extern NSString * const kBookmarksChangedNotification = @"BookmarksChangedNotification"; @interface BookmarksVC() { @@ -253,6 +255,8 @@ if (bm) { // Same as "Close". + MapViewController * mapVC = self.navigationController.viewControllers.firstObject; + mapVC.controlsManager.searchHidden = YES; f.ShowBookmark(BookmarkAndCategory(m_categoryIndex, indexPath.row)); [self.navigationController popToRootViewControllerAnimated:YES]; } @@ -313,6 +317,9 @@ NSValue * value = [NSValue valueWithBytes:&bookmarkAndCategory objCType:@encode(BookmarkAndCategory)]; [[NSNotificationCenter defaultCenter] postNotificationName:BOOKMARK_DELETED_NOTIFICATION object:value]; cat->DeleteBookmark(indexPath.row); + [NSNotificationCenter.defaultCenter postNotificationName:kBookmarksChangedNotification + object:nil + userInfo:nil]; } } cat->SaveToKMLFile(); diff --git a/iphone/Maps/Classes/Components/MWMMultilineLabel.h b/iphone/Maps/Classes/Components/MWMMultilineLabel.h new file mode 100644 index 0000000000..737a2639d0 --- /dev/null +++ b/iphone/Maps/Classes/Components/MWMMultilineLabel.h @@ -0,0 +1,3 @@ +@interface MWMMultilineLabel : UILabel + +@end diff --git a/iphone/Maps/Classes/Components/MWMMultilineLabel.m b/iphone/Maps/Classes/Components/MWMMultilineLabel.m new file mode 100644 index 0000000000..63830a6e7b --- /dev/null +++ b/iphone/Maps/Classes/Components/MWMMultilineLabel.m @@ -0,0 +1,20 @@ +#import "MWMMultilineLabel.h" + +@implementation MWMMultilineLabel + +- (void)setBounds:(CGRect)bounds +{ + [super setBounds:bounds]; + + // If this is a multiline label, need to make sure + // preferredMaxLayoutWidth always matches the frame width + // (i.e. orientation change can mess this up) + + if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) + { + self.preferredMaxLayoutWidth = self.bounds.size.width; + [self setNeedsUpdateConstraints]; + } +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.m b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.m index c7cf72457a..e3b0d76bdf 100644 --- a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.m +++ b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgress.m @@ -1,5 +1,6 @@ #import "MWMCircularProgress.h" #import "MWMCircularProgressView.h" +#import "UIKitCategories.h" @interface MWMCircularProgress () @@ -19,7 +20,7 @@ self = [super init]; if (self) { - [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + [[NSBundle mainBundle] loadNibNamed:self.class.className owner:self options:nil]; [parentView addSubview:self.rootView]; self.delegate = delegate; [self reset]; diff --git a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressView.m b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressView.m index 788a01e778..bb423d26c8 100644 --- a/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressView.m +++ b/iphone/Maps/Classes/CustomViews/CircularProgress/MWMCircularProgressView.m @@ -35,18 +35,18 @@ static inline CGFloat angleWithProgress(CGFloat progress) - (void)refreshBackground { - self.backgroundLayer.fillColor = [UIColor clearColor].CGColor; + self.backgroundLayer.fillColor = UIColor.clearColor.CGColor; self.backgroundLayer.lineWidth = kLineWidth; - self.backgroundLayer.strokeColor = [UIColor pressBackground].CGColor; + self.backgroundLayer.strokeColor = UIColor.pressBackground.CGColor; CGRect rect = CGRectInset(self.bounds, kLineWidth, kLineWidth); self.backgroundLayer.path = [UIBezierPath bezierPathWithOvalInRect:rect].CGPath; } - (void)refreshProgress { - self.progressLayer.fillColor = [UIColor clearColor].CGColor; + self.progressLayer.fillColor = UIColor.clearColor.CGColor; self.progressLayer.lineWidth = kLineWidth; - self.progressLayer.strokeColor = self.owner.failed ? [UIColor red].CGColor : [UIColor primary].CGColor; + self.progressLayer.strokeColor = self.owner.failed ? UIColor.red.CGColor : UIColor.linkBlue.CGColor; } - (void)updatePath:(CGFloat)progress diff --git a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.h b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.h index 9c2505fb53..0c3c35894b 100644 --- a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.h +++ b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.h @@ -1,4 +1,4 @@ -NS_ENUM(NSUInteger, MWMDownloadMapRequestState) +typedef NS_ENUM(NSUInteger, MWMDownloadMapRequestState) { MWMDownloadMapRequestStateDownload, MWMDownloadMapRequestStateRequestLocation, diff --git a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.mm b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.mm index 16b3dc7598..39cc474248 100644 --- a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.mm +++ b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequest.mm @@ -1,11 +1,12 @@ #import "Common.h" -#import "Framework.h" #import "LocationManager.h" #import "MapsAppDelegate.h" +#import "MWMCircularProgress.h" #import "MWMDownloadMapRequest.h" #import "MWMDownloadMapRequestView.h" -#import "MWMCircularProgress.h" +#import "UIKitCategories.h" +#include "Framework.h" #include "storage/index.hpp" @interface MWMDownloadMapRequest () @@ -35,7 +36,7 @@ self = [super init]; if (self) { - [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + [[NSBundle mainBundle] loadNibNamed:self.class.className owner:self options:nil]; [parentView addSubview:self.rootView]; self.progressView = [[MWMCircularProgress alloc] initWithParentView:self.progressViewWrapper delegate:self]; self.delegate = delegate; @@ -57,7 +58,6 @@ { self.currentCountryIndex = activeMapLayout.GetCurrentDownloadingCountryIndex(); self.progressView.failed = NO; - self.progressView.progress = 0.0; [self updateState:MWMDownloadMapRequestStateDownload]; } else @@ -90,8 +90,8 @@ - (void)downloadProgress:(CGFloat)progress countryName:(nonnull NSString *)countryName { - self.progressView.failed = NO; self.progressView.progress = progress; + [self showRequest]; self.mapTitleLabel.text = countryName; } @@ -118,6 +118,7 @@ { auto const mapType = self.downloadRoutesButton.selected ? MapOptions::MapWithCarRouting : MapOptions::Map; GetFramework().GetCountryTree().GetActiveMapLayout().DownloadMap(self.currentCountryIndex, mapType); + self.progressView.progress = 0.0; [self showRequest]; } @@ -137,7 +138,7 @@ - (void)updateState:(enum MWMDownloadMapRequestState)state { - [self.rootView stateUpdated:state]; + self.rootView.state = state; [self.delegate stateUpdated:state]; } diff --git a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.h b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.h index dd488f8b23..8afc2c7afe 100644 --- a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.h +++ b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.h @@ -8,6 +8,4 @@ - (nonnull instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("initWithFrame is not available"))); - (nonnull instancetype)init __attribute__((unavailable("init is not available"))); -- (void)stateUpdated:(enum MWMDownloadMapRequestState)state; - @end diff --git a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.m b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.m index 6fbfccd548..08ef3048a6 100644 --- a/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.m +++ b/iphone/Maps/Classes/CustomViews/DownloadMapRequest/MWMDownloadMapRequestView.m @@ -31,6 +31,7 @@ - (void)layoutSubviews { UIView * superview = self.superview; + self.frame = superview.bounds; BOOL const isLandscape = superview.height > superview.width; if (IPAD || isLandscape) { @@ -55,15 +56,14 @@ self.mapTitleLabel.numberOfLines = 0; } } - self.width = superview.width; - self.minX = 0.0; [super layoutSubviews]; } #pragma mark - Properties -- (void)stateUpdated:(enum MWMDownloadMapRequestState)state +- (void)setState:(enum MWMDownloadMapRequestState)state { + _state = state; switch (state) { case MWMDownloadMapRequestStateDownload: @@ -82,10 +82,10 @@ self.undefinedLocationLabel.hidden = YES; self.selectAnotherMapButton.hidden = NO; [self.selectAnotherMapButton setTitle:L(@"search_select_other_map") forState:UIControlStateNormal]; - [self.selectAnotherMapButton setTitleColor:[UIColor primary] forState:UIControlStateNormal]; + [self.selectAnotherMapButton setTitleColor:[UIColor linkBlue] forState:UIControlStateNormal]; [self.selectAnotherMapButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; [self.selectAnotherMapButton setBackgroundColor:[UIColor whiteColor] forState:UIControlStateNormal]; - [self.selectAnotherMapButton setBackgroundColor:[UIColor primary] forState:UIControlStateHighlighted]; + [self.selectAnotherMapButton setBackgroundColor:[UIColor linkBlue] forState:UIControlStateHighlighted]; break; case MWMDownloadMapRequestStateRequestUnknownLocation: self.progressViewWrapper.hidden = YES; @@ -97,8 +97,8 @@ [self.selectAnotherMapButton setTitle:L(@"search_select_map") forState:UIControlStateNormal]; [self.selectAnotherMapButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - [self.selectAnotherMapButton setBackgroundColor:[UIColor primary] forState:UIControlStateNormal]; - [self.selectAnotherMapButton setBackgroundColor:[UIColor primaryDark] forState:UIControlStateHighlighted]; + [self.selectAnotherMapButton setBackgroundColor:[UIColor linkBlue] forState:UIControlStateNormal]; + [self.selectAnotherMapButton setBackgroundColor:[UIColor linkBlueDark] forState:UIControlStateHighlighted]; break; } } diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.h b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.h index c647cce92e..df086f82f5 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.h @@ -1,22 +1,9 @@ -@class SearchView; - -@protocol MWMAPIBarProtocol - -@property (nonnull, nonatomic) SearchView * searchView; - -- (void)apiBarBecameVisible:(BOOL)visible; - -@end - @interface MWMAPIBar : NSObject -@property (nonatomic, readonly) BOOL isVisible; -@property (nonatomic, readonly) CGRect frame; +@property (nonatomic) BOOL isVisible; -- (nonnull instancetype)init __attribute__((unavailable("init is not available"))); -- (nonnull instancetype)initWithDelegate:(nonnull UIViewController *)delegate; +- (nullable instancetype)initWithController:(nonnull UIViewController *)controller; -- (void)show; -- (void)hideBarAndClearAnimated:(BOOL)animated; +- (void)back; @end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm index 47b45bbb3b..c2c3231196 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm @@ -1,96 +1,110 @@ #import "Common.h" #import "MWMAPIBar.h" #import "MWMAPIBarView.h" -#import "SearchView.h" #import "UIKitCategories.h" #include "Framework.h" +static NSString * const kKeyPath = @"subviews"; + @interface MWMAPIBar () @property (nonatomic) IBOutlet MWMAPIBarView * rootView; -@property (nonatomic) IBOutlet UILabel * titleLabel; +@property (weak, nonatomic) IBOutlet UIImageView * backArrow; +@property (weak, nonatomic) IBOutlet UILabel * backLabel; +@property (weak, nonatomic) IBOutlet UILabel * timeLabel; -@property (weak, nonatomic) UIViewController * delegate; -@property (nonatomic, setter = setVisible:) BOOL isVisible; +@property (nonatomic) NSDateFormatter * timeFormatter; +@property (nonatomic) NSTimer * timer; + +@property (weak, nonatomic) UIViewController * controller; @end @implementation MWMAPIBar -- (instancetype)initWithDelegate:(nonnull UIViewController *)delegate +- (nullable instancetype)initWithController:(nonnull UIViewController *)controller { self = [super init]; if (self) { + self.controller = controller; [[NSBundle mainBundle] loadNibNamed:@"MWMAPIBarView" owner:self options:nil]; - self.delegate = delegate; + + self.timeFormatter = [[NSDateFormatter alloc] init]; + self.timeFormatter.dateStyle = NSDateFormatterNoStyle; + self.timeFormatter.timeStyle = NSDateFormatterShortStyle; } return self; } -- (void)show +- (void)dealloc { - self.titleLabel.text = @(GetFramework().GetApiDataHolder().GetAppTitle().c_str()); - [self.delegate.view insertSubview:self.rootView belowSubview:self.delegate.searchView]; - self.rootView.width = self.delegate.view.width; - self.rootView.maxY = 0.0; - [UIView animateWithDuration:kDefaultAnimationDuration animations:^ - { - self.rootView.targetY = 0.0; - self.isVisible = YES; - }]; + self.isVisible = NO; } -- (void)hideAnimated:(BOOL)animated +- (void)timerUpdate { - [UIView animateWithDuration:animated ? kDefaultAnimationDuration : 0.0 animations:^ - { - self.rootView.targetY = -self.rootView.height; - self.isVisible = NO; - } - completion:^(BOOL finished) - { - [self.rootView removeFromSuperview]; - }]; + self.timeLabel.text = [self.timeFormatter stringFromDate:[NSDate date]]; } #pragma mark - Actions -- (IBAction)backButtonTouchUpInside:(UIButton *)sender +- (IBAction)back { - NSURL * url = [NSURL URLWithString:@(GetFramework().GetApiDataHolder().GetGlobalBackUrl().c_str())]; - [[UIApplication sharedApplication] openURL:url]; - [self hideBarAndClearAnimated:NO]; -} - -- (IBAction)clearButtonTouchUpInside:(UIButton *)sender -{ - [self hideBarAndClearAnimated:YES]; -} - -- (void)hideBarAndClearAnimated:(BOOL)animated -{ - [self hideAnimated:animated]; auto & f = GetFramework(); auto & bm = f.GetBalloonManager(); bm.RemovePin(); bm.Dismiss(); f.GetBookmarkManager().UserMarksClear(UserMarkContainer::API_MARK); f.Invalidate(); + self.isVisible = NO; + NSURL * url = [NSURL URLWithString:@(f.GetApiDataHolder().GetGlobalBackUrl().c_str())]; + [[UIApplication sharedApplication] openURL:url]; } #pragma mark - Properties -- (void)setVisible:(BOOL)visible +@synthesize isVisible = _isVisible; + +- (BOOL)isVisible { - _isVisible = visible; - [self.delegate apiBarBecameVisible:visible]; + if (isIOSVersionLessThan(9)) + return _isVisible; + return NO; } -- (CGRect)frame +- (void)setIsVisible:(BOOL)isVisible { - return self.rootView.frame; + if (!isIOSVersionLessThan(9)) + return; + if (_isVisible == isVisible) + return; + _isVisible = isVisible; + if (isVisible) + { + self.backLabel.text = + [NSString stringWithFormat:@"%@ %@", L(@"back_to"), + @(GetFramework().GetApiDataHolder().GetAppTitle().c_str())]; + [self.controller.view addSubview:self.rootView]; + [self.controller.view addObserver:self + forKeyPath:kKeyPath + options:NSKeyValueObservingOptionNew + context:nullptr]; + [self timerUpdate]; + self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 + target:self + selector:@selector(timerUpdate) + userInfo:nil + repeats:YES]; + } + else + { + [self.rootView.superview removeObserver:self forKeyPath:kKeyPath]; + [self.rootView removeFromSuperview]; + [self.timer invalidate]; + } + [self.controller setNeedsStatusBarAppearanceUpdate]; } @end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.h b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.h index e238079cde..570ffb143a 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.h @@ -2,8 +2,6 @@ @interface MWMAPIBarView : UIView -@property (nonatomic) CGFloat targetY; - - (nonnull instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("initWithFrame is not available"))); - (nonnull instancetype)init __attribute__((unavailable("init is not available"))); diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.m b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.m deleted file mode 100644 index 1fa0733047..0000000000 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.m +++ /dev/null @@ -1,44 +0,0 @@ -#import "MWMAPIBarView.h" -#import "UIKitCategories.h" - -@interface MWMAPIBarView () - -@property (nonatomic) CGFloat defaulhHeight; - -@end - -@implementation MWMAPIBarView - -- (instancetype)initWithCoder:(NSCoder *)aDecoder -{ - self = [super initWithCoder:aDecoder]; - if (self) - self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - return self; -} - -- (void)awakeFromNib -{ - [super awakeFromNib]; - self.defaulhHeight = self.height; - self.targetY = 0.0; -} - -- (void)layoutSubviews -{ - self.width = self.superview.width; - self.height = self.defaulhHeight; - self.minX = 0.0; - self.minY = self.targetY; - [super layoutSubviews]; -} - -#pragma mark - Properties - -- (void)setTargetY:(CGFloat)targetY -{ - _targetY = targetY; - [self layoutSubviews]; -} - -@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.mm new file mode 100644 index 0000000000..628c44113f --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBarView.mm @@ -0,0 +1,19 @@ +#import "MWMAPIBarView.h" + +@implementation MWMAPIBarView + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; + return self; +} + +- (void)layoutSubviews +{ + self.frame = {{}, {self.superview.bounds.size.width, 20.0}}; + [super layoutSubviews]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h index 601e04c5e6..a38f34c0c0 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.h @@ -6,12 +6,6 @@ @class MapViewController; -@protocol MWMMapViewControlsManagerDelegate - -- (void)addPlacePageViews:(NSArray *)views; - -@end - @interface MWMMapViewControlsManager : NSObject @property (nonatomic) BOOL hidden; @@ -19,15 +13,17 @@ @property (nonatomic) BOOL locationHidden; @property (nonatomic) MWMSideMenuState menuState; @property (nonatomic, readonly) MWMNavigationDashboardState navigationState; +@property (nonatomic) BOOL searchHidden; - (instancetype)init __attribute__((unavailable("init is not available"))); - (instancetype)initWithParentController:(MapViewController *)controller; #pragma mark - Layout -@property (nonatomic) CGFloat topBound; - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation; +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration; +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator; #pragma mark - MWMPlacePageViewManager diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm index 65cc1165a6..eb75e60b4e 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm @@ -1,4 +1,4 @@ -#import "Framework.h" +#import "CountryTreeVC.h" #import "MapsAppDelegate.h" #import "MapViewController.h" #import "MWMAPIBar.h" @@ -6,25 +6,38 @@ #import "MWMMapViewControlsManager.h" #import "MWMPlacePageViewManager.h" #import "MWMPlacePageViewManagerDelegate.h" +#import "MWMSearchManager.h" +#import "MWMSearchView.h" #import "MWMSideMenuManager.h" #import "MWMSideMenuManagerDelegate.h" #import "MWMZoomButtons.h" #import "RouteState.h" -@interface MWMMapViewControlsManager () +#import "3party/Alohalytics/src/alohalytics_objc.h" + +#include "Framework.h" + +extern NSString * const kAlohalyticsTapEventKey; + +@interface MWMMapViewControlsManager ()< + MWMPlacePageViewManagerProtocol, MWMNavigationDashboardManagerProtocol, + MWMSideMenuManagerProtocol, MWMSearchManagerProtocol, MWMSearchViewProtocol> @property (nonatomic) MWMZoomButtons * zoomButtons; @property (nonatomic) MWMLocationButton * locationButton; @property (nonatomic) MWMSideMenuManager * menuManager; @property (nonatomic) MWMPlacePageViewManager * placePageManager; @property (nonatomic) MWMNavigationDashboardManager * navigationManager; +@property (nonatomic) MWMSearchManager * searchManager; @property (weak, nonatomic) MapViewController * ownerController; @property (nonatomic) BOOL disableStandbyOnRouteFollowing; @property (nonatomic) m2::PointD routeDestination; +@property (nonatomic) CGFloat topBound; +@property (nonatomic) CGFloat leftBound; + @end @implementation MWMMapViewControlsManager @@ -42,6 +55,7 @@ self.menuManager = [[MWMSideMenuManager alloc] initWithParentController:controller delegate:self]; self.placePageManager = [[MWMPlacePageViewManager alloc] initWithViewController:controller delegate:self]; self.navigationManager = [[MWMNavigationDashboardManager alloc] initWithParentView:controller.view delegate:self]; + self.searchManager = [[MWMSearchManager alloc] initWithParentView:controller.view delegate:self]; self.hidden = NO; self.zoomHidden = NO; self.menuState = MWMSideMenuStateInactive; @@ -50,13 +64,29 @@ #pragma mark - Layout -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration +{ + [self.placePageManager willRotateToInterfaceOrientation:toInterfaceOrientation]; + [self.navigationManager willRotateToInterfaceOrientation:toInterfaceOrientation]; + [self.searchManager willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self refreshHelperPanels:UIInterfaceOrientationIsLandscape(toInterfaceOrientation)]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + [self.placePageManager viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + [self.navigationManager viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + [self.searchManager viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + [self refreshHelperPanels:size.height < size.width]; +} + +- (void)refreshHelperPanels:(BOOL)isLandscape { - [self.placePageManager willRotateToInterfaceOrientation:orientation]; - [self.navigationManager willRotateToInterfaceOrientation:orientation]; if (!self.placePageManager.entity) return; - if (UIInterfaceOrientationIsLandscape(orientation)) + if (isLandscape) [self.navigationManager hideHelperPanels]; else [self.navigationManager showHelperPanels]; @@ -72,13 +102,37 @@ - (void)showPlacePageWithUserMark:(unique_ptr)userMark { [self.placePageManager showPlacePageWithUserMark:move(userMark)]; - if (UIInterfaceOrientationIsLandscape(self.ownerController.interfaceOrientation)) - [self.navigationManager hideHelperPanels]; + [self refreshHelperPanels:UIInterfaceOrientationIsLandscape(self.ownerController.interfaceOrientation)]; } - (void)apiBack { - [self.ownerController.apiBar hideBarAndClearAnimated:NO]; + [self.ownerController.apiBar back]; +} + +#pragma mark - MWMSearchManagerProtocol + +- (void)searchViewWillEnterState:(MWMSearchManagerState)state +{ +} + +- (void)searchViewDidEnterState:(MWMSearchManagerState)state +{ + if (state == MWMSearchManagerStateHidden) + { + self.hidden = NO; + self.leftBound = self.topBound = 0.0; + } + [self.ownerController setNeedsStatusBarAppearanceUpdate]; +} + +#pragma mark - MWMSearchViewProtocol + +- (void)searchFrameUpdated:(CGRect)frame +{ + UIView * searchView = self.searchManager.view; + self.leftBound = searchView.width; + self.topBound = searchView.height; } #pragma mark - MWMSideMenuManagerProtocol @@ -88,6 +142,15 @@ [self.zoomButtons setBottomBound:self.menuManager.menuButtonFrameWithSpacing.origin.y]; } +#pragma mark - MWMSearchManagerProtocol & MWMSideMenuManagerProtocol + +- (void)actionDownloadMaps +{ + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"downloader"]; + CountryTreeVC * vc = [[CountryTreeVC alloc] initWithNodePosition:-1]; + [self.ownerController.navigationController pushViewController:vc animated:YES]; +} + #pragma mark - MWMPlacePageViewManagerDelegate - (void)dragPlacePage:(CGPoint)point @@ -104,7 +167,13 @@ - (void)addPlacePageViews:(NSArray *)views { - [self.ownerController addPlacePageViews:views]; + UIView * ownerView = self.ownerController.view; + UIView * searchView = self.searchManager.view; + for (UIView * view in views) + { + if (![ownerView.subviews containsObject:view]) + [ownerView insertSubview:view belowSubview:searchView]; + } } - (void)updateStatusBarStyle @@ -153,7 +222,8 @@ - (void)navigationDashBoardDidUpdate { CGFloat const topBound = self.topBound + self.navigationManager.height; - [self.zoomButtons setTopBound:topBound]; + if (!IPAD) + [self.zoomButtons setTopBound:topBound]; [self.placePageManager setTopBound:topBound]; } @@ -253,8 +323,26 @@ - (void)setTopBound:(CGFloat)topBound { - _topBound = topBound; - self.placePageManager.topBound = self.zoomButtons.topBound = self.navigationManager.topBound = topBound; + if (IPAD) + return; + _topBound = self.placePageManager.topBound = self.zoomButtons.topBound = self.navigationManager.topBound = topBound; +} + +- (void)setLeftBound:(CGFloat)leftBound +{ + if (!IPAD) + return; + _leftBound = self.placePageManager.leftBound = self.navigationManager.leftBound = leftBound; +} + +- (BOOL)searchHidden +{ + return self.searchManager.state == MWMSearchManagerStateHidden; +} + +- (void)setSearchHidden:(BOOL)searchHidden +{ + self.searchManager.state = searchHidden ? MWMSearchManagerStateHidden : MWMSearchManagerStateDefault; } @end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.h new file mode 100644 index 0000000000..9d2e883470 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.h @@ -0,0 +1,5 @@ +@interface MWMConsole : NSObject + ++ (BOOL)performCommand:(NSString *)cmd; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.mm new file mode 100644 index 0000000000..92944f0d02 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/Console/MWMConsole.mm @@ -0,0 +1,57 @@ +#import "MapsAppDelegate.h" +#import "MWMConsole.h" + +#include "Framework.h" + +extern NSString * const kMwmTextToSpeechEnable; +extern NSString * const kMwmTextToSpeechDisable; + +@implementation MWMConsole + ++ (BOOL)performCommand:(NSString *)cmd +{ + if ([self performMapStyle:cmd]) + return YES; + + if ([self performSound:cmd]) + return YES; + + return NO; +} + ++ (BOOL)performMapStyle:(NSString *)cmd +{ + // Hook for shell command on change map style + BOOL const isDark = [cmd isEqualToString:@"mapstyle:dark"] || [cmd isEqualToString:@"?dark"]; + BOOL const isLight = isDark ? NO : [cmd isEqualToString:@"mapstyle:light"] || [cmd isEqualToString:@"?light"]; + BOOL const isClear = isLight || isDark ? NO : [cmd isEqualToString:@"?newstyle"]; + + if (!isDark && !isLight && !isClear) + return NO; + + // change map style + MapStyle const mapStyle = isDark ? MapStyleDark : (isClear ? MapStyleClear : MapStyleLight); + [[MapsAppDelegate theApp] setMapStyle: mapStyle]; + + return YES; +} + ++ (BOOL)performSound:(NSString *)cmd +{ + // Hook for shell command on change map style + BOOL const sound = [cmd isEqualToString:@"?sound"]; + BOOL const nosound = sound ? NO : [cmd isEqualToString:@"?nosound"]; + + if (!sound && !nosound) + return NO; + + // turn notification + if (sound) + [[NSNotificationCenter defaultCenter] postNotificationName:kMwmTextToSpeechEnable object:nil]; + if (nosound) + [[NSNotificationCenter defaultCenter] postNotificationName:kMwmTextToSpeechDisable object:nil]; + + return YES; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.h new file mode 100644 index 0000000000..7f235270e5 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.h @@ -0,0 +1,11 @@ +typedef NS_ENUM(NSUInteger, MWMSearchDownloadViewState) +{ + MWMSearchDownloadViewStateProgress, + MWMSearchDownloadViewStateRequest +}; + +@interface MWMSearchDownloadView : UIView + +@property (nonatomic) enum MWMSearchDownloadViewState state; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.mm new file mode 100644 index 0000000000..b192af2f9e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadView.mm @@ -0,0 +1,69 @@ +#import "Common.h" +#import "MWMSearchDownloadView.h" +#import "UIKitCategories.h" + +@interface MWMSearchDownloadView () + +@property (weak, nonatomic) IBOutlet UILabel * hint; +@property (weak, nonatomic) IBOutlet UIImageView * image; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * hintTopOffset; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * downloadRequestWrapperTopOffset; + +@end + +@implementation MWMSearchDownloadView + +- (void)awakeFromNib +{ + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.layer.shouldRasterize = YES; + self.layer.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)layoutSubviews +{ + self.frame = self.superview.bounds; + [self update]; + [super layoutSubviews]; +} + +- (void)update +{ + UIView * superview = self.superview; + if (!superview) + return; + BOOL const isPortrait = superview.width < superview.height; + BOOL const isCompact = superview.height <= 480.0; + BOOL const defaultSize = IPAD || (isPortrait && !isCompact); + [self layoutIfNeeded]; + self.hintTopOffset.constant = defaultSize ? 40.0 : 12.0; + if (self.state == MWMSearchDownloadViewStateProgress) + self.downloadRequestWrapperTopOffset.constant = isPortrait ? 100.0 : 40.0; + else + self.downloadRequestWrapperTopOffset.constant = defaultSize ? 200.0 : 12.0; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ + { + if (self.state == MWMSearchDownloadViewStateProgress) + { + self.hint.alpha = self.image.alpha = 0.0; + } + else + { + self.hint.alpha = 1.0; + self.image.alpha = defaultSize ? 1.0 : 0.0; + } + [self layoutIfNeeded]; + }]; +} + +#pragma mark - Property + +- (void)setState:(enum MWMSearchDownloadViewState)state +{ + if (_state == state) + return; + _state = state; + [self update]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.h new file mode 100644 index 0000000000..03eea7428c --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.h @@ -0,0 +1,15 @@ +@protocol MWMSearchDownloadProtocol + +- (void)selectMapsAction; + +@end + +@interface MWMSearchDownloadViewController : UIViewController + +- (nonnull instancetype)init __attribute__((unavailable("init is not available"))); +- (nonnull instancetype)initWithDelegate:(nonnull id)delegate; + +- (void)downloadProgress:(CGFloat)progress countryName:(nonnull NSString *)countryName; +- (void)setDownloadFailed; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.mm new file mode 100644 index 0000000000..da63f3fc51 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/DownloadView/MWMSearchDownloadViewController.mm @@ -0,0 +1,114 @@ +#import "MWMDownloadMapRequest.h" +#import "MWMSearchDownloadView.h" +#import "MWMSearchDownloadViewController.h" + +@interface MWMSearchDownloadViewController () + +@property (nonatomic) IBOutlet UIView * downloadRequestHolder; + +@property (nonatomic) MWMDownloadMapRequest * downloadRequest; +@property (nonatomic) IBOutlet UIButton * dimButton; + +@property (nonnull, weak, nonatomic) id delegate; + +@end + +@implementation MWMSearchDownloadViewController + +- (nonnull instancetype)initWithDelegate:(id)delegate +{ + self = [super init]; + if (self) + self.delegate = delegate; + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.downloadRequest = + [[MWMDownloadMapRequest alloc] initWithParentView:self.downloadRequestHolder delegate:self]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillhide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)keyboardWillShow:(nonnull NSNotification *)aNotification +{ + UIButton * dim = self.dimButton; + dim.hidden = NO; + dim.alpha = 0.0; + NSNumber * duration = aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey]; + [UIView animateWithDuration:duration.floatValue animations:^ + { + dim.alpha = 1.0; + }]; +} + +- (void)keyboardWillhide:(nonnull NSNotification *)aNotification +{ + UIButton * dim = self.dimButton; + dim.alpha = 1.0; + NSNumber * duration = aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey]; + [UIView animateWithDuration:duration.floatValue animations:^ + { + dim.alpha = 0.0; + } + completion:^(BOOL finished) + { + dim.hidden = YES; + }]; +} + +#pragma mark - Process control + +- (void)downloadProgress:(CGFloat)progress countryName:(nonnull NSString *)countryName +{ + [self stateUpdated:MWMDownloadMapRequestStateDownload]; + [self.downloadRequest downloadProgress:progress countryName:countryName]; +} + +- (void)setDownloadFailed +{ + [self.downloadRequest setDownloadFailed]; +} + +#pragma mark - Actions + +- (IBAction)dimTouchUpInside:(nonnull UIButton *)sender +{ + [UIApplication.sharedApplication.keyWindow endEditing:YES]; +} + +#pragma mark - MWMDownloadMapRequestDelegate + +- (void)stateUpdated:(enum MWMDownloadMapRequestState)state +{ + MWMSearchDownloadViewState viewState = state == MWMDownloadMapRequestStateDownload + ? MWMSearchDownloadViewStateProgress + : MWMSearchDownloadViewStateRequest; + ((MWMSearchDownloadView *)self.view).state = viewState; +} + +- (void)selectMapsAction +{ + [self.delegate selectMapsAction]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.h new file mode 100644 index 0000000000..709bccd7f7 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.h @@ -0,0 +1,3 @@ +@interface MWMSearchContentView : UIView + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.mm new file mode 100644 index 0000000000..6f9cb7c566 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchContentView.mm @@ -0,0 +1,14 @@ +#import "MWMSearchContentView.h" + +@implementation MWMSearchContentView + +- (void)layoutSubviews +{ + [self.subviews enumerateObjectsUsingBlock:^(UIView * view, NSUInteger idx, BOOL * stop) + { + view.frame = self.bounds; + }]; + [super layoutSubviews]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.h new file mode 100644 index 0000000000..2ab148cf6d --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.h @@ -0,0 +1,40 @@ +#import "MWMSearchTextField.h" +#import "MWMSearchView.h" + +typedef NS_ENUM(NSUInteger, MWMSearchManagerState) +{ + MWMSearchManagerStateHidden, + MWMSearchManagerStateDefault, + MWMSearchManagerStateTableSearch, + MWMSearchManagerStateMapSearch +}; + +@protocol MWMSearchManagerProtocol + +- (void)searchViewWillEnterState:(MWMSearchManagerState)state; +- (void)searchViewDidEnterState:(MWMSearchManagerState)state; +- (void)actionDownloadMaps; + +@end + +@interface MWMSearchManager : NSObject + +@property (nonnull, weak, nonatomic) id delegate; +@property (nonnull, weak, nonatomic) IBOutlet MWMSearchTextField * searchTextField; + +@property (nonatomic) MWMSearchManagerState state; + +@property (nonnull, nonatomic, readonly) UIView * view; + +- (nullable instancetype)init __attribute__((unavailable("init is not available"))); +- (nullable instancetype)initWithParentView:(nonnull UIView *)view + delegate:(nonnull id)delegate; + +#pragma mark - Layout + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration; +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(nonnull id)coordinator; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.mm new file mode 100644 index 0000000000..619fac76c1 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchManager.mm @@ -0,0 +1,332 @@ +#import "MapsObservers.h" +#import "MWMConsole.h" +#import "MWMSearchDownloadViewController.h" +#import "MWMSearchManager.h" +#import "MWMSearchTabbedViewController.h" +#import "MWMSearchTabButtonsView.h" +#import "MWMSearchTableViewController.h" + +#import "3party/Alohalytics/src/alohalytics_objc.h" + +#include "Framework.h" +#include "map/active_maps_layout.hpp" + +extern NSString * const kAlohalyticsTapEventKey; + +@interface MWMSearchManager () + +@property (weak, nonatomic) UIView * parentView; +@property (nonatomic) IBOutlet MWMSearchView * rootView; +@property (weak, nonatomic) IBOutlet UIView * contentView; + +@property (nonatomic) IBOutletCollection(MWMSearchTabButtonsView) NSArray * tabButtons; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * scrollIndicatorOffset; +@property (weak, nonatomic) IBOutlet UIView * scrollIndicator; + +@property (nonatomic) UINavigationController * navigationController; +@property (nonatomic) MWMSearchTabbedViewController * tabbedController; +@property (nonatomic) MWMSearchTableViewController * tableViewController; +@property (nonatomic) MWMSearchDownloadViewController * downloadController; + +@end + +@implementation MWMSearchManager +{ + unique_ptr m_mapsObserver; + int m_mapsObserverSlotId; +} + +- (nullable instancetype)initWithParentView:(nonnull UIView *)view + delegate:(nonnull id)delegate +{ + self = [super init]; + if (self) + { + [NSBundle.mainBundle loadNibNamed:@"MWMSearchView" owner:self options:nil]; + self.delegate = delegate; + self.rootView.delegate = delegate; + self.parentView = view; + self.state = MWMSearchManagerStateHidden; + } + return self; +} + +- (void)beginSearch +{ + if (self.state == MWMSearchManagerStateDefault) + self.state = MWMSearchManagerStateTableSearch; + self.searchTextField.isSearching = YES; +} + +- (void)endSearch +{ + GetFramework().CancelInteractiveSearch(); + if (self.state != MWMSearchManagerStateHidden) + self.state = MWMSearchManagerStateDefault; + self.searchTextField.isSearching = NO; + self.searchTextField.text = @""; + [self.tableViewController searchText:@"" forInputLocale:nil]; +} + +#pragma mark - Actions + +- (IBAction)textFieldDidEndEditing:(UITextField *)textField +{ + if (self.searchTextField.text.length == 0) + [self endSearch]; +} + +- (IBAction)textFieldTextDidChange:(UITextField *)textField +{ + NSString * text = textField.text; + if (text.length > 0) + { + if ([MWMConsole performCommand:text]) + { + self.state = MWMSearchManagerStateHidden; + } + else + { + [self beginSearch]; + [self.tableViewController searchText:text + forInputLocale:self.searchTextField.textInputMode.primaryLanguage]; + } + } + else + { + [self endSearch]; + } +} + +- (IBAction)cancelButtonPressed +{ + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"searchCancel"]; + self.state = MWMSearchManagerStateHidden; +} + +- (void)tabButtonPressed:(MWMSearchTabButtonsView *)sender +{ + [self.searchTextField resignFirstResponder]; + [self.tabbedController tabButtonPressed:sender]; +} + +#pragma mark - Layout + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration +{ + [self.navigationController willRotateToInterfaceOrientation:toInterfaceOrientation + duration:duration]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + [self.navigationController viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; +} + +#pragma mark - MWMSearchTabbedViewProtocol + +- (void)searchText:(NSString *)text forInputLocale:(NSString *)locale +{ + [self beginSearch]; + self.searchTextField.text = text; + NSString * inputLocale = locale ? locale : self.searchTextField.textInputMode.primaryLanguage; + [self.tableViewController searchText:text forInputLocale:inputLocale]; +} + +#pragma mark - MWMSearchDownloadMapRequest + +- (void)selectMapsAction +{ + [self.delegate actionDownloadMaps]; +} + +#pragma mark - ActiveMapsObserverProtocol + +- (void)countryStatusChangedAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group +{ + auto const status = + GetFramework().GetCountryTree().GetActiveMapLayout().GetCountryStatus(group, position); + [self updateTopController]; + if (status == TStatus::EDownloadFailed) + [self.downloadController setDownloadFailed]; + if (self.state == MWMSearchManagerStateTableSearch || + self.state == MWMSearchManagerStateMapSearch) + { + NSString * text = self.searchTextField.text; + if (text.length > 0) + [self.tableViewController searchText:text + forInputLocale:self.searchTextField.textInputMode.primaryLanguage]; + } +} + +- (void)countryDownloadingProgressChanged:(LocalAndRemoteSizeT const &)progress + atPosition:(int)position + inGroup:(ActiveMapsLayout::TGroup const &)group +{ + CGFloat const normProgress = (CGFloat)progress.first / progress.second; + ActiveMapsLayout & activeMapLayout = GetFramework().GetCountryTree().GetActiveMapLayout(); + NSString * countryName = + @(activeMapLayout.GetFormatedCountryName(activeMapLayout.GetCoreIndex(group, position)) + .c_str()); + [self.downloadController downloadProgress:normProgress countryName:countryName]; +} + +#pragma mark - State changes + +- (void)updateTopController +{ + UIViewController * selfTopVC = self.topController; + self.rootView.tabBarIsVisible = + self.state == MWMSearchManagerStateDefault && [selfTopVC isEqual:self.tabbedController]; + if ([selfTopVC isEqual:self.navigationController.topViewController]) + return; + NSMutableArray * viewControllers = [self.navigationController.viewControllers mutableCopy]; + viewControllers[0] = selfTopVC; + [self.navigationController setViewControllers:viewControllers animated:NO]; +} + +- (void)changeFromHiddenState +{ + __weak auto weakSelf = self; + m_mapsObserver.reset(new ActiveMapsObserver(weakSelf)); + m_mapsObserverSlotId = GetFramework().GetCountryTree().GetActiveMapLayout().AddListener(m_mapsObserver.get()); +} + +- (void)changeToHiddenState +{ + [self endSearch]; + GetFramework().GetCountryTree().GetActiveMapLayout().RemoveListener(m_mapsObserverSlotId); + self.tabbedController.selectedButtonTag = 0; + self.tableViewController = nil; + self.downloadController = nil; + self.rootView.isVisible = NO; +} + +- (void)changeToDefaultState +{ + GetFramework().PrepareSearch(); + [self updateTopController]; + [self.navigationController popToRootViewControllerAnimated:NO]; + [self.parentView addSubview:self.rootView]; + self.rootView.compact = NO; + self.rootView.isVisible = YES; +} + +- (void)changeToTableSearchState +{ + self.rootView.tabBarIsVisible = NO; + self.tableViewController.searchOnMap = NO; + [self.navigationController pushViewController:self.tableViewController animated:NO]; +} + +- (void)changeToMapSearchState +{ + PinClickManager & bm = GetFramework().GetBalloonManager(); + bm.RemovePin(); + bm.Dismiss(); + [self.searchTextField resignFirstResponder]; + self.rootView.compact = YES; + self.tableViewController.searchOnMap = YES; +} + +#pragma mark - Properties + +- (UINavigationController *)navigationController +{ + if (!_navigationController) + { + _navigationController = [[UINavigationController alloc] initWithRootViewController:self.topController]; + [self.contentView addSubview:_navigationController.view]; + _navigationController.navigationBarHidden = YES; + } + return _navigationController; +} + +- (UIViewController *)topController +{ + auto & f = GetFramework(); + auto & activeMapLayout = f.GetCountryTree().GetActiveMapLayout(); + int const outOfDate = activeMapLayout.GetCountInGroup(storage::ActiveMapsLayout::TGroup::EOutOfDate); + int const upToDate = activeMapLayout.GetCountInGroup(storage::ActiveMapsLayout::TGroup::EUpToDate); + BOOL const haveMap = outOfDate > 0 || upToDate > 0; + return haveMap ? self.tabbedController : self.downloadController; +} + +- (MWMSearchDownloadViewController *)downloadController +{ + if (!_downloadController) + _downloadController = [[MWMSearchDownloadViewController alloc] initWithDelegate:self]; + return _downloadController; +} + +- (MWMSearchTabbedViewController *)tabbedController +{ + if (!_tabbedController) + { + _tabbedController = [[MWMSearchTabbedViewController alloc] init]; + _tabbedController.scrollIndicatorOffset = self.scrollIndicatorOffset; + _tabbedController.scrollIndicator = self.scrollIndicator; + _tabbedController.tabButtons = self.tabButtons; + _tabbedController.delegate = self; + } + return _tabbedController; +} + +- (MWMSearchTableViewController *)tableViewController +{ + if (!_tableViewController) + _tableViewController = [[MWMSearchTableViewController alloc] initWithDelegate:self]; + return _tableViewController; +} + +- (void)setScrollIndicatorOffset:(NSLayoutConstraint *)scrollIndicatorOffset +{ + _scrollIndicatorOffset = self.tabbedController.scrollIndicatorOffset = scrollIndicatorOffset; +} + +- (void)setScrollIndicator:(UIView *)scrollIndicator +{ + _scrollIndicator = self.tabbedController.scrollIndicator = scrollIndicator; +} + +- (void)setTabButtons:(NSArray *)tabButtons +{ + _tabButtons = self.tabbedController.tabButtons = tabButtons; +} + +- (void)setState:(MWMSearchManagerState)state +{ + if (_state == state) + return; + [self.delegate searchViewWillEnterState:state]; + if (_state == MWMSearchManagerStateHidden) + [self changeFromHiddenState]; + _state = state; + switch (state) + { + case MWMSearchManagerStateHidden: + [self changeToHiddenState]; + break; + case MWMSearchManagerStateDefault: + [self changeToDefaultState]; + break; + case MWMSearchManagerStateTableSearch: + [self changeToTableSearchState]; + break; + case MWMSearchManagerStateMapSearch: + [self changeToMapSearchState]; + break; + } + [self.delegate searchViewDidEnterState:state]; +} + +- (UIView *)view +{ + return self.rootView; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.h new file mode 100644 index 0000000000..e75397c54e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.h @@ -0,0 +1,5 @@ +@interface MWMSearchTextField : UITextField + +@property (nonatomic) BOOL isSearching; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.mm new file mode 100644 index 0000000000..c952c4c860 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchTextField.mm @@ -0,0 +1,41 @@ +#import "MWMSearchTextField.h" + +@implementation MWMSearchTextField + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (!self) + return nil; + self.isSearching = NO; + self.leftViewMode = UITextFieldViewModeAlways; + return self; +} + +- (CGRect)leftViewRectForBounds:(CGRect)bounds +{ + CGRect rect = [super leftViewRectForBounds:bounds]; + rect.origin.x += 8.0; + return rect; +} + +#pragma mark - Properties + +- (void)setIsSearching:(BOOL)isSearching +{ + _isSearching = isSearching; + if (isSearching) + { + UIActivityIndicatorView * view = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + view.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; + [view startAnimating]; + view.bounds = self.leftView.bounds; + self.leftView = view; + } + else + { + self.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ic_searchbar_search_light"]]; + } +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.h new file mode 100644 index 0000000000..b8f6f4e5c5 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.h @@ -0,0 +1,20 @@ +#import "UIKitCategories.h" + +@class MWMSearchTabButtonsView; + +@protocol MWMSearchViewProtocol + +- (void)searchFrameUpdated:(CGRect)frame; + +@end + +@interface MWMSearchView : SolidTouchView + +@property (nonatomic) BOOL isVisible; + +@property (nonatomic) BOOL tabBarIsVisible; +@property (nonatomic) BOOL compact; + +@property (weak, nonatomic) id delegate; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.mm new file mode 100644 index 0000000000..57af34ee0e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/MWMSearchView.mm @@ -0,0 +1,138 @@ +#import "Common.h" +#import "MWMSearchTabButtonsView.h" +#import "MWMSearchView.h" +#import "UIKitCategories.h" + +static CGFloat const kWidthForiPad = 320.0; + +@interface MWMSearchView () + +@property (weak, nonatomic) IBOutlet UIView * searchBar; + +@property (weak, nonatomic) IBOutlet UIView * infoWrapper; + +@property (weak, nonatomic) IBOutlet UIView * tabBar; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * tabBarTopOffset; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * tabBarHeight; + +@property (nonatomic) CGFloat correctMinX; + +@end + +@implementation MWMSearchView + +- (void)awakeFromNib +{ + self.autoresizingMask = UIViewAutoresizingFlexibleHeight; + self.correctMinX = -kWidthForiPad; + CALayer * sl = self.layer; + CALayer * sbl = self.searchBar.layer; + CALayer * tbl = self.tabBar.layer; + CGFloat const scale = UIScreen.mainScreen.scale; + sl.shouldRasterize = sbl.shouldRasterize = tbl.shouldRasterize = YES; + sl.rasterizationScale = sbl.rasterizationScale = tbl.rasterizationScale = scale; +} + +- (void)setFrame:(CGRect)frame +{ + BOOL const equal = CGRectEqualToRect(super.frame, frame); + super.frame = frame; + if (!equal && self.superview && self.isVisible) + [self.delegate searchFrameUpdated:frame]; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + if (IPAD) + { + self.frame = {{self.correctMinX, 0.0}, {kWidthForiPad, self.superview.height}}; + } + else + { + self.frame = self.superview.bounds; + if (self.compact) + self.height = self.searchBar.minY + self.searchBar.height; + } + if (self.tabBarIsVisible) + self.tabBar.hidden = NO; + CGFloat const tabBarHeight = self.height > self.width ? 64.0 : 44.0; + self.tabBarHeight.constant = tabBarHeight; + self.tabBarTopOffset.constant = self.tabBarIsVisible ? 0.0 : -tabBarHeight; + self.searchBar.layer.shadowRadius = self.tabBarIsVisible ? 0.0 : 2.0; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ + { + [self.tabBar.subviews enumerateObjectsUsingBlock:^(MWMSearchTabButtonsView * btn, NSUInteger idx, BOOL *stop) + { + [btn setNeedsLayout]; + }]; + if (!self.tabBarIsVisible) + self.tabBar.hidden = YES; + [self.tabBar layoutIfNeeded]; + }]; + [super layoutSubviews]; +} + +#pragma mark - Properties + +- (void)setIsVisible:(BOOL)isVisible +{ + if (_isVisible == isVisible) + return; + _isVisible = isVisible; + self.minY = 0.0; + self.height = self.superview.height; + if (IPAD) + { + if (isVisible) + self.hidden = NO; + self.correctMinX = self.minX = isVisible ? -kWidthForiPad : 0.0; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ + { + self.correctMinX = self.minX = isVisible ? 0.0: -kWidthForiPad; + } + completion:^(BOOL finished) + { + if (!isVisible) + { + self.hidden = YES; + [self removeFromSuperview]; + } + }]; + } + else + { + self.hidden = !isVisible; + if (!isVisible) + [self removeFromSuperview]; + } + [self setNeedsLayout]; +} + +- (void)setTabBarIsVisible:(BOOL)tabBarIsVisible +{ + if (_tabBarIsVisible == tabBarIsVisible) + return; + _tabBarIsVisible = tabBarIsVisible; + [self setNeedsLayout]; +} + +- (void)setCompact:(BOOL)compact +{ + _compact = compact; + if (!compact) + self.infoWrapper.hidden = NO; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ + { + self.infoWrapper.alpha = compact ? 0.0 : 1.0; + } + completion:^(BOOL finished) + { + if (compact) + self.infoWrapper.hidden = YES; + self.autoresizingMask = compact ? UIViewAutoresizingFlexibleWidth : UIViewAutoresizingFlexibleHeight; + [self setNeedsLayout]; + }]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.h new file mode 100644 index 0000000000..2510fe1018 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.h @@ -0,0 +1,18 @@ +@class MWMSearchTabButtonsView; + +@protocol MWMSearchTabButtonsViewProtocol + +- (void)tabButtonPressed:(MWMSearchTabButtonsView *)sender; + +@end + +IB_DESIGNABLE +@interface MWMSearchTabButtonsView : UIView + +@property (nonatomic) BOOL selected; + +@property (nonatomic) IBInspectable UIImage * iconImage; +@property (nonatomic) IBInspectable UIImage * iconImageHighlighted; +@property (nonatomic) IBInspectable NSString * localizedText; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.mm new file mode 100644 index 0000000000..e3d0de3a3f --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabButtons/MWMSearchTabButtonsView.mm @@ -0,0 +1,103 @@ +#import "MWMSearchManager.h" +#import "MWMSearchTabButtonsView.h" +#import "UIColor+MapsMeColor.h" +#import "UIKitCategories.h" + +static CGFloat const kIconToLabelSpacing = 4.0; + +@interface MWMSearchTabButtonsView () + +@property (nonatomic) IBOutlet UIView * rootView; + +@property (weak, nonatomic) IBOutlet UIImageView * icon; +@property (weak, nonatomic) IBOutlet UILabel * label; + +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * iconLeft; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * iconTop; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * labelLeft; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * labelTop; + +@property (weak, nonatomic) IBOutlet id delegate; + +@end + +@implementation MWMSearchTabButtonsView + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) + { + self.rootView = [[NSBundle.mainBundle loadNibNamed:self.class.className owner:self options:nil] firstObject]; + [self addSubview:self.rootView]; + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; + } + return self; +} + +- (IBAction)buttonTap:(UITapGestureRecognizer *)sender +{ + [self.delegate tabButtonPressed:self]; +} + +#pragma mark - Layout + +- (void)layoutPortrait +{ + CGFloat const contentHeight = self.icon.height + kIconToLabelSpacing + self.label.height; + CGFloat const topOffset = (self.height - contentHeight) / 2.0; + + self.iconTop.constant = nearbyint(topOffset); + self.labelTop.constant = nearbyint(topOffset + self.icon.height + kIconToLabelSpacing); + + self.iconLeft.constant = nearbyint((self.width - self.icon.width) / 2.0); + self.labelLeft.constant = nearbyint((self.width - self.label.width) / 2.0); +} + +- (void)layoutLandscape +{ + CGFloat const contentWidth = self.icon.width + kIconToLabelSpacing + self.label.width; + CGFloat const leftOffset = (self.width - contentWidth) / 2.0; + self.iconLeft.constant = nearbyint(leftOffset); + self.labelLeft.constant = nearbyint(leftOffset + self.icon.width + kIconToLabelSpacing); + + self.iconTop.constant = nearbyint((self.height - self.icon.height) / 2.0); + self.labelTop.constant = nearbyint((self.height - self.label.height) / 2.0); +} + +- (void)layoutSubviews +{ + self.rootView.frame = self.bounds; + if (self.height < 60.0) + [self layoutLandscape]; + else + [self layoutPortrait]; + [super layoutSubviews]; +} + +#pragma mark - Properties + +- (void)setSelected:(BOOL)selected +{ + _selected = self.icon.highlighted = selected; + self.label.textColor = selected ? UIColor.linkBlue : UIColor.blackSecondaryText; +} + +- (void)setIconImage:(UIImage *)iconImage +{ + _iconImage = self.icon.image = iconImage; +} + +- (void)setIconImageHighlighted:(UIImage *)iconImageHighlighted +{ + _iconImageHighlighted = self.icon.highlightedImage = iconImageHighlighted; +} + +- (void)setLocalizedText:(NSString *)localizedText +{ + _localizedText = self.label.text = L(localizedText); +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.h new file mode 100644 index 0000000000..1060616006 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.h @@ -0,0 +1,10 @@ +@interface MWMSearchBookmarksCell : UITableViewCell + +@property (nonatomic) BOOL isLightTheme; + +- (void)configForIndex:(NSInteger)index; + ++ (CGFloat)defaultCellHeight; +- (CGFloat)cellHeight; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.mm new file mode 100644 index 0000000000..4630fa4f8e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksCell.mm @@ -0,0 +1,97 @@ +#import "BookmarksVC.h" +#import "MWMSearchBookmarksCell.h" +#import "UIFont+MapsMeFonts.h" + +#include "Framework.h" + +@interface MWMSearchBookmarksCell () + +@property (nonatomic) NSInteger index; +@property (nonatomic) BOOL isVisible; +@property (nonatomic) NSUInteger count; + +@property (weak, nonatomic) IBOutlet UIButton * visibilityButton; +@property (weak, nonatomic) IBOutlet UILabel * titleLabel; +@property (weak, nonatomic) IBOutlet UILabel * countLabel; +@property (weak, nonatomic) IBOutlet UIImageView * openArrow; + +@end + +@implementation MWMSearchBookmarksCell + +- (void)awakeFromNib +{ + self.layer.shouldRasterize = YES; + self.layer.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)configForIndex:(NSInteger)index +{ + BookmarkCategory const * cat = GetFramework().GetBmCategory(index); + self.index = index; + self.isVisible = cat->IsVisible(); + self.count = cat->GetBookmarksCount() + cat->GetTracksCount(); + self.titleLabel.text = @(cat->GetName().c_str()); +} + +- (IBAction)toggleVisibility +{ + self.isVisible = !self.isVisible; + BookmarkCategory * cat = GetFramework().GetBmCategory(self.index); + cat->SetVisible(self.isVisible); + cat->SaveToKMLFile(); +} + +- (IBAction)openBookmarks +{ + BookmarksVC * bvc = [[BookmarksVC alloc] initWithCategory:self.index]; + UINavigationController * rootVC = (UINavigationController *)UIApplication.sharedApplication.delegate.window.rootViewController; + [rootVC pushViewController:bvc animated:YES]; +} + +- (void)setTitle:(NSString *)title +{ + self.titleLabel.text = title; +} + ++ (CGFloat)defaultCellHeight +{ + return 44.0; +} + +- (CGFloat)cellHeight +{ + return ceil([self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height); +} + +#pragma mark - Properties + +- (void)setIsVisible:(BOOL)isVisible +{ + _isVisible = self.visibilityButton.selected = isVisible; +} + +- (void)setCount:(NSUInteger)count +{ + _count = count; + self.countLabel.text = @(count).stringValue; +} + +- (void)setIsLightTheme:(BOOL)isLightTheme +{ + _isLightTheme = isLightTheme; + if (isLightTheme) + { + [self.visibilityButton setImage:[UIImage imageNamed:@"ic_hide_light"] forState:UIControlStateNormal]; + [self.visibilityButton setImage:[UIImage imageNamed:@"ic_show_light"] forState:UIControlStateSelected]; + self.openArrow.image = [UIImage imageNamed:@"ic_carrot_light"]; + } + else + { + [self.visibilityButton setImage:[UIImage imageNamed:@"ic_hide_dark"] forState:UIControlStateNormal]; + [self.visibilityButton setImage:[UIImage imageNamed:@"ic_show_dark"] forState:UIControlStateSelected]; + self.openArrow.image = [UIImage imageNamed:@"ic_carrot_dark"]; + } +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.h new file mode 100644 index 0000000000..d7a2a7ba88 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.h @@ -0,0 +1,10 @@ +#import "MWMSearchTabbedCollectionViewCell.h" +#import "MWMSearchTabbedViewProtocol.h" + +@interface MWMSearchBookmarksManager : NSObject + +@property (weak, nonatomic) id delegate; + +- (void)attachCell:(MWMSearchTabbedCollectionViewCell *)cell; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.mm new file mode 100644 index 0000000000..01ab0f5fd2 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/BookmarksTab/MWMSearchBookmarksManager.mm @@ -0,0 +1,109 @@ +#import "Macros.h" +#import "MWMSearchBookmarksCell.h" +#import "MWMSearchBookmarksManager.h" + +#include "Framework.h" + +extern NSString * const kBookmarksChangedNotification; + +static NSString * const kBookmarksCellIdentifier = @"MWMSearchBookmarksCell"; + +@interface MWMSearchBookmarksManager () + +@property (weak, nonatomic) MWMSearchTabbedCollectionViewCell * cell; + +@property (nonatomic) MWMSearchBookmarksCell * sizingCell; + +@end + +@implementation MWMSearchBookmarksManager + +- (instancetype)init +{ + self = [super init]; + if (self) + { + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateCell) name:kBookmarksChangedNotification object:nil]; + } + return self; +} + +- (void)dealloc +{ + [NSNotificationCenter.defaultCenter removeObserver:self]; +} + +- (void)attachCell:(MWMSearchTabbedCollectionViewCell *)cell +{ + self.cell = cell; + [self updateCell]; +} + +- (void)updateCell +{ + MWMSearchTabbedCollectionViewCell * cell = self.cell; + if (!cell) + return; + if (GetFramework().GetBmCategoriesCount() > 0) + { + cell.noResultsView.hidden = YES; + UITableView * tableView = cell.tableView; + tableView.hidden = NO; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerNib:[UINib nibWithNibName:kBookmarksCellIdentifier bundle:nil] + forCellReuseIdentifier:kBookmarksCellIdentifier]; + [tableView reloadData]; + } + else + { + cell.tableView.hidden = YES; + cell.noResultsView.hidden = NO; + cell.noResultsImage.image = [UIImage + imageNamed:IPAD ? @"img_no_bookmarks_ipad_light" : @"img_no_bookmarks_iphone_light"]; + cell.noResultsTitle.text = L(@"search_bookmarks_no_results_title"); + cell.noResultsText.text = L(@"search_bookmarks_no_results_text"); + } +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return GetFramework().GetBmCategoriesCount(); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return [tableView dequeueReusableCellWithIdentifier:kBookmarksCellIdentifier]; +} + +#pragma mark - UITableViewDelegate + +- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return MWMSearchBookmarksCell.defaultCellHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + [self.sizingCell configForIndex:indexPath.row]; + return self.sizingCell.cellHeight; +} + +- (void)tableView:(UITableView *)tableView willDisplayCell:(MWMSearchBookmarksCell *)cell +forRowAtIndexPath:(NSIndexPath *)indexPath +{ + [cell configForIndex:indexPath.row]; +} + +#pragma mark - Properties + +- (MWMSearchBookmarksCell *)sizingCell +{ + if (!_sizingCell) + _sizingCell = [self.cell.tableView dequeueReusableCellWithIdentifier:kBookmarksCellIdentifier]; + return _sizingCell; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.h new file mode 100644 index 0000000000..804561befa --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.h @@ -0,0 +1,10 @@ +#import "MWMSearchTabbedCollectionViewCell.h" +#import "MWMSearchTabbedViewProtocol.h" + +@interface MWMSearchCategoriesManager : NSObject + +@property (weak, nonatomic) id delegate; + +- (void)attachCell:(MWMSearchTabbedCollectionViewCell *)cell; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm new file mode 100644 index 0000000000..b006cc61d6 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm @@ -0,0 +1,61 @@ +#import "Macros.h" +#import "MWMSearchCategoriesManager.h" +#import "MWMSearchCategoryCell.h" +#import "Statistics.h" + +#include "base/macros.hpp" + +static NSString * const kCellIdentifier = @"MWMSearchCategoryCell"; + +static char const * categoriesNames[] = { + "food", "hotel", "tourism", "wifi", "transport", "fuel", "parking", "shop", + "atm", "bank", "entertainment", "hospital", "pharmacy", "police", "toilet", "post"}; +static size_t const kCategoriesCount = ARRAY_SIZE(categoriesNames); + +@implementation MWMSearchCategoriesManager + +- (void)attachCell:(MWMSearchTabbedCollectionViewCell *)cell +{ + cell.noResultsView.hidden = YES; + UITableView * tableView = cell.tableView; + tableView.hidden = NO; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerNib:[UINib nibWithNibName:kCellIdentifier bundle:nil] + forCellReuseIdentifier:kCellIdentifier]; + [tableView reloadData]; +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return kCategoriesCount; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; +} + +#pragma mark - UITableViewDelegate + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return 44.0; +} + +- (void)tableView:(UITableView *)tableView willDisplayCell:(MWMSearchCategoryCell *)cell +forRowAtIndexPath:(NSIndexPath *)indexPath +{ + [cell setCategory:@(categoriesNames[indexPath.row]) isLightTheme:YES]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSString * string = @(categoriesNames[indexPath.row]); + [Statistics.instance logEvent:@"Category Selection" withParameters:@{ @"Category" : string }]; + [self.delegate searchText:[L(string) stringByAppendingString:@" "] forInputLocale:nil]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.h new file mode 100644 index 0000000000..600b0b6ac8 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.h @@ -0,0 +1,5 @@ +@interface MWMSearchCategoryCell : UITableViewCell + +- (void)setCategory:(NSString *)category isLightTheme:(BOOL)isLightTheme; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.mm new file mode 100644 index 0000000000..953d63837f --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoryCell.mm @@ -0,0 +1,28 @@ +#import "Macros.h" +#import "MWMSearchCategoryCell.h" + +@interface MWMSearchCategoryCell () + +@property (weak, nonatomic) IBOutlet UIImageView * icon; +@property (weak, nonatomic) IBOutlet UILabel * label; + +@end + +@implementation MWMSearchCategoryCell + +- (void)awakeFromNib +{ + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)setCategory:(NSString *)category isLightTheme:(BOOL)isLightTheme; +{ + self.label.text = L(category); + NSString * theme = isLightTheme ? @"light" : @"dark"; + NSString * imageName = [NSString stringWithFormat:@"ic_%@_%@", category, theme]; + self.icon.image = [UIImage imageNamed:imageName]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.h new file mode 100644 index 0000000000..809f2e7383 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.h @@ -0,0 +1,7 @@ +@interface MWMSearchHistoryClearCell : UITableViewCell + +@property (nonatomic) BOOL isLightTheme; + ++ (CGFloat)cellHeight; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.mm new file mode 100644 index 0000000000..4d1a893b06 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryClearCell.mm @@ -0,0 +1,31 @@ +#import "MWMSearchHistoryClearCell.h" + +@interface MWMSearchHistoryClearCell () + +@property (weak, nonatomic) IBOutlet UIImageView * icon; + +@end + +@implementation MWMSearchHistoryClearCell + +- (void)awakeFromNib +{ + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; +} + ++ (CGFloat)cellHeight +{ + return 44.0; +} + +#pragma mark - Properties + +- (void)setIsLightTheme:(BOOL)isLightTheme +{ + _isLightTheme = isLightTheme; + self.icon.image = [UIImage imageNamed:isLightTheme ? @"ic_clear_light" : @"ic_clear_dark"]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.h new file mode 100644 index 0000000000..7e50fa441a --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.h @@ -0,0 +1,10 @@ +#import "MWMSearchTabbedCollectionViewCell.h" +#import "MWMSearchTabbedViewProtocol.h" + +@interface MWMSearchHistoryManager : NSObject + +@property (weak, nonatomic) id delegate; + +- (void)attachCell:(MWMSearchTabbedCollectionViewCell *)cell; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.mm new file mode 100644 index 0000000000..406a6dcf9e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryManager.mm @@ -0,0 +1,140 @@ +#import "Common.h" +#import "Macros.h" +#import "MWMSearchHistoryClearCell.h" +#import "MWMSearchHistoryManager.h" +#import "MWMSearchHistoryRequestCell.h" + +#include "Framework.h" + +static NSString * const kRequestCellIdentifier = @"MWMSearchHistoryRequestCell"; +static NSString * const kClearCellIdentifier = @"MWMSearchHistoryClearCell"; + +@interface MWMSearchHistoryManager () + +@property (weak, nonatomic) MWMSearchTabbedCollectionViewCell * cell; + +@property (nonatomic) MWMSearchHistoryRequestCell * sizingCell; + +@end + +@implementation MWMSearchHistoryManager + +- (void)attachCell:(MWMSearchTabbedCollectionViewCell *)cell +{ + self.cell = cell; + UITableView * tableView = cell.tableView; + tableView.alpha = cell.noResultsView.alpha = 1.0; + if (GetFramework().GetLastSearchQueries().empty()) + { + tableView.hidden = YES; + cell.noResultsView.hidden = NO; + } + else + { + cell.noResultsView.hidden = YES; + tableView.hidden = NO; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerNib:[UINib nibWithNibName:kRequestCellIdentifier bundle:nil] + forCellReuseIdentifier:kRequestCellIdentifier]; + [tableView registerNib:[UINib nibWithNibName:kClearCellIdentifier bundle:nil] + forCellReuseIdentifier:kClearCellIdentifier]; + [tableView reloadData]; + } + cell.noResultsImage.image = [UIImage imageNamed:@"img_no_history_light"]; + cell.noResultsTitle.text = L(@"search_history_no_results_title"); + cell.noResultsText.text = L(@"search_history_no_results_text"); +} + +- (search::QuerySaver::TSearchRequest const &)queryAtIndex:(NSInteger)index +{ + Framework & f = GetFramework(); + NSAssert(index >= 0 && index < f.GetLastSearchQueries().size(), @"Invalid search history index"); + auto it = f.GetLastSearchQueries().cbegin(); + advance(it, index); + return *it; +} + +- (NSString *)stringAtIndex:(NSInteger)index +{ + return @([self queryAtIndex:index].second.c_str()); +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return GetFramework().GetLastSearchQueries().size() + 1; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row < GetFramework().GetLastSearchQueries().size()) + return [tableView dequeueReusableCellWithIdentifier:kRequestCellIdentifier]; + else + return [tableView dequeueReusableCellWithIdentifier:kClearCellIdentifier]; +} + +#pragma mark - UITableViewDelegate + +- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row < GetFramework().GetLastSearchQueries().size()) + return MWMSearchHistoryRequestCell.defaultCellHeight; + else + return MWMSearchHistoryClearCell.cellHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row < GetFramework().GetLastSearchQueries().size()) + { + [self.sizingCell config:[self stringAtIndex:indexPath.row]]; + return self.sizingCell.cellHeight; + } + else + return MWMSearchHistoryClearCell.cellHeight; +} + +- (void)tableView:(UITableView *)tableView willDisplayCell:(MWMSearchHistoryRequestCell *)cell +forRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row < GetFramework().GetLastSearchQueries().size()) + [cell config:[self stringAtIndex:indexPath.row]]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + Framework & f = GetFramework(); + if (indexPath.row < f.GetLastSearchQueries().size()) + { + search::QuerySaver::TSearchRequest const & query = [self queryAtIndex:indexPath.row]; + [self.delegate searchText:@(query.second.c_str()) forInputLocale:@(query.first.c_str())]; + } + else + { + f.ClearSearchHistory(); + MWMSearchTabbedCollectionViewCell * cell = self.cell; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ + { + cell.tableView.alpha = 0.0; + cell.noResultsView.alpha = 1.0; + } + completion:^(BOOL finished) + { + cell.tableView.hidden = YES; + cell.noResultsView.hidden = NO; + }]; + } +} + +#pragma mark - Properties + +- (MWMSearchHistoryRequestCell *)sizingCell +{ + if (!_sizingCell) + _sizingCell = [self.cell.tableView dequeueReusableCellWithIdentifier:kRequestCellIdentifier]; + return _sizingCell; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.h new file mode 100644 index 0000000000..82ae326b92 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.h @@ -0,0 +1,10 @@ +@interface MWMSearchHistoryRequestCell : UITableViewCell + +@property (nonatomic) BOOL isLightTheme; + +- (void)config:(NSString *)title; + ++ (CGFloat)defaultCellHeight; +- (CGFloat)cellHeight; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.mm new file mode 100644 index 0000000000..85d2393b87 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/HistoryTab/MWMSearchHistoryRequestCell.mm @@ -0,0 +1,49 @@ +#import "MWMSearchHistoryRequestCell.h" +#import "UIFont+MapsMeFonts.h" + +static CGFloat kPreferredMaxLayoutWidth = 244.0; + +@interface MWMSearchHistoryRequestCell () + +@property (weak, nonatomic) IBOutlet UILabel * title; +@property (weak, nonatomic) IBOutlet UIImageView * icon; + +@end + +@implementation MWMSearchHistoryRequestCell + +- (void)awakeFromNib +{ + self.layer.shouldRasterize = YES; + self.layer.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)config:(NSString *)title +{ + self.title.text = title; + self.title.preferredMaxLayoutWidth = kPreferredMaxLayoutWidth; + [self.title sizeToFit]; + [self setNeedsLayout]; + [self layoutIfNeeded]; +} + ++ (CGFloat)defaultCellHeight +{ + return 44.0; +} + +- (CGFloat)cellHeight +{ + return ceil([self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height); +} + +#pragma mark - Properties + +- (void)setIsLightTheme:(BOOL)isLightTheme +{ + _isLightTheme = isLightTheme; + self.icon.image = + [UIImage imageNamed:isLightTheme ? @"ic_history_label_light" : @"ic_history_label_dark"]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.h new file mode 100644 index 0000000000..215bd0ad9e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.h @@ -0,0 +1,10 @@ +@interface MWMSearchTabbedCollectionViewCell : UICollectionViewCell + +@property (weak, nonatomic) IBOutlet UITableView * tableView; + +@property (weak, nonatomic) IBOutlet UIView * noResultsView; +@property (weak, nonatomic) IBOutlet UIImageView * noResultsImage; +@property (weak, nonatomic) IBOutlet UILabel * noResultsTitle; +@property (weak, nonatomic) IBOutlet UILabel * noResultsText; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.mm new file mode 100644 index 0000000000..0762a27071 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedCollectionViewCell.mm @@ -0,0 +1,28 @@ +#import "MWMSearchTabbedCollectionViewCell.h" +#import "UIKitCategories.h" + +@interface MWMSearchTabbedCollectionViewCell () + +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * titleTopOffset; + +@end + +@implementation MWMSearchTabbedCollectionViewCell + +- (void)awakeFromNib +{ + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)layoutSubviews +{ + CGFloat const textBottom = self.noResultsImage.height + self.noResultsTitle.height + self.noResultsText.height + 68.0; + BOOL const compact = textBottom > self.height; + self.titleTopOffset.constant = compact ? 20. : 196.; + self.noResultsImage.hidden = compact; + [super layoutSubviews]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.h new file mode 100644 index 0000000000..3bd969e9a4 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.h @@ -0,0 +1,14 @@ +#import "MWMSearchTabbedViewProtocol.h" +#import "MWMSearchTabButtonsView.h" + +@interface MWMSearchTabbedViewController : UIViewController + +@property (copy, nonatomic) NSArray * tabButtons; +@property (weak, nonatomic) NSLayoutConstraint * scrollIndicatorOffset; +@property (weak, nonatomic) UIView * scrollIndicator; +@property (weak, nonatomic) id delegate; +@property (nonatomic) NSInteger selectedButtonTag; + +- (void)tabButtonPressed:(MWMSearchTabButtonsView *)sender; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.mm new file mode 100644 index 0000000000..d40fe18d11 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewController.mm @@ -0,0 +1,231 @@ +//#import "MWMSearchBookmarksManager.h" +#import "MWMSearchCategoriesManager.h" +#import "MWMSearchHistoryManager.h" +#import "MWMSearchTabbedCollectionViewCell.h" +#import "MWMSearchTabbedViewController.h" +#import "MWMSearchTabbedViewLayout.h" +#import "MWMSearchTabbedViewProtocol.h" +#import "UIKitCategories.h" + +static NSString * const kCollectionCell = @"MWMSearchTabbedCollectionViewCell"; + +typedef NS_ENUM(NSInteger, MWMSearchTabbedViewCell) +{ + MWMSearchTabbedViewCellHistory, + MWMSearchTabbedViewCellCategories, +// MWMSearchTabbedViewCellBookmarks, + MWMSearchTabbedViewCellCount +}; + +BOOL isOffsetInButton(CGFloat offset, MWMSearchTabButtonsView * button) +{ + CGRect const frame = button.frame; + CGFloat const left = frame.origin.x; + CGFloat const right = left + frame.size.width; + return left <= offset && offset <= right; +} + +@interface MWMSearchTabbedViewController () + +@property (weak, nonatomic) IBOutlet UICollectionView * tablesCollectionView; + +@property (weak, nonatomic) MWMSearchTabButtonsView * selectedButton; + +@property (nonatomic) MWMSearchHistoryManager * historyManager; +@property (nonatomic) MWMSearchCategoriesManager * categoriesManager; +//@property (nonatomic) MWMSearchBookmarksManager * bookmarksManager; + +@property (nonatomic) BOOL isRotating; + +@end + +@implementation MWMSearchTabbedViewController + +- (instancetype)init +{ + self = [super init]; + if (self) + [self setupDataSources]; + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self setupCollectionView]; + self.selectedButtonTag = 0; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [self.tablesCollectionView reloadData]; + [self refreshScrollPosition]; + [super viewWillAppear:animated]; +} + +#pragma mark - Layout + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration +{ + self.isRotating = YES; + [UIView animateWithDuration:duration animations:^ + { + [self refreshScrollPosition]; + } + completion:^(BOOL finished) + { + [self refreshScrollPosition]; + self.isRotating = NO; + }]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + self.isRotating = YES; + [coordinator animateAlongsideTransition:^(id context) + { + [self refreshScrollPosition]; + } + completion:^(id context) + { + self.isRotating = NO; + }]; +} + +#pragma mark - Setup + +- (void)setupCollectionView +{ + [self.tablesCollectionView registerNib:[UINib nibWithNibName:kCollectionCell bundle:nil] + forCellWithReuseIdentifier:kCollectionCell]; + ((MWMSearchTabbedViewLayout *)self.tablesCollectionView.collectionViewLayout).tablesCount = + MWMSearchTabbedViewCellCount; +} + +- (void)setupDataSources +{ + self.categoriesManager = [[MWMSearchCategoriesManager alloc] init]; + self.historyManager = [[MWMSearchHistoryManager alloc] init]; +// self.bookmarksManager = [[MWMSearchBookmarksManager alloc] init]; +} + +- (void)tabButtonPressed:(MWMSearchTabButtonsView *)sender +{ + dispatch_async(dispatch_get_main_queue(), ^ + { + [self.tablesCollectionView + scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:sender.tag inSection:0] + atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally + animated:YES]; + }); +} + +- (void)updateScrollPosition:(CGFloat)position +{ + self.scrollIndicatorOffset.constant = nearbyint(position); + CGFloat const btnMid = position + 0.5 * self.scrollIndicator.width; + if (self.selectedButton && isOffsetInButton(btnMid, self.selectedButton)) + return; + [self.tabButtons enumerateObjectsUsingBlock:^(MWMSearchTabButtonsView * btn, NSUInteger idx, BOOL *stop) + { + if (isOffsetInButton(btnMid, btn)) + { + self.selectedButton = btn; + *stop = YES; + } + }]; +} + +- (void)refreshScrollPosition +{ + self.scrollIndicatorOffset.constant = nearbyint(self.selectedButton.minX); + [self tabButtonPressed:self.selectedButton]; +} + +#pragma mark - UICollectionViewDataSource + +- (NSInteger)collectionView:(nonnull UICollectionView *)collectionView + numberOfItemsInSection:(NSInteger)section +{ + return MWMSearchTabbedViewCellCount; +} + +- (nonnull UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView + cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath +{ + MWMSearchTabbedCollectionViewCell * cell = + [collectionView dequeueReusableCellWithReuseIdentifier:kCollectionCell + forIndexPath:indexPath]; + MWMSearchTabbedViewCell cellType = static_cast(indexPath.item); + switch (cellType) + { + case MWMSearchTabbedViewCellHistory: + [self.historyManager attachCell:cell]; + break; + case MWMSearchTabbedViewCellCategories: + [self.categoriesManager attachCell:cell]; + break; +// case MWMSearchTabbedViewCellBookmarks: +// [self.bookmarksManager attachCell:cell]; +// break; + default: + break; + } + return cell; +} + +#pragma mark - UIScrollViewDelegate + +- (void)scrollViewDidScroll:(nonnull UIScrollView *)scrollView +{ + if (self.isRotating) + return; + CGFloat const scrollOffset = scrollView.contentOffset.x; + CGFloat const indWidth = self.scrollIndicator.width; + CGFloat const scrWidth = self.view.width; + [self updateScrollPosition:scrollOffset * indWidth / scrWidth]; +} + +#pragma mark - Properties + +- (void)setSelectedButton:(MWMSearchTabButtonsView *)selectedButton +{ + [self.tabButtons enumerateObjectsUsingBlock:^(MWMSearchTabButtonsView * btn, NSUInteger idx, BOOL *stop) + { + btn.selected = NO; + }]; + _selectedButton = selectedButton; + selectedButton.selected = YES; +} + +- (void)setDelegate:(id)delegate +{ + _delegate = self.categoriesManager.delegate = self.historyManager.delegate = delegate; +// self.bookmarksManager.delegate = delegate; +} + +- (void)setSelectedButtonTag:(NSInteger)selectedButtonTag +{ + [self.tabButtons enumerateObjectsUsingBlock:^(MWMSearchTabButtonsView * btn, NSUInteger idx, BOOL * stop) + { + if (btn.tag == selectedButtonTag) + { + self.selectedButton = btn; + *stop = YES; + } + }]; + [self updateScrollPosition:self.selectedButton.minX]; + [self.tablesCollectionView + scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:selectedButtonTag inSection:0] + atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally + animated:NO]; +} + +- (NSInteger)selectedButtonTag +{ + return self.selectedButton.tag; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.h new file mode 100644 index 0000000000..0a2d52db84 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.h @@ -0,0 +1,5 @@ +@interface MWMSearchTabbedViewLayout : UICollectionViewLayout + +@property (nonatomic) NSInteger tablesCount; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.mm new file mode 100644 index 0000000000..5b7a784e94 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewLayout.mm @@ -0,0 +1,36 @@ +#import "MWMSearchTabbedViewLayout.h" + +@implementation MWMSearchTabbedViewLayout + +- (CGSize)collectionViewContentSize +{ + CGSize size = self.collectionView.frame.size; + return CGSizeMake(self.tablesCount * size.width, size.height); +} + +- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath +{ + UICollectionViewLayoutAttributes * attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; + CGSize size = self.collectionView.frame.size; + attr.size = size; + attr.center = CGPointMake((indexPath.item + 0.5) * size.width, 0.5 * size.height); + return attr; +} + +- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect +{ + NSMutableArray * attrs = [NSMutableArray array]; + for (NSUInteger index = 0; index < self.tablesCount; index++) + { + NSIndexPath * indexPath = [NSIndexPath indexPathForItem:index inSection:0]; + [attrs addObject:[self layoutAttributesForItemAtIndexPath:indexPath]]; + } + return attrs; +} + +- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds +{ + return YES; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewProtocol.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewProtocol.h new file mode 100644 index 0000000000..2b92fc1b49 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/MWMSearchTabbedViewProtocol.h @@ -0,0 +1,7 @@ +@protocol MWMSearchTabbedViewProtocol + +@required + +- (void)searchText:(NSString *)text forInputLocale:(NSString *)locale; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.h new file mode 100644 index 0000000000..02877705a5 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.h @@ -0,0 +1,9 @@ +#include "search/result.hpp" + +@interface MWMSearchCell : UITableViewCell + +- (void)config:(search::Result &)result; + +@property (nonatomic) CGFloat preferredMaxLayoutWidth; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.mm new file mode 100644 index 0000000000..e1a1d5bd5b --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCell.mm @@ -0,0 +1,61 @@ +#import "MWMSearchCell.h" + +#include "Framework.h" + +@interface MWMSearchCell () + +@property (weak, nonatomic) IBOutlet UILabel * titleLabel; + +@end + +@implementation MWMSearchCell + +- (void)awakeFromNib +{ + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)config:(search::Result &)result +{ + GetFramework().LoadSearchResultMetadata(result); + NSString * title = @(result.GetString()); + if (!title) + { + self.titleLabel.text = @""; + return; + } + NSDictionary * selectedTitleAttributes = [self selectedTitleAttributes]; + NSDictionary * unselectedTitleAttributes = [self unselectedTitleAttributes]; + if (!selectedTitleAttributes || !unselectedTitleAttributes) + { + self.titleLabel.text = title; + return; + } + NSMutableAttributedString * attributedTitle = + [[NSMutableAttributedString alloc] initWithString:title]; + [attributedTitle addAttributes:unselectedTitleAttributes range:NSMakeRange(0, title.length)]; + size_t const rangesCount = result.GetHighlightRangesCount(); + for (size_t i = 0; i < rangesCount; ++i) + { + pair const range = result.GetHighlightRange(i); + [attributedTitle addAttributes:selectedTitleAttributes + range:NSMakeRange(range.first, range.second)]; + } + self.titleLabel.attributedText = attributedTitle; + self.titleLabel.preferredMaxLayoutWidth = self.preferredMaxLayoutWidth; + [self.titleLabel sizeToFit]; +} + +- (NSDictionary *)selectedTitleAttributes +{ + return nil; +} + +- (NSDictionary *)unselectedTitleAttributes +{ + return nil; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.h new file mode 100644 index 0000000000..0d0bc010c7 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.h @@ -0,0 +1,12 @@ +#import "MWMSearchCell.h" + +#include "search/result.hpp" + +@interface MWMSearchCommonCell : MWMSearchCell + +@property (nonatomic) BOOL isLightTheme; + ++ (CGFloat)defaultCellHeight; +- (CGFloat)cellHeight; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.mm new file mode 100644 index 0000000000..bf33ad288c --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchCommonCell.mm @@ -0,0 +1,144 @@ +#import "LocationManager.h" +#import "MapsAppDelegate.h" +#import "MWMSearchCommonCell.h" +#import "UIColor+MapsMeColor.h" +#import "UIFont+MapsMeFonts.h" +#import "UIKitCategories.h" + +#include "indexer/mercator.hpp" +#include "platform/measurement_utils.hpp" + +@interface MWMSearchCommonCell () + +@property (weak, nonatomic) IBOutlet UILabel * typeLabel; +@property (weak, nonatomic) IBOutlet UIView * infoView; +@property (weak, nonatomic) IBOutlet UILabel * infoLabel; +@property (weak, nonatomic) IBOutlet UIView * infoRatingView; +@property (nonatomic) IBOutletCollection(UIImageView) NSArray * infoRatingStars; +@property (weak, nonatomic) IBOutlet UILabel * locationLabel; +@property (weak, nonatomic) IBOutlet UILabel * distanceLabel; +@property (weak, nonatomic) IBOutlet UIView * closedView; + +@end + +@implementation MWMSearchCommonCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + self.preferredMaxLayoutWidth = 220.0; +} + +- (void)config:(search::Result &)result +{ + [super config:result]; + self.typeLabel.text = @(result.GetFeatureType()); + + NSUInteger starsCount = result.GetStarsCount(); + NSString * cuisine = @(result.GetCuisine()); + if (starsCount > 0) + [self setInfoRating:starsCount]; + else if (cuisine.length > 0) + [self setInfoText:cuisine.capitalizedString]; + else + [self clearInfo]; + + self.locationLabel.text = @(result.GetRegionString()); + self.locationLabel.preferredMaxLayoutWidth = self.preferredMaxLayoutWidth; + [self.locationLabel sizeToFit]; + + self.closedView.hidden = !result.IsClosed(); + if (result.HasPoint()) + { + string distanceStr; + double lat, lon; + LocationManager * locationManager = MapsAppDelegate.theApp.m_locationManager; + if ([locationManager getLat:lat Lon:lon]) + { + m2::PointD const mercLoc = MercatorBounds::FromLatLon(lat, lon); + double const dist = MercatorBounds::DistanceOnEarth(mercLoc, result.GetFeatureCenter()); + MeasurementUtils::FormatDistance(dist, distanceStr); + } + self.distanceLabel.text = @(distanceStr.c_str()); + } + [self setNeedsLayout]; + [self layoutIfNeeded]; +} + +- (void)setInfoText:(NSString *)infoText +{ + self.infoView.hidden = NO; + self.infoLabel.hidden = NO; + self.infoRatingView.hidden = YES; + self.infoLabel.text = infoText; +} + +- (void)setInfoRating:(NSUInteger)infoRating +{ + self.infoView.hidden = NO; + self.infoRatingView.hidden = NO; + self.infoLabel.hidden = YES; + [self.infoRatingStars enumerateObjectsUsingBlock:^(UIImageView * star, NSUInteger idx, BOOL *stop) + { + star.highlighted = star.tag <= infoRating; + }]; +} + +- (void)clearInfo +{ + self.infoView.hidden = YES; +} + +- (NSDictionary *)selectedTitleAttributes +{ + static NSDictionary * selectedAttributes; + if (!selectedAttributes) + selectedAttributes = @{NSForegroundColorAttributeName : UIColor.blackPrimaryText, + NSFontAttributeName : UIFont.bold17}; + return selectedAttributes; +} + +- (NSDictionary *)unselectedTitleAttributes +{ + static NSDictionary * unselectedAttributes; + if (!unselectedAttributes) + unselectedAttributes = @{NSForegroundColorAttributeName : UIColor.blackPrimaryText, + NSFontAttributeName : UIFont.regular17}; + return unselectedAttributes; +} + ++ (CGFloat)defaultCellHeight +{ + return 80.0; +} + +- (CGFloat)cellHeight +{ + return ceil([self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height); +} + +#pragma mark - Properties + +- (void)setIsLightTheme:(BOOL)isLightTheme +{ + _isLightTheme = isLightTheme; + UIImage * star = nil; + UIImage * starHighlighted = nil; + if (isLightTheme) + { + star = [UIImage imageNamed:@"hotel_star_off_light"]; + starHighlighted = [UIImage imageNamed:@"hotel_star_on_light"]; + } + else + { + star = [UIImage imageNamed:@"hotel_star_off_dark"]; + starHighlighted = [UIImage imageNamed:@"hotel_star_on_dark"]; + } + [self.infoRatingStars enumerateObjectsUsingBlock:^(UIImageView * starView, NSUInteger idx, BOOL * stop) + { + [starView setImage:star]; + [starView setHighlightedImage:starHighlighted]; + }]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.h new file mode 100644 index 0000000000..57b1f83a80 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.h @@ -0,0 +1,7 @@ +@interface MWMSearchShowOnMapCell : UITableViewCell + +@property (nonatomic) BOOL isLightTheme; + ++ (CGFloat)cellHeight; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.mm new file mode 100644 index 0000000000..f14dc0dcd1 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchShowOnMapCell.mm @@ -0,0 +1,17 @@ +#import "MWMSearchShowOnMapCell.h" + +@implementation MWMSearchShowOnMapCell + +- (void)awakeFromNib +{ + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; +} + ++ (CGFloat)cellHeight +{ + return 44.0; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.h new file mode 100644 index 0000000000..802ee0d29e --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.h @@ -0,0 +1,10 @@ +#import "MWMSearchCell.h" + +@interface MWMSearchSuggestionCell : MWMSearchCell + +@property (nonatomic) BOOL isLightTheme; +@property (nonatomic) BOOL isLastCell; + ++ (CGFloat)cellHeight; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.mm new file mode 100644 index 0000000000..96657c6279 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchSuggestionCell.mm @@ -0,0 +1,51 @@ +#import "MWMSearchSuggestionCell.h" +#import "UIColor+MapsMeColor.h" +#import "UIFont+MapsMeFonts.h" + +@interface MWMSearchSuggestionCell () + +@property (weak, nonatomic) IBOutlet UIImageView * icon; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * separatorLeftOffset; + +@end + +@implementation MWMSearchSuggestionCell + +- (NSDictionary *)selectedTitleAttributes +{ + static NSDictionary * selectedAttributes; + if (!selectedAttributes) + selectedAttributes = @{NSForegroundColorAttributeName : UIColor.linkBlue, + NSFontAttributeName : UIFont.bold16}; + return selectedAttributes; +} + +- (NSDictionary *)unselectedTitleAttributes +{ + static NSDictionary * unselectedAttributes; + if (!unselectedAttributes) + unselectedAttributes = @{NSForegroundColorAttributeName : UIColor.linkBlue, + NSFontAttributeName : UIFont.regular16}; + return unselectedAttributes; +} + ++ (CGFloat)cellHeight +{ + return 44.0; +} + +#pragma mark - Properties + +- (void)setIsLightTheme:(BOOL)isLightTheme +{ + _isLightTheme = isLightTheme; + self.icon.image = [UIImage imageNamed:isLightTheme ? @"ic_search_suggest_light" : @"ic_search_suggest_dark"]; +} + +- (void)setIsLastCell:(BOOL)isLastCell +{ + _isLastCell = isLastCell; + self.separatorLeftOffset.constant = isLastCell ? 0.0 : 60.0; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.h new file mode 100644 index 0000000000..5c24f14517 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.h @@ -0,0 +1,9 @@ +@interface MWMSearchTableView : UIView + +@property (weak, nonatomic) IBOutlet UITableView * tableView; + +@property (weak, nonatomic) IBOutlet UIView * noResultsView; +@property (weak, nonatomic) IBOutlet UIImageView * noResultsImage; +@property (weak, nonatomic) IBOutlet UILabel * noResultsText; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.mm new file mode 100644 index 0000000000..974d5dc3df --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableView.mm @@ -0,0 +1,28 @@ +#import "MWMSearchTableView.h" +#import "UIKitCategories.h" + +@interface MWMSearchTableView () + +@property (weak, nonatomic) IBOutlet NSLayoutConstraint * textTopOffset; + +@end + +@implementation MWMSearchTableView + +- (void)awakeFromNib +{ + CALayer * sl = self.layer; + sl.shouldRasterize = YES; + sl.rasterizationScale = UIScreen.mainScreen.scale; +} + +- (void)layoutSubviews +{ + CGFloat const textBottom = self.noResultsImage.height + self.noResultsText.height + 68.0; + BOOL const compact = textBottom > self.height; + self.textTopOffset.constant = compact ? 20. : 160.; + self.noResultsImage.hidden = compact; + [super layoutSubviews]; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.h b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.h new file mode 100644 index 0000000000..5311e1dabd --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.h @@ -0,0 +1,22 @@ +#import "MWMSearchManager.h" +#import "MWMSearchTextField.h" +#import "MWMSearchTabbedViewProtocol.h" + +@protocol MWMSearchTableViewProtocol + +@property (nonnull, weak, nonatomic) MWMSearchTextField * searchTextField; + +@property (nonatomic) MWMSearchManagerState state; + +@end + +@interface MWMSearchTableViewController : UIViewController + +@property (nonatomic) BOOL searchOnMap; + +- (nonnull instancetype)init __attribute__((unavailable("init is not available"))); +- (nonnull instancetype)initWithDelegate:(nonnull id)delegate; + +- (void)searchText:(nonnull NSString *)text forInputLocale:(nullable NSString *)locale; + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.mm new file mode 100644 index 0000000000..eeedc7ff68 --- /dev/null +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TableView/MWMSearchTableViewController.mm @@ -0,0 +1,360 @@ +#import "LocationManager.h" +#import "Macros.h" +#import "MapsAppDelegate.h" +#import "MWMSearchCommonCell.h" +#import "MWMSearchShowOnMapCell.h" +#import "MWMSearchSuggestionCell.h" +#import "MWMSearchTableView.h" +#import "MWMSearchTableViewController.h" +#import "ToastView.h" +#import "UIKitCategories.h" + +#include "std/vector.hpp" + +static NSString * const kTableShowOnMapCell = @"MWMSearchShowOnMapCell"; +static NSString * const kTableSuggestionCell = @"MWMSearchSuggestionCell"; +static NSString * const kTableCommonCell = @"MWMSearchCommonCell"; + +typedef NS_ENUM(NSUInteger, MWMSearchTableCellType) +{ + MWMSearchTableCellTypeOnMap, + MWMSearchTableCellTypeSuggestion, + MWMSearchTableCellTypeCommon +}; + +NSString * identifierForType(MWMSearchTableCellType type) +{ + switch (type) + { + case MWMSearchTableCellTypeOnMap: + return kTableShowOnMapCell; + case MWMSearchTableCellTypeSuggestion: + return kTableSuggestionCell; + case MWMSearchTableCellTypeCommon: + return kTableCommonCell; + } +} + +@interface MWMSearchTableViewController () + +@property (weak, nonatomic) IBOutlet UITableView * tableView; + +@property (nonatomic) BOOL watchLocationUpdates; + +@property (nonatomic) MWMSearchCommonCell * commonSizingCell; + +@property (weak, nonatomic) id delegate; + +@end + +@implementation MWMSearchTableViewController +{ + search::SearchParams searchParams; + search::Results searchResults; +} + +- (nonnull instancetype)initWithDelegate:(id)delegate +{ + self = [super init]; + if (self) + { + self.delegate = delegate; + [self setupSearchParams]; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self setupTableView]; +} + +- (void)setupTableView +{ + [self.tableView registerNib:[UINib nibWithNibName:kTableShowOnMapCell bundle:nil] + forCellReuseIdentifier:kTableShowOnMapCell]; + [self.tableView registerNib:[UINib nibWithNibName:kTableSuggestionCell bundle:nil] + forCellReuseIdentifier:kTableSuggestionCell]; + [self.tableView registerNib:[UINib nibWithNibName:kTableCommonCell bundle:nil] + forCellReuseIdentifier:kTableCommonCell]; +} + +- (void)setupSearchParams +{ + __weak auto weakSelf = self; + searchParams.m_callback = ^(search::Results const & results) + { + __strong auto self = weakSelf; + if (!self) + return; + dispatch_async(dispatch_get_main_queue(), [=]() + { + if (results.IsEndMarker()) + [self completeSearch]; + else + searchResults = results; + [self updateSearchResults]; + }); + }; +} + +- (MWMSearchTableCellType)cellTypeForIndexPath:(NSIndexPath *)indexPath +{ + size_t const numSuggests = searchResults.GetSuggestsCount(); + if (numSuggests > 0) + { + return indexPath.row < numSuggests ? MWMSearchTableCellTypeSuggestion : MWMSearchTableCellTypeCommon; + } + else + { + if (IPAD) + return MWMSearchTableCellTypeCommon; + else + return indexPath.row == 0 ? MWMSearchTableCellTypeOnMap : MWMSearchTableCellTypeCommon; + } +} + +- (search::Result &)searchResultForIndexPath:(NSIndexPath *)indexPath +{ + MWMSearchTableCellType firstCellType = + [self cellTypeForIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; + size_t const searchPosition = + indexPath.row - (firstCellType == MWMSearchTableCellTypeOnMap ? 1 : 0); + return searchResults.GetResult(searchPosition); +} + +#pragma mark - Layout + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration +{ + [self updateSearchResultsInTable]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + [self updateSearchResultsInTable]; +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + MWMSearchTableCellType firstCellType = [self cellTypeForIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; + NSInteger const count = searchResults.GetCount(); + BOOL const showOnMap = firstCellType == MWMSearchTableCellTypeOnMap; + return count + (showOnMap ? 1 : 0); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + MWMSearchTableCellType const cellType = [self cellTypeForIndexPath:indexPath]; + return [tableView dequeueReusableCellWithIdentifier:identifierForType(cellType)]; +} + +#pragma mark - Config cells + +- (void)configSuggestionCell:(MWMSearchSuggestionCell *)cell result:(search::Result &)result + isLastCell:(BOOL)isLastCell +{ + [cell config:result]; + cell.isLastCell = isLastCell; +} + +#pragma mark - UITableViewDelegate + +- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + switch ([self cellTypeForIndexPath:indexPath]) + { + case MWMSearchTableCellTypeOnMap: + return MWMSearchShowOnMapCell.cellHeight; + case MWMSearchTableCellTypeSuggestion: + return MWMSearchSuggestionCell.cellHeight; + case MWMSearchTableCellTypeCommon: + return MWMSearchCommonCell.defaultCellHeight; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + MWMSearchTableCellType const cellType = [self cellTypeForIndexPath:indexPath]; + switch (cellType) + { + case MWMSearchTableCellTypeOnMap: + return MWMSearchShowOnMapCell.cellHeight; + case MWMSearchTableCellTypeSuggestion: + return MWMSearchSuggestionCell.cellHeight; + case MWMSearchTableCellTypeCommon: + [self.commonSizingCell config:[self searchResultForIndexPath:indexPath]]; + return self.commonSizingCell.cellHeight; + } +} + +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell +forRowAtIndexPath:(NSIndexPath *)indexPath +{ + switch ([self cellTypeForIndexPath:indexPath]) + { + case MWMSearchTableCellTypeOnMap: + break; + case MWMSearchTableCellTypeSuggestion: + [self configSuggestionCell:(MWMSearchSuggestionCell *)cell + result:[self searchResultForIndexPath:indexPath] + isLastCell:indexPath.row == searchResults.GetSuggestsCount() - 1]; + break; + case MWMSearchTableCellTypeCommon: + [(MWMSearchCommonCell *)cell config:[self searchResultForIndexPath:indexPath]]; + break; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + MWMSearchTableCellType cellType = [self cellTypeForIndexPath:indexPath]; + if (cellType == MWMSearchTableCellTypeOnMap) + { + self.delegate.state = MWMSearchManagerStateMapSearch; + } + else + { + search::Result const & result = [self searchResultForIndexPath:indexPath]; + if (cellType == MWMSearchTableCellTypeSuggestion) + { + [self.delegate searchText:@(result.GetSuggestionString()) forInputLocale:nil]; + } + else + { + Framework & f = GetFramework(); + f.ShowSearchResult(result); + f.SaveSearchQuery(make_pair(searchParams.m_inputLocale, searchParams.m_query)); + self.delegate.state = MWMSearchManagerStateHidden; + } + } +} + +- (void)completeSearch +{ + self.delegate.searchTextField.isSearching = NO; + MWMSearchTableView * view = (MWMSearchTableView *)self.view; + if (searchResults.GetCount() == 0) + { + view.tableView.hidden = YES; + view.noResultsView.hidden = NO; + view.noResultsText.text = L(@"search_not_found_query"); + if (self.searchOnMap) + { + ToastView * toastView = [[ToastView alloc] initWithMessage:view.noResultsText.text]; + [toastView show]; + } + } + else + { + view.tableView.hidden = NO; + view.noResultsView.hidden = YES; + } +} + +- (void)updateSearchResultsOnMap +{ + if (!self.searchOnMap) + return; + GetFramework().UpdateSearchResults(searchResults); +} + +- (void)updateSearchResultsInTable +{ + if (!IPAD && self.searchOnMap) + return; + dispatch_async(dispatch_get_main_queue(), ^ + { + self.commonSizingCell = nil; + [self.tableView reloadData]; + }); +} + +- (void)updateSearchResults +{ + [self updateSearchResultsOnMap]; + [self updateSearchResultsInTable]; +} + +#pragma mark - LocationObserver + +- (void)onLocationUpdate:(location::GpsInfo const &)info +{ + double lat, lon; + if (![MapsAppDelegate.theApp.m_locationManager getLat:lat Lon:lon]) + return; + searchParams.SetPosition(lat, lon); + [self updateSearchResultsInTable]; +} + +#pragma mark - Search + +- (void)searchText:(nonnull NSString *)text forInputLocale:(nullable NSString *)locale +{ + if (!text) + return; + if (locale) + searchParams.SetInputLocale(locale.UTF8String); + searchParams.m_query = text.precomposedStringWithCompatibilityMapping.UTF8String; + searchParams.SetForceSearch(true); + [self updateSearch]; +} + +- (void)updateSearch +{ + Framework & f = GetFramework(); + if (!searchParams.m_query.empty()) + { + searchResults.Clear(); + self.watchLocationUpdates = YES; + if (self.searchOnMap) + f.StartInteractiveSearch(searchParams); + else + f.Search(searchParams); + } + else + { + self.watchLocationUpdates = NO; + f.CancelInteractiveSearch(); + } +} + +#pragma mark - Properties + +- (void)setWatchLocationUpdates:(BOOL)watchLocationUpdates +{ + if (_watchLocationUpdates == watchLocationUpdates) + return; + _watchLocationUpdates = watchLocationUpdates; + if (watchLocationUpdates) + [[MapsAppDelegate theApp].m_locationManager start:self]; + else + [[MapsAppDelegate theApp].m_locationManager stop:self]; +} + +@synthesize searchOnMap = _searchOnMap; +- (void)setSearchOnMap:(BOOL)searchOnMap +{ + _searchOnMap = searchOnMap; + [self updateSearch]; +} + +- (BOOL)searchOnMap +{ + return IPAD || _searchOnMap; +} + +- (MWMSearchCommonCell *)commonSizingCell +{ + if (!_commonSizingCell) + _commonSizingCell = [self.tableView dequeueReusableCellWithIdentifier:kTableCommonCell]; + return _commonSizingCell; +} + +@end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManager.mm index eb843df47b..d2965ca6a3 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManager.mm @@ -1,5 +1,4 @@ #import "BookmarksRootVC.h" -#import "Framework.h" #import "LocationManager.h" #import "MapsAppDelegate.h" #import "MapViewController.h" @@ -17,6 +16,7 @@ #import "3party/Alohalytics/src/alohalytics_objc.h" +#include "Framework.h" #include "map/information_display.hpp" static NSString * const kMWMSideMenuViewsNibName = @"MWMSideMenuViews"; @@ -75,7 +75,7 @@ extern NSString * const kAlohalyticsTapEventKey; - (IBAction)menuActionDownloadMaps { - [self.controller pushDownloadMaps]; + [self.delegate actionDownloadMaps]; } - (IBAction)menuActionOpenSettings @@ -103,9 +103,9 @@ extern NSString * const kAlohalyticsTapEventKey; - (IBAction)menuActionOpenSearch { - self.controller.controlsManager.hidden = YES; + self.state = MWMSideMenuStateInactive; [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"search"]; - [self.controller.searchView setState:SearchViewStateFullscreen animated:YES]; + self.controller.controlsManager.searchHidden = NO; } - (void)toggleMenu diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManagerDelegate.h b/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManagerDelegate.h index 14a5699d3c..4122caf858 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManagerDelegate.h +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/SideMenu/MWMSideMenuManagerDelegate.h @@ -3,5 +3,6 @@ @protocol MWMSideMenuManagerProtocol - (void)sideMenuDidUpdateLayout; +- (void)actionDownloadMaps; @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h index 6f6686c9a9..6cd633e467 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.h @@ -29,6 +29,7 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) @property (nonatomic, readonly) MWMNavigationDashboardEntity * entity; @property (nonatomic) MWMNavigationDashboardState state; @property (nonatomic) CGFloat topBound; +@property (nonatomic) CGFloat leftBound; @property (nonatomic, readonly) CGFloat height; - (instancetype)init __attribute__((unavailable("init is not available"))); @@ -36,6 +37,8 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState) - (void)setupDashboard:(location::FollowingInfo const &)info; - (void)playTurnNotifications; - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation; +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator; - (void)setRouteBuildingProgress:(CGFloat)progress; - (void)showHelperPanels; - (void)hideHelperPanels; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm index cb21d0acb4..1a8a9d0c9e 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm @@ -71,7 +71,17 @@ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { - BOOL const isPortrait = UIInterfaceOrientationIsPortrait(orientation); + [self updateInterface:UIInterfaceOrientationIsPortrait(orientation)]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + [self updateInterface:size.height > size.width]; +} + +- (void)updateInterface:(BOOL)isPortrait +{ MWMRoutePreview * routePreview = isPortrait ? self.routePreviewPortrait : self.routePreviewLandscape; if (self.routePreview.isVisible && ![routePreview isEqual:self.routePreview]) { @@ -83,14 +93,14 @@ return; MWMNavigationDashboard * navigationDashboard = isPortrait ? self.navigationDashboardPortrait : - self.navigationDashboardLandscape; + self.navigationDashboardLandscape; if (self.navigationDashboard.isVisible && ![navigationDashboard isEqual:self.navigationDashboard]) { [self.navigationDashboard remove]; [navigationDashboard addToView:self.ownerView]; } self.navigationDashboard = navigationDashboard; - [self.drawer invalidateTopBounds:self.helperPanels.copy forOrientation:orientation]; + [self.drawer invalidateTopBounds:self.helperPanels.copy isPortrait:isPortrait]; } - (void)hideHelperPanels @@ -156,6 +166,7 @@ [self removePanel:self.nextTurnPanel]; } [self.drawer drawPanels:self.helperPanels.copy]; + [self.navigationDashboard setNeedsLayout]; } - (void)addPanel:(MWMRouteHelperPanel *)panel @@ -356,6 +367,12 @@ self.navigationDashboardLandscape.topBound = self.navigationDashboardPortrait.topBound = topBound; } +- (void)setLeftBound:(CGFloat)leftBound +{ + _leftBound = self.routePreviewLandscape.leftBound = self.routePreviewPortrait.leftBound = + self.navigationDashboardLandscape.leftBound = self.navigationDashboardPortrait.leftBound = leftBound; +} + - (CGFloat)height { switch (self.state) diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/Dashboard/MWMNavigationDashboard.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/Dashboard/MWMNavigationDashboard.mm index 3c46bf78cb..225cb5a8ae 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/Dashboard/MWMNavigationDashboard.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/Dashboard/MWMNavigationDashboard.mm @@ -57,7 +57,7 @@ - (CGRect)defaultFrame { if (IPAD) - return {{12., 28.}, {360., 186.}}; + return {{self.leftBound + 12, self.topBound + 8}, {360., 186.}}; return super.defaultFrame; } diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h index bc00902233..c7d40440f6 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.h @@ -3,6 +3,7 @@ @interface MWMNavigationView : UIView @property (nonatomic) CGFloat topBound; +@property (nonatomic) CGFloat leftBound; @property (nonatomic, readonly) CGFloat visibleHeight; @property (nonatomic, readonly) CGFloat defaultHeight; @property (nonatomic, readonly) BOOL isVisible; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.m b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.mm similarity index 84% rename from iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.m rename to iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.mm index abb5d0ad2a..dc04cbd6c8 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.m +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMNavigationView.mm @@ -1,3 +1,4 @@ +#import "Common.h" #import "MWMNavigationView.h" #import "UIKitCategories.h" @@ -21,6 +22,7 @@ static CGFloat const kStatusbarHeight = 20.0; self.statusbarBackground.backgroundColor = self.contentView.backgroundColor; self.defaultHeight = self.height; self.topBound = 0.0; + self.leftBound = 0.0; } - (void)addToView:(UIView *)superview @@ -41,7 +43,7 @@ static CGFloat const kStatusbarHeight = 20.0; - (void)layoutSubviews { - [UIView animateWithDuration:0.2f animations:^ + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ { if (!CGRectEqualToRect(self.frame, self.defaultFrame)) self.frame = self.defaultFrame; @@ -60,8 +62,8 @@ static CGFloat const kStatusbarHeight = 20.0; - (CGRect)defaultFrame { - return CGRectMake(0.0, self.isVisible ? self.topBound : - -self.defaultHeight, self.superview.width, self.defaultHeight); + return CGRectMake(self.leftBound, self.isVisible ? self.topBound : -self.defaultHeight, + self.superview.width, self.defaultHeight); } - (void)setTopBound:(CGFloat)topBound @@ -79,6 +81,12 @@ static CGFloat const kStatusbarHeight = 20.0; [self setNeedsLayout]; } +- (void)setLeftBound:(CGFloat)leftBound +{ + _leftBound = leftBound; + [self setNeedsLayout]; +} + - (void)setIsVisible:(BOOL)isVisible { _isVisible = isVisible; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanel.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanel.mm index 498324cc09..cc770c22c4 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanel.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanel.mm @@ -65,7 +65,7 @@ static CGFloat const kHeight = 40.; if (IPAD) self.minX = 0.; else - self.center = {self.parentView.center.x, self.center.y}; + self.midX = self.parentView.center.x; [super layoutSubviews]; } @@ -74,6 +74,7 @@ static CGFloat const kHeight = 40.; [super willMoveToSuperview:newSuperview]; self.alpha = 0.; self.hidden = YES; + [newSuperview setNeedsLayout]; } - (CGFloat)defaultHeight diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.h b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.h index bb0c3a9d5f..36d965af32 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.h +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.h @@ -6,6 +6,6 @@ - (instancetype)initWithView:(UIView *)view; - (void)drawPanels:(NSArray *)panels; -- (void)invalidateTopBounds:(NSArray *)panels forOrientation:(UIInterfaceOrientation)orientation; +- (void)invalidateTopBounds:(NSArray *)panels isPortrait:(BOOL)isPortrait; @end diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.mm index 6190885582..4877ae7fa3 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/MWMRouteHelperPanelsDrawer.mm @@ -25,11 +25,11 @@ static CGFloat const kBottomOffsetValueLandscape = 164.; return self; } -- (void)invalidateTopBounds:(NSArray *)panels forOrientation:(UIInterfaceOrientation)orientation +- (void)invalidateTopBounds:(NSArray *)panels isPortrait:(BOOL)isPortrait { if (IPAD || !panels.count) return; - [(MWMRouteHelperPanel *)panels.firstObject setTopBound:UIInterfaceOrientationIsPortrait(orientation) ? kTopOffsetValuePortrait : kTopOffsetValueLandscape]; + [(MWMRouteHelperPanel *)panels.firstObject setTopBound:isPortrait ? kTopOffsetValuePortrait : kTopOffsetValueLandscape]; } - (void)drawPanels:(NSArray *)panels @@ -96,7 +96,7 @@ static CGFloat const kBottomOffsetValueLandscape = 164.; else second = p; } - first.topBound = isPortrait ? kTopOffsetValuePortrait : kTopOffsetValuePortrait; + first.topBound = kTopOffsetValuePortrait; second.topBound = isPortrait ? kBottomOffsetValuePortrait : kBottomOffsetValueLandscape; return; } diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm index 7fc2fc74db..8be795b728 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Views/RoutePreview/MWMRoutePreview.mm @@ -75,6 +75,14 @@ #pragma mark - Properties +- (CGRect)defaultFrame +{ + CGRect frame = super.defaultFrame; + if (IPAD) + frame.size.width -= frame.origin.x; + return frame; +} + - (void)setShowGoButton:(BOOL)showGoButton { _showGoButton = showGoButton; diff --git a/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequest.m b/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequest.m index e29f48734b..d5e638e348 100644 --- a/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequest.m +++ b/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequest.m @@ -1,6 +1,7 @@ #import "MWMDownloadMapRequest.h" #import "MWMSearchDownloadMapRequest.h" #import "MWMSearchDownloadMapRequestView.h" +#import "UIKitCategories.h" @interface MWMSearchDownloadMapRequest () @@ -21,7 +22,7 @@ self = [super init]; if (self) { - [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + [[NSBundle mainBundle] loadNibNamed:self.class.className owner:self options:nil]; self.delegate = delegate; [parentView addSubview:self.rootView]; self.downloadRequest = [[MWMDownloadMapRequest alloc] initWithParentView:self.downloadRequestHolder delegate:self]; diff --git a/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequestView.m b/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequestView.mm similarity index 94% rename from iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequestView.m rename to iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequestView.mm index 16458c54f3..8b6255a5ef 100644 --- a/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequestView.m +++ b/iphone/Maps/Classes/CustomViews/SearchDownloadMapRequest/MWMSearchDownloadMapRequestView.mm @@ -1,3 +1,4 @@ +#import "Common.h" #import "MWMSearchDownloadMapRequest.h" #import "MWMSearchDownloadMapRequestView.h" #import "UIKitCategories.h" @@ -31,7 +32,7 @@ [self layoutIfNeeded]; self.state = state; [self update]; - [UIView animateWithDuration:0.2f animations:^{ [self layoutIfNeeded]; }]; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^{ [self layoutIfNeeded]; }]; } - (void)layoutSubviews diff --git a/iphone/Maps/Classes/MWMNavigationDelegate.h b/iphone/Maps/Classes/MWMNavigationDelegate.h deleted file mode 100644 index 883be0dc08..0000000000 --- a/iphone/Maps/Classes/MWMNavigationDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// MWMNavigationDelegate.h -// Maps -// -// Created by Ilya Grechuhin on 11.07.15. -// Copyright (c) 2015 MapsWithMe. All rights reserved. -// - -@protocol MWMNavigationDelegate - -- (void)pushDownloadMaps; - -@end diff --git a/iphone/Maps/Classes/MWMPlacePage.h b/iphone/Maps/Classes/MWMPlacePage.h index ce13ae444e..4c274aa090 100644 --- a/iphone/Maps/Classes/MWMPlacePage.h +++ b/iphone/Maps/Classes/MWMPlacePage.h @@ -11,6 +11,7 @@ @property (weak, nonatomic, readonly) MWMPlacePageViewManager * manager; @property (nonatomic) MWMPlacePageActionBar * actionBar; @property (nonatomic) CGFloat topBound; +@property (nonatomic) CGFloat leftBound; @property (nonatomic) CGFloat parentViewHeight; @property (nonatomic) CGFloat keyboardHeight; diff --git a/iphone/Maps/Classes/MWMPlacePageViewManager.h b/iphone/Maps/Classes/MWMPlacePageViewManager.h index 7f015f4a41..e2867e5f3f 100644 --- a/iphone/Maps/Classes/MWMPlacePageViewManager.h +++ b/iphone/Maps/Classes/MWMPlacePageViewManager.h @@ -11,9 +11,11 @@ @property (nonatomic, readonly) MWMPlacePageEntity * entity; @property (nonatomic) MWMPlacePageNavigationBar * iPhoneNavigationBar; @property (nonatomic) CGFloat topBound; +@property (nonatomic) CGFloat leftBound; @property (nonatomic, readonly) BOOL isDirectionViewShown; -- (instancetype)initWithViewController:(UIViewController *)viewController delegate:(id)delegate; +- (instancetype)initWithViewController:(UIViewController *)viewController + delegate:(id)delegate; - (void)showPlacePageWithUserMark:(unique_ptr)userMark; - (void)refreshPlacePage; - (void)dismissPlacePage; @@ -23,6 +25,8 @@ - (void)removeBookmark; - (void)apiBack; - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation; +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator; - (void)reloadBookmark; - (void)dragPlacePage:(CGPoint)point; - (void)showDirectionViewWithTitle:(NSString *)title type:(NSString *)type; diff --git a/iphone/Maps/Classes/MWMPlacePageViewManager.mm b/iphone/Maps/Classes/MWMPlacePageViewManager.mm index b8e6079610..5b41623f14 100644 --- a/iphone/Maps/Classes/MWMPlacePageViewManager.mm +++ b/iphone/Maps/Classes/MWMPlacePageViewManager.mm @@ -18,6 +18,8 @@ #include "Framework.h" +extern NSString * const kBookmarksChangedNotification; + typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) { MWMPlacePageManagerStateClosed, @@ -80,7 +82,20 @@ typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) [self configPlacePage]; } +#pragma mark - Layout + - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation +{ + [self rotateToOrientation:orientation]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + [self rotateToOrientation:size.height > size.width ? UIInterfaceOrientationPortrait : UIInterfaceOrientationLandscapeLeft]; +} + +- (void)rotateToOrientation:(UIInterfaceOrientation)orientation { if (!self.placePage) return; @@ -106,6 +121,7 @@ typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) self.entity.category = [[MapsAppDelegate theApp].m_locationManager formattedSpeedAndAltitude:hasSpeed]; } self.placePage.topBound = self.topBound; + self.placePage.leftBound = self.leftBound; self.placePage.parentViewHeight = self.ownerViewController.view.height; [self.placePage configure]; [self refreshPlacePage]; @@ -195,8 +211,8 @@ typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) Framework & f = GetFramework(); BookmarkData data = BookmarkData(self.entity.title.UTF8String, f.LastEditedBMType()); size_t const categoryIndex = f.LastEditedBMCategory(); - size_t const bookmarkIndex = f.GetBookmarkManager().AddBookmark(categoryIndex, m_userMark->GetUserMark()->GetOrg(), - data); + size_t const bookmarkIndex = + f.GetBookmarkManager().AddBookmark(categoryIndex, m_userMark->GetUserMark()->GetOrg(), data); self.entity.bac = make_pair(categoryIndex, bookmarkIndex); self.entity.type = MWMPlacePageEntityTypeBookmark; BookmarkCategory const * category = f.GetBmCategory(categoryIndex); @@ -204,6 +220,9 @@ typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) m_userMark.reset(new UserMarkCopy(bookmark, false)); f.ActivateUserMark(bookmark); f.Invalidate(); + [NSNotificationCenter.defaultCenter postNotificationName:kBookmarksChangedNotification + object:nil + userInfo:nil]; } - (void)removeBookmark @@ -222,6 +241,9 @@ typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) bookmarkCategory->SaveToKMLFile(); } f.Invalidate(); + [NSNotificationCenter.defaultCenter postNotificationName:kBookmarksChangedNotification + object:nil + userInfo:nil]; } - (void)reloadBookmark @@ -309,10 +331,14 @@ typedef NS_ENUM(NSUInteger, MWMPlacePageManagerState) return self.directionView.superview != nil; } -- (void)setTopBound:(CGFloat)bound +- (void)setTopBound:(CGFloat)topBound { - _topBound = bound; - self.placePage.topBound = bound; + _topBound = self.placePage.topBound = topBound; +} + +- (void)setLeftBound:(CGFloat)leftBound +{ + _leftBound = self.placePage.leftBound = leftBound; } @end diff --git a/iphone/Maps/Classes/MWMiPadPlacePage.mm b/iphone/Maps/Classes/MWMiPadPlacePage.mm index 41551f0d95..1b099c6b26 100644 --- a/iphone/Maps/Classes/MWMiPadPlacePage.mm +++ b/iphone/Maps/Classes/MWMiPadPlacePage.mm @@ -114,7 +114,8 @@ static CGFloat const kBottomOffset = 12.; UIView * view = self.navigationController.view; [UIView animateWithDuration:kDefaultAnimationDuration animations:^ { - view.minX = kLeftOffset; + view.minY = self.topBound + kTopOffset; + view.minX = self.leftBound + kLeftOffset; view.alpha = 1.0; }]; } @@ -193,11 +194,12 @@ static CGFloat const kBottomOffset = 12.; UIView * view = self.navigationController.view; UIView * superview = view.superview; + CGFloat const leftOffset = self.leftBound + kLeftOffset; view.minX += [sender translationInView:superview].x; - view.minX = MIN(view.minX, kLeftOffset); + view.minX = MIN(view.minX, leftOffset); [sender setTranslation:CGPointZero inView:superview]; - CGFloat const alpha = MAX(0.0, view.maxX) / (view.width + kLeftOffset); + CGFloat const alpha = MAX(0.0, view.maxX) / (view.width + leftOffset); view.alpha = alpha; UIGestureRecognizerState const state = sender.state; if (state == UIGestureRecognizerStateEnded || state == UIGestureRecognizerStateCancelled) @@ -220,8 +222,7 @@ static CGFloat const kBottomOffset = 12.; - (void)updatePlacePagePosition { UIView * view = self.navigationController.view; - view.maxY = [self getAvailableHeight] + kTopOffset; - view.minY = MIN(view.minY, self.topBound + kTopOffset); + view.minY = MIN([self getAvailableHeight] + kTopOffset - view.height, self.topBound + kTopOffset); [self configureContentInset]; } @@ -277,4 +278,12 @@ static CGFloat const kBottomOffset = 12.; }]; } +- (void)setLeftBound:(CGFloat)leftBound +{ + super.leftBound = leftBound; + [UIView animateWithDuration:kDefaultAnimationDuration animations:^ + { + self.navigationController.view.minX = leftBound + kLeftOffset; + }]; +} @end diff --git a/iphone/Maps/Classes/MapViewController.h b/iphone/Maps/Classes/MapViewController.h index 6feca78311..df851980a8 100644 --- a/iphone/Maps/Classes/MapViewController.h +++ b/iphone/Maps/Classes/MapViewController.h @@ -1,10 +1,7 @@ #import "LocationManager.h" #import "LocationPredictor.h" -#import "MWMNavigationDelegate.h" -#import "SearchView.h" #import "ViewController.h" -#import #include "geometry/point2d.hpp" #include "geometry/rect2d.hpp" @@ -16,7 +13,7 @@ namespace search { struct AddressInfo; } @class ShareActionSheet; @class MWMAPIBar; -@interface MapViewController : ViewController +@interface MapViewController : ViewController { bool m_isSticking; size_t m_StickyThreshold; @@ -43,15 +40,12 @@ namespace search { struct AddressInfo; } - (void)updateStatusBarStyle; -- (void)addPlacePageViews:(NSArray *)views; - - (void)showAPIBar; @property (nonatomic) UIPopoverController * popoverVC; -@property (nonatomic) SearchView * searchView; @property (nonatomic) ShareActionSheet * shareActionSheet; @property (nonatomic, readonly) MWMMapViewControlsManager * controlsManager; @property (nonatomic) m2::PointD restoreRouteDestination; -@property (nonatomic, readonly) MWMAPIBar * apiBar; +@property (nonatomic) MWMAPIBar * apiBar; @end diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 58c9307786..b8b7ed730a 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -1,8 +1,6 @@ #import "Common.h" -#import "CountryTreeVC.h" #import "EAGLView.h" #import "MapsAppDelegate.h" -#import "MapsObservers.h" #import "MapViewController.h" #import "MWMAlertViewController.h" #import "MWMAPIBar.h" @@ -43,12 +41,6 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction) UserTouchesActionScale }; -typedef NS_OPTIONS(NSUInteger, MapInfoView) -{ - MapInfoViewSearch = 1 << 0, - MapInfoViewAPIBar = 1 << 1 -}; - @interface NSValueWrapper : NSObject -(NSValue *)getInnerValue; @@ -80,7 +72,7 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) @end -@interface MapViewController () +@interface MapViewController () @property (nonatomic, readwrite) MWMMapViewControlsManager * controlsManager; @property (nonatomic) MWMSideMenuState menuRestoreState; @@ -92,19 +84,9 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) @property (nonatomic) UserTouchesAction userTouchesAction; -@property (nonatomic) MapInfoView mapInfoView; - -@property (nonatomic) BOOL haveMap; - -@property (nonatomic, readwrite) MWMAPIBar * apiBar; - @end @implementation MapViewController -{ - ActiveMapsObserver * m_mapsObserver; - int m_mapsObserverSlotId; -} #pragma mark - LocationManager Callbacks @@ -226,7 +208,7 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) Framework & f = GetFramework(); UserMark const * userMark = f.GetUserMark(pxClicked, isLongClick); - if (f.HasActiveUserMark() == false && self.searchView.state == SearchViewStateHidden && !f.IsRouteNavigable()) + if (f.HasActiveUserMark() == false && self.controlsManager.searchHidden && !f.IsRouteNavigable()) { if (userMark == nullptr) self.controlsManager.hidden = !self.controlsManager.hidden; @@ -457,11 +439,20 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) return YES; // We support all orientations } -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration { if (isIOSVersionLessThan(8)) - [(UIViewController *)self.childViewControllers.firstObject willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self.controlsManager willRotateToInterfaceOrientation:toInterfaceOrientation]; + [(UIViewController *)self.childViewControllers.firstObject + willRotateToInterfaceOrientation:toInterfaceOrientation + duration:duration]; + [self.controlsManager willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; +} + +- (void)viewWillTransitionToSize:(CGSize)size + withTransitionCoordinator:(id)coordinator +{ + [self.controlsManager viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation @@ -512,10 +503,6 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; [self invalidate]; - m_mapsObserverSlotId = GetFramework().GetCountryTree().GetActiveMapLayout().AddListener(m_mapsObserver); - if (self.searchView.state == SearchViewStateFullscreen) - [self.searchView setState:SearchViewStateFullscreen animated:NO]; - self.controlsManager.menuState = self.menuRestoreState; } @@ -524,9 +511,6 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) [super viewDidLoad]; self.view.clipsToBounds = YES; self.controlsManager = [[MWMMapViewControlsManager alloc] initWithParentController:self]; - [self.view addSubview:self.searchView]; - __weak MapViewController * weakSelf = self; - m_mapsObserver = new ActiveMapsObserver(weakSelf); } - (void)viewDidAppear:(BOOL)animated @@ -539,11 +523,8 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) { [super viewWillDisappear:animated]; - Framework & f = GetFramework(); - f.SetUpdatesEnabled(false); + GetFramework().SetUpdatesEnabled(false); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; - - f.GetCountryTree().GetActiveMapLayout().RemoveListener(m_mapsObserverSlotId); } - (void)orientationChanged:(NSNotification *)notification @@ -551,23 +532,21 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) [self willRotateToInterfaceOrientation:self.interfaceOrientation duration:0.]; } +- (BOOL)prefersStatusBarHidden +{ + return self.apiBar.isVisible; +} + - (UIStatusBarStyle)preferredStatusBarStyle { - if (self.apiBar.isVisible) - { + BOOL const isLight = !self.controlsManager.searchHidden || + self.controlsManager.menuState == MWMSideMenuStateActive || + self.controlsManager.isDirectionViewShown || + (GetFramework().GetMapStyle() == MapStyleDark && + self.controlsManager.navigationState == MWMNavigationDashboardStateHidden); + if (isLight) return UIStatusBarStyleLightContent; - } - else - { - BOOL const isLight = self.searchView.state != SearchViewStateHidden || - self.controlsManager.menuState == MWMSideMenuStateActive || - self.controlsManager.isDirectionViewShown || - (GetFramework().GetMapStyle() == MapStyleDark && - self.controlsManager.navigationState == MWMNavigationDashboardStateHidden); - if (isLight) - return UIStatusBarStyleLightContent; - return UIStatusBarStyleDefault; - } + return UIStatusBarStyleDefault; } - (void)updateStatusBarStyle @@ -667,7 +646,7 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) f.GetBalloonManager().RemovePin(); f.GetBalloonManager().Dismiss(); self.controlsManager.routeBuildingProgress = 100.; - [self.searchView setState:SearchViewStateHidden animated:YES]; + self.controlsManager.searchHidden = YES; if (self.forceRoutingStateChange == ForceRoutingStateChangeStartFollowing) [self.controlsManager routingNavigation]; else @@ -717,31 +696,13 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) - (MWMAPIBar *)apiBar { if (!_apiBar) - _apiBar = [[MWMAPIBar alloc] initWithDelegate:self]; + _apiBar = [[MWMAPIBar alloc] initWithController:self]; return _apiBar; } - (void)showAPIBar { - [self.apiBar show]; -} - -- (void)apiBarBecameVisible:(BOOL)visible -{ - if (visible) - { - [self setMapInfoViewFlag:MapInfoViewAPIBar]; - CGRect const apiRect = self.apiBar.frame; - self.searchView.topBound = apiRect.origin.y + apiRect.size.height; - } - else - { - [self clearMapInfoViewFlag:MapInfoViewAPIBar]; - self.searchView.topBound = 0.0; - } - [self dismissPopover]; - [self.searchView setState:SearchViewStateHidden animated:YES]; - [self updateStatusBarStyle]; + self.apiBar.isVisible = YES; } #pragma mark - ShowDialog callback @@ -779,112 +740,6 @@ typedef NS_OPTIONS(NSUInteger, MapInfoView) _alertController = [[MWMAlertViewController alloc] initWithViewController:self]; return _alertController; } -- (SearchView *)searchView -{ - if (!_searchView) - { - _searchView = [[SearchView alloc] initWithFrame:self.view.bounds]; - _searchView.delegate = self; - _searchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - } - return _searchView; -} - -#pragma mark - Map state - -- (void)checkCurrentLocationMap -{ - Framework & f = GetFramework(); - ActiveMapsLayout & activeMapLayout = f.GetCountryTree().GetActiveMapLayout(); - int const mapsCount = activeMapLayout.GetCountInGroup(ActiveMapsLayout::TGroup::EOutOfDate) + activeMapLayout.GetCountInGroup(ActiveMapsLayout::TGroup::EUpToDate); - self.haveMap = mapsCount > 0; -} - -#pragma mark - SearchViewDelegate - -- (void)searchViewWillEnterState:(SearchViewState)state -{ - [self checkCurrentLocationMap]; - switch (state) - { - case SearchViewStateHidden: - self.controlsManager.hidden = NO; - break; - case SearchViewStateResults: - self.controlsManager.hidden = NO; - break; - case SearchViewStateAlpha: - self.controlsManager.hidden = NO; - break; - case SearchViewStateFullscreen: - self.controlsManager.hidden = YES; - GetFramework().ActivateUserMark(NULL); - break; - } -} - -- (void)searchViewDidEnterState:(SearchViewState)state -{ - switch (state) - { - case SearchViewStateResults: - [self setMapInfoViewFlag:MapInfoViewSearch]; - break; - case SearchViewStateHidden: - case SearchViewStateAlpha: - case SearchViewStateFullscreen: - [self clearMapInfoViewFlag:MapInfoViewSearch]; - break; - } - [self updateStatusBarStyle]; -} - -#pragma mark - MWMNavigationDelegate - -- (void)pushDownloadMaps -{ - [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"downloader"]; - CountryTreeVC * vc = [[CountryTreeVC alloc] initWithNodePosition:-1]; - [self.navigationController pushViewController:vc animated:YES]; -} - -#pragma mark - MWMPlacePageViewManagerDelegate - -- (void)addPlacePageViews:(NSArray *)views -{ - [views enumerateObjectsUsingBlock:^(UIView * view, NSUInteger idx, BOOL *stop) - { - if ([self.view.subviews containsObject:view]) - return; - [self.view insertSubview:view belowSubview:self.searchView]; - }]; -} - -#pragma mark - ActiveMapsObserverProtocol - -- (void)countryStatusChangedAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group -{ - auto const status = GetFramework().GetCountryTree().GetActiveMapLayout().GetCountryStatus(group, position); - if (status == TStatus::EDownloadFailed) - { - [self.searchView downloadFailed]; - } - else if (status == TStatus::EOnDisk) - { - [self checkCurrentLocationMap]; - [self.searchView downloadComplete]; - } -} - -- (void)countryDownloadingProgressChanged:(LocalAndRemoteSizeT const &)progress atPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group -{ - if (self.searchView.state != SearchViewStateFullscreen) - return; - CGFloat const normProgress = (CGFloat)progress.first / (CGFloat)progress.second; - ActiveMapsLayout & activeMapLayout = GetFramework().GetCountryTree().GetActiveMapLayout(); - NSString * countryName = @(activeMapLayout.GetFormatedCountryName(activeMapLayout.GetCoreIndex(group, position)).c_str()); - [self.searchView downloadProgress:normProgress countryName:countryName]; -} #pragma mark - Public methods @@ -932,47 +787,6 @@ NSInteger compareAddress(id l, id r, void * context) [self invalidate]; } -- (void)updateInfoViews -{ - CGFloat topBound = 0.0; - if ([self testMapInfoViewFlag:MapInfoViewAPIBar]) - { - CGRect const apiRect = self.apiBar.frame; - topBound = MAX(topBound, apiRect.origin.y + apiRect.size.height); - } - if ([self testMapInfoViewFlag:MapInfoViewSearch]) - { - CGRect const searchRect = self.searchView.infoRect; - topBound = MAX(topBound, searchRect.origin.y + searchRect.size.height); - } - [self.controlsManager setTopBound:topBound]; -} - -#pragma mark - Properties - -- (BOOL)testMapInfoViewFlag:(MapInfoView)flag -{ - return (self.mapInfoView & flag) == flag; -} - -- (void)setMapInfoViewFlag:(MapInfoView)flag -{ - if (![self testMapInfoViewFlag:flag]) - self.mapInfoView |= flag; -} - -- (void)clearMapInfoViewFlag:(MapInfoView)flag -{ - if ([self testMapInfoViewFlag:flag]) - self.mapInfoView &= ~flag; -} - -- (void)setMapInfoView:(MapInfoView)mapInfoView -{ - _mapInfoView = mapInfoView; - [self updateInfoViews]; -} - - (void)setRestoreRouteDestination:(m2::PointD)restoreRouteDestination { _restoreRouteDestination = restoreRouteDestination; diff --git a/iphone/Maps/Classes/SearchBar.h b/iphone/Maps/Classes/SearchBar.h deleted file mode 100644 index 38ca0d8fba..0000000000 --- a/iphone/Maps/Classes/SearchBar.h +++ /dev/null @@ -1,24 +0,0 @@ - -#import -#import "UIKitCategories.h" - -@class SearchBar; -@protocol SearchBarDelegate - -- (void)searchBarDidPressCancelButton:(SearchBar *)searchBar; -- (void)searchBarDidPressClearButton:(SearchBar *)searchBar; - -@end - -@interface SearchBar : UIView - -@property (nonatomic, readonly) UITextField * textField; -@property (nonatomic, readonly) UIButton * cancelButton; -@property (nonatomic, readonly) UIButton * clearButton; -@property (nonatomic, readonly) SolidTouchView * fieldBackgroundView; - -@property (nonatomic, weak) id delegate; - -- (void)setSearching:(BOOL)searching; - -@end diff --git a/iphone/Maps/Classes/SearchBar.mm b/iphone/Maps/Classes/SearchBar.mm deleted file mode 100644 index dc348f35d4..0000000000 --- a/iphone/Maps/Classes/SearchBar.mm +++ /dev/null @@ -1,158 +0,0 @@ -#import "Framework.h" -#import "SearchBar.h" -#import "UIColor+MapsMeColor.h" -#import "UIFont+MapsMeFonts.h" - -#import "3party/Alohalytics/src/alohalytics_objc.h" - -@interface SearchBar () - -@property (nonatomic) UITextField * textField; -@property (nonatomic) UIButton * cancelButton; -@property (nonatomic) UIButton * clearButton; -@property (nonatomic) UIImageView * spotImageView; -@property (nonatomic) UIActivityIndicatorView * activity; -@property (nonatomic) SolidTouchView * fieldBackgroundView; - -@end - -extern NSString * const kAlohalyticsTapEventKey; - -@implementation SearchBar - -- (id)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - [self addSubview:self.fieldBackgroundView]; - self.fieldBackgroundView.maxY = self.height - 12; - self.fieldBackgroundView.minX = 8; - - [self.fieldBackgroundView addSubview:self.spotImageView]; - self.spotImageView.center = CGPointMake(14, self.fieldBackgroundView.height / 2 - 1); - [self.fieldBackgroundView addSubview:self.activity]; - self.activity.center = CGPointMake(self.spotImageView.center.x, self.spotImageView.center.y + INTEGRAL(0.5)); - - [self.fieldBackgroundView addSubview:self.clearButton]; - self.clearButton.midY = self.fieldBackgroundView.height / 2; - self.clearButton.midX = self.fieldBackgroundView.width - 14; - - self.cancelButton.midY = self.height / 2 - 5; - self.cancelButton.maxX = self.width - 8; - [self addSubview:self.cancelButton]; - - [self addSubview:self.textField]; - self.textField.midY = self.height / 2 - 3; - self.textField.minX = 36.; - - self.textField.tintColor = [UIColor blackHintText]; - - return self; -} - -- (void)setSearching:(BOOL)searching -{ - if (searching) - { - [self.activity startAnimating]; - self.spotImageView.alpha = 0; - } - else - { - [self.activity stopAnimating]; - self.spotImageView.alpha = 1; - } -} - -- (void)cancelButtonPressed:(id)sender -{ - [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"searchCancel"]; - [self.delegate searchBarDidPressCancelButton:self]; -} - -- (void)clearButtonPressed -{ - [self.delegate searchBarDidPressClearButton:self]; -} - -- (UIButton *)cancelButton -{ - if (!_cancelButton) - { - _cancelButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 52, 44)]; - _cancelButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:15]; - _cancelButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; - [_cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - [_cancelButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted]; - NSString * title = L(@"cancel"); - CGFloat const titleWidth = [title sizeWithDrawSize:CGSizeMake(80, 25) font:_cancelButton.titleLabel.font].width + 2; - _cancelButton.width = MAX(titleWidth, _cancelButton.width); - [_cancelButton setTitle:title forState:UIControlStateNormal]; - [_cancelButton addTarget:self action:@selector(cancelButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; - } - return _cancelButton; -} - -- (UIButton *)clearButton -{ - if (!_clearButton) - { - _clearButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)]; - _clearButton.contentMode = UIViewContentModeCenter; - _clearButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; - [_clearButton setImage:[UIImage imageNamed:@"SearchBarClearButton"] forState:UIControlStateNormal]; - [_clearButton addTarget:self action:@selector(clearButtonPressed) forControlEvents:UIControlEventTouchUpInside]; - } - return _clearButton; -} - -- (SolidTouchView *)fieldBackgroundView -{ - if (!_fieldBackgroundView) - { - _fieldBackgroundView = [[SolidTouchView alloc] initWithFrame:CGRectMake(0, 0, 0, 27)]; - _fieldBackgroundView.backgroundColor = [UIColor whiteColor]; - _fieldBackgroundView.userInteractionEnabled = YES; - _fieldBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _fieldBackgroundView.layer.cornerRadius = 4.; - } - return _fieldBackgroundView; -} - -- (UITextField *)textField -{ - if (!_textField) - { - _textField = [[UITextField alloc] initWithFrame:CGRectMake(1, 0, self.width, 22)]; - _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _textField.font = [UIFont regular16]; - _textField.textColor = [UIColor blackPrimaryText]; - _textField.placeholder = L(@"search"); - _textField.returnKeyType = UIReturnKeySearch; - _textField.autocorrectionType = UITextAutocorrectionTypeNo; - _textField.enablesReturnKeyAutomatically = YES; - } - return _textField; -} - -- (UIImageView *)spotImageView -{ - if (!_spotImageView) - { - _spotImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ic_search"]]; - _spotImageView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; - } - return _spotImageView; -} - -- (UIActivityIndicatorView *)activity -{ - if (!_activity) - { - _activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - _activity.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; - } - return _activity; -} - -@end diff --git a/iphone/Maps/Classes/SearchCategoryCell.h b/iphone/Maps/Classes/SearchCategoryCell.h deleted file mode 100644 index 75ef824dbd..0000000000 --- a/iphone/Maps/Classes/SearchCategoryCell.h +++ /dev/null @@ -1,10 +0,0 @@ - -#import "SearchCell.h" - -@interface SearchCategoryCell : SearchCell - -@property (nonatomic, readonly) UIImageView * iconImageView; - -+ (CGFloat)cellHeight; - -@end diff --git a/iphone/Maps/Classes/SearchCategoryCell.m b/iphone/Maps/Classes/SearchCategoryCell.m deleted file mode 100644 index 5f36f88d85..0000000000 --- a/iphone/Maps/Classes/SearchCategoryCell.m +++ /dev/null @@ -1,62 +0,0 @@ - -#import "SearchCategoryCell.h" -#import "UIColor+MapsMeColor.h" -#import "UIKitCategories.h" - -@interface SearchCategoryCell () - -@property (nonatomic) UIImageView * iconImageView; - -@end - -@implementation SearchCategoryCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) - { - [self.contentView addSubview:self.titleLabel]; - [self.contentView addSubview:self.iconImageView]; - } - - return self; -} - -- (void)configTitleLabel -{ - [super configTitleLabel]; - self.titleLabel.frame = CGRectMake(0, 0, 0, 24); - self.titleLabel.textColor = [UIColor blackPrimaryText]; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - CGFloat const offsetL = 56; - self.titleLabel.origin = CGPointMake(offsetL, 8); - self.titleLabel.width = self.width - self.titleLabel.minX - 20; - self.titleLabel.center = CGPointMake(self.titleLabel.center.x, self.height / 2.); - self.iconImageView.center = CGPointMake(self.iconImageView.center.x, self.titleLabel.center.y); - - self.separatorView.width = self.width - offsetL; - self.separatorView.minX = offsetL; -} - -+ (CGFloat)cellHeight -{ - return 44; -} - -- (UIImageView *)iconImageView -{ - if (!_iconImageView) - { - _iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(16, 9, 25, 25)]; - _iconImageView.contentMode = UIViewContentModeCenter; - } - return _iconImageView; -} - -@end diff --git a/iphone/Maps/Classes/SearchCell.h b/iphone/Maps/Classes/SearchCell.h deleted file mode 100644 index a9f0e99d58..0000000000 --- a/iphone/Maps/Classes/SearchCell.h +++ /dev/null @@ -1,12 +0,0 @@ - -#import - -@interface SearchCell : UITableViewCell - -@property (nonatomic) UIView * separatorView; -@property (nonatomic, readonly) UILabel * titleLabel; - -- (void)setTitle:(NSString *)title selectedRanges:(NSArray *)selectedRanges; -- (void)configTitleLabel; - -@end diff --git a/iphone/Maps/Classes/SearchCell.m b/iphone/Maps/Classes/SearchCell.m deleted file mode 100644 index 40af1a35da..0000000000 --- a/iphone/Maps/Classes/SearchCell.m +++ /dev/null @@ -1,80 +0,0 @@ - -#import "SearchCell.h" -#import "UIKitCategories.h" -#import "UIColor+MapsMeColor.h" -#import "UIFont+MapsMeFonts.h" - -@interface SearchCell () - -@property (nonatomic, readwrite) UILabel * titleLabel; - -@end - -@implementation SearchCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - self.backgroundColor = [UIColor clearColor]; - self.selectionStyle = UITableViewCellSelectionStyleDefault; - [self addSubview:self.separatorView]; - UIView * selectedView = [[UIView alloc] initWithFrame:self.bounds]; - selectedView.backgroundColor = [UIColor pressBackground]; - self.selectedBackgroundView = selectedView; - [self configTitleLabel]; - return self; -} - -- (void)configTitleLabel -{ - self.titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - self.titleLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; - self.titleLabel.backgroundColor = [UIColor clearColor]; - self.titleLabel.font = [UIFont regular16]; -} - -- (void)setTitle:(NSString *)title selectedRanges:(NSArray *)selectedRanges -{ - NSDictionary * selectedTitleAttributes = [self selectedTitleAttributes]; - NSDictionary * unselectedTitleAttributes = [self unselectedTitleAttributes]; - if (!title || !selectedTitleAttributes || !unselectedTitleAttributes) - { - self.titleLabel.text = @""; - return; - } - NSMutableAttributedString * attributedTitle = [[NSMutableAttributedString alloc] initWithString:title]; - [attributedTitle addAttributes:unselectedTitleAttributes range:NSMakeRange(0, [title length])]; - for (NSValue * range in selectedRanges) - [attributedTitle addAttributes:selectedTitleAttributes range:[range rangeValue]]; - self.titleLabel.attributedText = attributedTitle; -} - -- (NSDictionary *)selectedTitleAttributes -{ - return nil; -} - -- (NSDictionary *)unselectedTitleAttributes -{ - return nil; -} - -- (void)layoutSubviews -{ - self.separatorView.maxY = self.height; - self.selectedBackgroundView.frame = self.bounds; - self.backgroundView.frame = self.bounds; -} - -- (UIView *)separatorView -{ - if (!_separatorView) - { - _separatorView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, 1)]; - _separatorView.backgroundColor = [UIColor blackDividers]; - _separatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth; - } - return _separatorView; -} - -@end diff --git a/iphone/Maps/Classes/SearchResultCell.h b/iphone/Maps/Classes/SearchResultCell.h deleted file mode 100644 index 0a79c50fbf..0000000000 --- a/iphone/Maps/Classes/SearchResultCell.h +++ /dev/null @@ -1,14 +0,0 @@ - -#import -#import "SearchCell.h" - -@interface SearchResultCell : SearchCell - -@property (nonatomic, readonly) UILabel * typeLabel; -@property (nonatomic, readonly) UILabel * subtitleLabel; -@property (nonatomic, readonly) UILabel * distanceLabel; -@property (nonatomic, readonly) UIImageView * iconImageView; - -+ (CGFloat)cellHeightWithTitle:(NSString *)title type:(NSString *)type subtitle:(NSString *)subtitle distance:(NSString *)distance viewWidth:(CGFloat)width; - -@end diff --git a/iphone/Maps/Classes/SearchResultCell.m b/iphone/Maps/Classes/SearchResultCell.m deleted file mode 100644 index e3d29fa817..0000000000 --- a/iphone/Maps/Classes/SearchResultCell.m +++ /dev/null @@ -1,144 +0,0 @@ - -#import "SearchResultCell.h" -#import "UIColor+MapsMeColor.h" -#import "UIFont+MapsMeFonts.h" -#import "UIKitCategories.h" - -static CGFloat const kOffset = 16.; - -@interface SearchResultCell () - -@property (nonatomic) UILabel * typeLabel; -@property (nonatomic) UILabel * subtitleLabel; -@property (nonatomic) UILabel * distanceLabel; - -@end - -@implementation SearchResultCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) - { - [self.contentView addSubview:self.titleLabel]; - [self.contentView addSubview:self.typeLabel]; - [self.contentView addSubview:self.subtitleLabel]; - [self.contentView addSubview:self.distanceLabel]; - } - - return self; -} - -#define DISTANCE_FONT [UIFont regular14] -#define TYPE_FONT [UIFont light12] -#define SUBTITLE_FONT [UIFont light12] -#define SPACE 4 - -- (void)configTitleLabel -{ - [super configTitleLabel]; - self.titleLabel.numberOfLines = 0; - self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; - self.titleLabel.textColor = [UIColor blackPrimaryText]; -} - -- (NSDictionary *)selectedTitleAttributes -{ - static NSDictionary * selectedAttributes; - if (!selectedAttributes) - selectedAttributes = @{NSForegroundColorAttributeName : [UIColor blackPrimaryText], NSFontAttributeName : [UIFont bold16]}; - return selectedAttributes; -} - -- (NSDictionary *)unselectedTitleAttributes -{ - static NSDictionary * unselectedAttributes; - if (!unselectedAttributes) - unselectedAttributes = @{NSForegroundColorAttributeName : [UIColor blackPrimaryText], NSFontAttributeName : [UIFont regular16]}; - return unselectedAttributes; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - self.typeLabel.size = [[self class] typeSizeWithType:self.typeLabel.text]; - self.typeLabel.maxX = self.width - kOffset; - self.typeLabel.minY = 9; - - self.distanceLabel.width = 70; - [self.distanceLabel sizeToIntegralFit]; - self.distanceLabel.maxX = self.width - kOffset; - self.distanceLabel.maxY = self.height - 8; - - self.titleLabel.size = [[self class] titleSizeWithTitle:self.titleLabel.text viewWidth:self.width typeSize:self.typeLabel.size]; - self.titleLabel.minX = kOffset; - self.titleLabel.minY = self.typeLabel.minY - 4; - - self.subtitleLabel.size = CGSizeMake(self.width - self.distanceLabel.width - 2 * kOffset - SPACE, 16); - self.subtitleLabel.minX = kOffset; - self.subtitleLabel.maxY = self.distanceLabel.maxY; - - self.separatorView.width = self.width - kOffset; - self.separatorView.minX = kOffset; -} - -+ (CGSize)typeSizeWithType:(NSString *)type -{ - return [type sizeWithDrawSize:CGSizeMake(150, 22) font:TYPE_FONT]; -} - -+ (CGSize)titleSizeWithTitle:(NSString *)title viewWidth:(CGFloat)width typeSize:(CGSize)typeSize -{ - CGSize const titleDrawSize = CGSizeMake(width - typeSize.width - 2 * kOffset - SPACE, 300); - return [title sizeWithDrawSize:titleDrawSize font:[UIFont bold16]]; -} - -+ (CGFloat)cellHeightWithTitle:(NSString *)title type:(NSString *)type subtitle:(NSString *)subtitle distance:(NSString *)distance viewWidth:(CGFloat)width -{ - CGSize const typeSize = [self typeSizeWithType:type]; - return MAX(50, [self titleSizeWithTitle:title viewWidth:width typeSize:typeSize].height + ([subtitle length] ? 29 : 15)); -} - -- (UILabel *)typeLabel -{ - if (!_typeLabel) - { - _typeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _typeLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; - _typeLabel.font = TYPE_FONT; - _typeLabel.backgroundColor = [UIColor clearColor]; - _typeLabel.textColor = [UIColor blackSecondaryText]; - _typeLabel.textAlignment = NSTextAlignmentRight; - } - return _typeLabel; -} - -- (UILabel *)distanceLabel -{ - if (!_distanceLabel) - { - _distanceLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _distanceLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; - _distanceLabel.textColor = [UIColor blackPrimaryText]; - _distanceLabel.backgroundColor = [UIColor clearColor]; - _distanceLabel.font = DISTANCE_FONT; - _distanceLabel.textAlignment = NSTextAlignmentRight; - } - return _distanceLabel; -} - -- (UILabel *)subtitleLabel -{ - if (!_subtitleLabel) - { - _subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _subtitleLabel.backgroundColor = [UIColor clearColor]; - _subtitleLabel.textColor = [UIColor blackSecondaryText]; - _subtitleLabel.font = SUBTITLE_FONT; - } - return _subtitleLabel; -} - -@end diff --git a/iphone/Maps/Classes/SearchShowOnMapCell.h b/iphone/Maps/Classes/SearchShowOnMapCell.h deleted file mode 100644 index 5da2f97e28..0000000000 --- a/iphone/Maps/Classes/SearchShowOnMapCell.h +++ /dev/null @@ -1,8 +0,0 @@ - -#import "SearchCell.h" - -@interface SearchShowOnMapCell : SearchCell - -+ (CGFloat)cellHeight; - -@end diff --git a/iphone/Maps/Classes/SearchShowOnMapCell.m b/iphone/Maps/Classes/SearchShowOnMapCell.m deleted file mode 100644 index 338ca113e5..0000000000 --- a/iphone/Maps/Classes/SearchShowOnMapCell.m +++ /dev/null @@ -1,41 +0,0 @@ - -#import "SearchShowOnMapCell.h" -#import "UIColor+MapsMeColor.h" -#import "UIKitCategories.h" - -static CGFloat const kOffset = 16.; - -@implementation SearchShowOnMapCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) - [self.contentView addSubview:self.titleLabel]; - - return self; -} - -- (void)configTitleLabel -{ - [super configTitleLabel]; - self.titleLabel.frame = CGRectMake(kOffset, INTEGRAL(8.5), 0, 24); - self.titleLabel.textColor = [UIColor primary]; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - self.titleLabel.width = self.width - self.titleLabel.minX - kOffset; - self.titleLabel.minX = kOffset; - self.separatorView.width = self.width; - self.separatorView.minX = 0; - self.separatorView.minY = self.height - 1; -} - -+ (CGFloat)cellHeight -{ - return 44; -} - -@end diff --git a/iphone/Maps/Classes/SearchSuggestCell.h b/iphone/Maps/Classes/SearchSuggestCell.h deleted file mode 100644 index 8a92ed1b4c..0000000000 --- a/iphone/Maps/Classes/SearchSuggestCell.h +++ /dev/null @@ -1,11 +0,0 @@ - -#import -#import "SearchCell.h" - -@interface SearchSuggestCell : SearchCell - -@property (nonatomic, readonly) UIImageView * iconImageView; - -+ (CGFloat)cellHeight; - -@end diff --git a/iphone/Maps/Classes/SearchSuggestCell.m b/iphone/Maps/Classes/SearchSuggestCell.m deleted file mode 100644 index 5d3b03ddc5..0000000000 --- a/iphone/Maps/Classes/SearchSuggestCell.m +++ /dev/null @@ -1,82 +0,0 @@ - -#import "SearchSuggestCell.h" -#import "UIColor+MapsMeColor.h" -#import "UIFont+MapsMeFonts.h" -#import "UIKitCategories.h" - -@interface SearchSuggestCell () - -@property (nonatomic) UIImageView * iconImageView; - -@end - -@implementation SearchSuggestCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) - { - [self.contentView addSubview:self.titleLabel]; - [self.contentView addSubview:self.iconImageView]; - } - - return self; -} - -- (void)configTitleLabel -{ - [super configTitleLabel]; - self.titleLabel.frame = CGRectMake(0., INTEGRAL(8.5), 0, 24); - self.titleLabel.textColor = [UIColor primary]; -} - -- (NSDictionary *)selectedTitleAttributes -{ - static NSDictionary * selectedAttributes; - if (!selectedAttributes) - selectedAttributes = @{NSForegroundColorAttributeName : [UIColor primary], NSFontAttributeName : [UIFont bold16]}; - return selectedAttributes; -} - -- (NSDictionary *)unselectedTitleAttributes -{ - static NSDictionary * unselectedAttributes; - if (!unselectedAttributes) - unselectedAttributes = @{NSForegroundColorAttributeName : [UIColor primary], NSFontAttributeName : [UIFont regular16]}; - return unselectedAttributes; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - CGFloat const offset = 34.; - self.titleLabel.minX = offset; - self.titleLabel.width = self.width - self.titleLabel.minX - offset; - self.titleLabel.center = CGPointMake(self.titleLabel.center.x, self.height / 2.); - self.iconImageView.center = CGPointMake(self.iconImageView.center.x, self.titleLabel.center.y); - - - self.separatorView.width = self.width - 16.; - self.separatorView.minX = 16.; -} - -+ (CGFloat)cellHeight -{ - return 44; -} - -- (UIImageView *)iconImageView -{ - if (!_iconImageView) - { - _iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(16, 14, 12, 12)]; - _iconImageView.image = [UIImage imageNamed:@"ic_suggest"]; - _iconImageView.contentMode = UIViewContentModeCenter; - } - return _iconImageView; -} - - -@end diff --git a/iphone/Maps/Classes/SearchView.h b/iphone/Maps/Classes/SearchView.h deleted file mode 100644 index 3fd6472ecd..0000000000 --- a/iphone/Maps/Classes/SearchView.h +++ /dev/null @@ -1,45 +0,0 @@ - -#import "MWMNavigationDelegate.h" -#import "SearchBar.h" -#import - -#include "platform/country_defines.hpp" -#include "storage/index.hpp" - -typedef NS_ENUM(NSUInteger, SearchViewState) { - SearchViewStateHidden, - SearchViewStateResults, - SearchViewStateAlpha, - SearchViewStateFullscreen, -}; - -@class MWMMapViewControlsManager; - -@protocol SearchViewDelegate - -@property (nonatomic, readonly) BOOL haveMap; - -- (void)searchViewWillEnterState:(SearchViewState)state; -- (void)searchViewDidEnterState:(SearchViewState)state; - -@end - -@interface SearchView : UIView - -@property (nonnull, nonatomic) SearchBar * searchBar; - -@property (nonatomic) CGFloat topBound; - -- (void)setState:(SearchViewState)state animated:(BOOL)animated; -- (CGFloat)defaultSearchBarMinY; - -@property (nonnull, weak, nonatomic) id delegate; -@property (nonatomic, readonly) SearchViewState state; - -@property (nonatomic, readonly) CGRect infoRect; - -- (void)downloadProgress:(CGFloat)progress countryName:(nonnull NSString *)countryName; -- (void)downloadComplete; -- (void)downloadFailed; - -@end diff --git a/iphone/Maps/Classes/SearchView.mm b/iphone/Maps/Classes/SearchView.mm deleted file mode 100644 index f50827dc5d..0000000000 --- a/iphone/Maps/Classes/SearchView.mm +++ /dev/null @@ -1,884 +0,0 @@ -#import "Common.h" -#import "Framework.h" -#import "LocationManager.h" -#import "LocationManager.h" -#import "MapsAppDelegate.h" -#import "MapViewController.h" -#import "MWMMapViewControlsManager.h" -#import "MWMSearchDownloadMapRequest.h" -#import "SearchCategoryCell.h" -#import "SearchResultCell.h" -#import "SearchShowOnMapCell.h" -#import "SearchSuggestCell.h" -#import "SearchView.h" -#import "Statistics.h" -#import "ToastView.h" -#import "UIColor+MapsMeColor.h" -#import "UIFont+MapsMeFonts.h" -#import "UIKitCategories.h" - -#include "geometry/angles.hpp" -#include "geometry/distance_on_sphere.hpp" - -#include "indexer/mercator.hpp" - -#include "platform/platform.hpp" -#include "platform/preferred_languages.hpp" -#include "platform/settings.hpp" - -#include "search/params.hpp" -#include "search/result.hpp" - -extern NSString * const kMwmTextToSpeechEnable; -extern NSString * const kMwmTextToSpeechDisable; - -@interface SearchResultsWrapper : NSObject - -- (id)initWithResults:(search::Results const &)res; - -- (search::Result const &)resultWithPosition:(NSInteger)position; -- (NSInteger)suggestsCount; -- (NSInteger)count; -- (BOOL)isEndMarker; -- (BOOL)isEndedNormal; - -@end - -@interface SearchResultsWrapper () - -@property (nonatomic) NSMutableDictionary * distances; - -@end - -@implementation SearchResultsWrapper -{ - search::Results m_results; -} - -- (id)initWithResults:(search::Results const &)results -{ - self = [super init]; - - m_results = results; - - return self; -} - -- (NSMutableDictionary *)distances -{ - if (!_distances) - _distances = [[NSMutableDictionary alloc] init]; - return _distances; -} - -- (NSInteger)count -{ - return m_results.GetCount(); -} - -- (NSInteger)suggestsCount -{ - return m_results.GetSuggestsCount(); -} - -- (search::Result const &)resultWithPosition:(NSInteger)position -{ - return m_results.GetResult(position); -} - -- (BOOL)isEndMarker -{ - return m_results.IsEndMarker(); -} - -- (BOOL)isEndedNormal -{ - return m_results.IsEndedNormal(); -} - -@end - - -typedef NS_ENUM(NSUInteger, CellType) -{ - CellTypeResult, - CellTypeSuggest, - CellTypeShowOnMap, - CellTypeCategory -}; - - -@interface SearchView () - -@property (nonatomic) UITableView * tableView; -@property (nonatomic) SolidTouchView * topBackgroundView; -@property (nonatomic) UILabel * emptyResultLabel; - -@property (nonatomic) MWMSearchDownloadMapRequest * downloadRequest; - -@property (nonatomic) SearchResultsWrapper * wrapper; -@property (nonatomic) NSArray * categoriesNames; - -@end - -@implementation SearchView - -- (id)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - [self addSubview:self.tableView]; - [self addSubview:self.topBackgroundView]; - self.topBackgroundView.height = [self defaultTopBackgroundHeight]; - [self addSubview:self.searchBar]; - [self.tableView addSubview:self.emptyResultLabel]; - - self.emptyResultLabel.center = CGPointMake(self.width / 2, 40); - self.emptyResultLabel.hidden = YES; - - self.searchBar.midX = self.width / 2; - - [self setState:SearchViewStateHidden animated:NO]; - - [self.tableView registerClass:[SearchCategoryCell class] forCellReuseIdentifier:[SearchCategoryCell className]]; - [self.tableView registerClass:[SearchResultCell class] forCellReuseIdentifier:[SearchResultCell className]]; - [self.tableView registerClass:[SearchSuggestCell class] forCellReuseIdentifier:[SearchSuggestCell className]]; - [self.tableView registerClass:[SearchShowOnMapCell class] forCellReuseIdentifier:[SearchShowOnMapCell className]]; - - [self layoutSubviews]; - self.tableView.contentOffset = CGPointMake(0, -self.topBackgroundView.height); - - return self; -} - -static BOOL keyboardLoaded = NO; - -- (void)setState:(SearchViewState)state animated:(BOOL)animated -{ - [self.delegate searchViewWillEnterState:state]; - // Clear search results on the map when clear in the search bar on the map is pressed - if (_state == SearchViewStateResults && state == SearchViewStateHidden) - [self clearSearchResultsMode]; - - UIViewAnimationOptions const options = UIViewAnimationOptionCurveEaseInOut; - double const damping = 0.9; - NSTimeInterval const duration = animated ? 0.3 : 0; - CGFloat const searchBarOffset = (state == SearchViewStateHidden) ? -self.searchBar.height : [self defaultSearchBarMinY]; - - CGFloat const cancelButtonMinX = (state == SearchViewStateResults) ? self.searchBar.width - 4 : self.searchBar.cancelButton.minX; - CGFloat const textFieldBackgroundWidth = cancelButtonMinX - self.searchBar.fieldBackgroundView.minX - 8; - CGFloat const textFieldWidth = textFieldBackgroundWidth - 60.; - - [self hideDownloadMapRequest]; - LocationManager * locationManager = [MapsAppDelegate theApp].m_locationManager; - if (state == SearchViewStateFullscreen) - { - [locationManager start:self]; - - GetFramework().PrepareSearch(); - - [self showDownloadMapRequestIfRequired]; - if (keyboardLoaded && !self.downloadRequest) - [self.searchBar.textField becomeFirstResponder]; - [UIView animateWithDuration:kDefaultAnimationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ - self.tableView.alpha = 1; - } completion:nil]; - [UIView animateWithDuration:duration delay:0 damping:damping initialVelocity:0 options:options animations:^{ - self.searchBar.cancelButton.alpha = 1; - self.topBackgroundView.minY = 0; - self.topBackgroundView.height = [self defaultTopBackgroundHeight]; - self.searchBar.minY = searchBarOffset; - self.searchBar.alpha = 1; - self.searchBar.fieldBackgroundView.width = textFieldBackgroundWidth; - self.searchBar.textField.width = textFieldWidth; - [self.searchBar.clearButton setImage:[UIImage imageNamed:@"SearchBarClearButton"] forState:UIControlStateNormal]; - } completion:^(BOOL) { - if (!keyboardLoaded && !self.downloadRequest) - { - keyboardLoaded = YES; - [self.searchBar.textField becomeFirstResponder]; - } - }]; - } - else if (state == SearchViewStateResults) - { - [locationManager stop:self]; - [self.searchBar.textField resignFirstResponder]; - [UIView animateWithDuration:duration delay:0 damping:damping initialVelocity:0 options:options animations:^{ - self.alpha = 1; - self.searchBar.cancelButton.alpha = 0; - self.searchBar.alpha = 1; - self.topBackgroundView.minY = self.topBound; - self.searchBar.minY = searchBarOffset + self.topBound; - self.topBackgroundView.height = [self defaultTopBackgroundHeight]; - if (self.topBound > 0.0) - self.searchBar.minY -= 7.0; - if ([self iPhoneInLandscape]) - { - self.searchBar.minY -= 3; - self.topBackgroundView.height -= 10; - } - self.tableView.alpha = 0; - self.searchBar.fieldBackgroundView.width = textFieldBackgroundWidth; - self.searchBar.textField.width = textFieldWidth; - [self.searchBar.clearButton setImage:[UIImage imageNamed:@"SearchBarClearResultsButton"] forState:UIControlStateNormal]; - } completion:nil]; - } - else if (state == SearchViewStateHidden) - { - [locationManager stop:self]; - [self.searchBar.textField resignFirstResponder]; - [UIView animateWithDuration:duration delay:0 damping:damping initialVelocity:0 options:options animations:^{ - self.searchBar.cancelButton.alpha = 1; - self.searchBar.maxY = 0; - self.searchBar.alpha = 0; - self.topBackgroundView.maxY = 0; - self.tableView.alpha = 0; - self.searchBar.fieldBackgroundView.width = textFieldBackgroundWidth; - self.searchBar.textField.width = textFieldWidth; - [self.searchBar.clearButton setImage:[UIImage imageNamed:@"SearchBarClearButton"] forState:UIControlStateNormal]; - } completion:nil]; - } - else if (state == SearchViewStateAlpha) - { - [UIView animateWithDuration:duration delay:0.1 damping:damping initialVelocity:0 options:options animations:^{ - self.alpha = 0; - } completion:nil]; - [self.searchBar.textField resignFirstResponder]; - } - GetFramework().Invalidate(); - _state = state; - [self.delegate searchViewDidEnterState:state]; -} - -- (void)onLocationUpdate:(location::GpsInfo const &)info -{ - if (self.state == SearchViewStateFullscreen && ![self isShowingCategories]) - { - search::SearchParams params; - [self updateSearchParametersWithForce:NO outParams:params andQuery:self.searchBar.textField.text]; - params.SetPosition(info.m_latitude, info.m_longitude); - GetFramework().Search(params); - - [self recalculateDistances]; - [self.tableView reloadData]; - } -} - -- (void)recalculateDistances -{ - LocationManager * locationManager = [MapsAppDelegate theApp].m_locationManager; - - double north = -1.0; - [locationManager getNorthRad:north]; - double lat, lon; - if ([locationManager getLat:lat Lon:lon]) - { - SearchResultsWrapper * wrapper = self.wrapper; - for (NSInteger position = 0; position < [wrapper count]; position++) - { - search::Result const & result = [wrapper resultWithPosition:position]; - if (result.HasPoint()) - { - string distance; - double azimut = -1.0; - GetFramework().GetDistanceAndAzimut(result.GetFeatureCenter(), lat, lon, north, distance, azimut); - wrapper.distances[@(position)] = @(distance.c_str()); - } - } - } -} - -- (void)updateSearchParametersWithForce:(BOOL)force outParams:(search::SearchParams &)sp andQuery:(NSString *)newQuery -{ - sp.m_query = [[newQuery precomposedStringWithCompatibilityMapping] UTF8String]; - sp.m_callback = ^(search::Results const & results) - { - if (self.state == SearchViewStateHidden) - return; - SearchResultsWrapper * wrapper = [[SearchResultsWrapper alloc] initWithResults:results]; - dispatch_async(dispatch_get_main_queue(), ^ - { - [self frameworkDidAddSearchResult:wrapper]; - }); - }; - sp.SetInputLocale([[self keyboardInputLanguage] UTF8String]); - sp.SetForceSearch(force == YES); -} - -- (void)search:(NSString *)newTextQuery -{ - self.emptyResultLabel.hidden = YES; - [self.searchBar setSearching:YES]; - search::SearchParams sp; - [self updateSearchParametersWithForce:YES outParams:sp andQuery:newTextQuery]; - double lat, lon; - if ([[MapsAppDelegate theApp].m_locationManager getLat:lat Lon:lon]) - sp.SetPosition(lat, lon); - GetFramework().Search(sp); -} - -- (void)frameworkDidAddSearchResult:(SearchResultsWrapper *)wrapper -{ - // special buben for situation when textfield is empty and we should show categories (cause 'self.wrapper' == nil) - // but callbacks from previous non-empty search are coming and modifying 'self.wrapper' - // so, we see previous search results with empty textfield - if (![self.searchBar.textField.text length]) - return; - // ----------------------------------------- - - if ([wrapper isEndMarker]) - { - if ([wrapper isEndedNormal]) - { - [self.searchBar setSearching:NO]; - [self recalculateDistances]; - [self.tableView reloadData]; - } - } - else - { - self.emptyResultLabel.hidden = [self isShowingCategories] ? YES : ([self rowsCount] > 0); - self.wrapper = wrapper; - [self.tableView reloadData]; - [self.tableView setContentOffset:CGPointMake(0, -self.tableView.contentInset.top) animated:YES]; - } -} - -- (void)clearSearchResultsMode -{ - Framework & framework = GetFramework(); - framework.GetBalloonManager().RemovePin(); - framework.GetBalloonManager().Dismiss(); - framework.CancelInteractiveSearch(); -} - -- (void)searchBarDidPressClearButton:(SearchBar *)searchBar -{ - if (self.state == SearchViewStateResults) - [self setState:SearchViewStateHidden animated:YES]; - else - [self.searchBar.textField becomeFirstResponder]; - - self.searchBar.textField.text = nil; - [self textFieldTextChanged:nil]; -} - -- (void)searchBarDidPressCancelButton:(id)searchBar -{ - self.searchBar.textField.text = nil; - [self textFieldTextChanged:nil]; - [self setState:SearchViewStateHidden animated:YES]; -} - -// TODO: This code only for demonstration purposes and will be removed soon. -- (BOOL)tryChangeMapStyleCmd:(NSString *)cmd -{ - // Hook for shell command on change map style - BOOL const isDark = [cmd isEqualToString:@"mapstyle:dark"] || [cmd isEqualToString:@"?dark"]; - BOOL const isLight = isDark ? NO : [cmd isEqualToString:@"mapstyle:light"] || [cmd isEqualToString:@"?light"]; - BOOL const isClear = isLight || isDark ? NO : [cmd isEqualToString:@"?newstyle"]; - - if (!isDark && !isLight && !isClear) - return NO; - - // change map style - MapStyle const mapStyle = isDark ? MapStyleDark : (isClear ? MapStyleClear : MapStyleLight); - [[MapsAppDelegate theApp] setMapStyle: mapStyle]; - - // close Search panel - [self searchBarDidPressCancelButton:nil]; - - return YES; -} - -// TODO: This code only for demonstration purposes and will be removed soon. -- (BOOL)trySwitchOnTurnSound:(NSString *)cmd -{ - // Hook for shell command on change map style - BOOL const sound = [cmd isEqualToString:@"?sound"]; - BOOL const nosound = sound ? NO : [cmd isEqualToString:@"?nosound"]; - - if (!sound && !nosound) - return NO; - - // turn notification - if (sound) - [[NSNotificationCenter defaultCenter] postNotificationName:kMwmTextToSpeechEnable object:nil]; - if (nosound) - [[NSNotificationCenter defaultCenter] postNotificationName:kMwmTextToSpeechDisable object:nil]; - - // close Search panel - [self searchBarDidPressCancelButton:nil]; - - return YES; -} - -- (void)textFieldTextChanged:(id)sender -{ - NSString * currentText = self.searchBar.textField.text; - - // TODO: This code only for demonstration purposes and will be removed soon. - if ([self tryChangeMapStyleCmd:currentText]) - return; - - // TODO: This code only for demonstration purposes and will be removed soon. - if ([self trySwitchOnTurnSound:currentText]) - return; - - if ([currentText length]) - { - [self hideDownloadMapRequest]; - [self search:currentText]; - } - else - { - [self showDownloadMapRequestIfRequired]; - // nil wrapper means "Display Categories" mode - self.wrapper = nil; - [self.searchBar setSearching:NO]; - self.emptyResultLabel.hidden = YES; - [self.tableView reloadData]; - } -} - -- (void)textFieldBegin:(id)sender -{ - if (self.state == SearchViewStateResults) - [self clearSearchResultsMode]; -} - -- (void)showOnMap -{ - Framework & f = GetFramework(); - if (f.ShowAllSearchResults() == 0) - { - NSString * secondSentence = @""; - // Country in the viewport should be downloaded - m2::PointD const viewportCenter = f.GetViewportCenter(); - if (!f.IsCountryLoaded(viewportCenter)) - { - secondSentence = [NSString stringWithFormat:L(@"download_viewport_country_to_search"), - @(f.GetCountryName(viewportCenter).c_str())]; - } - else - { - LocationManager * locationManager = [MapsAppDelegate theApp].m_locationManager; - double lat, lon; - if ([locationManager getLat:lat Lon:lon]) - { - m2::PointD const mercatorLocation = MercatorBounds::FromLatLon(lat, lon); - if (!f.IsCountryLoaded(mercatorLocation)) { - secondSentence = [NSString stringWithFormat:L(@"download_location_country"), - @(f.GetCountryName(mercatorLocation).c_str())]; - } - } - } - - NSString * message = [NSString stringWithFormat:@"%@. %@", L(@"no_search_results_found"), secondSentence]; - ToastView * toastView = [[ToastView alloc] initWithMessage:message]; - [toastView show]; - } - - search::SearchParams params; - params.m_query = [[self.searchBar.textField.text precomposedStringWithCompatibilityMapping] UTF8String]; - params.SetInputLocale([[self keyboardInputLanguage] UTF8String]); - - f.StartInteractiveSearch(params); - - [self setState:SearchViewStateResults animated:YES]; -} - -- (BOOL)isShowingCategories -{ - // We are on the categories screen if wrapper is nil - return self.wrapper == nil; -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField -{ - if (![self isShowingCategories]) - { - [self showOnMap]; - return YES; - } - return NO; -} - -- (CGFloat)defaultSearchBarMinY -{ - return 20.0; -} - -- (CGFloat)defaultTopBackgroundHeight -{ - return 64.0; -} - -- (BOOL)iPhoneInLandscape -{ - return self.width > self.height && !IPAD; -} - -- (void)layoutSubviews -{ - if (self.state == SearchViewStateFullscreen) - self.searchBar.minY = [self defaultSearchBarMinY]; - self.tableView.contentInset = UIEdgeInsetsMake(self.topBackgroundView.height, 0, 0, 0); - self.tableView.scrollIndicatorInsets = self.tableView.contentInset; - [super layoutSubviews]; -} - -- (void)setCellAttributedTitle:(SearchCell *)cell result:(search::Result const &)result -{ - size_t const rangesCount = result.GetHighlightRangesCount(); - NSMutableArray * ranges = [NSMutableArray arrayWithCapacity:rangesCount]; - for (size_t i = 0; i < rangesCount; i++) - { - pair const & pairRange = result.GetHighlightRange(i); - NSRange range = NSMakeRange(pairRange.first, pairRange.second); - [ranges addObject:[NSValue valueWithRange:range]]; - } - NSString * title = @(result.GetString()); - [cell setTitle:title selectedRanges:ranges]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell * cell; - CellType cellType = [self cellTypeForIndexPath:indexPath]; - switch (cellType) - { - case CellTypeCategory: - { - SearchCategoryCell * customCell = [tableView dequeueReusableCellWithIdentifier:[SearchCategoryCell className]]; - customCell.titleLabel.text = L(self.categoriesNames[indexPath.row]); - NSString * iconName = [NSString stringWithFormat:@"CategoryIcon%@", [self.categoriesNames[indexPath.row] capitalizedString]]; - customCell.iconImageView.image = [UIImage imageNamed:iconName]; - cell = customCell; - break; - } - case CellTypeShowOnMap: - { - SearchShowOnMapCell * customCell = [tableView dequeueReusableCellWithIdentifier:[SearchShowOnMapCell className]]; - customCell.titleLabel.text = L(@"search_on_map"); - cell = customCell; - break; - } - case CellTypeResult: - { - SearchResultCell * customCell = [tableView dequeueReusableCellWithIdentifier:[SearchResultCell className]]; - NSInteger const position = [self searchResultPositionForIndexPath:indexPath]; - search::Result const & result = [self.wrapper resultWithPosition:position]; - [self setCellAttributedTitle:customCell result:result]; - customCell.subtitleLabel.text = @(result.GetRegionString()); - customCell.iconImageView.image = [UIImage imageNamed:@"SearchCellPinIcon"]; - customCell.distanceLabel.text = self.wrapper.distances[@(position)]; - customCell.typeLabel.text = @(result.GetFeatureType()); - cell = customCell; - break; - } - case CellTypeSuggest: - { - SearchSuggestCell * customCell = [tableView dequeueReusableCellWithIdentifier:[SearchSuggestCell className]]; - NSInteger const position = [self searchResultPositionForIndexPath:indexPath]; - search::Result const & result = [self.wrapper resultWithPosition:position]; - [self setCellAttributedTitle:customCell result:result]; - cell = customCell; - break; - } - } - return cell; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -{ - CellType cellType = [self cellTypeForIndexPath:indexPath]; - switch (cellType) - { - case CellTypeCategory: - { - return [SearchCategoryCell cellHeight]; - } - case CellTypeShowOnMap: - { - return [SearchShowOnMapCell cellHeight]; - } - case CellTypeResult: - { - NSInteger const position = [self searchResultPositionForIndexPath:indexPath]; - SearchResultsWrapper * wrapper = self.wrapper; - search::Result const & result = [wrapper resultWithPosition:position]; - NSString * title = @(result.GetString()); - NSString * subtitle; - NSString * type; - if (result.GetResultType() == search::Result::RESULT_FEATURE || result.GetResultType() == search::Result::RESULT_LATLON) - { - subtitle = @(result.GetRegionString()); - type = @(result.GetFeatureType()); - } - return [SearchResultCell cellHeightWithTitle:title type:type subtitle:subtitle distance:wrapper.distances[@(position)] viewWidth:tableView.width]; - } - case CellTypeSuggest: - { - return [SearchSuggestCell cellHeight]; - } - default: - { - return 0; - } - } -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [self rowsCount]; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [tableView deselectRowAtIndexPath:indexPath animated:YES]; - - CellType cellType = [self cellTypeForIndexPath:indexPath]; - - switch (cellType) - { - case CellTypeCategory: - { - [[Statistics instance] logEvent:@"Category Selection" withParameters:@{@"Category" : self.categoriesNames[indexPath.row]}]; - NSString * newQuery = [L(self.categoriesNames[indexPath.row]) stringByAppendingString:@" "]; - self.searchBar.textField.text = newQuery; - [self search:newQuery]; - - break; - } - case CellTypeShowOnMap: - { - [self showOnMap]; - break; - } - case CellTypeResult: - { - NSInteger const position = [self searchResultPositionForIndexPath:indexPath]; - search::Result const & result = [self.wrapper resultWithPosition:position]; - [self setState:SearchViewStateHidden animated:YES]; - GetFramework().ShowSearchResult(result); - break; - } - case CellTypeSuggest: - { - NSInteger const position = [self searchResultPositionForIndexPath:indexPath]; - search::Result const & result = [self.wrapper resultWithPosition:position]; - NSString * newQuery = @(result.GetSuggestionString()); - self.searchBar.textField.text = newQuery; - [self search:newQuery]; - - break; - } - } -} - -- (void)scrollViewDidScroll:(UIScrollView *)scrollView -{ - if (!scrollView.decelerating && scrollView.dragging) - [self.searchBar.textField resignFirstResponder]; -} - -- (CellType)cellTypeForIndexPath:(NSIndexPath *)indexPath -{ - if ([self isShowingCategories]) - { - return CellTypeCategory; - } - else - { - size_t const numSuggests = [self.wrapper suggestsCount]; - if (numSuggests) - return indexPath.row < numSuggests ? CellTypeSuggest : CellTypeResult; - else - return indexPath.row == 0 ? CellTypeShowOnMap : CellTypeResult; - } -} - -- (NSInteger)searchResultPositionForIndexPath:(NSIndexPath *)indexPath -{ - return [self.wrapper suggestsCount] ? indexPath.row : indexPath.row - 1; -} - -- (NSInteger)rowsCount -{ - if ([self isShowingCategories]) - { - if (self.delegate.haveMap) - return [self.categoriesNames count]; - else - return 0; - } - else - { - return [self.wrapper suggestsCount] ? [self.wrapper count] : [self.wrapper count] + 1; - } -} - -- (NSArray *)categoriesNames -{ - if (!_categoriesNames) - _categoriesNames = @[ - @"food", - @"hotel", - @"tourism", - @"wifi", - @"transport", - @"fuel", - @"parking", - @"shop", - @"atm", - @"bank", - @"entertainment", - @"hospital", - @"pharmacy", - @"police", - @"toilet", - @"post"]; - return _categoriesNames; -} - -- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event -{ - return CGRectContainsPoint(self.searchBar.frame, point) || self.state == SearchViewStateFullscreen; -} - -- (UITableView *)tableView -{ - if (!_tableView) - { - _tableView = [[UITableView alloc] initWithFrame:self.bounds]; - _tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _tableView.delegate = self; - _tableView.dataSource = self; - _tableView.backgroundColor = [UIColor whiteColor]; - _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - } - return _tableView; -} - -- (SolidTouchView *)topBackgroundView -{ - if (!_topBackgroundView) - { - _topBackgroundView = [[SolidTouchView alloc] initWithFrame:CGRectMake(0, 0, self.width, 0)]; - _topBackgroundView.backgroundColor = [UIColor colorWithColorCode:@"1F9952"]; - _topBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _topBackgroundView.userInteractionEnabled = YES; - } - return _topBackgroundView; -} - -- (SearchBar *)searchBar -{ - if (!_searchBar) - { - _searchBar = [[SearchBar alloc] initWithFrame:CGRectMake(0, 0, self.width, 44)]; - _searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _searchBar.textField.delegate = self; - _searchBar.delegate = self; - [_searchBar.textField addTarget:self action:@selector(textFieldTextChanged:) forControlEvents:UIControlEventEditingChanged]; - [_searchBar.textField addTarget:self action:@selector(textFieldBegin:) forControlEvents:UIControlEventEditingDidBegin]; - } - return _searchBar; -} - -- (UILabel *)emptyResultLabel -{ - if (!_emptyResultLabel) - { - _emptyResultLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.width, 60)]; - _emptyResultLabel.backgroundColor = [UIColor clearColor]; - _emptyResultLabel.font = [UIFont regular16]; - _emptyResultLabel.text = L(@"no_search_results_found"); - _emptyResultLabel.textColor = [UIColor primary]; - _emptyResultLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _emptyResultLabel.textAlignment = NSTextAlignmentCenter; - } - return _emptyResultLabel; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (NSString *)keyboardInputLanguage -{ - UITextInputMode * mode = [self textInputMode]; - if (mode) - return mode.primaryLanguage; - // Use system language as a fall-back - return [[NSLocale preferredLanguages] firstObject]; -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -{ - // Prevent super call to stop event propagation - // [super touchesBegan:touches withEvent:event]; -} - -#pragma mark - Download request - -- (void)showDownloadMapRequestIfRequired -{ - if (self.delegate.haveMap) - return; - self.downloadRequest = [[MWMSearchDownloadMapRequest alloc] initWithParentView:self.tableView delegate:self]; -} - -- (void)hideDownloadMapRequest -{ - self.downloadRequest = nil; -} - -#pragma mark - Download callbacks - -- (void)downloadProgress:(CGFloat)progress countryName:(NSString *)countryName -{ - [self.downloadRequest downloadProgress:progress countryName:countryName]; -} - -- (void)downloadComplete -{ - [self hideDownloadMapRequest]; -} - -- (void)downloadFailed -{ - [self.downloadRequest setDownloadFailed]; -} - -#pragma mark - MWMSearchDownloadMapRequest - -- (void)selectMapsAction -{ - [self.delegate pushDownloadMaps]; -} - -#pragma mark - Properties - -- (void)setDownloadRequest:(MWMSearchDownloadMapRequest *)downloadRequest -{ - _downloadRequest = downloadRequest; - self.tableView.scrollEnabled = (downloadRequest == nil); - [self.tableView reloadData]; -} - -- (CGRect)infoRect -{ - return [self convertRect:self.topBackgroundView.frame toView:self.superview]; -} - -- (void)setTopBound:(CGFloat)topBound -{ - _topBound = topBound; - [self setState:self.state animated:NO]; -} - -@end diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 0002c97bc2..6cdaf6b5e1 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -15,16 +15,25 @@ 28AD73880D9D96C1002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD73870D9D96C1002E5188 /* MainWindow.xib */; }; 340837131B7243CE00B5C185 /* MWMActivityViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340837121B7243CE00B5C185 /* MWMActivityViewController.m */; }; 340837161B72451A00B5C185 /* MWMShareLocationActivityItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340837151B72451A00B5C185 /* MWMShareLocationActivityItem.mm */; }; + 340E10601B944DAB00D975D5 /* MWMSearchHistoryManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340E105F1B944DAB00D975D5 /* MWMSearchHistoryManager.mm */; }; + 340E10631B949D1900D975D5 /* MWMSearchBookmarksManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340E10621B949D1900D975D5 /* MWMSearchBookmarksManager.mm */; }; 340F24631B14910500F874CD /* RouteState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340F24621B14910500F874CD /* RouteState.mm */; }; - 341522BF1B666A550077AA8F /* MWMAPIBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 341522BE1B666A550077AA8F /* MWMAPIBarView.m */; }; + 341522BF1B666A550077AA8F /* MWMAPIBarView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 341522BE1B666A550077AA8F /* MWMAPIBarView.mm */; }; 341C2A571B72092A00AD41A1 /* 02_droidsans-fallback.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF04B231B71010E00DACAF1 /* 02_droidsans-fallback.ttf */; }; 341C2A5B1B720B8A00AD41A1 /* MWMAPIBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 341C2A5A1B720B8A00AD41A1 /* MWMAPIBarView.xib */; }; 3428BC131B55477E00C85B30 /* MWMSideMenuDownloadBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = 3428BC121B55477E00C85B30 /* MWMSideMenuDownloadBadge.m */; }; 342AD76F1B53D30C00E0B997 /* UIButton+RuntimeAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 342AD76E1B53D30C00E0B997 /* UIButton+RuntimeAttributes.m */; }; 342AD7721B53D32F00E0B997 /* UIView+RuntimeAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 342AD7711B53D32F00E0B997 /* UIView+RuntimeAttributes.m */; }; + 3438CDF41B85F1170051AA78 /* MWMConsole.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3438CDF31B85F1170051AA78 /* MWMConsole.mm */; }; + 3438CDF81B8616760051AA78 /* MWMSearchShowOnMapCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3438CDF61B8616760051AA78 /* MWMSearchShowOnMapCell.mm */; }; + 3438CDF91B8616760051AA78 /* MWMSearchShowOnMapCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3438CDF71B8616760051AA78 /* MWMSearchShowOnMapCell.xib */; }; + 3438CDFC1B862F5C0051AA78 /* MWMSearchContentView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3438CDFB1B862F5C0051AA78 /* MWMSearchContentView.mm */; }; 343F262E1AEFC4A300388A6D /* MWMFrameworkUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 343F262D1AEFC4A300388A6D /* MWMFrameworkUtils.mm */; }; 343F26301AEFDB1A00388A6D /* Framework.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 343F262F1AEFDB1A00388A6D /* Framework.cpp */; }; 343F26311AEFDF3E00388A6D /* resources-xhdpi in Resources */ = {isa = PBXBuildFile; fileRef = 97FC99DA19C1A2CD00C1CF98 /* resources-xhdpi */; }; + 344825931B8DBADF00757B1B /* MWMSearchDownloadViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 344825911B8DBADF00757B1B /* MWMSearchDownloadViewController.mm */; }; + 344825941B8DBADF00757B1B /* MWMSearchDownloadViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 344825921B8DBADF00757B1B /* MWMSearchDownloadViewController.xib */; }; + 344825971B8DCEC400757B1B /* MWMSearchDownloadView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 344825961B8DCEC400757B1B /* MWMSearchDownloadView.mm */; }; 34570A361B13217C00E6D4FD /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34570A331B13217C00E6D4FD /* Bolts.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 34570A371B13217C00E6D4FD /* Parse.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34570A341B13217C00E6D4FD /* Parse.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 34570A381B13217C00E6D4FD /* ParseFacebookUtilsV4.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34570A351B13217C00E6D4FD /* ParseFacebookUtilsV4.framework */; settings = {ATTRIBUTES = (Required, ); }; }; @@ -38,6 +47,7 @@ 345C31781AE799B600EA0CC2 /* MWMSearchResultCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 345C31751AE799B600EA0CC2 /* MWMSearchResultCell.m */; }; 345C31791AE799B600EA0CC2 /* MWMSearchResultController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 345C31771AE799B600EA0CC2 /* MWMSearchResultController.mm */; }; 3465E7D81B6658C000854C4D /* MWMAPIBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3465E7D71B6658C000854C4D /* MWMAPIBar.mm */; }; + 346EDADB1B9F0E35004F8DB5 /* MWMMultilineLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 346EDADA1B9F0E35004F8DB5 /* MWMMultilineLabel.m */; }; 347274731B0F4EE000756B37 /* me.maps.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 347274721B0F4EE000756B37 /* me.maps.entitlements */; }; 347274771B0F4F3900756B37 /* me.maps.watchkitextension.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 347274761B0F4F3900756B37 /* me.maps.watchkitextension.entitlements */; }; 347274791B0F4FD900756B37 /* me.maps.watchkitextension.production.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 347274781B0F4FD900756B37 /* me.maps.watchkitextension.production.entitlements */; }; @@ -45,6 +55,8 @@ 3472EC051B4D44BE0085CB79 /* UIFont+MapsMeFonts.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3472EC041B4D44BE0085CB79 /* UIFont+MapsMeFonts.mm */; }; 347BAC691B733D540010FF78 /* MWMPedestrianShareAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347BAC681B733D540010FF78 /* MWMPedestrianShareAlert.xib */; }; 347BAC6E1B736BA70010FF78 /* MWMSharePedestrianRoutesToastActivityItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 347BAC6D1B736BA70010FF78 /* MWMSharePedestrianRoutesToastActivityItem.mm */; }; + 3485C0121B85C20E00F7712D /* MWMSearchTableViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3485C0101B85C20E00F7712D /* MWMSearchTableViewController.mm */; }; + 3485C0131B85C20E00F7712D /* MWMSearchTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3485C0111B85C20E00F7712D /* MWMSearchTableViewController.xib */; }; 348E578E1B0F3752000FA02A /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEB7E22111E9079400080A68 /* CoreLocation.framework */; }; 3497A93A1B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3497A9371B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm */; }; 349A357A1B53D4C9009677EE /* MWMCircularProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 349A35761B53D4C9009677EE /* MWMCircularProgress.m */; }; @@ -55,10 +67,25 @@ 349A35851B53E967009677EE /* MWMDownloadMapRequestView.m in Sources */ = {isa = PBXBuildFile; fileRef = 349A35821B53E967009677EE /* MWMDownloadMapRequestView.m */; }; 349A358C1B53EABC009677EE /* MWMSearchDownloadMapRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 349A35881B53EABC009677EE /* MWMSearchDownloadMapRequest.m */; }; 349A358D1B53EABC009677EE /* MWMSearchDownloadMapRequest.xib in Resources */ = {isa = PBXBuildFile; fileRef = 349A35891B53EABC009677EE /* MWMSearchDownloadMapRequest.xib */; }; - 349A358E1B53EABC009677EE /* MWMSearchDownloadMapRequestView.m in Sources */ = {isa = PBXBuildFile; fileRef = 349A358B1B53EABC009677EE /* MWMSearchDownloadMapRequestView.m */; }; + 349A358E1B53EABC009677EE /* MWMSearchDownloadMapRequestView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 349A358B1B53EABC009677EE /* MWMSearchDownloadMapRequestView.mm */; }; 34A742FE1AE5461A00CE15EB /* index.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34A742FD1AE5461A00CE15EB /* index.cpp */; }; 34A743001AE5468200CE15EB /* storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34A742FF1AE5468200CE15EB /* storage.cpp */; }; 34B16C451B72655D000D3A0D /* MWMPedestrianShareAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B16C441B72655D000D3A0D /* MWMPedestrianShareAlert.mm */; }; + 34B82AB21B8344E300180497 /* MWMSearchTextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AB11B8344E300180497 /* MWMSearchTextField.mm */; }; + 34B82ABA1B837FFD00180497 /* MWMSearchHistoryRequestCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AB81B837FFD00180497 /* MWMSearchHistoryRequestCell.mm */; }; + 34B82ABB1B837FFD00180497 /* MWMSearchHistoryRequestCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B82AB91B837FFD00180497 /* MWMSearchHistoryRequestCell.xib */; }; + 34B82AC41B84608600180497 /* MWMSearchHistoryClearCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AC21B84608600180497 /* MWMSearchHistoryClearCell.mm */; }; + 34B82AC51B84608600180497 /* MWMSearchHistoryClearCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B82AC31B84608600180497 /* MWMSearchHistoryClearCell.xib */; }; + 34B82ACA1B8465C100180497 /* MWMSearchCategoryCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AC81B8465C100180497 /* MWMSearchCategoryCell.mm */; }; + 34B82ACB1B8465C100180497 /* MWMSearchCategoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B82AC91B8465C100180497 /* MWMSearchCategoryCell.xib */; }; + 34B82AD01B846B2C00180497 /* MWMSearchBookmarksCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82ACE1B846B2C00180497 /* MWMSearchBookmarksCell.mm */; }; + 34B82AD11B846B2C00180497 /* MWMSearchBookmarksCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B82ACF1B846B2C00180497 /* MWMSearchBookmarksCell.xib */; }; + 34B82AD61B84746E00180497 /* MWMSearchSuggestionCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AD41B84746E00180497 /* MWMSearchSuggestionCell.mm */; }; + 34B82AD71B84746E00180497 /* MWMSearchSuggestionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B82AD51B84746E00180497 /* MWMSearchSuggestionCell.xib */; }; + 34B82ADA1B847FFC00180497 /* MWMSearchCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AD91B847FFC00180497 /* MWMSearchCell.mm */; }; + 34B82ADE1B84A4A000180497 /* MWMSearchCommonCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82ADC1B84A4A000180497 /* MWMSearchCommonCell.mm */; }; + 34B82ADF1B84A4A000180497 /* MWMSearchCommonCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34B82ADD1B84A4A000180497 /* MWMSearchCommonCell.xib */; }; + 34B82AE21B84AC5E00180497 /* MWMSearchCategoriesManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34B82AE11B84AC5E00180497 /* MWMSearchCategoriesManager.mm */; }; 34BC72211B0DECAE0012A34B /* MWMLocationButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BC720C1B0DECAE0012A34B /* MWMLocationButton.mm */; }; 34BC72221B0DECAE0012A34B /* MWMLocationButtonView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BC720E1B0DECAE0012A34B /* MWMLocationButtonView.mm */; }; 34BC72231B0DECAE0012A34B /* MWMLocationButton.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34BC720F1B0DECAE0012A34B /* MWMLocationButton.xib */; }; @@ -70,7 +97,18 @@ 34BC72291B0DECAE0012A34B /* MWMZoomButtons.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BC721D1B0DECAE0012A34B /* MWMZoomButtons.mm */; }; 34BC722A1B0DECAE0012A34B /* MWMZoomButtonsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BC721F1B0DECAE0012A34B /* MWMZoomButtonsView.m */; }; 34BC722B1B0DECAE0012A34B /* MWMZoomButtonsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34BC72201B0DECAE0012A34B /* MWMZoomButtonsView.xib */; }; + 34CC4C091B81F3B500E44C1F /* MWMSearchTabbedViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34CC4C071B81F3B500E44C1F /* MWMSearchTabbedViewController.mm */; }; + 34CC4C0A1B81F3B500E44C1F /* MWMSearchTabbedViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34CC4C081B81F3B500E44C1F /* MWMSearchTabbedViewController.xib */; }; + 34CC4C0E1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34CC4C0C1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.mm */; }; + 34CC4C0F1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34CC4C0D1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.xib */; }; + 34CC4C121B82120700E44C1F /* MWMSearchTabbedViewLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34CC4C111B82120700E44C1F /* MWMSearchTabbedViewLayout.mm */; }; + 34CFFE8B1B7DE6FD009D0C9F /* MWMSearchManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34CFFE8A1B7DE6FD009D0C9F /* MWMSearchManager.mm */; }; + 34CFFE8D1B7DE71C009D0C9F /* MWMSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34CFFE8C1B7DE71C009D0C9F /* MWMSearchView.xib */; }; + 34CFFE901B7DE83D009D0C9F /* MWMSearchView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34CFFE8F1B7DE83D009D0C9F /* MWMSearchView.mm */; }; 34DF4D111AE77B9F0012702D /* MWMWKInterfaceController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34DF4D101AE77B9F0012702D /* MWMWKInterfaceController.mm */; }; + 34F45E8E1B96E88100AC93F8 /* MWMSearchTabButtonsView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F45E8D1B96E88100AC93F8 /* MWMSearchTabButtonsView.mm */; }; + 34F45E901B96E8B100AC93F8 /* MWMSearchTabButtonsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34F45E8F1B96E8B100AC93F8 /* MWMSearchTabButtonsView.xib */; }; + 34F8ADD91B97229A004184CC /* MWMSearchTableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F8ADD81B97229A004184CC /* MWMSearchTableView.mm */; }; 45159BF91B0CA2D5009BFA85 /* resources-6plus in Resources */ = {isa = PBXBuildFile; fileRef = 45159BF81B0CA2D5009BFA85 /* resources-6plus */; }; 454040621AD2D75E007A9B12 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 46F26C7210F61FD600ECCA39 /* OpenGLES.framework */; }; 454040631AD2D83A007A9B12 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97C98655186C734000AF7E9E /* AVFoundation.framework */; }; @@ -151,15 +189,8 @@ 978F9244183B660F000D6C7C /* SwitchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 978F923B183B660F000D6C7C /* SwitchCell.m */; }; 978F9247183B6671000D6C7C /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 978F9246183B6671000D6C7C /* Main_iPhone.storyboard */; }; 978F9253183BD530000D6C7C /* NavigationController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 978F9252183BD530000D6C7C /* NavigationController.mm */; }; - 97908B2C19658767003DD7C6 /* SearchCategoryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97908B2B19658767003DD7C6 /* SearchCategoryCell.m */; }; - 97908B30196591F7003DD7C6 /* SearchShowOnMapCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97908B2F196591F7003DD7C6 /* SearchShowOnMapCell.m */; }; 97A5967F19B9CD47007A963F /* copyright.html in Resources */ = {isa = PBXBuildFile; fileRef = 97A5967E19B9CD47007A963F /* copyright.html */; }; - 97A8000C18B21363000C07A2 /* SearchView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000B18B21363000C07A2 /* SearchView.mm */; }; - 97A8001018B21395000C07A2 /* SearchBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000F18B21395000C07A2 /* SearchBar.mm */; }; - 97A8001418B2140A000C07A2 /* SearchResultCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8001318B2140A000C07A2 /* SearchResultCell.m */; }; - 97A8002718B2741C000C07A2 /* SearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8002618B2741C000C07A2 /* SearchCell.m */; }; 97C98522186AE3CF00AF7E9E /* AppInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97C98520186AE3CF00AF7E9E /* AppInfo.mm */; }; - 97CC93BB19599F4700369B42 /* SearchSuggestCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97CC93BA19599F4700369B42 /* SearchSuggestCell.m */; }; 97D40C0A184D031900A1D572 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97D40C09184D031900A1D572 /* Images.xcassets */; }; 97D807BE18A93C8800D416E0 /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97C98651186C5EF000AF7E9E /* iAd.framework */; }; 97ECD871183620CE00F77A46 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97ECD870183620CE00F77A46 /* AdSupport.framework */; settings = {ATTRIBUTES = (Required, ); }; }; @@ -251,7 +282,7 @@ F6BD337F1B62403B00F2CE18 /* MWMLandscapeRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BD337B1B62403B00F2CE18 /* MWMLandscapeRoutePreview.xib */; }; F6BD33801B62403B00F2CE18 /* MWMPortraitRoutePreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6BD337C1B62403B00F2CE18 /* MWMPortraitRoutePreview.xib */; }; F6BD33811B62403B00F2CE18 /* MWMRoutePreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD337E1B62403B00F2CE18 /* MWMRoutePreview.mm */; }; - F6BD33841B6240F200F2CE18 /* MWMNavigationView.m in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33831B6240F200F2CE18 /* MWMNavigationView.m */; }; + F6BD33841B6240F200F2CE18 /* MWMNavigationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */; }; F6BD33871B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6BD33861B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm */; }; F6C6FE201AD6BEA0009FDED7 /* MWMWatchLocationTracker.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6C6FE1F1AD6BEA0009FDED7 /* MWMWatchLocationTracker.mm */; }; F6C7B7121BA840A4004233F4 /* resources-xhdpi_clear in Resources */ = {isa = PBXBuildFile; fileRef = 4A23D1591B8B4DD700D4EB6F /* resources-xhdpi_clear */; }; @@ -356,11 +387,15 @@ 340837121B7243CE00B5C185 /* MWMActivityViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMActivityViewController.m; sourceTree = ""; }; 340837141B72451A00B5C185 /* MWMShareLocationActivityItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMShareLocationActivityItem.h; sourceTree = ""; }; 340837151B72451A00B5C185 /* MWMShareLocationActivityItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMShareLocationActivityItem.mm; sourceTree = ""; }; + 340E105E1B944DAB00D975D5 /* MWMSearchHistoryManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchHistoryManager.h; sourceTree = ""; }; + 340E105F1B944DAB00D975D5 /* MWMSearchHistoryManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchHistoryManager.mm; sourceTree = ""; }; + 340E10611B949D1900D975D5 /* MWMSearchBookmarksManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchBookmarksManager.h; sourceTree = ""; }; + 340E10621B949D1900D975D5 /* MWMSearchBookmarksManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchBookmarksManager.mm; sourceTree = ""; }; 340F24611B14910500F874CD /* RouteState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RouteState.h; sourceTree = ""; }; 340F24621B14910500F874CD /* RouteState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RouteState.mm; sourceTree = ""; }; 340F24641B15F01D00F874CD /* MWMSideMenuDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSideMenuDelegate.h; sourceTree = ""; }; 341522BD1B666A550077AA8F /* MWMAPIBarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAPIBarView.h; sourceTree = ""; }; - 341522BE1B666A550077AA8F /* MWMAPIBarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMAPIBarView.m; sourceTree = ""; }; + 341522BE1B666A550077AA8F /* MWMAPIBarView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAPIBarView.mm; sourceTree = ""; }; 341C2A5A1B720B8A00AD41A1 /* MWMAPIBarView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMAPIBarView.xib; sourceTree = ""; }; 3428BC111B55477E00C85B30 /* MWMSideMenuDownloadBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSideMenuDownloadBadge.h; sourceTree = ""; }; 3428BC121B55477E00C85B30 /* MWMSideMenuDownloadBadge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMSideMenuDownloadBadge.m; sourceTree = ""; }; @@ -369,9 +404,22 @@ 342AD7701B53D32F00E0B997 /* UIView+RuntimeAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+RuntimeAttributes.h"; sourceTree = ""; }; 342AD7711B53D32F00E0B997 /* UIView+RuntimeAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+RuntimeAttributes.m"; sourceTree = ""; }; 342E75A11B302FCC00A8635F /* MWMPlacePageViewManagerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMPlacePageViewManagerDelegate.h; sourceTree = ""; }; + 3438CDF21B85F1170051AA78 /* MWMConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMConsole.h; sourceTree = ""; }; + 3438CDF31B85F1170051AA78 /* MWMConsole.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMConsole.mm; sourceTree = ""; }; + 3438CDF51B8616760051AA78 /* MWMSearchShowOnMapCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchShowOnMapCell.h; sourceTree = ""; }; + 3438CDF61B8616760051AA78 /* MWMSearchShowOnMapCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchShowOnMapCell.mm; sourceTree = ""; }; + 3438CDF71B8616760051AA78 /* MWMSearchShowOnMapCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchShowOnMapCell.xib; sourceTree = ""; }; + 3438CDFA1B862F5C0051AA78 /* MWMSearchContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchContentView.h; sourceTree = ""; }; + 3438CDFB1B862F5C0051AA78 /* MWMSearchContentView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchContentView.mm; sourceTree = ""; }; 343F262C1AEFC4A300388A6D /* MWMFrameworkUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMFrameworkUtils.h; sourceTree = ""; }; 343F262D1AEFC4A300388A6D /* MWMFrameworkUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMFrameworkUtils.mm; sourceTree = ""; }; 343F262F1AEFDB1A00388A6D /* Framework.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Framework.cpp; path = ../../Classes/Framework.cpp; sourceTree = ""; }; + 344825901B8DBADF00757B1B /* MWMSearchDownloadViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchDownloadViewController.h; sourceTree = ""; }; + 344825911B8DBADF00757B1B /* MWMSearchDownloadViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchDownloadViewController.mm; sourceTree = ""; }; + 344825921B8DBADF00757B1B /* MWMSearchDownloadViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchDownloadViewController.xib; sourceTree = ""; }; + 344825951B8DCEC400757B1B /* MWMSearchDownloadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchDownloadView.h; sourceTree = ""; }; + 344825961B8DCEC400757B1B /* MWMSearchDownloadView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchDownloadView.mm; sourceTree = ""; }; + 344BDB021B9069810076DB31 /* MWMSearchTabbedViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSearchTabbedViewProtocol.h; sourceTree = ""; }; 34570A331B13217C00E6D4FD /* Bolts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Bolts.framework; path = PushNotifications/Bolts.framework; sourceTree = ""; }; 34570A341B13217C00E6D4FD /* Parse.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Parse.framework; path = PushNotifications/Parse.framework; sourceTree = ""; }; 34570A351B13217C00E6D4FD /* ParseFacebookUtilsV4.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ParseFacebookUtilsV4.framework; path = PushNotifications/ParseFacebookUtilsV4.framework; sourceTree = ""; }; @@ -390,6 +438,8 @@ 345C31771AE799B600EA0CC2 /* MWMSearchResultController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchResultController.mm; sourceTree = ""; }; 3465E7D61B6658C000854C4D /* MWMAPIBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAPIBar.h; sourceTree = ""; }; 3465E7D71B6658C000854C4D /* MWMAPIBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAPIBar.mm; sourceTree = ""; }; + 346EDAD91B9F0E35004F8DB5 /* MWMMultilineLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMMultilineLabel.h; sourceTree = ""; }; + 346EDADA1B9F0E35004F8DB5 /* MWMMultilineLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMMultilineLabel.m; sourceTree = ""; }; 347274721B0F4EE000756B37 /* me.maps.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = me.maps.entitlements; sourceTree = ""; }; 347274761B0F4F3900756B37 /* me.maps.watchkitextension.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = me.maps.watchkitextension.entitlements; sourceTree = ""; }; 347274781B0F4FD900756B37 /* me.maps.watchkitextension.production.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = me.maps.watchkitextension.production.entitlements; sourceTree = ""; }; @@ -400,6 +450,9 @@ 347BAC6C1B736BA70010FF78 /* MWMSharePedestrianRoutesToastActivityItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSharePedestrianRoutesToastActivityItem.h; sourceTree = ""; }; 347BAC6D1B736BA70010FF78 /* MWMSharePedestrianRoutesToastActivityItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSharePedestrianRoutesToastActivityItem.mm; sourceTree = ""; }; 348320CC1B6A2C52007EC039 /* MWMNavigationViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMNavigationViewProtocol.h; sourceTree = ""; }; + 3485C00F1B85C20E00F7712D /* MWMSearchTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTableViewController.h; sourceTree = ""; }; + 3485C0101B85C20E00F7712D /* MWMSearchTableViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTableViewController.mm; sourceTree = ""; }; + 3485C0111B85C20E00F7712D /* MWMSearchTableViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchTableViewController.xib; sourceTree = ""; }; 348E57981B0F49D8000FA02A /* maps.me dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "maps.me dbg.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 348E57C81B0F49EE000FA02A /* maps.me WatchKit Extension WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "maps.me WatchKit Extension WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 348E57D71B0F49EE000FA02A /* maps.me WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "maps.me WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -419,11 +472,35 @@ 349A35881B53EABC009677EE /* MWMSearchDownloadMapRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMSearchDownloadMapRequest.m; sourceTree = ""; }; 349A35891B53EABC009677EE /* MWMSearchDownloadMapRequest.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchDownloadMapRequest.xib; sourceTree = ""; }; 349A358A1B53EABC009677EE /* MWMSearchDownloadMapRequestView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchDownloadMapRequestView.h; sourceTree = ""; }; - 349A358B1B53EABC009677EE /* MWMSearchDownloadMapRequestView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMSearchDownloadMapRequestView.m; sourceTree = ""; }; + 349A358B1B53EABC009677EE /* MWMSearchDownloadMapRequestView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchDownloadMapRequestView.mm; sourceTree = ""; }; 34A742FD1AE5461A00CE15EB /* index.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = index.cpp; path = ../../../storage/index.cpp; sourceTree = ""; }; 34A742FF1AE5468200CE15EB /* storage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = storage.cpp; path = ../../../storage/storage.cpp; sourceTree = ""; }; 34B16C431B72655D000D3A0D /* MWMPedestrianShareAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMPedestrianShareAlert.h; sourceTree = ""; }; 34B16C441B72655D000D3A0D /* MWMPedestrianShareAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMPedestrianShareAlert.mm; sourceTree = ""; }; + 34B82AB01B8344E300180497 /* MWMSearchTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTextField.h; sourceTree = ""; }; + 34B82AB11B8344E300180497 /* MWMSearchTextField.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTextField.mm; sourceTree = ""; }; + 34B82AB71B837FFD00180497 /* MWMSearchHistoryRequestCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchHistoryRequestCell.h; sourceTree = ""; }; + 34B82AB81B837FFD00180497 /* MWMSearchHistoryRequestCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchHistoryRequestCell.mm; sourceTree = ""; }; + 34B82AB91B837FFD00180497 /* MWMSearchHistoryRequestCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchHistoryRequestCell.xib; sourceTree = ""; }; + 34B82AC11B84608600180497 /* MWMSearchHistoryClearCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchHistoryClearCell.h; sourceTree = ""; }; + 34B82AC21B84608600180497 /* MWMSearchHistoryClearCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchHistoryClearCell.mm; sourceTree = ""; }; + 34B82AC31B84608600180497 /* MWMSearchHistoryClearCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchHistoryClearCell.xib; sourceTree = ""; }; + 34B82AC71B8465C100180497 /* MWMSearchCategoryCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchCategoryCell.h; sourceTree = ""; }; + 34B82AC81B8465C100180497 /* MWMSearchCategoryCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchCategoryCell.mm; sourceTree = ""; }; + 34B82AC91B8465C100180497 /* MWMSearchCategoryCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchCategoryCell.xib; sourceTree = ""; }; + 34B82ACD1B846B2C00180497 /* MWMSearchBookmarksCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchBookmarksCell.h; sourceTree = ""; }; + 34B82ACE1B846B2C00180497 /* MWMSearchBookmarksCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchBookmarksCell.mm; sourceTree = ""; }; + 34B82ACF1B846B2C00180497 /* MWMSearchBookmarksCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchBookmarksCell.xib; sourceTree = ""; }; + 34B82AD31B84746E00180497 /* MWMSearchSuggestionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchSuggestionCell.h; sourceTree = ""; }; + 34B82AD41B84746E00180497 /* MWMSearchSuggestionCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchSuggestionCell.mm; sourceTree = ""; }; + 34B82AD51B84746E00180497 /* MWMSearchSuggestionCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchSuggestionCell.xib; sourceTree = ""; }; + 34B82AD81B847FFC00180497 /* MWMSearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchCell.h; sourceTree = ""; }; + 34B82AD91B847FFC00180497 /* MWMSearchCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchCell.mm; sourceTree = ""; }; + 34B82ADB1B84A4A000180497 /* MWMSearchCommonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchCommonCell.h; sourceTree = ""; }; + 34B82ADC1B84A4A000180497 /* MWMSearchCommonCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchCommonCell.mm; sourceTree = ""; }; + 34B82ADD1B84A4A000180497 /* MWMSearchCommonCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchCommonCell.xib; sourceTree = ""; }; + 34B82AE01B84AC5E00180497 /* MWMSearchCategoriesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchCategoriesManager.h; sourceTree = ""; }; + 34B82AE11B84AC5E00180497 /* MWMSearchCategoriesManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchCategoriesManager.mm; sourceTree = ""; }; 34BC720B1B0DECAE0012A34B /* MWMLocationButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMLocationButton.h; sourceTree = ""; }; 34BC720C1B0DECAE0012A34B /* MWMLocationButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMLocationButton.mm; sourceTree = ""; }; 34BC720D1B0DECAE0012A34B /* MWMLocationButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMLocationButtonView.h; sourceTree = ""; }; @@ -444,9 +521,27 @@ 34BC721E1B0DECAE0012A34B /* MWMZoomButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMZoomButtonsView.h; sourceTree = ""; }; 34BC721F1B0DECAE0012A34B /* MWMZoomButtonsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMZoomButtonsView.m; sourceTree = ""; }; 34BC72201B0DECAE0012A34B /* MWMZoomButtonsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMZoomButtonsView.xib; sourceTree = ""; }; + 34CC4C061B81F3B500E44C1F /* MWMSearchTabbedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTabbedViewController.h; sourceTree = ""; }; + 34CC4C071B81F3B500E44C1F /* MWMSearchTabbedViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTabbedViewController.mm; sourceTree = ""; }; + 34CC4C081B81F3B500E44C1F /* MWMSearchTabbedViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchTabbedViewController.xib; sourceTree = ""; }; + 34CC4C0B1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTabbedCollectionViewCell.h; sourceTree = ""; }; + 34CC4C0C1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTabbedCollectionViewCell.mm; sourceTree = ""; }; + 34CC4C0D1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchTabbedCollectionViewCell.xib; sourceTree = ""; }; + 34CC4C101B82120700E44C1F /* MWMSearchTabbedViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTabbedViewLayout.h; sourceTree = ""; }; + 34CC4C111B82120700E44C1F /* MWMSearchTabbedViewLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTabbedViewLayout.mm; sourceTree = ""; }; + 34CFFE891B7DE6FD009D0C9F /* MWMSearchManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchManager.h; sourceTree = ""; }; + 34CFFE8A1B7DE6FD009D0C9F /* MWMSearchManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchManager.mm; sourceTree = ""; }; + 34CFFE8C1B7DE71C009D0C9F /* MWMSearchView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchView.xib; sourceTree = ""; }; + 34CFFE8E1B7DE83D009D0C9F /* MWMSearchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchView.h; sourceTree = ""; }; + 34CFFE8F1B7DE83D009D0C9F /* MWMSearchView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchView.mm; sourceTree = ""; }; 34D56DDE1B3C310A00DFF4CC /* MWMSideMenuButtonDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSideMenuButtonDelegate.h; sourceTree = ""; }; 34DF4D0F1AE77B9F0012702D /* MWMWKInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMWKInterfaceController.h; sourceTree = ""; }; 34DF4D101AE77B9F0012702D /* MWMWKInterfaceController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMWKInterfaceController.mm; sourceTree = ""; }; + 34F45E8C1B96E88100AC93F8 /* MWMSearchTabButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTabButtonsView.h; sourceTree = ""; }; + 34F45E8D1B96E88100AC93F8 /* MWMSearchTabButtonsView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTabButtonsView.mm; sourceTree = ""; }; + 34F45E8F1B96E8B100AC93F8 /* MWMSearchTabButtonsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSearchTabButtonsView.xib; sourceTree = ""; }; + 34F8ADD71B97229A004184CC /* MWMSearchTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSearchTableView.h; sourceTree = ""; }; + 34F8ADD81B97229A004184CC /* MWMSearchTableView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSearchTableView.mm; sourceTree = ""; }; 3D443C9C19E421EE0025C2FC /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; 45159BF81B0CA2D5009BFA85 /* resources-6plus */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-6plus"; path = "../../data/resources-6plus"; sourceTree = ""; }; 454040681AD2D8D2007A9B12 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; @@ -527,19 +622,7 @@ 978F9246183B6671000D6C7C /* Main_iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main_iPhone.storyboard; sourceTree = ""; }; 978F9251183BD530000D6C7C /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = ""; }; 978F9252183BD530000D6C7C /* NavigationController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigationController.mm; sourceTree = ""; }; - 97908B2A19658767003DD7C6 /* SearchCategoryCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchCategoryCell.h; sourceTree = ""; }; - 97908B2B19658767003DD7C6 /* SearchCategoryCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchCategoryCell.m; sourceTree = ""; }; - 97908B2E196591F7003DD7C6 /* SearchShowOnMapCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchShowOnMapCell.h; sourceTree = ""; }; - 97908B2F196591F7003DD7C6 /* SearchShowOnMapCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchShowOnMapCell.m; sourceTree = ""; }; 97A5967E19B9CD47007A963F /* copyright.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = copyright.html; path = ../../data/copyright.html; sourceTree = ""; }; - 97A8000A18B21363000C07A2 /* SearchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchView.h; sourceTree = ""; }; - 97A8000B18B21363000C07A2 /* SearchView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchView.mm; sourceTree = ""; }; - 97A8000E18B21395000C07A2 /* SearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchBar.h; sourceTree = ""; }; - 97A8000F18B21395000C07A2 /* SearchBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchBar.mm; sourceTree = ""; }; - 97A8001218B2140A000C07A2 /* SearchResultCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchResultCell.h; sourceTree = ""; }; - 97A8001318B2140A000C07A2 /* SearchResultCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchResultCell.m; sourceTree = ""; }; - 97A8002518B2741C000C07A2 /* SearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchCell.h; sourceTree = ""; }; - 97A8002618B2741C000C07A2 /* SearchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchCell.m; sourceTree = ""; }; 97C98520186AE3CF00AF7E9E /* AppInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppInfo.mm; sourceTree = ""; }; 97C98521186AE3CF00AF7E9E /* AppInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppInfo.h; sourceTree = ""; }; 97C98647186C5E9900AF7E9E /* EventKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKit.framework; path = System/Library/Frameworks/EventKit.framework; sourceTree = SDKROOT; }; @@ -550,8 +633,6 @@ 97C98651186C5EF000AF7E9E /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 97C98653186C5F0500AF7E9E /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 97C98655186C734000AF7E9E /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; - 97CC93B919599F4700369B42 /* SearchSuggestCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchSuggestCell.h; sourceTree = ""; }; - 97CC93BA19599F4700369B42 /* SearchSuggestCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchSuggestCell.m; sourceTree = ""; }; 97D40C09184D031900A1D572 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = SOURCE_ROOT; }; 97DD585B18A8EB120079837E /* Flurry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flurry.h; sourceTree = ""; }; 97DEA09018D706C300C5F963 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = ""; }; @@ -695,7 +776,7 @@ 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.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMNavigationView.m; 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 = ""; }; F6BD33881B62423900F2CE18 /* MWMSideMenuManagerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSideMenuManagerDelegate.h; sourceTree = ""; }; @@ -864,6 +945,7 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + 346EDAD81B9F0E15004F8DB5 /* Components */, 340837101B7243B500B5C185 /* Share */, 340F24601B1490ED00F874CD /* RouteState */, F6588E291B15C25C00EE1E58 /* TextView */, @@ -1026,6 +1108,15 @@ path = RouteState; sourceTree = ""; }; + 3438CDF11B85F0C30051AA78 /* Console */ = { + isa = PBXGroup; + children = ( + 3438CDF21B85F1170051AA78 /* MWMConsole.h */, + 3438CDF31B85F1170051AA78 /* MWMConsole.mm */, + ); + path = Console; + sourceTree = ""; + }; 343F262B1AEFC4A300388A6D /* FrameworkUtils */ = { isa = PBXGroup; children = ( @@ -1035,6 +1126,18 @@ path = FrameworkUtils; sourceTree = ""; }; + 3448258F1B8DB05C00757B1B /* DownloadView */ = { + isa = PBXGroup; + children = ( + 344825951B8DCEC400757B1B /* MWMSearchDownloadView.h */, + 344825961B8DCEC400757B1B /* MWMSearchDownloadView.mm */, + 344825901B8DBADF00757B1B /* MWMSearchDownloadViewController.h */, + 344825911B8DBADF00757B1B /* MWMSearchDownloadViewController.mm */, + 344825921B8DBADF00757B1B /* MWMSearchDownloadViewController.xib */, + ); + path = DownloadView; + sourceTree = ""; + }; 345C316A1AE7939B00EA0CC2 /* Controllers */ = { isa = PBXGroup; children = ( @@ -1087,12 +1190,21 @@ 3465E7D61B6658C000854C4D /* MWMAPIBar.h */, 3465E7D71B6658C000854C4D /* MWMAPIBar.mm */, 341522BD1B666A550077AA8F /* MWMAPIBarView.h */, - 341522BE1B666A550077AA8F /* MWMAPIBarView.m */, + 341522BE1B666A550077AA8F /* MWMAPIBarView.mm */, 341C2A5A1B720B8A00AD41A1 /* MWMAPIBarView.xib */, ); path = APIBar; sourceTree = ""; }; + 346EDAD81B9F0E15004F8DB5 /* Components */ = { + isa = PBXGroup; + children = ( + 346EDAD91B9F0E35004F8DB5 /* MWMMultilineLabel.h */, + 346EDADA1B9F0E35004F8DB5 /* MWMMultilineLabel.m */, + ); + path = Components; + sourceTree = ""; + }; 347274711B0F4EB300756B37 /* Entitlements */ = { isa = PBXGroup; children = ( @@ -1167,12 +1279,22 @@ 349A35881B53EABC009677EE /* MWMSearchDownloadMapRequest.m */, 349A35891B53EABC009677EE /* MWMSearchDownloadMapRequest.xib */, 349A358A1B53EABC009677EE /* MWMSearchDownloadMapRequestView.h */, - 349A358B1B53EABC009677EE /* MWMSearchDownloadMapRequestView.m */, + 349A358B1B53EABC009677EE /* MWMSearchDownloadMapRequestView.mm */, ); name = SearchDownloadMapRequest; path = CustomViews/SearchDownloadMapRequest; sourceTree = ""; }; + 34A774DB1B95D88100BC0D86 /* TabButtons */ = { + isa = PBXGroup; + children = ( + 34F45E8C1B96E88100AC93F8 /* MWMSearchTabButtonsView.h */, + 34F45E8D1B96E88100AC93F8 /* MWMSearchTabButtonsView.mm */, + 34F45E8F1B96E8B100AC93F8 /* MWMSearchTabButtonsView.xib */, + ); + path = TabButtons; + sourceTree = ""; + }; 34B16C421B72653B000D3A0D /* PedestrianShareAlert */ = { isa = PBXGroup; children = ( @@ -1183,9 +1305,72 @@ path = PedestrianShareAlert; sourceTree = ""; }; + 34B82AB31B83616A00180497 /* HistoryTab */ = { + isa = PBXGroup; + children = ( + 340E105E1B944DAB00D975D5 /* MWMSearchHistoryManager.h */, + 340E105F1B944DAB00D975D5 /* MWMSearchHistoryManager.mm */, + 34B82AB71B837FFD00180497 /* MWMSearchHistoryRequestCell.h */, + 34B82AB81B837FFD00180497 /* MWMSearchHistoryRequestCell.mm */, + 34B82AB91B837FFD00180497 /* MWMSearchHistoryRequestCell.xib */, + 34B82AC11B84608600180497 /* MWMSearchHistoryClearCell.h */, + 34B82AC21B84608600180497 /* MWMSearchHistoryClearCell.mm */, + 34B82AC31B84608600180497 /* MWMSearchHistoryClearCell.xib */, + ); + path = HistoryTab; + sourceTree = ""; + }; + 34B82AC61B84645F00180497 /* CategoriesTab */ = { + isa = PBXGroup; + children = ( + 34B82AE01B84AC5E00180497 /* MWMSearchCategoriesManager.h */, + 34B82AE11B84AC5E00180497 /* MWMSearchCategoriesManager.mm */, + 34B82AC71B8465C100180497 /* MWMSearchCategoryCell.h */, + 34B82AC81B8465C100180497 /* MWMSearchCategoryCell.mm */, + 34B82AC91B8465C100180497 /* MWMSearchCategoryCell.xib */, + ); + path = CategoriesTab; + sourceTree = ""; + }; + 34B82ACC1B846B0100180497 /* BookmarksTab */ = { + isa = PBXGroup; + children = ( + 340E10611B949D1900D975D5 /* MWMSearchBookmarksManager.h */, + 340E10621B949D1900D975D5 /* MWMSearchBookmarksManager.mm */, + 34B82ACD1B846B2C00180497 /* MWMSearchBookmarksCell.h */, + 34B82ACE1B846B2C00180497 /* MWMSearchBookmarksCell.mm */, + 34B82ACF1B846B2C00180497 /* MWMSearchBookmarksCell.xib */, + ); + path = BookmarksTab; + sourceTree = ""; + }; + 34B82AD21B84740000180497 /* TableView */ = { + isa = PBXGroup; + children = ( + 3438CDF51B8616760051AA78 /* MWMSearchShowOnMapCell.h */, + 3438CDF61B8616760051AA78 /* MWMSearchShowOnMapCell.mm */, + 3438CDF71B8616760051AA78 /* MWMSearchShowOnMapCell.xib */, + 34B82AD31B84746E00180497 /* MWMSearchSuggestionCell.h */, + 34B82AD41B84746E00180497 /* MWMSearchSuggestionCell.mm */, + 34B82AD51B84746E00180497 /* MWMSearchSuggestionCell.xib */, + 34B82ADB1B84A4A000180497 /* MWMSearchCommonCell.h */, + 34B82ADC1B84A4A000180497 /* MWMSearchCommonCell.mm */, + 34B82ADD1B84A4A000180497 /* MWMSearchCommonCell.xib */, + 34B82AD81B847FFC00180497 /* MWMSearchCell.h */, + 34B82AD91B847FFC00180497 /* MWMSearchCell.mm */, + 3485C00F1B85C20E00F7712D /* MWMSearchTableViewController.h */, + 3485C0101B85C20E00F7712D /* MWMSearchTableViewController.mm */, + 3485C0111B85C20E00F7712D /* MWMSearchTableViewController.xib */, + 34F8ADD71B97229A004184CC /* MWMSearchTableView.h */, + 34F8ADD81B97229A004184CC /* MWMSearchTableView.mm */, + ); + path = TableView; + sourceTree = ""; + }; 34BC72091B0DECAE0012A34B /* MapViewControls */ = { isa = PBXGroup; children = ( + 34CFFE881B7DE67F009D0C9F /* Search */, 3465E7D51B66589900854C4D /* APIBar */, 34BC72101B0DECAE0012A34B /* MWMMapViewControlsManager.h */, 34BC72111B0DECAE0012A34B /* MWMMapViewControlsManager.mm */, @@ -1243,12 +1428,52 @@ path = ZoomButtons; sourceTree = ""; }; + 34CC4C051B81F38E00E44C1F /* TabbedView */ = { + isa = PBXGroup; + children = ( + 34B82AB31B83616A00180497 /* HistoryTab */, + 34B82AC61B84645F00180497 /* CategoriesTab */, + 34B82ACC1B846B0100180497 /* BookmarksTab */, + 34CC4C061B81F3B500E44C1F /* MWMSearchTabbedViewController.h */, + 34CC4C071B81F3B500E44C1F /* MWMSearchTabbedViewController.mm */, + 34CC4C081B81F3B500E44C1F /* MWMSearchTabbedViewController.xib */, + 34CC4C0B1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.h */, + 34CC4C0C1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.mm */, + 34CC4C0D1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.xib */, + 34CC4C101B82120700E44C1F /* MWMSearchTabbedViewLayout.h */, + 34CC4C111B82120700E44C1F /* MWMSearchTabbedViewLayout.mm */, + 344BDB021B9069810076DB31 /* MWMSearchTabbedViewProtocol.h */, + ); + path = TabbedView; + sourceTree = ""; + }; + 34CFFE881B7DE67F009D0C9F /* Search */ = { + isa = PBXGroup; + children = ( + 34A774DB1B95D88100BC0D86 /* TabButtons */, + 3438CDF11B85F0C30051AA78 /* Console */, + 34B82AD21B84740000180497 /* TableView */, + 34CC4C051B81F38E00E44C1F /* TabbedView */, + 3448258F1B8DB05C00757B1B /* DownloadView */, + 34CFFE891B7DE6FD009D0C9F /* MWMSearchManager.h */, + 34CFFE8A1B7DE6FD009D0C9F /* MWMSearchManager.mm */, + 34CFFE8C1B7DE71C009D0C9F /* MWMSearchView.xib */, + 34CFFE8E1B7DE83D009D0C9F /* MWMSearchView.h */, + 34CFFE8F1B7DE83D009D0C9F /* MWMSearchView.mm */, + 3438CDFA1B862F5C0051AA78 /* MWMSearchContentView.h */, + 3438CDFB1B862F5C0051AA78 /* MWMSearchContentView.mm */, + 34B82AB01B8344E300180497 /* MWMSearchTextField.h */, + 34B82AB11B8344E300180497 /* MWMSearchTextField.mm */, + ); + path = Search; + sourceTree = ""; + }; 34D783C71B5F9D7800E0C0EE /* Views */ = { isa = PBXGroup; children = ( 348320CC1B6A2C52007EC039 /* MWMNavigationViewProtocol.h */, F6BD33821B6240F200F2CE18 /* MWMNavigationView.h */, - F6BD33831B6240F200F2CE18 /* MWMNavigationView.m */, + F6BD33831B6240F200F2CE18 /* MWMNavigationView.mm */, F68E6BCF1B8DB7810040566D /* Panels */, F6BD33731B62400E00F2CE18 /* Dashboard */, 34D783CD1B5F9D7800E0C0EE /* RoutePreview */, @@ -1353,34 +1578,12 @@ name = Cells; sourceTree = ""; }; - 97A8000918B210DC000C07A2 /* Search */ = { - isa = PBXGroup; - children = ( - 97A8000A18B21363000C07A2 /* SearchView.h */, - 97A8000B18B21363000C07A2 /* SearchView.mm */, - 97A8000E18B21395000C07A2 /* SearchBar.h */, - 97A8000F18B21395000C07A2 /* SearchBar.mm */, - 97A8002518B2741C000C07A2 /* SearchCell.h */, - 97A8002618B2741C000C07A2 /* SearchCell.m */, - 97A8001218B2140A000C07A2 /* SearchResultCell.h */, - 97A8001318B2140A000C07A2 /* SearchResultCell.m */, - 97CC93B919599F4700369B42 /* SearchSuggestCell.h */, - 97CC93BA19599F4700369B42 /* SearchSuggestCell.m */, - 97908B2A19658767003DD7C6 /* SearchCategoryCell.h */, - 97908B2B19658767003DD7C6 /* SearchCategoryCell.m */, - 97908B2E196591F7003DD7C6 /* SearchShowOnMapCell.h */, - 97908B2F196591F7003DD7C6 /* SearchShowOnMapCell.m */, - ); - name = Search; - sourceTree = ""; - }; 97B4E9271851DAB300BEC5D7 /* Custom Views */ = { isa = PBXGroup; children = ( 349A35741B53D4C9009677EE /* CircularProgress */, 349A357D1B53E967009677EE /* DownloadMapRequest */, 34BC72091B0DECAE0012A34B /* MapViewControls */, - 97A8000918B210DC000C07A2 /* Search */, 349A35861B53EABC009677EE /* SearchDownloadMapRequest */, 974386DB19373EA400FD5659 /* ToastView.h */, 974386DC19373EA400FD5659 /* ToastView.m */, @@ -2096,7 +2299,10 @@ 28AD73880D9D96C1002E5188 /* MainWindow.xib in Resources */, F67BC26F1B254B2000FE1D7B /* MWMPlacePageDescriptionView.xib in Resources */, EE026F0611D6AC0D00645242 /* classificator.txt in Resources */, + 34CC4C0A1B81F3B500E44C1F /* MWMSearchTabbedViewController.xib in Resources */, + 34B82ACB1B8465C100180497 /* MWMSearchCategoryCell.xib in Resources */, FA065FED128614C400FEA989 /* MainWindow-iPad.xib in Resources */, + 34CC4C0F1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.xib in Resources */, FA46DA2C12D4166E00968C36 /* countries.txt in Resources */, 4A23D15C1B8B4DD700D4EB6F /* resources-6plus_clear in Resources */, EE583CBB12F773F00042CBE3 /* unicode_blocks.txt in Resources */, @@ -2125,7 +2331,9 @@ 97FC99DE19C1A2CD00C1CF98 /* resources-xhdpi in Resources */, 97D40C0A184D031900A1D572 /* Images.xcassets in Resources */, F6BD337F1B62403B00F2CE18 /* MWMLandscapeRoutePreview.xib in Resources */, + 344825941B8DBADF00757B1B /* MWMSearchDownloadViewController.xib in Resources */, B0DFE6311A1B78A200B6C35E /* LocalNotifications.plist in Resources */, + 34B82ABB1B837FFD00180497 /* MWMSearchHistoryRequestCell.xib in Resources */, 978D4A31199A11E600D72CA7 /* faq.html in Resources */, F66A8FB21B0A0954001B9C97 /* PlacePageView.xib in Resources */, 97FC99E019C1A2CD00C1CF98 /* resources-xxhdpi in Resources */, @@ -2133,13 +2341,16 @@ F64F19A41AB81A00006EAF7E /* MWMDownloadTransitMapAlert.xib in Resources */, F6BBF2C81B4FFB8C000CF8E2 /* MWMLocationAlert.xib in Resources */, 4A4765B31BA6FF5F00540CC4 /* city_rank.txt in Resources */, + 34B82AD71B84746E00180497 /* MWMSearchSuggestionCell.xib in Resources */, 97A5967F19B9CD47007A963F /* copyright.html in Resources */, + 34B82ADF1B84A4A000180497 /* MWMSearchCommonCell.xib in Resources */, 978F9247183B6671000D6C7C /* Main_iPhone.storyboard in Resources */, 4A7D89C51B2EBF3B00AC843E /* resources-6plus_dark in Resources */, FA459EB414327AF700B5BB3C /* WorldCoasts.mwm in Resources */, FA85F633145DDDC20090E1A0 /* packed_polygons.bin in Resources */, F6ED13561B16439E0095C6DE /* MWMDirectionView.xib in Resources */, FA99CB73147089B100689A9A /* Localizable.strings in Resources */, + 34CFFE8D1B7DE71C009D0C9F /* MWMSearchView.xib in Resources */, F7FDD823147F30CC005900FA /* drules_proto.bin in Resources */, F6588E381B15D87A00EE1E58 /* MWMBookmarkColorCell.xib in Resources */, FAAEA7D1161BD26600CCD661 /* synonyms.txt in Resources */, @@ -2150,22 +2361,27 @@ F61579361AC2CEB60032D8E9 /* MWMRateAlert.xib in Resources */, FA140653162A6288002BC1ED /* empty.png in Resources */, FA140655162A6288002BC1ED /* eye.png in Resources */, + 3438CDF91B8616760051AA78 /* MWMSearchShowOnMapCell.xib in Resources */, FA140657162A6288002BC1ED /* eye@2x.png in Resources */, 34BC72231B0DECAE0012A34B /* MWMLocationButton.xib in Resources */, 349A358D1B53EABC009677EE /* MWMSearchDownloadMapRequest.xib in Resources */, 4A23D15B1B8B4DD700D4EB6F /* drules_proto_clear.bin in Resources */, 341C2A5B1B720B8A00AD41A1 /* MWMAPIBarView.xib in Resources */, + 34B82AC51B84608600180497 /* MWMSearchHistoryClearCell.xib in Resources */, 349A357B1B53D4C9009677EE /* MWMCircularProgress.xib in Resources */, F6CB21621AEE902B00FB8963 /* PlacePageLinkCell.xib in Resources */, 349A35841B53E967009677EE /* MWMDownloadMapRequest.xib in Resources */, F6E0047B1B908CF5003BF5D8 /* MWMNiPadNavigationDashboard.xib in Resources */, F6BD33801B62403B00F2CE18 /* MWMPortraitRoutePreview.xib in Resources */, + 34B82AD11B846B2C00180497 /* MWMSearchBookmarksCell.xib in Resources */, 4A7D89C61B2EBF3B00AC843E /* resources-mdpi_dark in Resources */, F6BC1E541ACBF9AB00EF0360 /* MWMFacebookAlert.xib in Resources */, F6CB21641AEFC42800FB8963 /* PlacePageActionBar.xib in Resources */, F6CB216A1AF1303900FB8963 /* PlacePageBookmarkCell.xib in Resources */, + 34F45E901B96E8B100AC93F8 /* MWMSearchTabButtonsView.xib in Resources */, F6BD337A1B62400E00F2CE18 /* MWMPortraitNavigationDashboard.xib in Resources */, F64F4B6F1B46A5380081A24A /* MWMDownloaderDialogCell.xib in Resources */, + 3485C0131B85C20E00F7712D /* MWMSearchTableViewController.xib in Resources */, F6ED13931B1EFA2F0095C6DE /* MWMBookmarkDescriptionViewController.xib in Resources */, 4A23D15E1B8B4DD700D4EB6F /* resources-xhdpi_clear in Resources */, F64F199A1AB81A00006EAF7E /* MWMAlertViewController.xib in Resources */, @@ -2259,20 +2475,25 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 344825971B8DCEC400757B1B /* MWMSearchDownloadView.mm in Sources */, 978D4A251996B0EC00D72CA7 /* CommunityVC.m in Sources */, 1D60589B0D05DD56006BFB54 /* main.mm in Sources */, + 34CC4C091B81F3B500E44C1F /* MWMSearchTabbedViewController.mm in Sources */, 340837161B72451A00B5C185 /* MWMShareLocationActivityItem.mm in Sources */, 978D4A291996C17300D72CA7 /* RichTextVC.m in Sources */, 9747278418338F0C006B7CB7 /* UIViewController+Navigation.mm in Sources */, F6BC1E521ACBF98600EF0360 /* MWMFacebookAlert.mm in Sources */, - 97908B30196591F7003DD7C6 /* SearchShowOnMapCell.m in Sources */, F64F199D1AB81A00006EAF7E /* MWMDefaultAlert.mm in Sources */, + 3438CDF81B8616760051AA78 /* MWMSearchShowOnMapCell.mm in Sources */, 976D86F119C877E600C920EF /* MapCell.mm in Sources */, + 34F45E8E1B96E88100AC93F8 /* MWMSearchTabButtonsView.mm in Sources */, F6C934401AE64E4200DDC624 /* MWMSpringAnimation.mm in Sources */, + 34B82ACA1B8465C100180497 /* MWMSearchCategoryCell.mm in Sources */, 977E26C219E31BCC00BA2219 /* ActiveMapsVC.mm in Sources */, 1D3623260D0F684500981E51 /* MapsAppDelegate.mm in Sources */, - 341522BF1B666A550077AA8F /* MWMAPIBarView.m in Sources */, + 341522BF1B666A550077AA8F /* MWMAPIBarView.mm in Sources */, 349A35831B53E967009677EE /* MWMDownloadMapRequest.mm in Sources */, + 3438CDF41B85F1170051AA78 /* MWMConsole.mm in Sources */, A32B6D4C1A14980500E54A65 /* iosOGLContext.mm in Sources */, 560634F21B78806100F3D670 /* MWMTextToSpeech.mm in Sources */, 46F26CD810F623BA00ECCA39 /* EAGLView.mm in Sources */, @@ -2282,17 +2503,22 @@ EE7F29811219ECA300EB67A9 /* RenderBuffer.mm in Sources */, 6C93FAEC1AD8063900A2C4AE /* MWMWatchNotification.mm in Sources */, F62404FB1AAF3DB200B58DB6 /* UILabel+RuntimeAttributes.mm in Sources */, + 34CC4C0E1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.mm in Sources */, F6588E2C1B15C26700EE1E58 /* MWMTextView.mm in Sources */, F61B0F2C1B8B82DB00C08258 /* MWMNextTurnPanel.mm in Sources */, F6F722F81AE1572400DA3DA1 /* MWMiPhonePortraitPlacePage.mm in Sources */, F6CB21681AEFC6AA00FB8963 /* MWMPlacePageActionBar.mm in Sources */, F68E6BD21B8DB7AE0040566D /* MWMRouteHelperPanel.mm in Sources */, 34BC72291B0DECAE0012A34B /* MWMZoomButtons.mm in Sources */, + 34B82ADE1B84A4A000180497 /* MWMSearchCommonCell.mm in Sources */, 978F9253183BD530000D6C7C /* NavigationController.mm in Sources */, F66A8FA81B09F052001B9C97 /* MWMiPhoneLandscapePlacePage.mm in Sources */, 974386DD19373EA400FD5659 /* ToastView.m in Sources */, F6C9343C1AE4F94A00DDC624 /* MWMAnimator.mm in Sources */, + 3438CDFC1B862F5C0051AA78 /* MWMSearchContentView.mm in Sources */, + 3485C0121B85C20E00F7712D /* MWMSearchTableViewController.mm in Sources */, 977E26B919E2E64200BA2219 /* MapsObservers.mm in Sources */, + 34CFFE8B1B7DE6FD009D0C9F /* MWMSearchManager.mm in Sources */, F6BBF2C61B4FFB72000CF8E2 /* MWMLocationAlert.mm in Sources */, F66A8FB01B09F268001B9C97 /* MWMPlacePage.mm in Sources */, EE7F29821219ECA300EB67A9 /* RenderContext.mm in Sources */, @@ -2309,11 +2535,10 @@ 9747264318323080006B7CB7 /* UIKitCategories.mm in Sources */, F6BD33811B62403B00F2CE18 /* MWMRoutePreview.mm in Sources */, 977E26BE19E31BBE00BA2219 /* CountryTreeVC.mm in Sources */, - 97A8001418B2140A000C07A2 /* SearchResultCell.m in Sources */, 97F0817E19AF72590098FB0B /* BadgeView.m in Sources */, + 34B82AC41B84608600180497 /* MWMSearchHistoryClearCell.mm in Sources */, F64F4B741B4A45FD0081A24A /* MWMDownloaderDialogHeader.mm in Sources */, - 97A8002718B2741C000C07A2 /* SearchCell.m in Sources */, - 97908B2C19658767003DD7C6 /* SearchCategoryCell.m in Sources */, + 34F8ADD91B97229A004184CC /* MWMSearchTableView.mm in Sources */, F67BC2751B254F5500FE1D7B /* MWMPlacePageTypeDescription.mm in Sources */, B08AA8DA1A26299A00810B1C /* TimeUtils.m in Sources */, F6CB216D1AF13EBD00FB8963 /* MWMPlacePageBookmarkCell.mm in Sources */, @@ -2326,28 +2551,32 @@ F6D409FA1B319BD70041730F /* ContextViews.mm in Sources */, 349A357A1B53D4C9009677EE /* MWMCircularProgress.m in Sources */, 3428BC131B55477E00C85B30 /* MWMSideMenuDownloadBadge.m in Sources */, - 97A8000C18B21363000C07A2 /* SearchView.mm in Sources */, FAA5C2A2144F135F005337F6 /* LocationManager.mm in Sources */, + 34B82ADA1B847FFC00180497 /* MWMSearchCell.mm in Sources */, F66A8FAC1B09F137001B9C97 /* MWMiPadPlacePage.mm in Sources */, 978F9240183B660F000D6C7C /* SettingsViewController.mm in Sources */, F6BD33871B62412E00F2CE18 /* MWMNavigationDashboardEntity.mm in Sources */, F6CB21601AEE7A5B00FB8963 /* MWMPlacePageInfoCell.mm in Sources */, + 340E10601B944DAB00D975D5 /* MWMSearchHistoryManager.mm in Sources */, F6DBF9B61AA8779300F2EC2C /* CALayer+RuntimeAttributes.mm in Sources */, FA36B80D15403A4F004560CC /* BookmarksVC.mm in Sources */, F6ED135B1B18AA930095C6DE /* MWMExtendedPlacePageView.m in Sources */, 34B16C451B72655D000D3A0D /* MWMPedestrianShareAlert.mm in Sources */, 347BAC6E1B736BA70010FF78 /* MWMSharePedestrianRoutesToastActivityItem.mm in Sources */, + 34B82AD61B84746E00180497 /* MWMSearchSuggestionCell.mm in Sources */, F6588E2F1B15D2BC00EE1E58 /* MWMBookmarkColorViewController.mm in Sources */, - 349A358E1B53EABC009677EE /* MWMSearchDownloadMapRequestView.m in Sources */, + 349A358E1B53EABC009677EE /* MWMSearchDownloadMapRequestView.mm in Sources */, A32B6D4D1A14980500E54A65 /* iosOGLContextFactory.mm in Sources */, FAF457E715597D4600DCCC49 /* Framework.cpp in Sources */, - 97CC93BB19599F4700369B42 /* SearchSuggestCell.m in Sources */, FA054612155C465E001F4E37 /* SelectSetVC.mm in Sources */, FAA614B8155F16950031C345 /* AddSetVC.mm in Sources */, 977E26C619E31BDF00BA2219 /* DownloaderParentVC.mm in Sources */, + 34CC4C121B82120700E44C1F /* MWMSearchTabbedViewLayout.mm in Sources */, FAAEA7D5161D8D3100CCD661 /* BookmarksRootVC.mm in Sources */, 340837131B7243CE00B5C185 /* MWMActivityViewController.m in Sources */, 3497A93A1B5CF8A900F51E55 /* MWMNavigationDashboardManager.mm in Sources */, + 344825931B8DBADF00757B1B /* MWMSearchDownloadViewController.mm in Sources */, + 34B82ABA1B837FFD00180497 /* MWMSearchHistoryRequestCell.mm in Sources */, B0FBFA2B1A515B4C0086819E /* TableViewController.m in Sources */, F785EB4016386FC4003A38A8 /* BookmarkCell.mm in Sources */, 34BC72241B0DECAE0012A34B /* MWMMapViewControlsManager.mm in Sources */, @@ -2355,8 +2584,10 @@ 974D041D1977DE430081D0A7 /* LocalNotificationManager.mm in Sources */, 97C98522186AE3CF00AF7E9E /* AppInfo.mm in Sources */, 978F9242183B660F000D6C7C /* SelectableCell.m in Sources */, + 34B82AE21B84AC5E00180497 /* MWMSearchCategoriesManager.mm in Sources */, 34BC722A1B0DECAE0012A34B /* MWMZoomButtonsView.m in Sources */, F6F533A31B3C248900C1940B /* UIColor+MapsMeColor.mm in Sources */, + 346EDADB1B9F0E35004F8DB5 /* MWMMultilineLabel.m in Sources */, CB252D6F16FF82C9001E41E9 /* Statistics.mm in Sources */, 6BA0BCD11B74DDBA00CC9969 /* MWMCustomFacebookEvents.mm in Sources */, 978F9244183B660F000D6C7C /* SwitchCell.m in Sources */, @@ -2369,20 +2600,23 @@ 34BC72211B0DECAE0012A34B /* MWMLocationButton.mm in Sources */, F64F19A31AB81A00006EAF7E /* MWMDownloadTransitMapAlert.mm in Sources */, 97F61794183E7445009919E2 /* LinkCell.m in Sources */, + 34B82AD01B846B2C00180497 /* MWMSearchBookmarksCell.mm in Sources */, 976D86EC19C8697700C920EF /* ProgressView.m in Sources */, B0FBFA271A515AFD0086819E /* ViewController.m in Sources */, - F6BD33841B6240F200F2CE18 /* MWMNavigationView.m in Sources */, + F6BD33841B6240F200F2CE18 /* MWMNavigationView.mm in Sources */, 3472EC051B4D44BE0085CB79 /* UIFont+MapsMeFonts.mm in Sources */, 342AD76F1B53D30C00E0B997 /* UIButton+RuntimeAttributes.m in Sources */, 349A358C1B53EABC009677EE /* MWMSearchDownloadMapRequest.m in Sources */, F63732961AE9431E00A03764 /* MWMBasePlacePageView.mm in Sources */, - 97A8001018B21395000C07A2 /* SearchBar.mm in Sources */, F64F199B1AB81A00006EAF7E /* MWMAlert.mm in Sources */, 34BC72261B0DECAE0012A34B /* MWMSideMenuManager.mm in Sources */, ED48BBB517C267F5003E7E92 /* ColorPickerView.mm in Sources */, 6C24A3B21AD7D65500A47B99 /* MWMWatchEventInfo.mm in Sources */, ED48BBBA17C2B1E2003E7E92 /* CircleView.mm in Sources */, + 340E10631B949D1900D975D5 /* MWMSearchBookmarksManager.mm in Sources */, + 34CFFE901B7DE83D009D0C9F /* MWMSearchView.mm in Sources */, F6FE2C151B04A44E009814AA /* MWMPlacePageEntity.mm in Sources */, + 34B82AB21B8344E300180497 /* MWMSearchTextField.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iphone/Maps/Platform/LocationManager.mm b/iphone/Maps/Platform/LocationManager.mm index 8102e5b842..5d8c284194 100644 --- a/iphone/Maps/Platform/LocationManager.mm +++ b/iphone/Maps/Platform/LocationManager.mm @@ -1,6 +1,7 @@ #import "LocationManager.h" -#import "MapViewController.h" #import "MapsAppDelegate.h" +#import "MapViewController.h" +#import "MWMMapViewControlsManager.h" #import "Statistics.h" #import "3party/Alohalytics/src/alohalytics_objc.h" @@ -213,7 +214,7 @@ static NSString * const kAlohalyticsLocationRequestAlwaysFailed = @"$locationAlw if (!on) return NO; - if ([MapsAppDelegate theApp].m_mapViewController.searchView.state == SearchViewStateResults) + if (!MapsAppDelegate.theApp.m_mapViewController.controlsManager.searchHidden) return NO; if (!manager.heading) return YES; diff --git a/iphone/Maps/maps.me WatchKit Extension/FrameworkUtils/MWMFrameworkUtils.mm b/iphone/Maps/maps.me WatchKit Extension/FrameworkUtils/MWMFrameworkUtils.mm index e47fb0afb3..5c6ed990ba 100644 --- a/iphone/Maps/maps.me WatchKit Extension/FrameworkUtils/MWMFrameworkUtils.mm +++ b/iphone/Maps/maps.me WatchKit Extension/FrameworkUtils/MWMFrameworkUtils.mm @@ -112,7 +112,7 @@ extern NSString * const kSearchResultPointKey; NSMutableArray * res = [NSMutableArray arrayWithCapacity:maxResultsForWatch]; for (size_t index = 0; index < maxResultsForWatch; ++index) { - search::Result result = results.GetResult(index); + search::Result const & result = results.GetResult(index); NSMutableDictionary * d = [NSMutableDictionary dictionary]; d[kSearchResultTitleKey] = @(result.GetString()); d[kSearchResultCategoryKey] = @(result.GetFeatureType()); diff --git a/map/framework.cpp b/map/framework.cpp index 539dacdb53..844be1328d 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -986,7 +986,6 @@ void Framework::UpdateUserViewportChanged() if (IsISActive()) { (void)GetCurrentPosition(m_lastSearch.m_lat, m_lastSearch.m_lon); - m_lastSearch.m_callback = bind(&Framework::OnSearchResultsCallback, this, _1); m_lastSearch.SetSearchMode(search::SearchParams::IN_VIEWPORT_ONLY); m_lastSearch.SetForceSearch(false); @@ -994,24 +993,10 @@ void Framework::UpdateUserViewportChanged() } } -void Framework::OnSearchResultsCallback(search::Results const & results) +void Framework::UpdateSearchResults(search::Results const & results) { - if (!results.IsEndMarker() && results.GetCount() > 0) - { - // Got here from search thread. Need to switch into GUI thread to modify search mark container. - // Do copy the results structure to pass into GUI thread. - GetPlatform().RunOnGuiThread(bind(&Framework::OnSearchResultsCallbackUI, this, results)); - } -} - -void Framework::OnSearchResultsCallbackUI(search::Results const & results) -{ - if (IsISActive()) - { - FillSearchResultsMarks(results); - - Invalidate(); - } + FillSearchResultsMarks(results); + Invalidate(); } void Framework::ClearAllCaches() diff --git a/map/framework.hpp b/map/framework.hpp index 4f6c3c61ec..0fd1caecf4 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -324,8 +324,6 @@ private: search::SearchParams m_lastSearch; uint8_t m_fixedSearchResults; - void OnSearchResultsCallback(search::Results const & results); - void OnSearchResultsCallbackUI(search::Results const & results); void FillSearchResultsMarks(search::Results const & results); public: @@ -345,6 +343,7 @@ public: void ShowSearchResult(search::Result const & res); size_t ShowAllSearchResults(); + void UpdateSearchResults(search::Results const & results); void StartInteractiveSearch(search::SearchParams const & params) { m_lastSearch = params; } bool IsISActive() const { return !m_lastSearch.m_query.empty(); } diff --git a/search/result.hpp b/search/result.hpp index e762919cb6..c0ca12acba 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -150,6 +150,12 @@ public: inline size_t GetCount() const { return m_vec.size(); } size_t GetSuggestsCount() const; + inline Result & GetResult(size_t i) + { + ASSERT_LESS(i, m_vec.size(), ()); + return m_vec[i]; + } + inline Result const & GetResult(size_t i) const { ASSERT_LESS(i, m_vec.size(), ());