forked from organicmaps/organicmaps
[ios] Downloader UI
This commit is contained in:
parent
545aaaafec
commit
e5f65a930e
38 changed files with 2071 additions and 757 deletions
7
iphone/Maps/ActiveMapsVC.h
Normal file
7
iphone/Maps/ActiveMapsVC.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "DownloaderParentVC.h"
|
||||
|
||||
@interface ActiveMapsVC : DownloaderParentVC
|
||||
|
||||
@end
|
371
iphone/Maps/ActiveMapsVC.mm
Normal file
371
iphone/Maps/ActiveMapsVC.mm
Normal file
|
@ -0,0 +1,371 @@
|
|||
|
||||
#import "ActiveMapsVC.h"
|
||||
#import "CustomAlertView.h"
|
||||
#import "Statistics.h"
|
||||
#import "MapCell.h"
|
||||
#import "BadgeView.h"
|
||||
|
||||
@interface ActiveMapsVC () <ActiveMapsObserverProtocol>
|
||||
|
||||
@property (nonatomic) BadgeView * outOfDateBadge;
|
||||
@property (nonatomic) ActiveMapsLayout::TGroup selectedGroup;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ActiveMapsVC
|
||||
{
|
||||
ActiveMapsObserver * m_mapsObserver;
|
||||
int m_mapsObserverSlotId;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
self.title = L(@"downloader_downloaded_maps");
|
||||
|
||||
__weak ActiveMapsVC * weakSelf = self;
|
||||
m_mapsObserver = new ActiveMapsObserver(weakSelf);
|
||||
m_mapsObserverSlotId = self.mapsLayout.AddListener(m_mapsObserver);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
if (self.isMovingFromParentViewController)
|
||||
self.mapsLayout.RemoveListener(m_mapsObserverSlotId);
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
[self refreshTopRightButton];
|
||||
}
|
||||
|
||||
- (void)outOfDateCountriesCountChanged:(NSNotification *)notification
|
||||
{
|
||||
self.outOfDateBadge.value = [[notification userInfo][@"OutOfDate"] integerValue];
|
||||
}
|
||||
|
||||
- (void)refreshTopRightButton
|
||||
{
|
||||
UIBarButtonItem * item;
|
||||
if (self.mapsLayout.IsDownloadingActive())
|
||||
item = [[UIBarButtonItem alloc] initWithTitle:L(@"downloader_cancel_all") style:UIBarButtonItemStylePlain target:self action:@selector(cancelAllMaps:)];
|
||||
else if (self.mapsLayout.GetCountInGroup(ActiveMapsLayout::TGroup::EOutOfDate) > 0)
|
||||
item = [[UIBarButtonItem alloc] initWithTitle:L(@"downloader_update_all") style:UIBarButtonItemStylePlain target:self action:@selector(updateAllMaps:)];
|
||||
|
||||
[self.navigationItem setRightBarButtonItem:item animated:YES];
|
||||
}
|
||||
|
||||
- (void)updateAllMaps:(id)sender
|
||||
{
|
||||
self.mapsLayout.UpdateAll();
|
||||
}
|
||||
|
||||
- (void)cancelAllMaps:(id)sender
|
||||
{
|
||||
self.mapsLayout.CancelAll();
|
||||
}
|
||||
|
||||
#pragma mark - Helpers
|
||||
|
||||
- (ActiveMapsLayout &)mapsLayout
|
||||
{
|
||||
return GetFramework().GetCountryTree().GetActiveMapLayout();
|
||||
}
|
||||
|
||||
- (ActiveMapsLayout::TGroup)groupWithSection:(NSInteger)section
|
||||
{
|
||||
ASSERT(section < (NSInteger)ActiveMapsLayout::TGroup::EGroupCount, ());
|
||||
return static_cast<ActiveMapsLayout::TGroup>(section);
|
||||
}
|
||||
|
||||
- (MapCell *)cellAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group
|
||||
{
|
||||
return (MapCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:position inSection:(NSInteger)group]];
|
||||
}
|
||||
|
||||
- (void)markSelectedMapIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
self.selectedPosition = indexPath.row;
|
||||
self.selectedGroup = [self groupWithSection:indexPath.section];
|
||||
}
|
||||
|
||||
#pragma mark - DownloaderParentVC virtual methods implementation
|
||||
|
||||
- (NSString *)parentTitle
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)selectedMapName
|
||||
{
|
||||
return [NSString stringWithUTF8String:self.mapsLayout.GetCountryName(self.selectedGroup, self.selectedPosition).c_str()];
|
||||
}
|
||||
|
||||
- (NSString *)selectedMapGuideName
|
||||
{
|
||||
guides::GuideInfo info;
|
||||
if (self.mapsLayout.GetGuideInfo(self.selectedGroup, self.selectedPosition, info))
|
||||
{
|
||||
string const lang = languages::GetCurrentNorm();
|
||||
return [NSString stringWithUTF8String:info.GetAdTitle(lang).c_str()];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (size_t)selectedMapSizeWithOptions:(storage::TMapOptions)options
|
||||
{
|
||||
return self.mapsLayout.GetCountrySize(self.selectedGroup, self.selectedPosition, options).second;
|
||||
}
|
||||
|
||||
- (TStatus)selectedMapStatus
|
||||
{
|
||||
return self.mapsLayout.GetCountryStatus(self.selectedGroup, self.selectedPosition);
|
||||
}
|
||||
|
||||
- (TMapOptions)selectedMapOptions
|
||||
{
|
||||
return self.mapsLayout.GetCountryOptions(self.selectedGroup, self.selectedPosition);
|
||||
}
|
||||
|
||||
- (void)performAction:(DownloaderAction)action
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case DownloaderActionDownloadAll:
|
||||
case DownloaderActionDownloadMap:
|
||||
case DownloaderActionDownloadCarRouting:
|
||||
if ([self canDownloadSelectedMap])
|
||||
self.mapsLayout.DownloadMap(self.selectedGroup, self.selectedPosition, self.selectedInActionSheetOptions);
|
||||
break;
|
||||
|
||||
case DownloaderActionDeleteAll:
|
||||
case DownloaderActionDeleteMap:
|
||||
case DownloaderActionDeleteCarRouting:
|
||||
self.mapsLayout.DeleteMap(self.selectedGroup, self.selectedPosition, self.selectedInActionSheetOptions);
|
||||
break;
|
||||
|
||||
case DownloaderActionCancelDownloading:
|
||||
self.mapsLayout.CancelDownloading(self.selectedGroup, self.selectedPosition);
|
||||
break;
|
||||
|
||||
case DownloaderActionZoomToCountry:
|
||||
self.mapsLayout.ShowMap(self.selectedGroup, self.selectedPosition);
|
||||
[[Statistics instance] logEvent:@"Show Map From Download Countries Screen"];
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
break;
|
||||
|
||||
case DownloaderActionShowGuide:
|
||||
guides::GuideInfo info;
|
||||
if (self.mapsLayout.GetGuideInfo(self.selectedGroup, self.selectedPosition, info))
|
||||
[self openGuideWithInfo:info];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - TableView
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
ActiveMapsLayout::TGroup const group = [self groupWithSection:section];
|
||||
|
||||
if (group == ActiveMapsLayout::TGroup::ENewMap)
|
||||
return nil;
|
||||
|
||||
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 40)];
|
||||
view.clipsToBounds = YES;
|
||||
UILabel * label = [[UILabel alloc] initWithFrame:view.bounds];
|
||||
label.font = [UIFont fontWithName:@"HelveticaNeue" size:13];
|
||||
label.backgroundColor = [UIColor clearColor];
|
||||
|
||||
if (group == ActiveMapsLayout::TGroup::EOutOfDate)
|
||||
label.text = L(@"downloader_outdated_maps").uppercaseString;
|
||||
else if (group == ActiveMapsLayout::TGroup::EUpToDate)
|
||||
label.text = L(@"downloader_uptodate_maps").uppercaseString;
|
||||
|
||||
[label sizeToFit];
|
||||
[view addSubview:label];
|
||||
label.minX = 13;
|
||||
label.maxY = view.height - 5;
|
||||
if (group == ActiveMapsLayout::TGroup::EOutOfDate)
|
||||
{
|
||||
BadgeView * badge = [[BadgeView alloc] init];
|
||||
badge.value = self.mapsLayout.GetCountInGroup(ActiveMapsLayout::TGroup::EOutOfDate);
|
||||
badge.center = CGPointMake(label.maxX + badge.width - 2, label.midY);
|
||||
[view addSubview:badge];
|
||||
self.outOfDateBadge = badge;
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
ActiveMapsLayout::TGroup const group = [self groupWithSection:section];
|
||||
if (group == ActiveMapsLayout::TGroup::EOutOfDate || group == ActiveMapsLayout::TGroup::EUpToDate)
|
||||
return self.mapsLayout.GetCountInGroup(group) == 0 ? 0.001 : 42;
|
||||
else
|
||||
return 0.001;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
|
||||
{
|
||||
return 0.001;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return (NSInteger)ActiveMapsLayout::TGroup::EGroupCount;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.mapsLayout.GetCountInGroup([self groupWithSection:section]);
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MapCell * cell = [tableView dequeueReusableCellWithIdentifier:[MapCell className]];
|
||||
if (!cell)
|
||||
cell = [[MapCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[MapCell className]];
|
||||
|
||||
int const position = indexPath.row;
|
||||
ActiveMapsLayout::TGroup const group = [self groupWithSection:indexPath.section];
|
||||
TStatus const status = self.mapsLayout.GetCountryStatus(group, position);
|
||||
TMapOptions const options = self.mapsLayout.GetCountryOptions(group, position);
|
||||
|
||||
cell.titleLabel.text = [NSString stringWithUTF8String:self.mapsLayout.GetCountryName(group, position).c_str()];
|
||||
cell.parentMode = NO;
|
||||
cell.status = status;
|
||||
cell.options = options;
|
||||
cell.delegate = self;
|
||||
cell.badgeView.value = 0;
|
||||
|
||||
NSString * sizeString;
|
||||
if (status == TStatus::ENotDownloaded)
|
||||
{
|
||||
LocalAndRemoteSizeT const size = self.mapsLayout.GetRemoteCountrySizes(position);
|
||||
sizeString = [NSString stringWithFormat:@"%@ / %@", [self formattedMapSize:size.first], [self formattedMapSize:size.second]];
|
||||
}
|
||||
else if (status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate)
|
||||
{
|
||||
size_t const size = self.mapsLayout.GetCountrySize(position, options).second;
|
||||
sizeString = [self formattedMapSize:size];
|
||||
}
|
||||
else if (status == TStatus::EOutOfMemFailed || status == TStatus::EDownloadFailed || status == TStatus::EDownloading || status == TStatus::EInQueue)
|
||||
{
|
||||
LocalAndRemoteSizeT const size = self.mapsLayout.GetDownloadableCountrySize(position);
|
||||
sizeString = [self formattedMapSize:size.second];
|
||||
cell.downloadProgress = (double)size.first / size.second;
|
||||
}
|
||||
|
||||
cell.sizeLabel.text = sizeString;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
TStatus const status = self.mapsLayout.GetCountryStatus([self groupWithSection:indexPath.section], indexPath.row);
|
||||
return status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete)
|
||||
{
|
||||
int const position = indexPath.row;
|
||||
ActiveMapsLayout::TGroup const group = [self groupWithSection:position];
|
||||
TMapOptions const options = self.mapsLayout.GetCountryOptions(group, position);
|
||||
|
||||
self.mapsLayout.DeleteMap(group, position, options);
|
||||
|
||||
[tableView setEditing:NO animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[self markSelectedMapIndexPath:indexPath];
|
||||
|
||||
MapCell * cell = [self cellAtPosition:self.selectedPosition inGroup:self.selectedGroup];
|
||||
UIActionSheet * actionSheet = [self actionSheetToPerformActionOnSelectedMap];
|
||||
[actionSheet showFromRect:cell.frame inView:cell.superview animated:YES];
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [MapCell cellHeight];
|
||||
}
|
||||
|
||||
#pragma mark - MapCellDelegate
|
||||
|
||||
- (void)mapCellDidStartDownloading:(MapCell *)cell
|
||||
{
|
||||
[self markSelectedMapIndexPath:[self.tableView indexPathForCell:cell]];
|
||||
TStatus const status = [self selectedMapStatus];
|
||||
if (status == TStatus::EDownloadFailed || status == TStatus::EOutOfMemFailed)
|
||||
if ([self canDownloadSelectedMap])
|
||||
self.mapsLayout.RetryDownloading(self.selectedGroup, self.selectedPosition);
|
||||
}
|
||||
|
||||
- (void)mapCellDidCancelDownloading:(MapCell *)cell
|
||||
{
|
||||
NSIndexPath * indexPath = [self.tableView indexPathForCell:cell];
|
||||
self.selectedPosition = indexPath.row;
|
||||
self.selectedGroup = [self groupWithSection:indexPath.section];
|
||||
|
||||
[[self actionSheetToDeleteSelectedMap] showFromRect:cell.frame inView:cell.superview animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - ActiveMaps core callbacks
|
||||
|
||||
- (void)countryStatusChangedAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group
|
||||
{
|
||||
[self refreshTopRightButton];
|
||||
|
||||
MapCell * cell = [self cellAtPosition:position inGroup:group];
|
||||
[cell setStatus:self.mapsLayout.GetCountryStatus(group, position) options:self.mapsLayout.GetCountryOptions(group, position) animated:YES];
|
||||
|
||||
self.outOfDateBadge.value = self.mapsLayout.GetCountInGroup(ActiveMapsLayout::TGroup::EOutOfDate);
|
||||
}
|
||||
|
||||
- (void)countryOptionsChangedAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group
|
||||
{
|
||||
MapCell * cell = [self cellAtPosition:position inGroup:group];
|
||||
[cell setStatus:self.mapsLayout.GetCountryStatus(group, position) options:self.mapsLayout.GetCountryOptions(group, position) animated:YES];
|
||||
}
|
||||
|
||||
- (void)countryGroupChangedFromPosition:(int)oldPosition inGroup:(ActiveMapsLayout::TGroup const &)oldGroup toPosition:(int)newPosition inGroup:(ActiveMapsLayout::TGroup const &)newGroup
|
||||
{
|
||||
if (oldGroup == newGroup && oldPosition == -1)
|
||||
{
|
||||
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:newPosition inSection:(NSInteger)newGroup];
|
||||
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
else if (oldGroup == newGroup && newPosition == -1)
|
||||
{
|
||||
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:oldPosition inSection:(NSInteger)oldGroup];
|
||||
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
else if (oldGroup != newGroup && oldPosition >= 0 && newPosition >= 0)
|
||||
{
|
||||
NSIndexPath * oldIndexPath = [NSIndexPath indexPathForRow:oldPosition inSection:(NSInteger)oldGroup];
|
||||
NSIndexPath * newIndexPath = [NSIndexPath indexPathForRow:newPosition inSection:(NSInteger)newGroup];
|
||||
[self.tableView moveRowAtIndexPath:oldIndexPath toIndexPath:newIndexPath];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)countryDownloadingProgressChanged:(LocalAndRemoteSizeT const &)progress atPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group
|
||||
{
|
||||
MapCell * cell = [self cellAtPosition:position inGroup:group];
|
||||
[cell setDownloadProgress:((double)progress.first / progress.second) animated:YES];
|
||||
}
|
||||
|
||||
@end
|
8
iphone/Maps/Classes/BadgeView.h
Normal file
8
iphone/Maps/Classes/BadgeView.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BadgeView : UIImageView
|
||||
|
||||
@property (nonatomic) NSInteger value;
|
||||
|
||||
@end
|
33
iphone/Maps/Classes/BadgeView.m
Normal file
33
iphone/Maps/Classes/BadgeView.m
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
#import "BadgeView.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
@implementation BadgeView
|
||||
|
||||
- (void)setValue:(NSInteger)value
|
||||
{
|
||||
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
self.hidden = value == 0;
|
||||
|
||||
UIFont * font = [UIFont fontWithName:@"HelveticaNeue-Light" size:12];
|
||||
UIImage * image = [UIImage imageNamed:@"Badge"];
|
||||
CGFloat const textWidth = [@(value).stringValue sizeWithDrawSize:CGSizeMake(100, 20) font:font].width;
|
||||
CGFloat const offset = 4;
|
||||
CGFloat const imageDiameter = 17;
|
||||
|
||||
self.size = CGSizeMake(MAX(textWidth + 2 * offset, imageDiameter), imageDiameter);
|
||||
self.image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(imageDiameter / 2, imageDiameter / 2, imageDiameter / 2, imageDiameter / 2)];
|
||||
|
||||
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(offset, 0, textWidth, self.height)];
|
||||
label.backgroundColor = [UIColor clearColor];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.textColor = [UIColor whiteColor];
|
||||
label.font = font;
|
||||
label.text = @(value).stringValue;
|
||||
label.center = CGPointMake(self.width / 2, self.height / 2);
|
||||
[self addSubview:label];
|
||||
|
||||
_value = value;
|
||||
}
|
||||
|
||||
@end
|
|
@ -6,6 +6,8 @@
|
|||
#include "../../../platform/settings.hpp"
|
||||
#import "AppInfo.h"
|
||||
#import "ImageDownloader.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "Framework.h"
|
||||
|
||||
@interface BottomMenu () <UITableViewDataSource, UITableViewDelegate, ImageDownloaderDelegate>
|
||||
|
||||
|
@ -23,8 +25,8 @@
|
|||
self = [super initWithFrame:frame];
|
||||
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
[self addSubview:self.fadeView];
|
||||
|
||||
[self addSubview:self.fadeView];
|
||||
[self addSubview:self.tableView];
|
||||
|
||||
_menuHidden = YES;
|
||||
|
@ -32,10 +34,20 @@
|
|||
self.imageDownloaders = [[NSMutableDictionary alloc] init];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appInfoSynced:) name:AppInfoSyncedNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outOfDateCountriesCountChanged:) name:MapsStatusChangedNotification object:nil];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)outOfDateCountriesCountChanged:(NSNotification *)notification
|
||||
{
|
||||
NSInteger const row = [self.items indexOfObjectPassingTest:^(id obj, NSUInteger i, BOOL *stop){
|
||||
return [obj[@"Id"] isEqualToString:@"Maps"];
|
||||
}];
|
||||
BottomMenuCell * cell = (BottomMenuCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]];
|
||||
cell.badgeView.value = [[notification userInfo][@"OutOfDate"] integerValue];
|
||||
}
|
||||
|
||||
- (NSArray *)generateItems
|
||||
{
|
||||
NSMutableArray * items = [[NSMutableArray alloc] init];
|
||||
|
@ -154,6 +166,11 @@
|
|||
cell.titleLabel.text = title;
|
||||
}
|
||||
|
||||
if ([item[@"Id"] isEqualToString:@"Maps"])
|
||||
cell.badgeView.value = GetFramework().GetCountryTree().GetActiveMapLayout().GetCountInGroup(storage::ActiveMapsLayout::TGroup::EOutOfDate);
|
||||
else
|
||||
cell.badgeView.value = 0;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "BadgeView.h"
|
||||
|
||||
@interface BottomMenuCell : UITableViewCell
|
||||
|
||||
@property (nonatomic) UIImageView * iconImageView;
|
||||
@property (nonatomic) UILabel * titleLabel;
|
||||
@property (nonatomic, readonly) UIImageView * iconImageView;
|
||||
@property (nonatomic, readonly) UILabel * titleLabel;
|
||||
@property (nonatomic, readonly) BadgeView * badgeView;
|
||||
|
||||
+ (CGFloat)cellHeight;
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
@interface BottomMenuCell ()
|
||||
|
||||
@property (nonatomic) UIImageView * separator;
|
||||
@property (nonatomic) UIImageView * iconImageView;
|
||||
@property (nonatomic) UILabel * titleLabel;
|
||||
@property (nonatomic) BadgeView * badgeView;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -23,6 +26,7 @@
|
|||
[self.contentView addSubview:self.titleLabel];
|
||||
[self.contentView addSubview:self.iconImageView];
|
||||
[self.contentView addSubview:self.separator];
|
||||
[self.contentView addSubview:self.badgeView];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -41,7 +45,14 @@
|
|||
self.separator.width = self.width - 2 * shift;
|
||||
self.separator.maxY = self.height;
|
||||
|
||||
self.titleLabel.frame = CGRectMake(53, -2, self.width - 70, self.height);
|
||||
self.titleLabel.size = CGSizeMake(self.width - 70, self.height);
|
||||
[self.titleLabel sizeToFit];
|
||||
self.titleLabel.minX = 53;
|
||||
self.titleLabel.midY = self.height / 2 - 2;
|
||||
|
||||
self.badgeView.minX = self.titleLabel.maxX + 4;
|
||||
self.badgeView.minY = self.titleLabel.minY - 5;
|
||||
|
||||
self.iconImageView.origin = CGPointMake(11, 4.5);
|
||||
}
|
||||
|
||||
|
@ -50,7 +61,7 @@
|
|||
if (!_separator)
|
||||
{
|
||||
UIImage * separatorImage = [[UIImage imageNamed:@"SearchCellSeparator"] resizableImageWithCapInsets:UIEdgeInsetsZero];
|
||||
_separator = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, separatorImage.size.height)];
|
||||
_separator = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, 1)];
|
||||
_separator.image = separatorImage;
|
||||
}
|
||||
return _separator;
|
||||
|
@ -77,4 +88,11 @@
|
|||
return _titleLabel;
|
||||
}
|
||||
|
||||
- (BadgeView *)badgeView
|
||||
{
|
||||
if (!_badgeView)
|
||||
_badgeView = [[BadgeView alloc] init];
|
||||
return _badgeView;
|
||||
}
|
||||
|
||||
@end
|
39
iphone/Maps/Classes/MapCell.h
Normal file
39
iphone/Maps/Classes/MapCell.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ProgressView.h"
|
||||
#import "BadgeView.h"
|
||||
|
||||
#include "../../storage/storage_defines.hpp"
|
||||
|
||||
using namespace storage;
|
||||
|
||||
@class MapCell;
|
||||
@protocol MapCellDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
- (void)mapCellDidStartDownloading:(MapCell *)cell;
|
||||
- (void)mapCellDidCancelDownloading:(MapCell *)cell;
|
||||
|
||||
@end
|
||||
|
||||
@interface MapCell : UITableViewCell
|
||||
|
||||
@property (nonatomic, readonly) UILabel * titleLabel;
|
||||
@property (nonatomic, readonly) UILabel * subtitleLabel;
|
||||
@property (nonatomic, readonly) UILabel * sizeLabel;
|
||||
@property (nonatomic, readonly) BadgeView * badgeView;
|
||||
|
||||
@property (nonatomic) BOOL parentMode;
|
||||
|
||||
@property (nonatomic) TStatus status;
|
||||
@property (nonatomic) TMapOptions options;
|
||||
@property (nonatomic) double downloadProgress;
|
||||
|
||||
@property (nonatomic, weak) id <MapCellDelegate> delegate;
|
||||
|
||||
- (void)setStatus:(TStatus)status options:(TMapOptions)options animated:(BOOL)animated;
|
||||
- (void)setDownloadProgress:(double)downloadProgress animated:(BOOL)animated;
|
||||
|
||||
+ (CGFloat)cellHeight;
|
||||
|
||||
@end
|
336
iphone/Maps/Classes/MapCell.mm
Normal file
336
iphone/Maps/Classes/MapCell.mm
Normal file
|
@ -0,0 +1,336 @@
|
|||
|
||||
#import "MapCell.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
@interface MapCell () <ProgressViewDelegate>
|
||||
|
||||
@property (nonatomic) UILabel * titleLabel;
|
||||
@property (nonatomic) UILabel * subtitleLabel;
|
||||
@property (nonatomic) UILabel * statusLabel;
|
||||
@property (nonatomic) UILabel * sizeLabel;
|
||||
@property (nonatomic) ProgressView * progressView;
|
||||
@property (nonatomic) UIView * rightTapZone;
|
||||
@property (nonatomic) UIImageView * arrowView;
|
||||
@property (nonatomic) BadgeView * badgeView;
|
||||
@property (nonatomic) UIImageView * routingImageView;
|
||||
@property (nonatomic) UIImageView * separator;
|
||||
|
||||
@property (nonatomic, readonly) BOOL progressMode;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MapCell
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
|
||||
NSArray * subviews = @[self.titleLabel, self.subtitleLabel, self.statusLabel, self.sizeLabel, self.progressView, self.arrowView, self.badgeView, self.routingImageView, self.separator];
|
||||
for (UIView * subview in subviews)
|
||||
[self.contentView addSubview:subview];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setStatus:(TStatus)status options:(TMapOptions)options animated:(BOOL)animated
|
||||
{
|
||||
self.status = status;
|
||||
self.options = options;
|
||||
|
||||
self.rightTapZone.userInteractionEnabled = NO;
|
||||
self.progressView.failedMode = NO;
|
||||
|
||||
if (options == TMapOptions::EMapOnly)
|
||||
self.routingImageView.image = [UIImage imageNamed:@"DownloadRoutingButton"];
|
||||
else
|
||||
self.routingImageView.image = [UIImage imageNamed:@"RoutingDownloadedButton"];
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case TStatus::ENotDownloaded:
|
||||
case TStatus::EOnDiskOutOfDate:
|
||||
if (status == TStatus::ENotDownloaded)
|
||||
self.statusLabel.text = L(@"download").uppercaseString;
|
||||
else
|
||||
self.statusLabel.text = L(@"downloader_status_outdated").uppercaseString;
|
||||
|
||||
self.statusLabel.textColor = [UIColor colorWithColorCode:@"179E4D"];
|
||||
self.rightTapZone.userInteractionEnabled = YES;
|
||||
[self setProgressMode:NO withAnimatedLayout:animated];
|
||||
break;
|
||||
|
||||
case TStatus::EInQueue:
|
||||
self.statusLabel.text = L(@"downloader_queued").uppercaseString;
|
||||
self.statusLabel.textColor = [UIColor colorWithColorCode:@"999999"];
|
||||
[self.progressView setProgress:0 animated:animated];
|
||||
[self setProgressMode:YES withAnimatedLayout:animated];
|
||||
break;
|
||||
|
||||
case TStatus::EDownloading:
|
||||
self.statusLabel.textColor = [UIColor colorWithColorCode:@"999999"];
|
||||
[self.progressView setProgress:self.downloadProgress animated:animated];
|
||||
[self setProgressMode:YES withAnimatedLayout:animated];
|
||||
break;
|
||||
|
||||
case TStatus::EOnDisk:
|
||||
{
|
||||
self.statusLabel.text = L(@"downloader_downloaded").uppercaseString;
|
||||
self.statusLabel.textColor = [UIColor colorWithColorCode:@"999999"];
|
||||
if (animated)
|
||||
{
|
||||
[self alignSubviews];
|
||||
[self performAfterDelay:0.3 block:^{
|
||||
[self setProgressMode:NO withAnimatedLayout:YES];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setProgressMode:NO withAnimatedLayout:NO];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TStatus::EOutOfMemFailed:
|
||||
case TStatus::EDownloadFailed:
|
||||
self.progressView.failedMode = YES;
|
||||
self.statusLabel.text = L(@"downloader_retry").uppercaseString;
|
||||
self.statusLabel.textColor = [UIColor colorWithColorCode:@"FF4436"];
|
||||
self.rightTapZone.userInteractionEnabled = YES;
|
||||
[self setProgressMode:YES withAnimatedLayout:animated];
|
||||
break;
|
||||
|
||||
case TStatus::EUnknown:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDownloadProgress:(double)downloadProgress animated:(BOOL)animated
|
||||
{
|
||||
self.downloadProgress = downloadProgress;
|
||||
self.statusLabel.text = [NSString stringWithFormat:@"%i%%", NSInteger(downloadProgress * 100)];
|
||||
[self.progressView setProgress:downloadProgress animated:animated];
|
||||
if (!self.progressMode)
|
||||
[self setProgressMode:YES withAnimatedLayout:animated];
|
||||
}
|
||||
|
||||
- (void)setProgressMode:(BOOL)progressMode withAnimatedLayout:(BOOL)withLayout
|
||||
{
|
||||
_progressMode = progressMode;
|
||||
if (withLayout)
|
||||
{
|
||||
if (progressMode)
|
||||
self.progressView.hidden = NO;
|
||||
[UIView animateWithDuration:0.5 delay:0 damping:0.9 initialVelocity:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
||||
[self alignProgressView];
|
||||
[self alignSubviews];
|
||||
} completion:^(BOOL finished) {
|
||||
if (!progressMode)
|
||||
self.progressView.hidden = YES;
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self alignSubviews];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)alignProgressView
|
||||
{
|
||||
self.progressView.minX = self.progressMode ? self.width - [self rightOffset] + 2 : self.width;
|
||||
}
|
||||
|
||||
- (void)alignSubviews
|
||||
{
|
||||
self.progressView.hidden = self.parentMode || !self.progressMode;
|
||||
self.progressView.midY = self.height / 2;
|
||||
|
||||
self.arrowView.center = CGPointMake(self.width - [self minimumRightOffset] - 4, self.height / 2);
|
||||
self.arrowView.hidden = !self.parentMode;
|
||||
|
||||
[self.statusLabel sizeToFit];
|
||||
self.statusLabel.width = MAX(self.statusLabel.width, 60);
|
||||
[self.sizeLabel sizeToFit];
|
||||
self.statusLabel.frame = CGRectMake(self.width - [self rightOffset] - self.statusLabel.width, 14, self.statusLabel.width, 16);
|
||||
self.statusLabel.hidden = self.parentMode;
|
||||
|
||||
CGFloat const sizeLabelMinY = self.statusLabel.maxY;
|
||||
self.sizeLabel.frame = CGRectMake(self.width - [self rightOffset] - self.sizeLabel.width, sizeLabelMinY, self.sizeLabel.width, 16);
|
||||
self.sizeLabel.textColor = [UIColor colorWithColorCode:@"999999"];
|
||||
self.sizeLabel.hidden = self.parentMode;
|
||||
|
||||
CGFloat const rightLabelsMaxWidth = self.parentMode ? 10 : MAX(self.statusLabel.width, self.sizeLabel.width);
|
||||
CGFloat const leftLabelsWith = self.width - [self leftOffset] - [self betweenSpace] - rightLabelsMaxWidth - [self rightOffset];
|
||||
|
||||
self.titleLabel.frame = CGRectMake([self leftOffset], self.subtitleLabel.text == nil ? 19 : 10, leftLabelsWith, 20);
|
||||
self.subtitleLabel.frame = CGRectMake([self leftOffset], self.titleLabel.maxY + 1, leftLabelsWith, 18);
|
||||
self.subtitleLabel.hidden = self.subtitleLabel.text == nil;
|
||||
|
||||
CGFloat const rightTapWidth = rightLabelsMaxWidth + [self rightOffset] + [self betweenSpace];
|
||||
self.rightTapZone.frame = CGRectMake(self.width - rightTapWidth, 0, rightTapWidth - [self rightOffset] + 4, self.height);
|
||||
if (self.parentMode)
|
||||
self.rightTapZone.userInteractionEnabled = NO;
|
||||
|
||||
self.routingImageView.center = CGPointMake(self.width - 25, self.height / 2 - 1);
|
||||
self.routingImageView.alpha = [self shouldShowRoutingView];
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowRoutingView
|
||||
{
|
||||
return !self.progressMode && !self.parentMode && self.status != TStatus::ENotDownloaded;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[self alignProgressView];
|
||||
[self setStatus:self.status options:self.options animated:NO];
|
||||
|
||||
self.badgeView.minX = self.titleLabel.maxX + 4;
|
||||
self.badgeView.minY = self.titleLabel.minY - 5;
|
||||
|
||||
self.separator.minX = self.titleLabel.minX;
|
||||
self.separator.size = CGSizeMake(self.width - 2 * self.separator.minX, 1);
|
||||
self.separator.maxY = self.height + 0.5;
|
||||
}
|
||||
|
||||
- (CGFloat)leftOffset
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
- (CGFloat)betweenSpace
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
- (CGFloat)rightOffset
|
||||
{
|
||||
return self.progressMode || [self shouldShowRoutingView] ? 50 : [self minimumRightOffset];
|
||||
}
|
||||
|
||||
- (CGFloat)minimumRightOffset
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
+ (CGFloat)cellHeight
|
||||
{
|
||||
return 59;
|
||||
}
|
||||
|
||||
- (void)rightTap:(id)sender
|
||||
{
|
||||
[self.delegate mapCellDidStartDownloading:self];
|
||||
}
|
||||
|
||||
- (void)progressViewDidStart:(ProgressView *)progress
|
||||
{
|
||||
[self.delegate mapCellDidStartDownloading:self];
|
||||
}
|
||||
|
||||
- (void)progressViewDidCancel:(ProgressView *)progress
|
||||
{
|
||||
[self.delegate mapCellDidCancelDownloading:self];
|
||||
}
|
||||
|
||||
- (UIImageView *)arrowView
|
||||
{
|
||||
if (!_arrowView)
|
||||
_arrowView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AccessoryView"]];
|
||||
return _arrowView;
|
||||
}
|
||||
|
||||
- (ProgressView *)progressView
|
||||
{
|
||||
if (!_progressView)
|
||||
{
|
||||
_progressView = [[ProgressView alloc] init];
|
||||
_progressView.delegate = self;
|
||||
}
|
||||
return _progressView;
|
||||
}
|
||||
|
||||
- (UILabel *)titleLabel
|
||||
{
|
||||
if (!_titleLabel)
|
||||
{
|
||||
_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_titleLabel.backgroundColor = [UIColor clearColor];
|
||||
_titleLabel.textColor = [UIColor blackColor];
|
||||
_titleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:17];
|
||||
}
|
||||
return _titleLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)subtitleLabel
|
||||
{
|
||||
if (!_subtitleLabel)
|
||||
{
|
||||
_subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_subtitleLabel.backgroundColor = [UIColor clearColor];
|
||||
_subtitleLabel.textColor = [UIColor colorWithColorCode:@"999999"];
|
||||
_subtitleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:13];
|
||||
}
|
||||
return _subtitleLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)statusLabel
|
||||
{
|
||||
if (!_statusLabel)
|
||||
{
|
||||
_statusLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_statusLabel.backgroundColor = [UIColor clearColor];
|
||||
_statusLabel.textAlignment = NSTextAlignmentRight;
|
||||
_statusLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:13];
|
||||
}
|
||||
return _statusLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)sizeLabel
|
||||
{
|
||||
if (!_sizeLabel)
|
||||
{
|
||||
_sizeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_sizeLabel.backgroundColor = [UIColor clearColor];
|
||||
_sizeLabel.textAlignment = NSTextAlignmentRight;
|
||||
_sizeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:13];
|
||||
}
|
||||
return _sizeLabel;
|
||||
}
|
||||
|
||||
- (UIView *)rightTapZone
|
||||
{
|
||||
if (!_rightTapZone)
|
||||
{
|
||||
_rightTapZone = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(rightTap:)];
|
||||
[_rightTapZone addGestureRecognizer:tap];
|
||||
}
|
||||
return _rightTapZone;
|
||||
}
|
||||
|
||||
- (UIImageView *)routingImageView
|
||||
{
|
||||
if (!_routingImageView)
|
||||
_routingImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"DownloadRoutingButton"]];
|
||||
return _routingImageView;
|
||||
}
|
||||
|
||||
- (BadgeView *)badgeView
|
||||
{
|
||||
if (!_badgeView)
|
||||
_badgeView = [[BadgeView alloc] init];
|
||||
return _badgeView;
|
||||
}
|
||||
|
||||
- (UIImageView *)separator
|
||||
{
|
||||
if (!_separator)
|
||||
{
|
||||
UIImage * separatorImage = [[UIImage imageNamed:@"MapCellSeparator"] resizableImageWithCapInsets:UIEdgeInsetsZero];
|
||||
_separator = [[UIImageView alloc] initWithFrame:CGRectZero];
|
||||
_separator.image = separatorImage;
|
||||
}
|
||||
return _separator;
|
||||
}
|
||||
|
||||
@end
|
|
@ -35,7 +35,8 @@
|
|||
#define ALERT_VIEW_FACEBOOK 1
|
||||
#define ALERT_VIEW_APPSTORE 2
|
||||
#define ALERT_VIEW_BOOKMARKS 4
|
||||
#define ALERT_VIEW_ERROR 5
|
||||
#define ALERT_VIEW_DOWNLOADER 5
|
||||
#define ALERT_VIEW_PRO_VERSION_ROUTING 6
|
||||
#define FACEBOOK_URL @"http://www.facebook.com/MapsWithMe"
|
||||
#define FACEBOOK_SCHEME @"fb://profile/111923085594432"
|
||||
|
||||
|
@ -513,10 +514,6 @@
|
|||
[self.view addSubview:self.containerView];
|
||||
|
||||
[self.view addSubview:self.bottomMenu];
|
||||
|
||||
// [self performAfterDelay:0.3 block:^{
|
||||
// [self bottomMenu:self.bottomMenu didPressItemWithName:@"Maps" appURL:nil webURL:nil];
|
||||
// }];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
|
@ -606,19 +603,23 @@
|
|||
|
||||
f.SetRouteBuildingListener([self, &f](bool isSuccess, string const & message, bool openDownloader)
|
||||
{
|
||||
[self.containerView.placePage showBuildingRoutingActivity:NO];
|
||||
if (isSuccess)
|
||||
{
|
||||
f.GetBalloonManager().RemovePin();
|
||||
f.GetBalloonManager().Dismiss();
|
||||
[self.containerView.placePage setState:PlacePageStateHidden animated:YES withCallback:YES];
|
||||
[self.searchView setState:SearchViewStateHidden animated:YES withCallback:YES];
|
||||
[self performAfterDelay:0.3 block:^{
|
||||
[self.routeView setVisible:YES animated:YES];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
/// if openDownloader == true than we need show dialog with 2 button. On positive button - open downloader
|
||||
[self showDialogWithMessageID:message];
|
||||
if (openDownloader)
|
||||
[self showDownloaderDialogWithMessageID:message];
|
||||
else
|
||||
[self showDialogWithMessageID:message];
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -633,16 +634,24 @@
|
|||
}
|
||||
|
||||
#pragma mark - ShowDialog callback
|
||||
|
||||
- (void)showDialogWithMessageID:(string const &)message
|
||||
{
|
||||
///@TODO for goga.
|
||||
[[[UIAlertView alloc] initWithTitle:[NSString stringWithUTF8String:message.c_str()] message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil] show];
|
||||
}
|
||||
|
||||
- (void)showDownloaderDialogWithMessageID:(string const &)message
|
||||
{
|
||||
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithUTF8String:message.c_str()] message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", nil) otherButtonTitles:NSLocalizedString(@"ok", nil), nil];
|
||||
alertView.tag = ALERT_VIEW_DOWNLOADER;
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
- (void)showBuyProDialog
|
||||
{
|
||||
///@TODO for goga. Show buy pro dialog with text [routing_failed_buy_pro]
|
||||
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"routing_failed_buy_pro", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil] show];
|
||||
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"routing_failed_buy_pro", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", nil) otherButtonTitles:NSLocalizedString(@"get_it_now", nil), nil];
|
||||
alert.tag = ALERT_VIEW_PRO_VERSION_ROUTING;
|
||||
[alert show];
|
||||
}
|
||||
|
||||
#pragma mark - Getters
|
||||
|
@ -753,6 +762,8 @@
|
|||
return _apiTitleLabel;
|
||||
}
|
||||
|
||||
#pragma mark - Api methods
|
||||
|
||||
- (void)clearApiMode:(id)sender
|
||||
{
|
||||
[self setApiMode:NO animated:YES];
|
||||
|
@ -765,17 +776,14 @@
|
|||
[[UIApplication sharedApplication] openURL:url];
|
||||
}
|
||||
|
||||
#pragma mark - ToolbarView delegate
|
||||
|
||||
- (void)toolbar:(ToolbarView *)toolbar didPressItemWithName:(NSString *)itemName
|
||||
{
|
||||
if ([itemName isEqualToString:@"Location"])
|
||||
{
|
||||
// [self onMyPositionClicked:nil];
|
||||
[self.routeView setVisible:!self.routeView.visible animated:YES];
|
||||
}
|
||||
[self onMyPositionClicked:nil];
|
||||
else if ([itemName isEqualToString:@"Search"])
|
||||
{
|
||||
[self.searchView setState:SearchViewStateFullscreen animated:YES withCallback:YES];
|
||||
}
|
||||
else if ([itemName isEqualToString:@"Bookmarks"])
|
||||
{
|
||||
if (GetPlatform().IsPro())
|
||||
|
@ -791,14 +799,15 @@
|
|||
}
|
||||
}
|
||||
else if ([itemName isEqualToString:@"Menu"])
|
||||
{
|
||||
[self.bottomMenu setMenuHidden:NO animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)routeViewDidStartRouting:(RouteView *)routeView
|
||||
{
|
||||
#pragma mark - Routing
|
||||
|
||||
- (void)routeViewDidStartFollowing:(RouteView *)routeView
|
||||
{
|
||||
[routeView hideFollowButton];
|
||||
GetFramework().FollowRoute();
|
||||
}
|
||||
|
||||
- (void)routeViewDidCancelRouting:(RouteView *)routeView
|
||||
|
@ -811,6 +820,7 @@
|
|||
|
||||
- (void)placePageViewDidStartRouting:(PlacePageView *)placePage
|
||||
{
|
||||
[placePage showBuildingRoutingActivity:YES];
|
||||
GetFramework().BuildRoute([placePage pinPoint]);
|
||||
}
|
||||
|
||||
|
@ -988,11 +998,24 @@
|
|||
[[UIApplication sharedApplication] openProVersionFrom:@"ios_toolabar_bookmarks"];
|
||||
}
|
||||
}
|
||||
case ALERT_VIEW_ERROR:
|
||||
case ALERT_VIEW_DOWNLOADER:
|
||||
{
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
|
||||
CountryTreeVC * vc = [[CountryTreeVC alloc] initWithNodePosition:-1];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
}
|
||||
case ALERT_VIEW_PRO_VERSION_ROUTING:
|
||||
{
|
||||
if (buttonIndex == alertView.cancelButtonIndex)
|
||||
{
|
||||
[[Statistics instance] logProposalReason:@"Routing Menu" withAnswer:@"NO"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[UIApplication sharedApplication] openProVersionFrom:@"ios_routing_alert"];
|
||||
[[Statistics instance] logProposalReason:@"Routing Menu" withAnswer:@"YES"];
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
@ -1017,7 +1040,8 @@
|
|||
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.toolbarView.maxY = self.view.height;
|
||||
self.routeView.alpha = 1;
|
||||
if (GetFramework().IsRoutingActive())
|
||||
self.routeView.minY = 0;
|
||||
}];
|
||||
break;
|
||||
}
|
||||
|
@ -1045,11 +1069,11 @@
|
|||
framework.SetViewportCenterAnimated(framework.GetViewportCenter() + offset);
|
||||
}
|
||||
}
|
||||
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||
self.toolbarView.maxY = self.view.height;
|
||||
self.routeView.alpha = 0;
|
||||
}];
|
||||
if (GetFramework().IsRoutingActive())
|
||||
self.routeView.minY = self.containerView.placePage.maxY - 20;
|
||||
} completion:^(BOOL finished) {}];
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1071,6 +1095,20 @@
|
|||
GetFramework().ActivateUserMark(NULL);
|
||||
[self.containerView.placePage setState:PlacePageStateHidden animated:YES withCallback:NO];
|
||||
}
|
||||
else if (self.searchView.state == SearchViewStateResults)
|
||||
{
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
if (GetFramework().IsRoutingActive())
|
||||
self.routeView.minY = self.searchView.searchBar.maxY - 14;
|
||||
}];
|
||||
}
|
||||
else if (self.searchView.state == SearchViewStateHidden)
|
||||
{
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
if (GetFramework().IsRoutingActive())
|
||||
self.routeView.minY = 0;
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "NavigationController.h"
|
||||
#import "MapsObservers.h"
|
||||
|
||||
@class MapViewController;
|
||||
@class SettingsManager;
|
||||
@class LocationManager;
|
||||
|
||||
@interface MapsAppDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate>
|
||||
extern NSString * const MapsStatusChangedNotification;
|
||||
|
||||
@interface MapsAppDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate, ActiveMapsObserverProtocol>
|
||||
{
|
||||
SettingsManager * m_settingsManager;
|
||||
NSInteger m_standbyCounter;
|
||||
NSInteger m_activeDownloadsCounter;
|
||||
UIBackgroundTaskIdentifier m_backgroundTask;
|
||||
|
@ -21,8 +23,6 @@
|
|||
|
||||
+ (MapsAppDelegate *)theApp;
|
||||
|
||||
- (SettingsManager *)settingsManager;
|
||||
|
||||
- (void)disableStandby;
|
||||
- (void)enableStandby;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#import "MapsAppDelegate.h"
|
||||
#import "MapViewController.h"
|
||||
#import "SettingsManager.h"
|
||||
#import "Preferences.h"
|
||||
#import "LocationManager.h"
|
||||
#import "Statistics.h"
|
||||
|
@ -15,14 +14,13 @@
|
|||
|
||||
#import <FacebookSDK/FacebookSDK.h>
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "../../../storage/storage_defines.hpp"
|
||||
|
||||
#include "../../../platform/settings.hpp"
|
||||
#include "../../../platform/platform.hpp"
|
||||
#include "../../../platform/preferred_languages.hpp"
|
||||
|
||||
NSString * const MapsStatusChangedNotification = @"MapsStatusChangedNotification";
|
||||
|
||||
#define NOTIFICATION_ALERT_VIEW_TAG 665
|
||||
|
||||
|
@ -67,6 +65,7 @@ void InitLocalizedStrings()
|
|||
|
||||
NSString * m_scheme;
|
||||
NSString * m_sourceApplication;
|
||||
ActiveMapsObserver * m_mapsObserver;
|
||||
}
|
||||
|
||||
+ (MapsAppDelegate *)theApp
|
||||
|
@ -229,7 +228,7 @@ void InitLocalizedStrings()
|
|||
UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
|
||||
if ([pasteboard.string length])
|
||||
{
|
||||
if (GetFramework().ShowMapForURL([pasteboard.string UTF8String]))
|
||||
if (f.ShowMapForURL([pasteboard.string UTF8String]))
|
||||
{
|
||||
[self showMap];
|
||||
pasteboard.string = @"";
|
||||
|
@ -255,17 +254,13 @@ void InitLocalizedStrings()
|
|||
#ifdef OMIM_FULL
|
||||
[[AccountManager sharedManager] applicationDidBecomeActive:application];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (SettingsManager *)settingsManager
|
||||
{
|
||||
if (!m_settingsManager)
|
||||
m_settingsManager = [[SettingsManager alloc] init];
|
||||
return m_settingsManager;
|
||||
f.GetLocationState()->InvalidatePosition();
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
// Global cleanup
|
||||
DeleteFramework();
|
||||
}
|
||||
|
@ -424,36 +419,38 @@ void InitLocalizedStrings()
|
|||
|
||||
- (void)subscribeToStorage
|
||||
{
|
||||
typedef void (*TChangeFunc)(id, SEL, storage::TIndex const &);
|
||||
SEL changeSel = @selector(OnCountryChange:);
|
||||
TChangeFunc changeImpl = (TChangeFunc)[self methodForSelector:changeSel];
|
||||
__weak MapsAppDelegate * weakSelf = self;
|
||||
m_mapsObserver = new ActiveMapsObserver(weakSelf);
|
||||
GetFramework().GetCountryTree().GetActiveMapLayout().AddListener(m_mapsObserver);
|
||||
|
||||
typedef void (*TProgressFunc)(id, SEL, storage::TIndex const &, pair<int64_t, int64_t> const &);
|
||||
SEL emptySel = @selector(EmptyFunction:withProgress:);
|
||||
TProgressFunc progressImpl = (TProgressFunc)[self methodForSelector:emptySel];
|
||||
|
||||
GetFramework().Storage().Subscribe(bind(changeImpl, self, changeSel, _1),
|
||||
bind(progressImpl, self, emptySel, _1, _2));
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outOfDateCountriesCountChanged:) name:MapsStatusChangedNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)OnCountryChange:(storage::TIndex const &)index
|
||||
- (void)countryStatusChangedAtPosition:(int)position inGroup:(storage::ActiveMapsLayout::TGroup const &)group
|
||||
{
|
||||
Framework const & f = GetFramework();
|
||||
guides::GuideInfo guide;
|
||||
if (f.GetCountryStatus(index) == storage::TStatus::EOnDisk && f.GetGuideInfo(index, guide))
|
||||
[self ShowNotificationWithGuideInfo:guide];
|
||||
ActiveMapsLayout & l = GetFramework().GetCountryTree().GetActiveMapLayout();
|
||||
TStatus const & status = l.GetCountryStatus(group, position);
|
||||
guides::GuideInfo info;
|
||||
if (status == storage::TStatus::EOnDisk && l.GetGuideInfo(group, position, info))
|
||||
[self showNotificationWithGuideInfo:info];
|
||||
|
||||
int const outOfDateCount = l.GetCountInGroup(storage::ActiveMapsLayout::TGroup::EOutOfDate);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MapsStatusChangedNotification object:nil userInfo:@{@"OutOfDate" : @(outOfDateCount)}];
|
||||
}
|
||||
|
||||
- (void)EmptyFunction:(storage::TIndex const &)index withProgress:(pair<int64_t, int64_t> const &)progress {}
|
||||
- (void)outOfDateCountriesCountChanged:(NSNotification *)notification
|
||||
{
|
||||
[UIApplication sharedApplication].applicationIconBadgeNumber = [[notification userInfo][@"OutOfDate"] integerValue];
|
||||
}
|
||||
|
||||
- (BOOL)ShowNotificationWithGuideInfo:(guides::GuideInfo const &)guide
|
||||
- (void)showNotificationWithGuideInfo:(guides::GuideInfo const &)guide
|
||||
{
|
||||
guides::GuidesManager & guidesManager = GetFramework().GetGuidesManager();
|
||||
string const appID = guide.GetAppID();
|
||||
|
||||
if (guidesManager.WasAdvertised(appID) ||
|
||||
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[NSString stringWithUTF8String:appID.c_str()]]])
|
||||
return NO;
|
||||
return;
|
||||
|
||||
UILocalNotification * notification = [[UILocalNotification alloc] init];
|
||||
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
|
||||
|
@ -474,8 +471,6 @@ void InitLocalizedStrings()
|
|||
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
|
||||
|
||||
guidesManager.SetWasAdvertised(appID);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
54
iphone/Maps/Classes/MapsObservers.h
Normal file
54
iphone/Maps/Classes/MapsObservers.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
#include "Framework.h"
|
||||
#include "../../storage/storage_defines.hpp"
|
||||
|
||||
using namespace storage;
|
||||
|
||||
@protocol ActiveMapsObserverProtocol <NSObject>
|
||||
|
||||
- (void)countryStatusChangedAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group;
|
||||
|
||||
@optional
|
||||
- (void)countryGroupChangedFromPosition:(int)oldPosition inGroup:(ActiveMapsLayout::TGroup const &)oldGroup toPosition:(int)newPosition inGroup:(ActiveMapsLayout::TGroup const &)newGroup;
|
||||
- (void)countryOptionsChangedAtPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group;
|
||||
- (void)countryDownloadingProgressChanged:(LocalAndRemoteSizeT const &)progress atPosition:(int)position inGroup:(ActiveMapsLayout::TGroup const &)group;
|
||||
|
||||
@end
|
||||
|
||||
@protocol CountryTreeObserverProtocol <NSObject>
|
||||
|
||||
- (void)countryStatusChangedAtPositionInNode:(int)position;
|
||||
- (void)countryDownloadingProgressChanged:(LocalAndRemoteSizeT const &)progress atPositionInNode:(int)position;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
class ActiveMapsObserver : public ActiveMapsLayout::ActiveMapsListener
|
||||
{
|
||||
public:
|
||||
ActiveMapsObserver(id<ActiveMapsObserverProtocol> delegateObject);
|
||||
|
||||
virtual void CountryGroupChanged(ActiveMapsLayout::TGroup const & oldGroup, int oldPosition,
|
||||
ActiveMapsLayout::TGroup const & newGroup, int newPosition);
|
||||
virtual void CountryStatusChanged(ActiveMapsLayout::TGroup const & group, int position,
|
||||
TStatus const & oldStatus, TStatus const & newStatus);
|
||||
virtual void CountryOptionsChanged(ActiveMapsLayout::TGroup const & group, int position,
|
||||
TMapOptions const & oldOpt, TMapOptions const & newOpt);
|
||||
virtual void DownloadingProgressUpdate(ActiveMapsLayout::TGroup const & group, int position, LocalAndRemoteSizeT const & progress);
|
||||
|
||||
private:
|
||||
id<ActiveMapsObserverProtocol> m_delegateObject;
|
||||
};
|
||||
|
||||
|
||||
class CountryTreeObserver : public CountryTree::CountryTreeListener
|
||||
{
|
||||
public:
|
||||
CountryTreeObserver(id<CountryTreeObserverProtocol> delegateObject);
|
||||
|
||||
virtual void ItemStatusChanged(int childPosition);
|
||||
virtual void ItemProgressChanged(int childPosition, LocalAndRemoteSizeT const & sizes);
|
||||
|
||||
private:
|
||||
id<CountryTreeObserverProtocol> m_delegateObject;
|
||||
};
|
52
iphone/Maps/Classes/MapsObservers.mm
Normal file
52
iphone/Maps/Classes/MapsObservers.mm
Normal file
|
@ -0,0 +1,52 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MapsObservers.h"
|
||||
|
||||
ActiveMapsObserver::ActiveMapsObserver(id<ActiveMapsObserverProtocol> delegateObject)
|
||||
: m_delegateObject(delegateObject)
|
||||
{
|
||||
}
|
||||
|
||||
void ActiveMapsObserver::CountryGroupChanged(ActiveMapsLayout::TGroup const & oldGroup, int oldPosition,
|
||||
ActiveMapsLayout::TGroup const & newGroup, int newPosition)
|
||||
{
|
||||
if ([m_delegateObject respondsToSelector:@selector(countryGroupChangedFromPosition:inGroup:toPosition:inGroup:)])
|
||||
[m_delegateObject countryGroupChangedFromPosition:oldPosition inGroup:oldGroup toPosition:newPosition inGroup:newGroup];
|
||||
}
|
||||
|
||||
void ActiveMapsObserver::CountryStatusChanged(ActiveMapsLayout::TGroup const & group, int position,
|
||||
TStatus const & oldStatus, TStatus const & newStatus)
|
||||
{
|
||||
if ([m_delegateObject respondsToSelector:@selector(countryStatusChangedAtPosition:inGroup:)])
|
||||
[m_delegateObject countryStatusChangedAtPosition:position inGroup:group];
|
||||
}
|
||||
|
||||
void ActiveMapsObserver::CountryOptionsChanged(ActiveMapsLayout::TGroup const & group, int position, TMapOptions const & oldOpt, TMapOptions const & newOpt)
|
||||
{
|
||||
if ([m_delegateObject respondsToSelector:@selector(countryOptionsChangedAtPosition:inGroup:)])
|
||||
[m_delegateObject countryOptionsChangedAtPosition:position inGroup:group];
|
||||
}
|
||||
|
||||
void ActiveMapsObserver::DownloadingProgressUpdate(ActiveMapsLayout::TGroup const & group, int position, LocalAndRemoteSizeT const & progress)
|
||||
{
|
||||
if ([m_delegateObject respondsToSelector:@selector(countryDownloadingProgressChanged:atPosition:inGroup:)])
|
||||
[m_delegateObject countryDownloadingProgressChanged:progress atPosition:position inGroup:group];
|
||||
}
|
||||
|
||||
|
||||
CountryTreeObserver::CountryTreeObserver(id<CountryTreeObserverProtocol> delegateObject)
|
||||
: m_delegateObject(delegateObject)
|
||||
{
|
||||
}
|
||||
|
||||
void CountryTreeObserver::ItemStatusChanged(int childPosition)
|
||||
{
|
||||
if ([m_delegateObject respondsToSelector:@selector(countryStatusChangedAtPositionInNode:)])
|
||||
[m_delegateObject countryStatusChangedAtPositionInNode:childPosition];
|
||||
}
|
||||
|
||||
void CountryTreeObserver::ItemProgressChanged(int childPosition, storage::LocalAndRemoteSizeT const & sizes)
|
||||
{
|
||||
if ([m_delegateObject respondsToSelector:@selector(countryDownloadingProgressChanged:atPositionInNode:)])
|
||||
[m_delegateObject countryDownloadingProgressChanged:sizes atPositionInNode:childPosition];
|
||||
}
|
|
@ -38,4 +38,6 @@ typedef NS_ENUM(NSUInteger, PlacePageState) {
|
|||
@property (nonatomic, readonly) NSString * temporaryTitle;
|
||||
@property (nonatomic) BOOL statusBarIncluded;
|
||||
|
||||
- (void)showBuildingRoutingActivity:(BOOL)buiding;
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef NS_ENUM(NSUInteger, CellRow)
|
|||
@property (nonatomic) CopyLabel * titleLabel;
|
||||
@property (nonatomic) UIButton * bookmarkButton;
|
||||
@property (nonatomic) UIButton * routeButton;
|
||||
@property (nonatomic) UIActivityIndicatorView * routingActivity;
|
||||
@property (nonatomic) UILabel * typeLabel;
|
||||
@property (nonatomic) UIButton * shareButton;
|
||||
@property (nonatomic) UIImageView * editImageView;
|
||||
|
@ -342,6 +343,7 @@ typedef NS_ENUM(NSUInteger, CellRow)
|
|||
self.bookmarkButton.midY = 36;
|
||||
}
|
||||
self.routeButton.midY = self.bookmarkButton.midY - 1;
|
||||
self.routeButton.hidden = [self isMyPosition];
|
||||
}
|
||||
|
||||
- (CGFloat)headerHeight
|
||||
|
@ -812,6 +814,23 @@ typedef NS_ENUM(NSUInteger, CellRow)
|
|||
m_bookmarkData = NULL;
|
||||
}
|
||||
|
||||
- (void)showBuildingRoutingActivity:(BOOL)building
|
||||
{
|
||||
if (building)
|
||||
{
|
||||
self.routeButton.hidden = YES;
|
||||
self.routingActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
self.routingActivity.center = CGPointMake(self.routeButton.midX, self.routeButton.midY + 2);
|
||||
[self.routeButton.superview addSubview:self.routingActivity];
|
||||
[self.routingActivity startAnimating];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.routeButton.hidden = NO;
|
||||
[self.routingActivity removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isMarkOfType:(UserMark::Type)type
|
||||
{
|
||||
return m_mark ? [self userMark]->GetMarkType() == type : NO;
|
||||
|
|
20
iphone/Maps/Classes/ProgressView.h
Normal file
20
iphone/Maps/Classes/ProgressView.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class ProgressView;
|
||||
@protocol ProgressViewDelegate <NSObject>
|
||||
|
||||
- (void)progressViewDidCancel:(ProgressView *)progress;
|
||||
- (void)progressViewDidStart:(ProgressView *)progress;
|
||||
|
||||
@end
|
||||
|
||||
@interface ProgressView : UIView
|
||||
|
||||
@property (nonatomic) BOOL failedMode;
|
||||
@property (nonatomic) double progress;
|
||||
- (void)setProgress:(double)progress animated:(BOOL)animated;
|
||||
|
||||
@property (nonatomic, weak) id <ProgressViewDelegate> delegate;
|
||||
|
||||
@end
|
169
iphone/Maps/Classes/ProgressView.m
Normal file
169
iphone/Maps/Classes/ProgressView.m
Normal file
|
@ -0,0 +1,169 @@
|
|||
|
||||
#import "ProgressView.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
@interface ProgressView ()
|
||||
|
||||
@property (nonatomic) CAShapeLayer * progressLayer;
|
||||
@property (nonatomic) CAShapeLayer * backgroundCircleLayer;
|
||||
@property (nonatomic) CAShapeLayer * stopRectLayer;
|
||||
@property (nonatomic) UIImageView * startTriangleView;
|
||||
@property (nonatomic) UIButton * button;
|
||||
@property (nonatomic) NSNumber * nextProgressToAnimate;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ProgressView
|
||||
|
||||
#define CIRCLE_RADIUS 18
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super initWithFrame:CGRectMake(0, 0, 44, 44)];
|
||||
|
||||
[self.layer addSublayer:self.backgroundCircleLayer];
|
||||
[self.layer addSublayer:self.progressLayer];
|
||||
[self.layer addSublayer:self.stopRectLayer];
|
||||
[self addSubview:self.startTriangleView];
|
||||
self.startTriangleView.center = CGPointMake(self.width / 2 + 1, self.height / 2);
|
||||
[self addSubview:self.button];
|
||||
|
||||
[self setProgress:0 animated:NO];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)buttonPressed:(id)sender
|
||||
{
|
||||
if (self.failedMode)
|
||||
[self.delegate progressViewDidStart:self];
|
||||
else
|
||||
[self.delegate progressViewDidCancel:self];
|
||||
}
|
||||
|
||||
- (CGFloat)angleWithProgress:(double)progress
|
||||
{
|
||||
return 2 * M_PI * progress - M_PI_2;
|
||||
}
|
||||
|
||||
NSString * const CircleAnimationKey = @"CircleAnimation";
|
||||
|
||||
- (void)setProgress:(double)progress animated:(BOOL)animated
|
||||
{
|
||||
if ([self.progressLayer animationForKey:CircleAnimationKey])
|
||||
{
|
||||
self.nextProgressToAnimate = @(progress);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.nextProgressToAnimate = nil;
|
||||
CGPoint const center = CGPointMake(self.width / 2, self.height / 2);
|
||||
CGFloat const radius = CIRCLE_RADIUS - self.progressLayer.lineWidth;
|
||||
UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:[self angleWithProgress:0] endAngle:[self angleWithProgress:progress] clockwise:YES];
|
||||
if (animated)
|
||||
{
|
||||
self.progressLayer.path = path.CGPath;
|
||||
|
||||
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
|
||||
animation.duration = 0.3;
|
||||
animation.repeatCount = 1;
|
||||
animation.fromValue = @(_progress / progress);
|
||||
animation.toValue = @1;
|
||||
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
|
||||
animation.delegate = self;
|
||||
[self.progressLayer addAnimation:animation forKey:CircleAnimationKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.progressLayer.path = path.CGPath;
|
||||
}
|
||||
_progress = progress;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
|
||||
{
|
||||
if (self.nextProgressToAnimate)
|
||||
[self setProgress:[self.nextProgressToAnimate doubleValue] animated:YES];
|
||||
}
|
||||
|
||||
- (CGColorRef)redColor
|
||||
{
|
||||
return [UIColor colorWithColorCode:@"FF4436"].CGColor;
|
||||
}
|
||||
|
||||
- (CGColorRef)blueColor
|
||||
{
|
||||
return [UIColor colorWithColorCode:@"0585FF"].CGColor;
|
||||
}
|
||||
|
||||
- (void)setFailedMode:(BOOL)failedMode
|
||||
{
|
||||
_failedMode = failedMode;
|
||||
|
||||
self.progressLayer.strokeColor = failedMode ? [self redColor] : [self blueColor];
|
||||
self.stopRectLayer.hidden = failedMode;
|
||||
self.startTriangleView.hidden = !failedMode;
|
||||
}
|
||||
|
||||
- (UIButton *)button
|
||||
{
|
||||
if (!_button)
|
||||
{
|
||||
_button = [[UIButton alloc] initWithFrame:self.bounds];
|
||||
[_button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _button;
|
||||
}
|
||||
|
||||
- (CAShapeLayer *)stopRectLayer
|
||||
{
|
||||
if (!_stopRectLayer)
|
||||
{
|
||||
_stopRectLayer = [CAShapeLayer layer];
|
||||
CGFloat const side = 11;
|
||||
CGRect const rect = CGRectMake((self.width - side) / 2, (self.width - side) / 2, side, side);
|
||||
_stopRectLayer.fillColor = [self blueColor];
|
||||
_stopRectLayer.path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:2].CGPath;
|
||||
}
|
||||
return _stopRectLayer;
|
||||
}
|
||||
|
||||
- (UIImageView *)startTriangleView
|
||||
{
|
||||
if (!_startTriangleView)
|
||||
_startTriangleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ProgressTriangle"]];
|
||||
return _startTriangleView;
|
||||
}
|
||||
|
||||
- (CAShapeLayer *)backgroundCircleLayer
|
||||
{
|
||||
if (!_backgroundCircleLayer)
|
||||
{
|
||||
_backgroundCircleLayer = [CAShapeLayer layer];
|
||||
_backgroundCircleLayer.fillColor = [UIColor clearColor].CGColor;
|
||||
_backgroundCircleLayer.lineWidth = 2;
|
||||
_backgroundCircleLayer.strokeColor = [[UIColor colorWithColorCode:@"F0F0F0"] CGColor];
|
||||
_backgroundCircleLayer.shouldRasterize = YES;
|
||||
_backgroundCircleLayer.rasterizationScale = 2 * [UIScreen mainScreen].scale;
|
||||
CGRect rect = CGRectMake(self.width / 2 - CIRCLE_RADIUS, self.height / 2 - CIRCLE_RADIUS, 2 * CIRCLE_RADIUS, 2 * CIRCLE_RADIUS);
|
||||
rect = CGRectInset(rect, _backgroundCircleLayer.lineWidth, _backgroundCircleLayer.lineWidth);
|
||||
_backgroundCircleLayer.path = [UIBezierPath bezierPathWithOvalInRect:rect].CGPath;
|
||||
}
|
||||
return _backgroundCircleLayer;
|
||||
}
|
||||
|
||||
- (CAShapeLayer *)progressLayer
|
||||
{
|
||||
if (!_progressLayer)
|
||||
{
|
||||
_progressLayer = [CAShapeLayer layer];
|
||||
_progressLayer.fillColor = [UIColor clearColor].CGColor;
|
||||
_progressLayer.lineWidth = 3;
|
||||
_progressLayer.shouldRasterize = YES;
|
||||
_progressLayer.rasterizationScale = 2 * [UIScreen mainScreen].scale;
|
||||
}
|
||||
return _progressLayer;
|
||||
}
|
||||
|
||||
@end
|
|
@ -6,13 +6,14 @@
|
|||
@protocol RouteViewDelegate <NSObject>
|
||||
|
||||
- (void)routeViewDidCancelRouting:(RouteView *)routeView;
|
||||
- (void)routeViewDidStartRouting:(RouteView *)routeView;
|
||||
- (void)routeViewDidStartFollowing:(RouteView *)routeView;
|
||||
|
||||
@end
|
||||
|
||||
@interface RouteView : UIView
|
||||
|
||||
- (void)setVisible:(BOOL)visible animated:(BOOL)animated;
|
||||
- (void)hideFollowButton;
|
||||
|
||||
- (void)updateDistance:(NSString *)distance withMetrics:(NSString *)metrics;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
|
||||
|
||||
[self addSubview:self.distanceView];
|
||||
[self.distanceView addSubview:self.wrapView];
|
||||
|
@ -38,7 +39,7 @@
|
|||
- (void)updateDistance:(NSString *)distance withMetrics:(NSString *)metrics
|
||||
{
|
||||
self.distanceLabel.text = distance;
|
||||
self.metricsLabel.text = metrics;
|
||||
self.metricsLabel.text = metrics.uppercaseString;
|
||||
[self layoutSubviews];
|
||||
}
|
||||
|
||||
|
@ -51,13 +52,14 @@
|
|||
|
||||
CGFloat const betweenOffset = 0;
|
||||
self.wrapView.size = CGSizeMake(self.distanceLabel.width + betweenOffset + self.metricsLabel.width, 40);
|
||||
self.distanceLabel.midY = self.wrapView.height / 2;
|
||||
self.metricsLabel.maxY = self.distanceLabel.maxY - 4;
|
||||
self.wrapView.center = CGPointMake(self.wrapView.superview.width / 2, self.wrapView.superview.height / 2);
|
||||
|
||||
self.distanceLabel.minX = 0;
|
||||
self.metricsLabel.minX = self.distanceLabel.minX + self.distanceLabel.width + betweenOffset;
|
||||
self.distanceLabel.midY = self.wrapView.height / 2;
|
||||
self.metricsLabel.maxY = self.distanceLabel.maxY - 4;
|
||||
|
||||
self.distanceView.size = CGSizeMake(self.wrapView.width + 24, BUTTON_HEIGHT);
|
||||
self.wrapView.center = CGPointMake(self.wrapView.superview.width / 2, self.wrapView.superview.height / 2);
|
||||
}
|
||||
|
||||
- (void)didMoveToSuperview
|
||||
|
@ -73,7 +75,15 @@
|
|||
|
||||
- (void)startButtonPressed:(id)sender
|
||||
{
|
||||
[self.delegate routeViewDidStartRouting:self];
|
||||
[self.delegate routeViewDidStartFollowing:self];
|
||||
}
|
||||
|
||||
- (void)hideFollowButton
|
||||
{
|
||||
self.startButton.userInteractionEnabled = NO;
|
||||
[UIView animateWithDuration:0.5 delay:0.1 damping:0.83 initialVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.startButton.maxY = -30;
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
- (void)setVisible:(BOOL)visible animated:(BOOL)animated
|
||||
|
@ -82,9 +92,11 @@
|
|||
CGFloat const offsetInnerX = 3;
|
||||
CGFloat const offsetBetweenX = 0;
|
||||
CGFloat const offsetOuterX = 18;
|
||||
[UIView animateWithDuration:(animated ? 0.5 : 0) delay:0 damping:0.8 initialVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
[UIView animateWithDuration:(animated ? 0.5 : 0) delay:0 damping:0.83 initialVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
if (visible)
|
||||
{
|
||||
self.startButton.userInteractionEnabled = YES;
|
||||
self.startButton.minY = self.closeButton.minY;
|
||||
self.distanceView.minX = offsetInnerX;
|
||||
self.closeButton.maxX = self.width - offsetInnerX;
|
||||
self.startButton.maxX = self.closeButton.minX - offsetBetweenX;
|
||||
|
@ -126,7 +138,7 @@
|
|||
if (!_startButton)
|
||||
{
|
||||
UIImageView * imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"StartRoutingButton"]];
|
||||
NSString * title = @"Поехали!";
|
||||
NSString * title = NSLocalizedString(@"routing_go", nil);
|
||||
UIFont * font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14];
|
||||
CGFloat const width = [title sizeWithDrawSize:CGSizeMake(200, 30) font:font].width + imageView.width + 40;
|
||||
|
||||
|
@ -180,7 +192,6 @@
|
|||
UIImage * image = [[UIImage imageNamed:@"RoutingButtonBackground"] resizableImageWithCapInsets:UIEdgeInsetsMake(5, 5, 5, 5)];
|
||||
_distanceView.image = image;
|
||||
_distanceView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
|
||||
[_distanceView addSubview:self.wrapView];
|
||||
}
|
||||
return _distanceView;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
|
||||
#import "ToolbarView.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "Framework.h"
|
||||
#import "BadgeView.h"
|
||||
|
||||
@interface ToolbarView ()
|
||||
|
||||
@property (nonatomic) UIButton * searchButton;
|
||||
@property (nonatomic) UIButton * bookmarkButton;
|
||||
@property (nonatomic) UIButton * menuButton;
|
||||
@property (nonatomic) BadgeView * menuBadge;
|
||||
@property (nonatomic) UIImageView * backgroundImageView;
|
||||
|
||||
@end
|
||||
|
@ -32,9 +36,30 @@
|
|||
|
||||
[self layoutButtons];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outOfDateCountriesCountChanged:) name:MapsStatusChangedNotification object:nil];
|
||||
[self updateMenuBadgeWithCount:GetFramework().GetCountryTree().GetActiveMapLayout().GetCountInGroup(storage::ActiveMapsLayout::TGroup::EOutOfDate)];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)outOfDateCountriesCountChanged:(NSNotification *)notification
|
||||
{
|
||||
[self updateMenuBadgeWithCount:[[notification userInfo][@"OutOfDate"] integerValue]];
|
||||
}
|
||||
|
||||
- (void)updateMenuBadgeWithCount:(NSInteger)count
|
||||
{
|
||||
[self.menuBadge removeFromSuperview];
|
||||
if (count > 0)
|
||||
{
|
||||
BadgeView * badge = [[BadgeView alloc] init];
|
||||
badge.value = count;
|
||||
badge.minY = 4;
|
||||
badge.minX = self.menuButton.width / 2 + 10;
|
||||
[self.menuButton addSubview:badge];
|
||||
self.menuBadge = badge;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)locationButtonPressed:(id)sender
|
||||
{
|
||||
[self.delegate toolbar:self didPressItemWithName:@"Location"];
|
||||
|
@ -106,4 +131,9 @@
|
|||
return _backgroundImageView;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
@end
|
9
iphone/Maps/CountryTreeVC.h
Normal file
9
iphone/Maps/CountryTreeVC.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "DownloaderParentVC.h"
|
||||
|
||||
@interface CountryTreeVC : DownloaderParentVC
|
||||
|
||||
- (id)initWithNodePosition:(int)position;
|
||||
|
||||
@end
|
329
iphone/Maps/CountryTreeVC.mm
Normal file
329
iphone/Maps/CountryTreeVC.mm
Normal file
|
@ -0,0 +1,329 @@
|
|||
|
||||
#import "CountryTreeVC.h"
|
||||
#import "ActiveMapsVC.h"
|
||||
#import "CustomAlertView.h"
|
||||
#import "Statistics.h"
|
||||
|
||||
@interface CountryTreeVC () <CountryTreeObserverProtocol>
|
||||
|
||||
@end
|
||||
|
||||
@implementation CountryTreeVC
|
||||
{
|
||||
CountryTreeObserver * m_treeObserver;
|
||||
}
|
||||
|
||||
- (id)initWithNodePosition:(int)position
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (position == -1)
|
||||
{
|
||||
self.tree.SetDefaultRoot();
|
||||
self.title = L(@"download_maps");
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(position < self.tree.GetChildCount(), ());
|
||||
self.title = [NSString stringWithUTF8String:self.tree.GetChildName(position).c_str()];
|
||||
self.tree.SetChildAsRoot(position);
|
||||
}
|
||||
|
||||
__weak CountryTreeVC * weakSelf = self;
|
||||
m_treeObserver = new CountryTreeObserver(weakSelf);
|
||||
self.tree.SetListener(m_treeObserver);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
if (self.isMovingFromParentViewController)
|
||||
{
|
||||
if (self.tree.HasParent())
|
||||
self.tree.SetParentAsRoot();
|
||||
else
|
||||
self.tree.ResetListener();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
#define TOP_ROWS_COUNT 1
|
||||
|
||||
- (NSIndexPath *)downloadedCountriesIndexPath
|
||||
{
|
||||
return [NSIndexPath indexPathForRow:0 inSection:0];
|
||||
}
|
||||
|
||||
- (void)outOfDateCountriesCountChanged:(NSNotification *)notification
|
||||
{
|
||||
NSInteger const count = [[notification userInfo][@"OutOfDate"] integerValue];
|
||||
if ([self isRootScreen])
|
||||
{
|
||||
MapCell * cell = (MapCell *)[self.tableView cellForRowAtIndexPath:[self downloadedCountriesIndexPath]];
|
||||
cell.badgeView.value = count;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Helpers
|
||||
|
||||
- (BOOL)isRootScreen
|
||||
{
|
||||
return !self.tree.HasParent();
|
||||
}
|
||||
|
||||
- (CountryTree &)tree
|
||||
{
|
||||
return GetFramework().GetCountryTree();
|
||||
}
|
||||
|
||||
- (MapCell *)cellAtPositionInNode:(int)position
|
||||
{
|
||||
NSInteger const section = [self isRootScreen] ? [self downloadedCountriesIndexPath].section + 1 : 0;
|
||||
return (MapCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:position inSection:section]];
|
||||
}
|
||||
|
||||
- (BOOL)isActiveMapsIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [self isRootScreen] && [indexPath isEqual:[self downloadedCountriesIndexPath]];
|
||||
}
|
||||
|
||||
#pragma mark - DownloaderParentVC virtual methods implementation
|
||||
|
||||
- (NSString *)parentTitle
|
||||
{
|
||||
return self.tree.IsCountryRoot() ? [NSString stringWithUTF8String:self.tree.GetRootName().c_str()] : nil;
|
||||
}
|
||||
|
||||
- (NSString *)selectedMapName
|
||||
{
|
||||
return [NSString stringWithUTF8String:self.tree.GetChildName(self.selectedPosition).c_str()];
|
||||
}
|
||||
|
||||
- (NSString *)selectedMapGuideName
|
||||
{
|
||||
guides::GuideInfo info;
|
||||
if (self.tree.GetLeafGuideInfo(self.selectedPosition, info))
|
||||
{
|
||||
string const lang = languages::GetCurrentNorm();
|
||||
return [NSString stringWithUTF8String:info.GetAdTitle(lang).c_str()];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (size_t)selectedMapSizeWithOptions:(storage::TMapOptions)options
|
||||
{
|
||||
return self.tree.GetLeafSize(self.selectedPosition, options).second;
|
||||
}
|
||||
|
||||
- (TStatus)selectedMapStatus
|
||||
{
|
||||
return self.tree.GetLeafStatus(self.selectedPosition);
|
||||
}
|
||||
|
||||
- (TMapOptions)selectedMapOptions
|
||||
{
|
||||
return self.tree.GetLeafOptions(self.selectedPosition);
|
||||
}
|
||||
|
||||
- (void)performAction:(DownloaderAction)action
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case DownloaderActionDownloadAll:
|
||||
case DownloaderActionDownloadMap:
|
||||
case DownloaderActionDownloadCarRouting:
|
||||
if ([self canDownloadSelectedMap])
|
||||
self.tree.DownloadCountry(self.selectedPosition, self.selectedInActionSheetOptions);
|
||||
break;
|
||||
|
||||
case DownloaderActionDeleteAll:
|
||||
case DownloaderActionDeleteMap:
|
||||
case DownloaderActionDeleteCarRouting:
|
||||
self.tree.DeleteCountry(self.selectedPosition, self.selectedInActionSheetOptions);
|
||||
break;
|
||||
|
||||
case DownloaderActionCancelDownloading:
|
||||
self.tree.CancelDownloading(self.selectedPosition);
|
||||
break;
|
||||
|
||||
case DownloaderActionZoomToCountry:
|
||||
self.tree.ShowLeafOnMap(self.selectedPosition);
|
||||
[[Statistics instance] logEvent:@"Show Map From Download Countries Screen"];
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
break;
|
||||
|
||||
case DownloaderActionShowGuide:
|
||||
guides::GuideInfo info;
|
||||
if (self.tree.GetLeafGuideInfo(self.selectedPosition, info))
|
||||
[self openGuideWithInfo:info];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - TableView
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
|
||||
{
|
||||
return 0.001;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return [self isRootScreen] ? 1 + TOP_ROWS_COUNT : 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
if ([self isRootScreen] && section == [self downloadedCountriesIndexPath].section)
|
||||
return TOP_ROWS_COUNT;
|
||||
else
|
||||
return self.tree.GetChildCount();
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MapCell * cell = [tableView dequeueReusableCellWithIdentifier:[MapCell className]];
|
||||
if (!cell)
|
||||
cell = [[MapCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[MapCell className]];
|
||||
|
||||
if ([self isActiveMapsIndexPath:indexPath])
|
||||
{
|
||||
cell.titleLabel.text = L(@"downloader_downloaded_maps");
|
||||
cell.subtitleLabel.text = nil;
|
||||
cell.parentMode = YES;
|
||||
cell.badgeView.value = self.tree.GetActiveMapLayout().GetCountInGroup(ActiveMapsLayout::TGroup::EOutOfDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
int const position = indexPath.row;
|
||||
bool const isLeaf = self.tree.IsLeaf(position);
|
||||
|
||||
cell.titleLabel.text = [NSString stringWithUTF8String:self.tree.GetChildName(position).c_str()];
|
||||
cell.subtitleLabel.text = [self parentTitle];
|
||||
cell.delegate = self;
|
||||
cell.badgeView.value = 0;
|
||||
cell.parentMode = !isLeaf;
|
||||
if (isLeaf)
|
||||
{
|
||||
TMapOptions const options = self.tree.GetLeafOptions(position);
|
||||
TStatus const status = self.tree.GetLeafStatus(position);
|
||||
|
||||
NSString * sizeString;
|
||||
if (status == TStatus::ENotDownloaded)
|
||||
{
|
||||
LocalAndRemoteSizeT const size = self.tree.GetRemoteLeafSizes(position);
|
||||
sizeString = [NSString stringWithFormat:@"%@ / %@", [self formattedMapSize:size.first], [self formattedMapSize:size.second]];
|
||||
}
|
||||
else if (status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate)
|
||||
{
|
||||
size_t const size = self.tree.GetLeafSize(position, options).second;
|
||||
sizeString = [self formattedMapSize:size];
|
||||
}
|
||||
else if (status == TStatus::EOutOfMemFailed || status == TStatus::EDownloadFailed || status == TStatus::EDownloading || status == TStatus::EInQueue)
|
||||
{
|
||||
LocalAndRemoteSizeT const size = self.tree.GetDownloadableLeafSize(position);
|
||||
sizeString = [self formattedMapSize:size.second];
|
||||
cell.downloadProgress = (double)size.first / size.second;
|
||||
}
|
||||
|
||||
cell.sizeLabel.text = sizeString;
|
||||
cell.status = status;
|
||||
cell.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
TStatus const status = self.tree.GetLeafStatus(indexPath.row);
|
||||
return status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete)
|
||||
{
|
||||
self.tree.DeleteCountry(indexPath.row, TMapOptions::EMapWithCarRouting);
|
||||
[tableView setEditing:NO animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if ([self isActiveMapsIndexPath:indexPath])
|
||||
{
|
||||
ActiveMapsVC * vc = [[ActiveMapsVC alloc] init];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.selectedPosition = indexPath.row;
|
||||
if (self.tree.IsLeaf(self.selectedPosition))
|
||||
{
|
||||
MapCell * cell = [self cellAtPositionInNode:self.selectedPosition];
|
||||
UIActionSheet * actionSheet = [self actionSheetToPerformActionOnSelectedMap];
|
||||
[actionSheet showFromRect:cell.frame inView:cell.superview animated:YES];
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
CountryTreeVC * vc = [[CountryTreeVC alloc] initWithNodePosition:self.selectedPosition];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [MapCell cellHeight];
|
||||
}
|
||||
|
||||
#pragma mark - MapCellDelegate
|
||||
|
||||
- (void)mapCellDidStartDownloading:(MapCell *)cell
|
||||
{
|
||||
self.selectedPosition = [self.tableView indexPathForCell:cell].row;
|
||||
TStatus const status = [self selectedMapStatus];
|
||||
if (status == TStatus::EDownloadFailed || status == TStatus::EOutOfMemFailed)
|
||||
if ([self canDownloadSelectedMap])
|
||||
self.tree.RetryDownloading(self.selectedPosition);
|
||||
}
|
||||
|
||||
- (void)mapCellDidCancelDownloading:(MapCell *)cell
|
||||
{
|
||||
self.selectedPosition = [self.tableView indexPathForCell:cell].row;
|
||||
[[self actionSheetToDeleteSelectedMap] showFromRect:cell.frame inView:cell.superview animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - CountryTree core callbacks
|
||||
|
||||
- (void)countryStatusChangedAtPositionInNode:(int)position
|
||||
{
|
||||
MapCell * cell = [self cellAtPositionInNode:position];
|
||||
[cell setStatus:self.tree.GetLeafStatus(position) options:self.tree.GetLeafOptions(position) animated:YES];
|
||||
}
|
||||
|
||||
- (void)countryDownloadingProgressChanged:(LocalAndRemoteSizeT const &)progress atPositionInNode:(int)position
|
||||
{
|
||||
MapCell * cell = [self cellAtPositionInNode:position];
|
||||
[cell setDownloadProgress:((double)progress.first / progress.second) animated:YES];
|
||||
}
|
||||
|
||||
@end
|
50
iphone/Maps/DownloaderParentVC.h
Normal file
50
iphone/Maps/DownloaderParentVC.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "MapsObservers.h"
|
||||
#import "MapCell.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
#include "../../storage/storage_defines.hpp"
|
||||
|
||||
#include "../../platform/preferred_languages.hpp"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, DownloaderAction)
|
||||
{
|
||||
DownloaderActionDownloadAll,
|
||||
DownloaderActionDownloadMap,
|
||||
DownloaderActionDownloadCarRouting,
|
||||
DownloaderActionDeleteAll,
|
||||
DownloaderActionDeleteMap,
|
||||
DownloaderActionDeleteCarRouting,
|
||||
DownloaderActionCancelDownloading,
|
||||
DownloaderActionZoomToCountry,
|
||||
DownloaderActionShowGuide
|
||||
};
|
||||
|
||||
using namespace storage;
|
||||
|
||||
@interface DownloaderParentVC : UITableViewController <MapCellDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
|
||||
|
||||
- (NSString *)formattedMapSize:(size_t)size;
|
||||
- (void)openGuideWithInfo:(guides::GuideInfo const &)info;
|
||||
|
||||
- (BOOL)canDownloadSelectedMap;
|
||||
- (UIActionSheet *)actionSheetToDeleteSelectedMap;
|
||||
- (UIActionSheet *)actionSheetToCancelDownloadingSelectedMap;
|
||||
- (UIActionSheet *)actionSheetToPerformActionOnSelectedMap;
|
||||
|
||||
@property (nonatomic) NSInteger selectedPosition;
|
||||
|
||||
@property (nonatomic) TMapOptions selectedInActionSheetOptions;
|
||||
@property (nonatomic) NSMutableDictionary * actionSheetActions;
|
||||
|
||||
// virtual
|
||||
- (NSString *)parentTitle;
|
||||
- (NSString *)selectedMapName;
|
||||
- (NSString *)selectedMapGuideName;
|
||||
- (size_t)selectedMapSizeWithOptions:(TMapOptions)options;
|
||||
- (TStatus)selectedMapStatus;
|
||||
- (TMapOptions)selectedMapOptions;
|
||||
- (void)performAction:(DownloaderAction)action;
|
||||
|
||||
@end
|
282
iphone/Maps/DownloaderParentVC.mm
Normal file
282
iphone/Maps/DownloaderParentVC.mm
Normal file
|
@ -0,0 +1,282 @@
|
|||
|
||||
#import "DownloaderParentVC.h"
|
||||
#import "CustomAlertView.h"
|
||||
#import "DiskFreeSpace.h"
|
||||
#import "Statistics.h"
|
||||
#import "Reachability.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
|
||||
@interface DownloaderParentVC ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation DownloaderParentVC
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStyleGrouped];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outOfDateCountriesCountChanged:) name:MapsStatusChangedNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
if (self.selectedInActionSheetOptions == TMapOptions::EMapOnly)
|
||||
[self performAction:DownloaderActionDownloadMap];
|
||||
else if (self.selectedInActionSheetOptions == TMapOptions::ECarRouting)
|
||||
[self performAction:DownloaderActionDownloadCarRouting];
|
||||
else if (self.selectedInActionSheetOptions == TMapOptions::EMapWithCarRouting)
|
||||
[self performAction:DownloaderActionDownloadAll];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)allButtonsInActionSheetAreAboutDownloading:(TStatus const)status
|
||||
{
|
||||
return status == TStatus::ENotDownloaded;
|
||||
}
|
||||
|
||||
#pragma mark - Virtual methods
|
||||
|
||||
- (void)performAction:(DownloaderAction)action {}
|
||||
- (NSString *)parentTitle { return nil; }
|
||||
- (NSString *)selectedMapName { return nil; }
|
||||
- (NSString *)selectedMapGuideName { return nil; }
|
||||
- (size_t)selectedMapSizeWithOptions:(TMapOptions)options { return 0; }
|
||||
- (TStatus)selectedMapStatus { return TStatus::EUnknown; }
|
||||
- (TMapOptions)selectedMapOptions { return TMapOptions::EMapOnly; }
|
||||
|
||||
#pragma mark - Public methods for successors
|
||||
|
||||
#define MB (1024 * 1024)
|
||||
|
||||
- (NSString *)formattedMapSize:(size_t)size
|
||||
{
|
||||
NSString * sizeString;
|
||||
if (size > MB)
|
||||
sizeString = [NSString stringWithFormat:@"%ld %@", (size + 512 * 1024) / MB, L(@"mb")];
|
||||
else
|
||||
sizeString = [NSString stringWithFormat:@"%ld %@", (size + 1023) / 1024, L(@"kb")];
|
||||
return [sizeString uppercaseString];
|
||||
}
|
||||
|
||||
- (BOOL)canDownloadSelectedMap
|
||||
{
|
||||
size_t const size = [self selectedMapSizeWithOptions:self.selectedInActionSheetOptions];
|
||||
NSString * name = [self selectedMapName];
|
||||
|
||||
Reachability * reachability = [Reachability reachabilityForInternetConnection];
|
||||
if ([reachability isReachable])
|
||||
{
|
||||
if ([reachability isReachableViaWWAN] && size > 50 * MB)
|
||||
{
|
||||
NSString * title = [NSString stringWithFormat:L(@"no_wifi_ask_cellular_download"), name];
|
||||
[[[CustomAlertView alloc] initWithTitle:title message:nil delegate:self cancelButtonTitle:L(@"cancel") otherButtonTitles:L(@"use_cellular_data"), nil] show];
|
||||
}
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
[[[CustomAlertView alloc] initWithTitle:L(@"no_internet_connection_detected") message:L(@"use_wifi_recommendation_text") delegate:nil cancelButtonTitle:L(@"ok") otherButtonTitles:nil] show];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)openGuideWithInfo:(const guides::GuideInfo &)info
|
||||
{
|
||||
string const lang = languages::GetCurrentNorm();
|
||||
NSURL * guideUrl = [NSURL URLWithString:[NSString stringWithUTF8String:info.GetAppID().c_str()]];
|
||||
[[Statistics instance] logEvent:@"Open Guide Country" withParameters:@{@"Country Name" : [self selectedMapName]}];
|
||||
UIApplication * application = [UIApplication sharedApplication];
|
||||
if ([application canOpenURL:guideUrl])
|
||||
{
|
||||
[application openURL:guideUrl];
|
||||
[[Statistics instance] logEvent:@"Open Guide Button" withParameters:@{@"Guide downloaded" : @"YES"}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[application openURL:[NSURL URLWithString:[NSString stringWithUTF8String:info.GetURL().c_str()]]];
|
||||
[[Statistics instance] logEvent:@"Open Guide Button" withParameters:@{@"Guide downloaded" : @"NO"}];
|
||||
}
|
||||
}
|
||||
|
||||
#define ROUTING_SYMBOL @"\xF0\x9F\x9A\x97"
|
||||
|
||||
- (UIActionSheet *)actionSheetToPerformActionOnSelectedMap
|
||||
{
|
||||
TStatus const status = [self selectedMapStatus];
|
||||
TMapOptions const options = [self selectedMapOptions];
|
||||
|
||||
[self.actionSheetActions removeAllObjects];
|
||||
|
||||
NSString * title;
|
||||
if ([self allButtonsInActionSheetAreAboutDownloading:status])
|
||||
title = [NSString stringWithFormat:@"%@ %@", L(@"download").uppercaseString, [self actionSheetTitle]];
|
||||
else
|
||||
title = [self actionSheetTitle];
|
||||
|
||||
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
|
||||
|
||||
if (status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate)
|
||||
{
|
||||
if ([self selectedMapGuideName])
|
||||
[self addButtonWithTitle:[self selectedMapGuideName] action:DownloaderActionShowGuide toActionSheet:actionSheet];
|
||||
|
||||
[self addButtonWithTitle:L(@"zoom_to_country") action:DownloaderActionZoomToCountry toActionSheet:actionSheet];
|
||||
}
|
||||
|
||||
if (status == TStatus::ENotDownloaded || status == TStatus::EOutOfMemFailed || status == TStatus::EDownloadFailed)
|
||||
{
|
||||
NSString * size = [self formattedMapSize:[self selectedMapSizeWithOptions:TMapOptions::EMapOnly]];
|
||||
NSString * title;
|
||||
if ([self allButtonsInActionSheetAreAboutDownloading:status])
|
||||
title = [NSString stringWithFormat:@"%@, %@", L(@"downloader_map_only"), size];
|
||||
else
|
||||
title = [NSString stringWithFormat:@"%@, %@", L(@"downloader_download_map"), size];
|
||||
[self addButtonWithTitle:title action:DownloaderActionDownloadMap toActionSheet:actionSheet];
|
||||
}
|
||||
|
||||
if (status == TStatus::ENotDownloaded || status == TStatus::EOutOfMemFailed || status == TStatus::EDownloadFailed)
|
||||
{
|
||||
NSString * size = [self formattedMapSize:[self selectedMapSizeWithOptions:TMapOptions::EMapWithCarRouting]];
|
||||
NSString * title;
|
||||
if ([self allButtonsInActionSheetAreAboutDownloading:status])
|
||||
title = [NSString stringWithFormat:@"%@%@, %@", L(@"downloader_map_and_routing"), ROUTING_SYMBOL, size];
|
||||
else
|
||||
title = [NSString stringWithFormat:@"%@%@, %@", L(@"downloader_download_map_and_routing"), ROUTING_SYMBOL, size];
|
||||
|
||||
[self addButtonWithTitle:title action:DownloaderActionDownloadAll toActionSheet:actionSheet];
|
||||
}
|
||||
|
||||
if (status == TStatus::EOnDiskOutOfDate && options == TMapOptions::EMapWithCarRouting)
|
||||
{
|
||||
NSString * size = [self formattedMapSize:[self selectedMapSizeWithOptions:TMapOptions::EMapWithCarRouting]];
|
||||
NSString * title = [NSString stringWithFormat:@"%@%@, %@", L(@"downloader_update_map_and_routing"), ROUTING_SYMBOL, size];
|
||||
[self addButtonWithTitle:title action:DownloaderActionDownloadAll toActionSheet:actionSheet];
|
||||
}
|
||||
|
||||
if (status == TStatus::EOnDisk && options == TMapOptions::EMapOnly)
|
||||
{
|
||||
NSString * size = [self formattedMapSize:[self selectedMapSizeWithOptions:TMapOptions::ECarRouting]];
|
||||
NSString * title = [NSString stringWithFormat:@"%@, %@", L(@"downloader_download_routing"), size];
|
||||
[self addButtonWithTitle:title action:DownloaderActionDownloadCarRouting toActionSheet:actionSheet];
|
||||
}
|
||||
|
||||
if (status == TStatus::EOnDiskOutOfDate && options == TMapOptions::EMapOnly)
|
||||
{
|
||||
NSString * size = [self formattedMapSize:[self selectedMapSizeWithOptions:TMapOptions::EMapOnly]];
|
||||
NSString * title = [NSString stringWithFormat:@"%@, %@", L(@"downloader_update_map"), size];
|
||||
[self addButtonWithTitle:title action:DownloaderActionDownloadMap toActionSheet:actionSheet];
|
||||
}
|
||||
|
||||
if (status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate)
|
||||
{
|
||||
if (options == TMapOptions::EMapWithCarRouting)
|
||||
[self addButtonWithTitle:L(@"downloader_delete_routing") action:DownloaderActionDeleteCarRouting toActionSheet:actionSheet];
|
||||
|
||||
[self addButtonWithTitle:L(@"downloader_delete_map") action:DownloaderActionDeleteMap toActionSheet:actionSheet];
|
||||
actionSheet.destructiveButtonIndex = actionSheet.numberOfButtons - 1;
|
||||
}
|
||||
|
||||
if (status == TStatus::EDownloading)
|
||||
{
|
||||
[self addButtonWithTitle:L(@"cancel_download") action:DownloaderActionCancelDownloading toActionSheet:actionSheet];
|
||||
actionSheet.destructiveButtonIndex = actionSheet.numberOfButtons - 1;
|
||||
}
|
||||
|
||||
if (!IPAD)
|
||||
{
|
||||
[actionSheet addButtonWithTitle:L(@"cancel")];
|
||||
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1;
|
||||
}
|
||||
|
||||
return actionSheet;
|
||||
}
|
||||
|
||||
- (UIActionSheet *)actionSheetToDeleteSelectedMap
|
||||
{
|
||||
[self.actionSheetActions removeAllObjects];
|
||||
self.actionSheetActions[@0] = @(DownloaderActionDeleteAll);
|
||||
|
||||
return [[UIActionSheet alloc] initWithTitle:[self actionSheetTitle] delegate:self cancelButtonTitle:L(@"cancel") destructiveButtonTitle:L(@"downloader_delete_map") otherButtonTitles:nil];
|
||||
}
|
||||
|
||||
- (UIActionSheet *)actionSheetToCancelDownloadingSelectedMap
|
||||
{
|
||||
[self.actionSheetActions removeAllObjects];
|
||||
self.actionSheetActions[@0] = @(DownloaderActionCancelDownloading);
|
||||
|
||||
return [[UIActionSheet alloc] initWithTitle:[self actionSheetTitle] delegate:self cancelButtonTitle:L(@"cancel") destructiveButtonTitle:L(@"cancel_download") otherButtonTitles:nil];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString *)actionSheetTitle
|
||||
{
|
||||
if ([self parentTitle])
|
||||
return [NSString stringWithFormat:@"%@, %@", [self selectedMapName].uppercaseString, [self parentTitle].uppercaseString];
|
||||
else
|
||||
return [self selectedMapName].uppercaseString;
|
||||
}
|
||||
|
||||
- (void)addButtonWithTitle:(NSString *)title action:(DownloaderAction)action toActionSheet:(UIActionSheet *)actionSheet
|
||||
{
|
||||
[actionSheet addButtonWithTitle:title];
|
||||
self.actionSheetActions[@(actionSheet.numberOfButtons - 1)] = @(action);
|
||||
}
|
||||
|
||||
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex != actionSheet.cancelButtonIndex)
|
||||
{
|
||||
DownloaderAction const action = (DownloaderAction)[self.actionSheetActions[@(buttonIndex)] integerValue];
|
||||
switch (action)
|
||||
{
|
||||
case DownloaderActionDownloadAll:
|
||||
case DownloaderActionDeleteAll:
|
||||
self.selectedInActionSheetOptions = TMapOptions::EMapWithCarRouting;
|
||||
break;
|
||||
|
||||
case DownloaderActionDownloadMap:
|
||||
case DownloaderActionDeleteMap:
|
||||
self.selectedInActionSheetOptions = TMapOptions::EMapOnly;
|
||||
break;
|
||||
|
||||
case DownloaderActionDownloadCarRouting:
|
||||
case DownloaderActionDeleteCarRouting:
|
||||
self.selectedInActionSheetOptions = TMapOptions::ECarRouting;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[self performAction:action];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSMutableDictionary *)actionSheetActions
|
||||
{
|
||||
if (!_actionSheetActions)
|
||||
_actionSheetActions = [[NSMutableDictionary alloc] init];
|
||||
return _actionSheetActions;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
@end
|
22
iphone/Maps/Images.xcassets/Downloader/MapCellSeparator.imageset/Contents.json
vendored
Normal file
22
iphone/Maps/Images.xcassets/Downloader/MapCellSeparator.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "MapCellSeparator@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "MapCellSeparator@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
iphone/Maps/Images.xcassets/Downloader/MapCellSeparator.imageset/MapCellSeparator@2x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Downloader/MapCellSeparator.imageset/MapCellSeparator@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
iphone/Maps/Images.xcassets/Downloader/MapCellSeparator.imageset/MapCellSeparator@3x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Downloader/MapCellSeparator.imageset/MapCellSeparator@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
|
@ -3,25 +3,21 @@
|
|||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x",
|
||||
"filename" : "drive.png"
|
||||
"filename" : "ProgressTriangle.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "drive@2x.png"
|
||||
"filename" : "ProgressTriangle@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "drive@3x.png"
|
||||
"filename" : "ProgressTriangle@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
=======
|
||||
}
|
||||
>>>>>>> 56a28db... [ios] Downloader UI
|
||||
}
|
BIN
iphone/Maps/Images.xcassets/Downloader/ProgressTriangle.imageset/ProgressTriangle.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Downloader/ProgressTriangle.imageset/ProgressTriangle.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 276 B |
BIN
iphone/Maps/Images.xcassets/Downloader/ProgressTriangle.imageset/ProgressTriangle@2x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Downloader/ProgressTriangle.imageset/ProgressTriangle@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 512 B |
BIN
iphone/Maps/Images.xcassets/Downloader/ProgressTriangle.imageset/ProgressTriangle@3x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Downloader/ProgressTriangle.imageset/ProgressTriangle@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 752 B |
|
@ -23,8 +23,8 @@
|
|||
974386DA1934CBAD00FD5659 /* FacebookSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 974386D81934CBAC00FD5659 /* FacebookSDK.framework */; };
|
||||
974386DD19373EA400FD5659 /* ToastView.m in Sources */ = {isa = PBXBuildFile; fileRef = 974386DC19373EA400FD5659 /* ToastView.m */; };
|
||||
974386DE19373EA400FD5659 /* ToastView.m in Sources */ = {isa = PBXBuildFile; fileRef = 974386DC19373EA400FD5659 /* ToastView.m */; };
|
||||
9746492718EEE2F8004B4658 /* ToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9746492618EEE2F8004B4658 /* ToolbarView.m */; };
|
||||
9746492818EEE2F8004B4658 /* ToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9746492618EEE2F8004B4658 /* ToolbarView.m */; };
|
||||
9746492718EEE2F8004B4658 /* ToolbarView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9746492618EEE2F8004B4658 /* ToolbarView.mm */; };
|
||||
9746492818EEE2F8004B4658 /* ToolbarView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9746492618EEE2F8004B4658 /* ToolbarView.mm */; };
|
||||
9747264318323080006B7CB7 /* UIKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 9747264118323080006B7CB7 /* UIKitCategories.m */; };
|
||||
9747264418323080006B7CB7 /* UIKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 9747264118323080006B7CB7 /* UIKitCategories.m */; };
|
||||
9747278418338F0C006B7CB7 /* UIViewController+Navigation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9747278318338F0C006B7CB7 /* UIViewController+Navigation.m */; };
|
||||
|
@ -47,6 +47,10 @@
|
|||
9767702519B718D800402693 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 9767701D19B718D700402693 /* LICENSE */; };
|
||||
9769D6EF1912BF3000CA6158 /* ContainerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9769D6EE1912BF3000CA6158 /* ContainerView.mm */; };
|
||||
9769D6F01912BF3000CA6158 /* ContainerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9769D6EE1912BF3000CA6158 /* ContainerView.mm */; };
|
||||
976D86EC19C8697700C920EF /* ProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 976D86EB19C8697700C920EF /* ProgressView.m */; };
|
||||
976D86ED19C8697700C920EF /* ProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 976D86EB19C8697700C920EF /* ProgressView.m */; };
|
||||
976D86F119C877E600C920EF /* MapCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 976D86F019C877E600C920EF /* MapCell.mm */; };
|
||||
976D86F219C877E600C920EF /* MapCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 976D86F019C877E600C920EF /* MapCell.mm */; };
|
||||
976D86F519CB21BD00C920EF /* RouteView.m in Sources */ = {isa = PBXBuildFile; fileRef = 976D86F419CB21BD00C920EF /* RouteView.m */; };
|
||||
976D86F619CB21BD00C920EF /* RouteView.m in Sources */ = {isa = PBXBuildFile; fileRef = 976D86F419CB21BD00C920EF /* RouteView.m */; };
|
||||
97719D451843B6DC00BDD815 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97719D441843B6DC00BDD815 /* MessageUI.framework */; };
|
||||
|
@ -63,6 +67,14 @@
|
|||
9778E9A2191A663700AD850A /* BookmarkNameVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9778E9A0191A663700AD850A /* BookmarkNameVC.mm */; };
|
||||
9778E9A5191A86D800AD850A /* SelectedColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9778E9A4191A86D800AD850A /* SelectedColorView.m */; };
|
||||
9778E9A6191A86D800AD850A /* SelectedColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9778E9A4191A86D800AD850A /* SelectedColorView.m */; };
|
||||
977E26B919E2E64200BA2219 /* MapsObservers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26B819E2E64200BA2219 /* MapsObservers.mm */; };
|
||||
977E26BA19E2E64200BA2219 /* MapsObservers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26B819E2E64200BA2219 /* MapsObservers.mm */; };
|
||||
977E26BE19E31BBE00BA2219 /* CountryTreeVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26BD19E31BBE00BA2219 /* CountryTreeVC.mm */; };
|
||||
977E26BF19E31BBE00BA2219 /* CountryTreeVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26BD19E31BBE00BA2219 /* CountryTreeVC.mm */; };
|
||||
977E26C219E31BCC00BA2219 /* ActiveMapsVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26C119E31BCC00BA2219 /* ActiveMapsVC.mm */; };
|
||||
977E26C319E31BCC00BA2219 /* ActiveMapsVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26C119E31BCC00BA2219 /* ActiveMapsVC.mm */; };
|
||||
977E26C619E31BDF00BA2219 /* DownloaderParentVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26C519E31BDF00BA2219 /* DownloaderParentVC.mm */; };
|
||||
977E26C719E31BDF00BA2219 /* DownloaderParentVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 977E26C519E31BDF00BA2219 /* DownloaderParentVC.mm */; };
|
||||
9789DB56188D5E2A007C6FAE /* InAppMessagesManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9789DB55188D5E2A007C6FAE /* InAppMessagesManager.mm */; };
|
||||
9789DB57188D5E2A007C6FAE /* InAppMessagesManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9789DB55188D5E2A007C6FAE /* InAppMessagesManager.mm */; };
|
||||
9789DB5A188D94F9007C6FAE /* InterstitialView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9789DB59188D94F9007C6FAE /* InterstitialView.mm */; };
|
||||
|
@ -89,8 +101,8 @@
|
|||
97908B31196591FB003DD7C6 /* SearchShowOnMapCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97908B2F196591F7003DD7C6 /* SearchShowOnMapCell.m */; };
|
||||
97A0EEFA192F3B43009B2779 /* BottomMenu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A0EEF7192F3B43009B2779 /* BottomMenu.mm */; };
|
||||
97A0EEFB192F3B43009B2779 /* BottomMenu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A0EEF7192F3B43009B2779 /* BottomMenu.mm */; };
|
||||
97A0EEFC192F3B43009B2779 /* BottomMenuCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A0EEF9192F3B43009B2779 /* BottomMenuCell.m */; };
|
||||
97A0EEFD192F3B43009B2779 /* BottomMenuCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A0EEF9192F3B43009B2779 /* BottomMenuCell.m */; };
|
||||
97A0EEFC192F3B43009B2779 /* BottomMenuCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A0EEF9192F3B43009B2779 /* BottomMenuCell.mm */; };
|
||||
97A0EEFD192F3B43009B2779 /* BottomMenuCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A0EEF9192F3B43009B2779 /* BottomMenuCell.mm */; };
|
||||
97A5967F19B9CD47007A963F /* copyright.html in Resources */ = {isa = PBXBuildFile; fileRef = 97A5967E19B9CD47007A963F /* copyright.html */; };
|
||||
97A5968019B9CD47007A963F /* copyright.html in Resources */ = {isa = PBXBuildFile; fileRef = 97A5967E19B9CD47007A963F /* copyright.html */; };
|
||||
97A8000C18B21363000C07A2 /* SearchView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000B18B21363000C07A2 /* SearchView.mm */; };
|
||||
|
@ -151,6 +163,8 @@
|
|||
97ECD881183674CA00F77A46 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97ECD87718362B3D00F77A46 /* CoreTelephony.framework */; };
|
||||
97ECD8821836751100F77A46 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97ECD87918362B5400F77A46 /* MobileCoreServices.framework */; };
|
||||
97EDDCE518A299C000AEFB7A /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97EDDCE418A299C000AEFB7A /* Twitter.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
97F0817E19AF72590098FB0B /* BadgeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 97F0817D19AF72590098FB0B /* BadgeView.m */; };
|
||||
97F0817F19AF72590098FB0B /* BadgeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 97F0817D19AF72590098FB0B /* BadgeView.m */; };
|
||||
97F61781183E6172009919E2 /* LocationButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97F6177F183E6172009919E2 /* LocationButton.mm */; };
|
||||
97F61782183E6172009919E2 /* LocationButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97F6177F183E6172009919E2 /* LocationButton.mm */; };
|
||||
97F61794183E7445009919E2 /* LinkCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97F61793183E7445009919E2 /* LinkCell.m */; };
|
||||
|
@ -238,8 +252,6 @@
|
|||
FA34BECA1338D72F00FFB2A7 /* CustomAlertView.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA34BEC81338D72F00FFB2A7 /* CustomAlertView.mm */; };
|
||||
FA36B80D15403A4F004560CC /* BookmarksVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA36B80615403A4F004560CC /* BookmarksVC.mm */; };
|
||||
FA36B80E15403A4F004560CC /* BookmarksVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA36B80615403A4F004560CC /* BookmarksVC.mm */; };
|
||||
FA4135EA120A263C0062D5B4 /* CountriesViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA4135E2120A263C0062D5B4 /* CountriesViewController.mm */; };
|
||||
FA4135ED120A263C0062D5B4 /* SettingsManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA4135E7120A263C0062D5B4 /* SettingsManager.mm */; };
|
||||
FA459EB414327AF700B5BB3C /* WorldCoasts.mwm in Resources */ = {isa = PBXBuildFile; fileRef = FA459EB314327AF700B5BB3C /* WorldCoasts.mwm */; };
|
||||
FA46DA2C12D4166E00968C36 /* countries.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA46DA2B12D4166E00968C36 /* countries.txt */; };
|
||||
FA64D9A913F975AD00350ECF /* types.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA64D9A813F975AD00350ECF /* types.txt */; };
|
||||
|
@ -1297,8 +1309,6 @@
|
|||
FAFB08EA151215EE0041901D /* MapsAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* MapsAppDelegate.mm */; };
|
||||
FAFB08EB151215EE0041901D /* EAGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46F26CD710F623BA00ECCA39 /* EAGLView.mm */; };
|
||||
FAFB08EC151215EE0041901D /* MapViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = EED10A4411F78D120095FAD4 /* MapViewController.mm */; };
|
||||
FAFB08ED151215EE0041901D /* CountriesViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA4135E2120A263C0062D5B4 /* CountriesViewController.mm */; };
|
||||
FAFB08EE151215EE0041901D /* SettingsManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA4135E7120A263C0062D5B4 /* SettingsManager.mm */; };
|
||||
FAFB08EF151215EE0041901D /* RenderBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = EE7F297D1219ECA300EB67A9 /* RenderBuffer.mm */; };
|
||||
FAFB08F0151215EE0041901D /* RenderContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = EE7F297E1219ECA300EB67A9 /* RenderContext.mm */; };
|
||||
FAFB08F1151215EE0041901D /* WebViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAFCB63513366E78001A5C59 /* WebViewController.mm */; };
|
||||
|
@ -1345,7 +1355,7 @@
|
|||
974386DB19373EA400FD5659 /* ToastView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToastView.h; sourceTree = "<group>"; };
|
||||
974386DC19373EA400FD5659 /* ToastView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ToastView.m; sourceTree = "<group>"; };
|
||||
9746492518EEE2F8004B4658 /* ToolbarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToolbarView.h; sourceTree = "<group>"; };
|
||||
9746492618EEE2F8004B4658 /* ToolbarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ToolbarView.m; sourceTree = "<group>"; };
|
||||
9746492618EEE2F8004B4658 /* ToolbarView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ToolbarView.mm; sourceTree = "<group>"; };
|
||||
9747264118323080006B7CB7 /* UIKitCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UIKitCategories.m; path = Categories/UIKitCategories.m; sourceTree = "<group>"; };
|
||||
9747264218323080006B7CB7 /* UIKitCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UIKitCategories.h; path = Categories/UIKitCategories.h; sourceTree = "<group>"; };
|
||||
9747278218338F0C006B7CB7 /* UIViewController+Navigation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Navigation.h"; path = "Classes/UIViewController+Navigation.h"; sourceTree = "<group>"; };
|
||||
|
@ -1365,6 +1375,10 @@
|
|||
9767701F19B718D700402693 /* LocalyticsSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalyticsSession.h; sourceTree = "<group>"; };
|
||||
9769D6ED1912BF3000CA6158 /* ContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerView.h; sourceTree = "<group>"; };
|
||||
9769D6EE1912BF3000CA6158 /* ContainerView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContainerView.mm; sourceTree = "<group>"; };
|
||||
976D86EA19C8697700C920EF /* ProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressView.h; path = Classes/ProgressView.h; sourceTree = "<group>"; };
|
||||
976D86EB19C8697700C920EF /* ProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressView.m; path = Classes/ProgressView.m; sourceTree = "<group>"; };
|
||||
976D86EF19C877E600C920EF /* MapCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapCell.h; path = Classes/MapCell.h; sourceTree = "<group>"; };
|
||||
976D86F019C877E600C920EF /* MapCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MapCell.mm; path = Classes/MapCell.mm; sourceTree = "<group>"; };
|
||||
976D86F319CB21BD00C920EF /* RouteView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RouteView.h; sourceTree = "<group>"; };
|
||||
976D86F419CB21BD00C920EF /* RouteView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RouteView.m; sourceTree = "<group>"; };
|
||||
97719D441843B6DC00BDD815 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
|
||||
|
@ -1378,6 +1392,14 @@
|
|||
9778E9A0191A663700AD850A /* BookmarkNameVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BookmarkNameVC.mm; sourceTree = "<group>"; };
|
||||
9778E9A3191A86D800AD850A /* SelectedColorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectedColorView.h; sourceTree = "<group>"; };
|
||||
9778E9A4191A86D800AD850A /* SelectedColorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectedColorView.m; sourceTree = "<group>"; };
|
||||
977E26B819E2E64200BA2219 /* MapsObservers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MapsObservers.mm; path = Classes/MapsObservers.mm; sourceTree = "<group>"; };
|
||||
977E26BB19E2E65E00BA2219 /* MapsObservers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapsObservers.h; path = Classes/MapsObservers.h; sourceTree = "<group>"; };
|
||||
977E26BC19E31BBE00BA2219 /* CountryTreeVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountryTreeVC.h; sourceTree = "<group>"; };
|
||||
977E26BD19E31BBE00BA2219 /* CountryTreeVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CountryTreeVC.mm; sourceTree = "<group>"; };
|
||||
977E26C019E31BCC00BA2219 /* ActiveMapsVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveMapsVC.h; sourceTree = "<group>"; };
|
||||
977E26C119E31BCC00BA2219 /* ActiveMapsVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ActiveMapsVC.mm; sourceTree = "<group>"; };
|
||||
977E26C419E31BDF00BA2219 /* DownloaderParentVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloaderParentVC.h; sourceTree = "<group>"; };
|
||||
977E26C519E31BDF00BA2219 /* DownloaderParentVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DownloaderParentVC.mm; sourceTree = "<group>"; };
|
||||
9789DB54188D5E2A007C6FAE /* InAppMessagesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppMessagesManager.h; sourceTree = "<group>"; };
|
||||
9789DB55188D5E2A007C6FAE /* InAppMessagesManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InAppMessagesManager.mm; sourceTree = "<group>"; };
|
||||
9789DB58188D94F9007C6FAE /* InterstitialView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterstitialView.h; sourceTree = "<group>"; };
|
||||
|
@ -1403,7 +1425,7 @@
|
|||
97A0EEF6192F3B43009B2779 /* BottomMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BottomMenu.h; sourceTree = "<group>"; };
|
||||
97A0EEF7192F3B43009B2779 /* BottomMenu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BottomMenu.mm; sourceTree = "<group>"; };
|
||||
97A0EEF8192F3B43009B2779 /* BottomMenuCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BottomMenuCell.h; sourceTree = "<group>"; };
|
||||
97A0EEF9192F3B43009B2779 /* BottomMenuCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BottomMenuCell.m; sourceTree = "<group>"; };
|
||||
97A0EEF9192F3B43009B2779 /* BottomMenuCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BottomMenuCell.mm; sourceTree = "<group>"; };
|
||||
97A5967E19B9CD47007A963F /* copyright.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = copyright.html; path = ../../data/copyright.html; sourceTree = "<group>"; };
|
||||
97A8000A18B21363000C07A2 /* SearchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchView.h; sourceTree = "<group>"; };
|
||||
97A8000B18B21363000C07A2 /* SearchView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchView.mm; sourceTree = "<group>"; };
|
||||
|
@ -1458,6 +1480,8 @@
|
|||
97ECD87918362B5400F77A46 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||
97ECD87E1836594400F77A46 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
97EDDCE418A299C000AEFB7A /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; };
|
||||
97F0817C19AF72590098FB0B /* BadgeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BadgeView.h; path = Classes/BadgeView.h; sourceTree = "<group>"; };
|
||||
97F0817D19AF72590098FB0B /* BadgeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BadgeView.m; path = Classes/BadgeView.m; sourceTree = "<group>"; };
|
||||
97F6177F183E6172009919E2 /* LocationButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocationButton.mm; sourceTree = "<group>"; };
|
||||
97F61780183E6172009919E2 /* LocationButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocationButton.h; sourceTree = "<group>"; };
|
||||
97F6178F183E742E009919E2 /* LinkCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LinkCell.h; path = Settings/LinkCell.h; sourceTree = "<group>"; };
|
||||
|
@ -1557,10 +1581,6 @@
|
|||
FA34BEC91338D72F00FFB2A7 /* CustomAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomAlertView.h; sourceTree = "<group>"; };
|
||||
FA36B80515403A4F004560CC /* BookmarksVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BookmarksVC.h; path = Bookmarks/BookmarksVC.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
FA36B80615403A4F004560CC /* BookmarksVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = BookmarksVC.mm; path = Bookmarks/BookmarksVC.mm; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
FA4135E1120A263C0062D5B4 /* CountriesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = CountriesViewController.h; path = Settings/CountriesViewController.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
FA4135E2120A263C0062D5B4 /* CountriesViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = CountriesViewController.mm; path = Settings/CountriesViewController.mm; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
FA4135E6120A263C0062D5B4 /* SettingsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SettingsManager.h; path = Settings/SettingsManager.h; sourceTree = SOURCE_ROOT; };
|
||||
FA4135E7120A263C0062D5B4 /* SettingsManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = SettingsManager.mm; path = Settings/SettingsManager.mm; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
FA459EB314327AF700B5BB3C /* WorldCoasts.mwm */ = {isa = PBXFileReference; lastKnownFileType = file; name = WorldCoasts.mwm; path = ../../data/WorldCoasts.mwm; sourceTree = "<group>"; };
|
||||
FA46DA2B12D4166E00968C36 /* countries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = countries.txt; path = ../../data/countries.txt; sourceTree = SOURCE_ROOT; };
|
||||
FA5940D2171C964D0045C9BB /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
|
@ -2224,6 +2244,7 @@
|
|||
CB252D6816FF82C8001E41E9 /* Statistics */,
|
||||
FA36B8011540388B004560CC /* Bookmarks */,
|
||||
FA34BEC71338D6DB00FFB2A7 /* Common */,
|
||||
976D86EE19C8777500C920EF /* Downloader */,
|
||||
97354B6B196EDCE200352536 /* Login & sharing */,
|
||||
FA6E1F1B124E6B2800F59149 /* Platform */,
|
||||
080E96DDFE201D6D7F000001 /* Classes */,
|
||||
|
@ -2334,6 +2355,27 @@
|
|||
path = Localitycs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
976D86EE19C8777500C920EF /* Downloader */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97F0817C19AF72590098FB0B /* BadgeView.h */,
|
||||
97F0817D19AF72590098FB0B /* BadgeView.m */,
|
||||
976D86EA19C8697700C920EF /* ProgressView.h */,
|
||||
976D86EB19C8697700C920EF /* ProgressView.m */,
|
||||
976D86EF19C877E600C920EF /* MapCell.h */,
|
||||
976D86F019C877E600C920EF /* MapCell.mm */,
|
||||
977E26BB19E2E65E00BA2219 /* MapsObservers.h */,
|
||||
977E26B819E2E64200BA2219 /* MapsObservers.mm */,
|
||||
977E26C419E31BDF00BA2219 /* DownloaderParentVC.h */,
|
||||
977E26C519E31BDF00BA2219 /* DownloaderParentVC.mm */,
|
||||
977E26BC19E31BBE00BA2219 /* CountryTreeVC.h */,
|
||||
977E26BD19E31BBE00BA2219 /* CountryTreeVC.mm */,
|
||||
977E26C019E31BCC00BA2219 /* ActiveMapsVC.h */,
|
||||
977E26C119E31BCC00BA2219 /* ActiveMapsVC.mm */,
|
||||
);
|
||||
name = Downloader;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9770A04618AD19D300126E5C /* More Apps */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -2375,7 +2417,7 @@
|
|||
97A0EEF6192F3B43009B2779 /* BottomMenu.h */,
|
||||
97A0EEF7192F3B43009B2779 /* BottomMenu.mm */,
|
||||
97A0EEF8192F3B43009B2779 /* BottomMenuCell.h */,
|
||||
97A0EEF9192F3B43009B2779 /* BottomMenuCell.m */,
|
||||
97A0EEF9192F3B43009B2779 /* BottomMenuCell.mm */,
|
||||
9750841D199501F100A7457D /* ImageDownloader.h */,
|
||||
9750841E199501F100A7457D /* ImageDownloader.m */,
|
||||
);
|
||||
|
@ -2410,7 +2452,7 @@
|
|||
97D092AD190A67CA00FF645B /* Place Page */,
|
||||
97A8000918B210DC000C07A2 /* Search */,
|
||||
9746492518EEE2F8004B4658 /* ToolbarView.h */,
|
||||
9746492618EEE2F8004B4658 /* ToolbarView.m */,
|
||||
9746492618EEE2F8004B4658 /* ToolbarView.mm */,
|
||||
976D86F319CB21BD00C920EF /* RouteView.h */,
|
||||
976D86F419CB21BD00C920EF /* RouteView.m */,
|
||||
974386DB19373EA400FD5659 /* ToastView.h */,
|
||||
|
@ -2603,10 +2645,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
978F924D183BB5D6000D6C7C /* Cells */,
|
||||
FA4135E1120A263C0062D5B4 /* CountriesViewController.h */,
|
||||
FA4135E2120A263C0062D5B4 /* CountriesViewController.mm */,
|
||||
FA4135E6120A263C0062D5B4 /* SettingsManager.h */,
|
||||
FA4135E7120A263C0062D5B4 /* SettingsManager.mm */,
|
||||
978F923F183B660F000D6C7C /* SettingsViewController.h */,
|
||||
978F9239183B660F000D6C7C /* SettingsViewController.mm */,
|
||||
97508421199522D300A7457D /* SettingsAndMoreVC.h */,
|
||||
|
@ -4469,26 +4507,29 @@
|
|||
978D4A291996C17300D72CA7 /* RichTextVC.m in Sources */,
|
||||
9747278418338F0C006B7CB7 /* UIViewController+Navigation.m in Sources */,
|
||||
97908B30196591F7003DD7C6 /* SearchShowOnMapCell.m in Sources */,
|
||||
976D86F119C877E600C920EF /* MapCell.mm in Sources */,
|
||||
977E26C219E31BCC00BA2219 /* ActiveMapsVC.mm in Sources */,
|
||||
1D3623260D0F684500981E51 /* MapsAppDelegate.mm in Sources */,
|
||||
9746492718EEE2F8004B4658 /* ToolbarView.m in Sources */,
|
||||
9746492718EEE2F8004B4658 /* ToolbarView.mm in Sources */,
|
||||
46F26CD810F623BA00ECCA39 /* EAGLView.mm in Sources */,
|
||||
EED10A4511F78D120095FAD4 /* MapViewController.mm in Sources */,
|
||||
FA4135EA120A263C0062D5B4 /* CountriesViewController.mm in Sources */,
|
||||
FA4135ED120A263C0062D5B4 /* SettingsManager.mm in Sources */,
|
||||
EE7F29811219ECA300EB67A9 /* RenderBuffer.mm in Sources */,
|
||||
97D092B5190A6E1D00FF645B /* PlacePageEditCell.mm in Sources */,
|
||||
9750841F199501F100A7457D /* ImageDownloader.m in Sources */,
|
||||
978F9253183BD530000D6C7C /* NavigationController.mm in Sources */,
|
||||
974386DD19373EA400FD5659 /* ToastView.m in Sources */,
|
||||
97C9851E186AE3C500AF7E9E /* Reachability.m in Sources */,
|
||||
977E26B919E2E64200BA2219 /* MapsObservers.mm in Sources */,
|
||||
EE7F29821219ECA300EB67A9 /* RenderContext.mm in Sources */,
|
||||
FAFCB63613366E78001A5C59 /* WebViewController.mm in Sources */,
|
||||
FA34BECA1338D72F00FFB2A7 /* CustomAlertView.mm in Sources */,
|
||||
97F61781183E6172009919E2 /* LocationButton.mm in Sources */,
|
||||
9747264318323080006B7CB7 /* UIKitCategories.m in Sources */,
|
||||
97A0EEFC192F3B43009B2779 /* BottomMenuCell.m in Sources */,
|
||||
977E26BE19E31BBE00BA2219 /* CountryTreeVC.mm in Sources */,
|
||||
97A0EEFC192F3B43009B2779 /* BottomMenuCell.mm in Sources */,
|
||||
97D092B9190AA69700FF645B /* SmallCompassView.mm in Sources */,
|
||||
97A8001418B2140A000C07A2 /* SearchResultCell.m in Sources */,
|
||||
97F0817E19AF72590098FB0B /* BadgeView.m in Sources */,
|
||||
97A8002718B2741C000C07A2 /* SearchCell.m in Sources */,
|
||||
97908B2C19658767003DD7C6 /* SearchCategoryCell.m in Sources */,
|
||||
9778E9A5191A86D800AD850A /* SelectedColorView.m in Sources */,
|
||||
|
@ -4509,6 +4550,7 @@
|
|||
97CC93BB19599F4700369B42 /* SearchSuggestCell.m in Sources */,
|
||||
FA054612155C465E001F4E37 /* SelectSetVC.mm in Sources */,
|
||||
FAA614B8155F16950031C345 /* AddSetVC.mm in Sources */,
|
||||
977E26C619E31BDF00BA2219 /* DownloaderParentVC.mm in Sources */,
|
||||
FAAEA7D5161D8D3100CCD661 /* BookmarksRootVC.mm in Sources */,
|
||||
F785EB4016386FC4003A38A8 /* BookmarkCell.mm in Sources */,
|
||||
9789DB56188D5E2A007C6FAE /* InAppMessagesManager.mm in Sources */,
|
||||
|
@ -4524,6 +4566,7 @@
|
|||
9773DB8F198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m in Sources */,
|
||||
97ABBA4518C8DF620079333C /* PlacePageView.mm in Sources */,
|
||||
97F61794183E7445009919E2 /* LinkCell.m in Sources */,
|
||||
976D86EC19C8697700C920EF /* ProgressView.m in Sources */,
|
||||
97D092B1190A681F00FF645B /* PlacePageInfoCell.mm in Sources */,
|
||||
97A8001018B21395000C07A2 /* SearchBar.mm in Sources */,
|
||||
EDC5C543175F2CA600420E92 /* ShareActionSheet.mm in Sources */,
|
||||
|
@ -4543,26 +4586,29 @@
|
|||
978D4A2A1996C17300D72CA7 /* RichTextVC.m in Sources */,
|
||||
FAFB08EA151215EE0041901D /* MapsAppDelegate.mm in Sources */,
|
||||
97908B31196591FB003DD7C6 /* SearchShowOnMapCell.m in Sources */,
|
||||
976D86F219C877E600C920EF /* MapCell.mm in Sources */,
|
||||
977E26C319E31BCC00BA2219 /* ActiveMapsVC.mm in Sources */,
|
||||
FAFB08EB151215EE0041901D /* EAGLView.mm in Sources */,
|
||||
97A8001118B21395000C07A2 /* SearchBar.mm in Sources */,
|
||||
FAFB08EC151215EE0041901D /* MapViewController.mm in Sources */,
|
||||
FAFB08ED151215EE0041901D /* CountriesViewController.mm in Sources */,
|
||||
FAFB08EE151215EE0041901D /* SettingsManager.mm in Sources */,
|
||||
FAFB08EF151215EE0041901D /* RenderBuffer.mm in Sources */,
|
||||
97DEA09718D75BB000C5F963 /* ContextViews.mm in Sources */,
|
||||
978F9254183BD530000D6C7C /* NavigationController.mm in Sources */,
|
||||
97508420199501F100A7457D /* ImageDownloader.m in Sources */,
|
||||
97A0EEFD192F3B43009B2779 /* BottomMenuCell.m in Sources */,
|
||||
97A0EEFD192F3B43009B2779 /* BottomMenuCell.mm in Sources */,
|
||||
97C9851F186AE3C500AF7E9E /* Reachability.m in Sources */,
|
||||
97ABBA4618C8DF620079333C /* PlacePageView.mm in Sources */,
|
||||
977E26BA19E2E64200BA2219 /* MapsObservers.mm in Sources */,
|
||||
9789DB5B188D94F9007C6FAE /* InterstitialView.mm in Sources */,
|
||||
FAFB08F0151215EE0041901D /* RenderContext.mm in Sources */,
|
||||
FAFB08F1151215EE0041901D /* WebViewController.mm in Sources */,
|
||||
9769D6F01912BF3000CA6158 /* ContainerView.mm in Sources */,
|
||||
FAFB08F2151215EE0041901D /* CustomAlertView.mm in Sources */,
|
||||
977E26BF19E31BBE00BA2219 /* CountryTreeVC.mm in Sources */,
|
||||
97F61782183E6172009919E2 /* LocationButton.mm in Sources */,
|
||||
9747264418323080006B7CB7 /* UIKitCategories.m in Sources */,
|
||||
FAFB08F5151215EE0041901D /* Preferences.mm in Sources */,
|
||||
97F0817F19AF72590098FB0B /* BadgeView.m in Sources */,
|
||||
97D807BD18A933FB00D416E0 /* MoreAppsCell.m in Sources */,
|
||||
97908B2D1965876C003DD7C6 /* SearchCategoryCell.m in Sources */,
|
||||
FAFB08F6151215EE0041901D /* LocationManager.mm in Sources */,
|
||||
|
@ -4583,6 +4629,7 @@
|
|||
97CC93BC19599F4700369B42 /* SearchSuggestCell.m in Sources */,
|
||||
FAA614B9155F16950031C345 /* AddSetVC.mm in Sources */,
|
||||
FAAEA7D6161D8D3100CCD661 /* BookmarksRootVC.mm in Sources */,
|
||||
977E26C719E31BDF00BA2219 /* DownloaderParentVC.mm in Sources */,
|
||||
97D092B6190A6E1D00FF645B /* PlacePageEditCell.mm in Sources */,
|
||||
F785EB4116386FC4003A38A8 /* BookmarkCell.mm in Sources */,
|
||||
97C98523186AE3CF00AF7E9E /* AppInfo.mm in Sources */,
|
||||
|
@ -4598,11 +4645,12 @@
|
|||
9773DB90198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m in Sources */,
|
||||
97F61795183E7445009919E2 /* LinkCell.m in Sources */,
|
||||
EDC5C544175F2CA600420E92 /* ShareActionSheet.mm in Sources */,
|
||||
976D86ED19C8697700C920EF /* ProgressView.m in Sources */,
|
||||
9778E9A6191A86D800AD850A /* SelectedColorView.m in Sources */,
|
||||
97A8000D18B21363000C07A2 /* SearchView.mm in Sources */,
|
||||
ED48BBBB17C2B1E2003E7E92 /* CircleView.mm in Sources */,
|
||||
97D092B2190A681F00FF645B /* PlacePageInfoCell.mm in Sources */,
|
||||
9746492818EEE2F8004B4658 /* ToolbarView.m in Sources */,
|
||||
9746492818EEE2F8004B4658 /* ToolbarView.mm in Sources */,
|
||||
ED48BBC417C3B3BF003E7E92 /* ColorPickerView.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include "../../../storage/storage.hpp"
|
||||
|
||||
@interface CountriesViewController
|
||||
: UIViewController <UINavigationBarDelegate, UITableViewDelegate, UITableViewDataSource,
|
||||
UIActionSheetDelegate, UIAlertViewDelegate>
|
||||
{
|
||||
storage::TIndex m_index;
|
||||
|
||||
/// Params for using self as delegate in confirmations.
|
||||
storage::TStatus m_countryStatus;
|
||||
storage::TIndex m_clickedIndex;
|
||||
uint64_t m_downloadSize;
|
||||
UITableViewCell * m_clickedCell;
|
||||
}
|
||||
|
||||
- (id)initWithIndex:(storage::TIndex const &)index andHeader:(NSString *)header;
|
||||
|
||||
- (void)OnCountryChange:(storage::TIndex const &)index;
|
||||
- (void)OnDownload:(storage::TIndex const &)index withProgress:(pair<int64_t, int64_t> const &)progress;
|
||||
- (void)TryDownloadCountry;
|
||||
|
||||
@end
|
|
@ -1,499 +0,0 @@
|
|||
#import "CountriesViewController.h"
|
||||
#import "SettingsManager.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "MapViewController.h"
|
||||
#import "WebViewController.h"
|
||||
#import "CustomAlertView.h"
|
||||
#import "DiskFreeSpace.h"
|
||||
#import "Statistics.h"
|
||||
#import "Reachability.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "../../storage/storage_defines.hpp"
|
||||
|
||||
#include "../../platform/platform.hpp"
|
||||
#include "../../platform/preferred_languages.hpp"
|
||||
|
||||
|
||||
#define MAX_3G_MEGABYTES (50)
|
||||
#define MB (1024*1024)
|
||||
#define BAG_TAG 664
|
||||
|
||||
|
||||
using namespace storage;
|
||||
|
||||
static TIndex CalculateIndex(TIndex const & parentIndex, NSIndexPath * indexPath)
|
||||
{
|
||||
TIndex index = parentIndex;
|
||||
if (index.m_group == TIndex::INVALID)
|
||||
index.m_group = indexPath.row;
|
||||
else if (index.m_country == TIndex::INVALID)
|
||||
index.m_country = indexPath.row;
|
||||
else
|
||||
index.m_region = indexPath.row;
|
||||
return index;
|
||||
}
|
||||
|
||||
static NSInteger RowFromIndex(TIndex const & index)
|
||||
{
|
||||
if (index.m_region != TIndex::INVALID)
|
||||
return index.m_region;
|
||||
else if (index.m_country != TIndex::INVALID)
|
||||
return index.m_country;
|
||||
else
|
||||
return index.m_group;
|
||||
}
|
||||
|
||||
static bool IsOurIndex(TIndex const & theirs, TIndex const & ours)
|
||||
{
|
||||
TIndex theirsFixed = theirs;
|
||||
if (theirsFixed.m_region != -1)
|
||||
theirsFixed.m_region = -1;
|
||||
else if (theirsFixed.m_country != -1)
|
||||
theirsFixed.m_country = -1;
|
||||
else
|
||||
theirsFixed.m_group = -1;
|
||||
return ours == theirsFixed;
|
||||
}
|
||||
|
||||
static bool getGuideName(string & name, TIndex const & index)
|
||||
{
|
||||
guides::GuideInfo info;
|
||||
Framework & f = GetFramework();
|
||||
if ((f.Storage().CountriesCount(index) == 0) && f.GetGuideInfo(index, info))
|
||||
{
|
||||
string const lang = languages::GetCurrentNorm();
|
||||
name = info.GetAdTitle(lang);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@implementation CountriesViewController
|
||||
|
||||
- (void)onCloseButton:(id)sender
|
||||
{
|
||||
[[[MapsAppDelegate theApp] settingsManager] hide];
|
||||
}
|
||||
|
||||
- (id)initWithIndex:(TIndex const &)index andHeader:(NSString *)header
|
||||
{
|
||||
m_index = index;
|
||||
if ((self = [super initWithNibName:nil bundle:nil]))
|
||||
{
|
||||
self.navigationItem.title = header;
|
||||
// Show Close button only on the first page
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
CGRect appRect = [UIScreen mainScreen].applicationFrame;
|
||||
UITableView * countriesTableView = [[UITableView alloc] initWithFrame:appRect style:UITableViewStylePlain];
|
||||
countriesTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
||||
countriesTableView.delegate = self;
|
||||
countriesTableView.dataSource = self;
|
||||
self.view = countriesTableView;
|
||||
}
|
||||
|
||||
// Override to allow orientations other than the default portrait orientation.
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
TIndex const index = CalculateIndex(m_index, indexPath);
|
||||
Framework & frm = GetFramework();
|
||||
|
||||
TStatus const status = frm.GetCountryStatus(index);
|
||||
if (status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate)
|
||||
{
|
||||
frm.ShowCountry(index);
|
||||
[[[MapsAppDelegate theApp] settingsManager] hide];
|
||||
[[Statistics instance] logEvent:@"Show Map From Download Countries Screen"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return GetFramework().Storage().CountriesCount(m_index);
|
||||
}
|
||||
|
||||
- (NSString *)GetStringForSize: (size_t)size
|
||||
{
|
||||
if (size > MB)
|
||||
{
|
||||
// do the correct rounding of Mb
|
||||
return [NSString stringWithFormat:@"%ld %@", (size + 512 * 1024) / MB, NSLocalizedString(@"mb", nil)];
|
||||
}
|
||||
else
|
||||
{
|
||||
// get upper bound size for Kb
|
||||
return [NSString stringWithFormat:@"%ld %@", (size + 1023) / 1024, NSLocalizedString(@"kb", nil)];
|
||||
}
|
||||
}
|
||||
|
||||
// @TODO Refactor UI to use good icon for "zoom to the country" action
|
||||
- (UITableViewCellAccessoryType)getZoomIconType
|
||||
{
|
||||
static const UITableViewCellAccessoryType iconType =
|
||||
[UIDevice currentDevice].systemVersion.floatValue < 7.0 ? UITableViewCellAccessoryDetailDisclosureButton
|
||||
: UITableViewCellAccessoryDetailButton;
|
||||
return iconType;
|
||||
}
|
||||
|
||||
/// @todo Pass correct options from UI.
|
||||
TMapOptions const g_mapOptions = TMapOptions::EMapWithCarRouting;
|
||||
|
||||
- (void)UpdateCell:(UITableViewCell *)cell forCountry:(TIndex const &)countryIndex
|
||||
{
|
||||
cell.accessoryView = nil;
|
||||
|
||||
Framework & frm = GetFramework();
|
||||
Storage & s = frm.Storage();
|
||||
|
||||
string const & flag = s.CountryFlag(countryIndex);
|
||||
guides::GuideInfo info;
|
||||
|
||||
if (flag.empty())
|
||||
cell.imageView.image = nil;
|
||||
else
|
||||
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%s.png", flag.c_str()]];
|
||||
|
||||
// do not show status for parent categories
|
||||
if (![cell.reuseIdentifier isEqual:@"ParentCell"])
|
||||
{
|
||||
TStatus const st = frm.GetCountryStatus(countryIndex);
|
||||
|
||||
switch (st)
|
||||
{
|
||||
case TStatus::EOnDisk:
|
||||
cell.textLabel.textColor = [UIColor colorWithRed:0.f/255.f
|
||||
green:161.f/255.f
|
||||
blue:68.f/255.f
|
||||
alpha:1.f];
|
||||
cell.detailTextLabel.text = [NSString stringWithFormat:NSLocalizedString(@"downloaded_touch_to_delete", nil), [self GetStringForSize: s.CountrySizeInBytes(countryIndex, g_mapOptions).first]];
|
||||
|
||||
// also add "sight" icon for centering on the country
|
||||
cell.accessoryType = [self getZoomIconType];
|
||||
break;
|
||||
|
||||
case TStatus::EOnDiskOutOfDate:
|
||||
cell.textLabel.textColor = [UIColor colorWithRed:1.f
|
||||
green:105.f/255.f
|
||||
blue:180.f/255.f
|
||||
alpha:1.f];
|
||||
cell.detailTextLabel.text = [NSString stringWithFormat:NSLocalizedString(@"downloaded_touch_to_update", nil), [self GetStringForSize: s.CountrySizeInBytes(countryIndex, g_mapOptions).first]];
|
||||
|
||||
// also add "sight" icon for centering on the country
|
||||
cell.accessoryType = [self getZoomIconType];
|
||||
break;
|
||||
|
||||
case TStatus::EDownloading:
|
||||
{
|
||||
cell.textLabel.textColor = [UIColor colorWithRed:52.f/255.f
|
||||
green:43.f/255.f
|
||||
blue:182.f/255.f
|
||||
alpha:1.f];
|
||||
cell.detailTextLabel.text = NSLocalizedString(@"downloading", nil);
|
||||
UIActivityIndicatorView * indicator = [[UIActivityIndicatorView alloc]
|
||||
initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
|
||||
cell.accessoryView = indicator;
|
||||
[indicator startAnimating];
|
||||
break;
|
||||
}
|
||||
|
||||
case TStatus::EOutOfMemFailed:
|
||||
/// @TODO show specific message for EOutOfMemFailed
|
||||
case TStatus::EDownloadFailed:
|
||||
cell.textLabel.textColor = [UIColor redColor];
|
||||
cell.detailTextLabel.text = NSLocalizedString(@"download_has_failed", nil);
|
||||
break;
|
||||
|
||||
case TStatus::EInQueue:
|
||||
{
|
||||
cell.textLabel.textColor = [UIColor colorWithRed:91.f/255.f
|
||||
green:148.f/255.f
|
||||
blue:222.f/255.f
|
||||
alpha:1.f];
|
||||
cell.detailTextLabel.text = NSLocalizedString(@"marked_for_downloading", nil);
|
||||
}
|
||||
break;
|
||||
|
||||
case TStatus::ENotDownloaded:
|
||||
cell.textLabel.textColor = [UIColor blackColor];
|
||||
cell.detailTextLabel.text = NSLocalizedString(@"touch_to_download", nil);
|
||||
break;
|
||||
|
||||
case TStatus::EUnknown:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Customize the appearance of table view cells.
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
TIndex index = CalculateIndex(m_index, indexPath);
|
||||
Storage & s = GetFramework().Storage();
|
||||
bool const hasChildren = s.CountriesCount(index) != 0;
|
||||
|
||||
NSString * cellId = hasChildren ? @"ParentCell" : @"DetailCell";
|
||||
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellId];
|
||||
if (cell == nil)
|
||||
{
|
||||
if (hasChildren)
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
|
||||
else
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
|
||||
}
|
||||
|
||||
if (hasChildren)
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
else
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
|
||||
cell.textLabel.text = [NSString stringWithUTF8String:s.CountryName(index).c_str()];
|
||||
|
||||
[self UpdateCell:cell forCountry:index];
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex != actionSheet.cancelButtonIndex)
|
||||
{
|
||||
Framework & f = GetFramework();
|
||||
NSString * title = [actionSheet buttonTitleAtIndex:buttonIndex];
|
||||
guides::GuideInfo info;
|
||||
BOOL isGuideAvailable = f.GetGuideInfo(m_clickedIndex, info);
|
||||
string const lang = languages::GetCurrentNorm();
|
||||
if (isGuideAvailable && [title isEqualToString:[NSString stringWithUTF8String:info.GetAdTitle(lang).c_str()]])
|
||||
{
|
||||
NSURL * guideUrl = [NSURL URLWithString:[NSString stringWithUTF8String:info.GetAppID().c_str()]];
|
||||
NSString * countryName = [NSString stringWithUTF8String:f.Storage().CountryName(m_clickedIndex).c_str()];
|
||||
[[Statistics instance] logEvent:@"Open Guide Country" withParameters:@{@"Country Name" : countryName}];
|
||||
UIApplication * application = [UIApplication sharedApplication];
|
||||
if ([application canOpenURL:guideUrl])
|
||||
{
|
||||
[application openURL:guideUrl];
|
||||
[[Statistics instance] logEvent:@"Open Guide Button" withParameters:@{@"Guide downloaded" : @"YES"}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[application openURL:[NSURL URLWithString:[NSString stringWithUTF8String:info.GetURL().c_str()]]];
|
||||
[[Statistics instance] logEvent:@"Open Guide Button" withParameters:@{@"Guide downloaded" : @"NO"}];
|
||||
}
|
||||
}
|
||||
else if ([title rangeOfString:[NSString stringWithFormat:NSLocalizedString(@"download_mb_or_kb", nil), @""]].location != NSNotFound
|
||||
|| [title rangeOfString:[NSString stringWithFormat:NSLocalizedString(@"update_mb_or_kb", nil), @""]].location != NSNotFound)
|
||||
[self TryDownloadCountry];
|
||||
else if ([title isEqualToString:NSLocalizedString(@"cancel_download", nil)] || [title isEqualToString:NSLocalizedString(@"delete", nil)])
|
||||
{
|
||||
f.DeleteCountry(m_clickedIndex, g_mapOptions);
|
||||
m_clickedCell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
else
|
||||
ASSERT ( false, () );
|
||||
}
|
||||
}
|
||||
|
||||
- (void)DoDownloadCountry
|
||||
{
|
||||
GetFramework().DownloadCountry(m_clickedIndex, g_mapOptions);
|
||||
}
|
||||
|
||||
// 3G warning confirmation handler
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
[self DoDownloadCountry];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) TryDownloadCountry
|
||||
{
|
||||
NSString * countryName = m_clickedCell.textLabel.text;
|
||||
|
||||
if (FreeDiskSpaceInBytes() < (m_downloadSize + MB))
|
||||
{
|
||||
// No enough disk space - display warning dialog
|
||||
NSString * message = [NSString stringWithFormat:NSLocalizedString(@"free_space_for_country", nil), [self GetStringForSize: m_downloadSize], countryName];
|
||||
[[[CustomAlertView alloc] initWithTitle:NSLocalizedString(@"not_enough_disk_space", nil)
|
||||
message:message
|
||||
delegate:nil
|
||||
cancelButtonTitle:NSLocalizedString(@"ok", nil)
|
||||
otherButtonTitles:nil] show];
|
||||
}
|
||||
else
|
||||
{
|
||||
Reachability * reachability = [Reachability reachabilityForInternetConnection];
|
||||
if (![reachability isReachable])
|
||||
{
|
||||
// No any connection - skip downloading
|
||||
[[[CustomAlertView alloc] initWithTitle:NSLocalizedString(@"no_internet_connection_detected", nil)
|
||||
message:NSLocalizedString(@"use_wifi_recommendation_text", nil)
|
||||
delegate:nil
|
||||
cancelButtonTitle:NSLocalizedString(@"ok", nil)
|
||||
otherButtonTitles:nil] show];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([reachability isReachableViaWWAN] && m_downloadSize > MAX_3G_MEGABYTES * MB)
|
||||
{
|
||||
// If user uses 3G, show warning before downloading
|
||||
[[[CustomAlertView alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@"no_wifi_ask_cellular_download", nil), countryName]
|
||||
message:nil
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"cancel", nil)
|
||||
otherButtonTitles:NSLocalizedString(@"use_cellular_data", nil), nil] show];
|
||||
}
|
||||
else
|
||||
[self DoDownloadCountry];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// deselect the current row (don't keep the table selection persistent)
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath];
|
||||
|
||||
// Push the new table view on the stack
|
||||
TIndex const index = CalculateIndex(m_index, indexPath);
|
||||
Framework & frm = GetFramework();
|
||||
Storage & s = frm.Storage();
|
||||
|
||||
if (s.CountriesCount(index))
|
||||
{
|
||||
CountriesViewController * newController = [[CountriesViewController alloc] initWithIndex:index andHeader:cell.textLabel.text];
|
||||
[self.navigationController pushViewController:newController animated:YES];
|
||||
}
|
||||
else
|
||||
[self createActionSheetForCountry:indexPath];
|
||||
}
|
||||
|
||||
- (void)OnCountryChange:(TIndex const &)index
|
||||
{
|
||||
if (IsOurIndex(index, m_index))
|
||||
{
|
||||
UITableView * tableView = (UITableView *)self.view;
|
||||
UITableViewCell * cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:RowFromIndex(index) inSection:0]];
|
||||
|
||||
if (cell)
|
||||
[self UpdateCell:cell forCountry:index];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)OnDownload:(TIndex const &)index withProgress:(pair<int64_t, int64_t> const &)progress
|
||||
{
|
||||
if (IsOurIndex(index, m_index))
|
||||
{
|
||||
UITableView * tableView = (UITableView *)self.view;
|
||||
UITableViewCell * cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:RowFromIndex(index) inSection:0]];
|
||||
|
||||
if (cell)
|
||||
cell.detailTextLabel.text = [NSString stringWithFormat:NSLocalizedString(@"downloading_touch_to_cancel", nil), progress.first * 100 / progress.second];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)createActionSheetForCountry:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableView * table = (UITableView *)(self.view);
|
||||
UITableViewCell * cell = [table cellForRowAtIndexPath:indexPath];
|
||||
|
||||
Framework & frm = GetFramework();
|
||||
m_clickedIndex = CalculateIndex(m_index, indexPath);
|
||||
m_countryStatus = frm.GetCountryStatus(m_clickedIndex);
|
||||
m_clickedCell = cell;
|
||||
Storage & s = GetFramework().Storage();
|
||||
m_downloadSize = s.CountrySizeInBytes(m_clickedIndex, g_mapOptions).second;
|
||||
|
||||
NSMutableArray * buttonNames = [[NSMutableArray alloc] init];
|
||||
|
||||
bool canDelete = NO;
|
||||
|
||||
switch (m_countryStatus)
|
||||
{
|
||||
case TStatus::EOnDisk:
|
||||
canDelete = YES;
|
||||
break;
|
||||
|
||||
case TStatus::EOnDiskOutOfDate:
|
||||
canDelete = YES;
|
||||
[buttonNames addObject:[NSString stringWithFormat:NSLocalizedString(@"update_mb_or_kb", nil), [self GetStringForSize:m_downloadSize]]];
|
||||
break;
|
||||
|
||||
case TStatus::ENotDownloaded:
|
||||
[buttonNames addObject:[NSString stringWithFormat:NSLocalizedString(@"download_mb_or_kb", nil), [self GetStringForSize:m_downloadSize]]];
|
||||
break;
|
||||
|
||||
case TStatus::EDownloadFailed:
|
||||
case TStatus::EOutOfMemFailed:
|
||||
[self DoDownloadCountry];
|
||||
return;
|
||||
|
||||
case TStatus::EDownloading:
|
||||
{
|
||||
// special one, with destructive button
|
||||
string guideAdevertiseString;
|
||||
NSString * guideAd = nil;
|
||||
if (getGuideName(guideAdevertiseString, m_clickedIndex))
|
||||
guideAd = [NSString stringWithUTF8String:guideAdevertiseString.c_str()];
|
||||
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:cell.textLabel.text
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"do_nothing", nil)
|
||||
destructiveButtonTitle:NSLocalizedString(@"cancel_download", nil)
|
||||
otherButtonTitles:guideAd, nil];
|
||||
[actionSheet showFromRect:cell.frame inView:table animated:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
case TStatus::EInQueue:
|
||||
{
|
||||
frm.DeleteCountry(m_clickedIndex, g_mapOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
ASSERT ( false, () );
|
||||
}
|
||||
|
||||
UIActionSheet * as = [[UIActionSheet alloc] initWithTitle:cell.textLabel.text
|
||||
delegate:self
|
||||
cancelButtonTitle:nil
|
||||
destructiveButtonTitle:nil
|
||||
otherButtonTitles:nil];
|
||||
|
||||
for (NSString * str in buttonNames)
|
||||
[as addButtonWithTitle:str];
|
||||
size_t numOfButtons = [buttonNames count];
|
||||
if (canDelete)
|
||||
{
|
||||
[as addButtonWithTitle:NSLocalizedString(@"delete", nil)];
|
||||
as.destructiveButtonIndex = numOfButtons++;
|
||||
}
|
||||
|
||||
string guideAdevertiseString;
|
||||
if (getGuideName(guideAdevertiseString, m_clickedIndex))
|
||||
{
|
||||
[as addButtonWithTitle:[NSString stringWithUTF8String:guideAdevertiseString.c_str()]];
|
||||
++numOfButtons;
|
||||
}
|
||||
if (!IPAD)
|
||||
{
|
||||
[as addButtonWithTitle:NSLocalizedString(@"cancel", nil)];
|
||||
as.cancelButtonIndex = numOfButtons;
|
||||
}
|
||||
[as showFromRect:cell.frame inView:(UITableView *)self.view animated: YES];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,14 +0,0 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/// Responsible for all settings dialogs
|
||||
@interface SettingsManager : NSObject <UIActionSheetDelegate>
|
||||
{
|
||||
UINavigationController * m_navigationController;
|
||||
int m_slotID;
|
||||
}
|
||||
|
||||
- (void)show:(UIViewController *)prevController;
|
||||
- (void)hide;
|
||||
|
||||
@end
|
|
@ -1,106 +0,0 @@
|
|||
#import "SettingsManager.h"
|
||||
#import "CountriesViewController.h"
|
||||
#import "MapViewController.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "../../../std/bind.hpp"
|
||||
|
||||
using namespace storage;
|
||||
|
||||
// Settings are always present globally
|
||||
@implementation SettingsManager
|
||||
|
||||
/// Get right controller from the stack
|
||||
- (UIViewController *)ControllerByIndex:(TIndex const &)index
|
||||
{
|
||||
NSArray * controllers = m_navigationController.viewControllers;
|
||||
NSInteger count = [controllers count] - 1;
|
||||
if (index.m_region != TIndex::INVALID && count >= 3)
|
||||
return controllers[3];
|
||||
else if (index.m_country != TIndex::INVALID && count >= 2)
|
||||
return controllers[2];
|
||||
else if (index.m_group != TIndex::INVALID && count >= 1)
|
||||
return controllers[1];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)OnCountryChange:(TIndex const &)index
|
||||
{
|
||||
UIViewController * controller = [self ControllerByIndex:index];
|
||||
if (controller && [controller respondsToSelector:@selector(OnCountryChange:)])
|
||||
[(CountriesViewController *)controller OnCountryChange: index];
|
||||
}
|
||||
|
||||
- (void)OnCountryDownload:(TIndex const &)index withProgress:(pair<int64_t, int64_t> const &)progress
|
||||
{
|
||||
UIViewController * controller = [self ControllerByIndex:index];
|
||||
if (controller && [controller respondsToSelector:@selector(OnDownload:withProgress:)])
|
||||
[(CountriesViewController *)controller OnDownload:index withProgress:progress];
|
||||
}
|
||||
|
||||
- (void)show:(UIViewController *)prevController
|
||||
{
|
||||
NSString * header = NSLocalizedString(@"download_maps", @"Settings/Downloader - Main downloader window title");
|
||||
CountriesViewController * countriesController = [[CountriesViewController alloc] initWithIndex:TIndex() andHeader:header];
|
||||
|
||||
// m_navigationController = [[UINavigationController alloc] initWithRootViewController:countriesController];
|
||||
Framework & f = GetFramework();
|
||||
// Subscribe to storage callbacks AND load country names after calling Storage::Subscribe()
|
||||
{
|
||||
// tricky boost::bind for objC class methods
|
||||
typedef void (*TChangeFunc)(id, SEL, TIndex const &);
|
||||
SEL changeSel = @selector(OnCountryChange:);
|
||||
TChangeFunc changeImpl = (TChangeFunc)[self methodForSelector:changeSel];
|
||||
|
||||
typedef void (*TProgressFunc)(id, SEL, TIndex const &, pair<int64_t, int64_t> const &);
|
||||
SEL progressSel = @selector(OnCountryDownload:withProgress:);
|
||||
TProgressFunc progressImpl = (TProgressFunc)[self methodForSelector:progressSel];
|
||||
|
||||
m_slotID = f.Storage().Subscribe(bind(changeImpl, self, changeSel, _1),
|
||||
bind(progressImpl, self, progressSel, _1, _2));
|
||||
}
|
||||
// display controller only when countries are loaded
|
||||
m_navigationController = prevController.navigationController;
|
||||
[m_navigationController pushViewController:countriesController animated:YES];
|
||||
|
||||
// We do force delete of old maps at startup from this moment.
|
||||
/*
|
||||
// display upgrade/delete old maps dialog if necessary
|
||||
if (f.NeedToDeleteOldMaps())
|
||||
{
|
||||
UIActionSheet * dialog = [[UIActionSheet alloc]
|
||||
initWithTitle:NSLocalizedString(@"new_map_data_format_upgrade_dialog", @"Downloader/Upgrade dialog title")
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"cancel", @"Downloader/Upgrade Cancel button")
|
||||
destructiveButtonTitle:NSLocalizedString(@"delete_old_maps", @"Downloader/Upgrade OK button")
|
||||
otherButtonTitles:nil];
|
||||
[dialog showInView:m_navigationController.view];
|
||||
[dialog release];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Hides all opened settings windows
|
||||
- (void)hide
|
||||
{
|
||||
GetFramework().Storage().Unsubscribe(m_slotID);
|
||||
[m_navigationController popToRootViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
/*
|
||||
// Called from Upgrade/Delete old maps dialog
|
||||
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex == 0)
|
||||
{ // delete old maps and show downloader
|
||||
GetFramework().DeleteOldMaps();
|
||||
}
|
||||
else
|
||||
{ // User don't want to upgrade at the moment - so be it.
|
||||
[self hide];
|
||||
}
|
||||
}
|
||||
*/
|
||||
@end
|
|
@ -395,13 +395,12 @@ void ActiveMapsLayout::StatusChangedCallback(TIndex const & index)
|
|||
int newPosition = MoveItemToGroup(group, position, TGroup::EUpToDate);
|
||||
NotifyMove(group, position, TGroup::EUpToDate, newPosition);
|
||||
}
|
||||
else
|
||||
else if (item.m_options != options)
|
||||
{
|
||||
// Here we handle
|
||||
// "Actual map without routing" -> "Actual map with routing"
|
||||
// "Actual map with routing" -> "Actual map without routing"
|
||||
ASSERT(item.m_options != options, ());
|
||||
TMapOptions requestOpt = item.m_downloadRequest;
|
||||
TMapOptions requestOpt = item.m_downloadRequest;
|
||||
item.m_options = item.m_downloadRequest = options;
|
||||
NotifyOptionsChanged(group, position, item.m_options, requestOpt);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue