From bd58513c89974e16d560608e5e1784b0cddcbda2 Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Wed, 5 Jan 2011 05:10:11 +0200 Subject: [PATCH] [iPhone] Draft Downloader UI implementation --- iphone/Maps/Maps.xcodeproj/project.pbxproj | 8 + .../Maps/Settings/CountriesViewController.h | 6 +- .../Maps/Settings/CountriesViewController.mm | 302 ++++++++---------- iphone/Maps/Settings/SettingsManager.mm | 45 ++- storage/country.cpp | 2 +- storage/storage.cpp | 4 +- 6 files changed, 182 insertions(+), 185 deletions(-) diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 0bdc991c72..0fbd12deca 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -46,6 +46,8 @@ FA0660041286168700FEA989 /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = FA0660021286168700FEA989 /* Default-Landscape.png */; }; FA4135EA120A263C0062D5B4 /* CountriesViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA4135E2120A263C0062D5B4 /* CountriesViewController.mm */; }; FA4135ED120A263C0062D5B4 /* SettingsManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA4135E7120A263C0062D5B4 /* SettingsManager.mm */; }; + FA46DA0512D414D200968C36 /* maps.update in Resources */ = {isa = PBXBuildFile; fileRef = FA46DA0412D414D200968C36 /* maps.update */; }; + FA46DA2C12D4166E00968C36 /* countries.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA46DA2B12D4166E00968C36 /* countries.txt */; }; FA5005621287BFCE002961F0 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = FA50055C1287BFCE002961F0 /* Icon-72.png */; }; FA5005631287BFCE002961F0 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = FA50055D1287BFCE002961F0 /* Icon-Small-50.png */; }; FA5005641287BFCE002961F0 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = FA50055E1287BFCE002961F0 /* Icon-Small.png */; }; @@ -112,6 +114,8 @@ FA4135E2120A263C0062D5B4 /* CountriesViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CountriesViewController.mm; path = Settings/CountriesViewController.mm; sourceTree = SOURCE_ROOT; }; 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; name = SettingsManager.mm; path = Settings/SettingsManager.mm; sourceTree = SOURCE_ROOT; }; + FA46DA0412D414D200968C36 /* maps.update */ = {isa = PBXFileReference; lastKnownFileType = file; name = maps.update; path = ../../data/maps.update; sourceTree = SOURCE_ROOT; }; + FA46DA2B12D4166E00968C36 /* countries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = countries.txt; path = ../../data/countries.txt; sourceTree = SOURCE_ROOT; }; FA50055C1287BFCE002961F0 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = SOURCE_ROOT; }; FA50055D1287BFCE002961F0 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small-50.png"; sourceTree = SOURCE_ROOT; }; FA50055E1287BFCE002961F0 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-Small.png"; sourceTree = SOURCE_ROOT; }; @@ -243,6 +247,8 @@ FA065FC61286143F00FEA989 /* External Resources */ = { isa = PBXGroup; children = ( + FA46DA2B12D4166E00968C36 /* countries.txt */, + FA46DA0412D414D200968C36 /* maps.update */, EE12092B12BD67C900068DC3 /* wqy-microhei.ttf */, EEFC0A9512B561B7002914FF /* dejavusans.ttf */, EEE4C9411298A31B007231A9 /* basic_highres.skn */, @@ -379,6 +385,8 @@ EEE4C9421298A31B007231A9 /* basic_highres.skn in Resources */, EEFC0A9612B561B7002914FF /* dejavusans.ttf in Resources */, EE12092C12BD67C900068DC3 /* wqy-microhei.ttf in Resources */, + FA46DA0512D414D200968C36 /* maps.update in Resources */, + FA46DA2C12D4166E00968C36 /* countries.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iphone/Maps/Settings/CountriesViewController.h b/iphone/Maps/Settings/CountriesViewController.h index 1ad7bbd286..9294bbe56f 100644 --- a/iphone/Maps/Settings/CountriesViewController.h +++ b/iphone/Maps/Settings/CountriesViewController.h @@ -1,12 +1,14 @@ #import -namespace storage { class Storage; } +#include "../../../storage/storage.hpp" @interface CountriesViewController : UIViewController { + storage::Storage * m_storage; + storage::TIndex m_index; } -- (id) initWithStorage: (storage::Storage &) storage; +- (id) initWithStorage: (storage::Storage &) storage andIndex: (storage::TIndex const &) index andHeader: (NSString *) header; @end diff --git a/iphone/Maps/Settings/CountriesViewController.mm b/iphone/Maps/Settings/CountriesViewController.mm index 941073ebb5..9c679bdab6 100644 --- a/iphone/Maps/Settings/CountriesViewController.mm +++ b/iphone/Maps/Settings/CountriesViewController.mm @@ -5,9 +5,6 @@ #include #import -#include "../../../storage/storage.hpp" -#include - #define NAVIGATION_BAR_HEIGHT 44 #define MAX_3G_MEGABYTES 100 @@ -16,87 +13,48 @@ using namespace storage; - -///////////////////////////////////////////////////////////////// -// needed for trick with back button -@interface NotAnimatedNavigationBar : UINavigationBar -@end; -@implementation NotAnimatedNavigationBar -- (UINavigationItem *) popNavigationItemAnimated: (BOOL)animated +TIndex CalculateIndex(TIndex const & parentIndex, NSIndexPath * indexPath) { - return [super popNavigationItemAnimated:NO]; + TIndex index = parentIndex; + if (index.m_group == -1) + index.m_group = indexPath.row; + else if (index.m_country == -1) + index.m_country = indexPath.row; + else + index.m_region = indexPath.row; + return index; } -@end -///////////////////////////////////////////////////////////////// @implementation CountriesViewController - Storage * g_pStorage = 0; - -- (id) initWithStorage: (Storage &)storage -{ - g_pStorage = &storage; - if ((self = [super initWithNibName:@"CountriesViewController" bundle:nil])) - { - // tricky boost::bind for objC class methods - typedef void (*TFinishFunc)(id, SEL, TIndex const &); - SEL finishSel = @selector(OnDownloadFinished:); - TFinishFunc finishImpl = (TFinishFunc)[self methodForSelector:finishSel]; - - typedef void (*TProgressFunc)(id, SEL, TIndex const &, TDownloadProgress const &); - SEL progressSel = @selector(OnDownload:withProgress:); - TProgressFunc progressImpl = (TProgressFunc)[self methodForSelector:progressSel]; - - storage.Subscribe(boost::bind(finishImpl, self, finishSel, _1), - boost::bind(progressImpl, self, progressSel, _1, _2), NULL); - } - return self; -} - -- (void) dealloc -{ - g_pStorage->Unsubscribe(); - [super dealloc]; -} - -// called on Map button click -- (void) navigationBar: (UINavigationBar *)navigationBar didPopItem: (UINavigationItem *)item +- (void) OnCloseButton: (id) sender { [SettingsManager Hide]; } +- (id) initWithStorage: (Storage &)storage andIndex: (TIndex const &) index andHeader: (NSString *)header +{ + m_storage = &storage; + m_index = index; + if ((self = [super initWithNibName:nil bundle:nil])) + { + UIBarButtonItem * button = [[UIBarButtonItem alloc] initWithTitle:@"Close" style: UIBarButtonItemStyleDone + target:self action:@selector(OnCloseButton:)]; + self.navigationItem.rightBarButtonItem = button; + self.navigationItem.title = header; + } + return self; +} + - (void) loadView { CGRect appRect = [UIScreen mainScreen].applicationFrame; - UIView * rootView = [[UIView alloc] initWithFrame:appRect]; - rootView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - - CGRect navBarRect = CGRectMake(0, 0, appRect.size.width, NAVIGATION_BAR_HEIGHT); - NotAnimatedNavigationBar * bar = [[NotAnimatedNavigationBar alloc] initWithFrame:navBarRect]; - bar.delegate = self; - - UINavigationItem * item1 = [[UINavigationItem alloc] initWithTitle:@"Map"]; // title for Back button - [item1.backBarButtonItem setAction:@selector(OnBackClick:)]; - [bar pushNavigationItem:item1 animated:NO]; - [item1 release]; - UINavigationItem * item2 = [[UINavigationItem alloc] initWithTitle:@"Download Manager"]; - [item2 setHidesBackButton:NO animated:NO]; - [bar pushNavigationItem:item2 animated:NO]; - [item2 release]; - - [rootView addSubview:bar]; - [bar release]; - - CGRect tableRect = CGRectMake(0, navBarRect.size.height, navBarRect.size.width, appRect.size.height - navBarRect.size.height); - UITableView * countriesTableView = [[UITableView alloc] initWithFrame:tableRect style:UITableViewStylePlain]; + UITableView * countriesTableView = [[UITableView alloc] initWithFrame:appRect style:UITableViewStylePlain]; + countriesTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; countriesTableView.delegate = self; - countriesTableView.dataSource = self; - - [rootView addSubview:countriesTableView]; - [countriesTableView release]; - - self.view = rootView; - [rootView release]; + countriesTableView.dataSource = self; + self.view = countriesTableView; + [countriesTableView release]; } // Override to allow orientations other than the default portrait orientation. @@ -105,26 +63,26 @@ using namespace storage; return YES; } -- (NSInteger) numberOfSectionsInTableView: (UITableView *)tableView -{ - return 0;//g_pStorage->GroupsCount(); -} - -- (NSString *) tableView: (UITableView *)tableView titleForHeaderInSection: (NSInteger)section -{ - return @"TODO";//[NSString stringWithUTF8String: g_pStorage->GroupName(section).c_str()]; -} +//- (NSInteger) numberOfSectionsInTableView: (UITableView *)tableView +//{ +// return 0; +//} +// +//- (NSString *) tableView: (UITableView *)tableView titleForHeaderInSection: (NSInteger)section +//{ +// return nil; +//} - (NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section { - return 0;//g_pStorage->CountriesCountInGroup(section); + return m_storage->CountriesCount(m_index); } - (void) UpdateCell: (UITableViewCell *) cell forCountry: (TIndex const &) countryIndex { UIActivityIndicatorView * indicator = (UIActivityIndicatorView *)cell.accessoryView; - switch (g_pStorage->CountryStatus(countryIndex)) + switch (m_storage->CountryStatus(countryIndex)) { case EOnDisk: { @@ -201,10 +159,13 @@ using namespace storage; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellId]; if (cell == nil) cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier:cellId] autorelease]; - TIndex countryIndex(indexPath.section, indexPath.row); - cell.textLabel.text = [NSString stringWithUTF8String:g_pStorage->CountryName(countryIndex).c_str()]; - cell.accessoryType = UITableViewCellAccessoryNone; - [self UpdateCell: cell forCountry: countryIndex]; + TIndex index = CalculateIndex(m_index, indexPath); + cell.textLabel.text = [NSString stringWithUTF8String:m_storage->CountryName(index).c_str()]; + if (m_storage->CountriesCount(index)) + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + else + cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; +// [self UpdateCell: cell forCountry: countryIndex]; return cell; } @@ -216,14 +177,14 @@ TIndex g_clickedIndex; { if (buttonIndex == 0) { // Delete country - switch (g_pStorage->CountryStatus(g_clickedIndex)) + switch (m_storage->CountryStatus(g_clickedIndex)) { case ENotDownloaded: case EDownloadFailed: - g_pStorage->DownloadCountry(g_clickedIndex); + m_storage->DownloadCountry(g_clickedIndex); break; default: - g_pStorage->DeleteCountry(g_clickedIndex); + m_storage->DeleteCountry(g_clickedIndex); } } } @@ -257,85 +218,90 @@ TIndex g_clickedIndex; // deselect the current row (don't keep the table selection persistent) [tableView deselectRowAtIndexPath: indexPath animated:YES]; UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath]; - NSString * countryName = [[cell textLabel] text]; - - g_clickedIndex = TIndex(indexPath.section, indexPath.row); - switch (g_pStorage->CountryStatus(g_clickedIndex)) - { - case EOnDisk: - { // display confirmation popup - UIActionSheet * popupQuery = [[UIActionSheet alloc] - initWithTitle: countryName - delegate: self - cancelButtonTitle: @"Cancel" - destructiveButtonTitle: @"Delete" - otherButtonTitles: nil]; - [popupQuery showFromRect: [cell frame] inView: tableView animated: YES]; - [popupQuery release]; - } - break; - case ENotDownloaded: - case EDownloadFailed: - { // display confirmation popup with country size - BOOL isWifiConnected = [CountriesViewController IsUsingWIFI]; - - uint64_t size = 0;//g_pStorage->CountrySizeInBytes(g_clickedIndex); - // convert size to human readable values - NSString * strTitle = nil; - NSString * strDownload = nil; - if (size > GB) - { - size /= GB; - if (isWifiConnected) - strTitle = [NSString stringWithFormat:@"%@", countryName]; - else - strTitle = [NSString stringWithFormat:@"We strongly recommend using WIFI for downloading %@", countryName]; - strDownload = [NSString stringWithFormat:@"Download %qu GB", size]; - } - else if (size > MB) - { - size /= MB; - if (isWifiConnected || size < MAX_3G_MEGABYTES) - strTitle = [NSString stringWithFormat:@"%@", countryName]; - else - strTitle = [NSString stringWithFormat:@"We strongly recommend using WIFI for downloading %@", countryName]; - strDownload = [NSString stringWithFormat:@"Download %qu MB", size]; - } - else - { - size = (size + 999) / 1000; - strTitle = [NSString stringWithFormat:@"%@", countryName]; - strDownload = [NSString stringWithFormat:@"Download %qu kB", size]; - } - - UIActionSheet * popupQuery = [[UIActionSheet alloc] - initWithTitle: strTitle - delegate: self - cancelButtonTitle: @"Cancel" - destructiveButtonTitle: strDownload - otherButtonTitles: nil]; - [popupQuery showFromRect: [cell frame] inView: tableView animated: YES]; - [popupQuery release]; -// g_pStorage->DownloadCountry(g_clickedIndex); - } - break; - case EDownloading: - { // display confirmation popup - UIActionSheet * popupQuery = [[UIActionSheet alloc] - initWithTitle: countryName - delegate: self - cancelButtonTitle: @"Do Nothing" - destructiveButtonTitle: @"Cancel Download" - otherButtonTitles: nil]; - [popupQuery showFromRect: [cell frame] inView: tableView animated: YES]; - [popupQuery release]; - } - break; - case EInQueue: - // cancel download - g_pStorage->DeleteCountry(g_clickedIndex); - break; - } + // Push the new table view on the stack + TIndex index = CalculateIndex(m_index, indexPath); + CountriesViewController * newController = [[CountriesViewController alloc] initWithStorage:*m_storage + andIndex: index andHeader: cell.textLabel.text]; + [self.navigationController pushViewController:newController animated:YES]; +// NSString * countryName = [[cell textLabel] text]; +// +// g_clickedIndex = TIndex(indexPath.section, indexPath.row); +// switch (g_pStorage->CountryStatus(g_clickedIndex)) +// { +// case EOnDisk: +// { // display confirmation popup +// UIActionSheet * popupQuery = [[UIActionSheet alloc] +// initWithTitle: countryName +// delegate: self +// cancelButtonTitle: @"Cancel" +// destructiveButtonTitle: @"Delete" +// otherButtonTitles: nil]; +// [popupQuery showFromRect: [cell frame] inView: tableView animated: YES]; +// [popupQuery release]; +// } +// break; +// case ENotDownloaded: +// case EDownloadFailed: +// { // display confirmation popup with country size +// BOOL isWifiConnected = [CountriesViewController IsUsingWIFI]; +// +// uint64_t size = 0;//g_pStorage->CountrySizeInBytes(g_clickedIndex); +// // convert size to human readable values +// NSString * strTitle = nil; +// NSString * strDownload = nil; +// if (size > GB) +// { +// size /= GB; +// if (isWifiConnected) +// strTitle = [NSString stringWithFormat:@"%@", countryName]; +// else +// strTitle = [NSString stringWithFormat:@"We strongly recommend using WIFI for downloading %@", countryName]; +// strDownload = [NSString stringWithFormat:@"Download %qu GB", size]; +// } +// else if (size > MB) +// { +// size /= MB; +// if (isWifiConnected || size < MAX_3G_MEGABYTES) +// strTitle = [NSString stringWithFormat:@"%@", countryName]; +// else +// strTitle = [NSString stringWithFormat:@"We strongly recommend using WIFI for downloading %@", countryName]; +// strDownload = [NSString stringWithFormat:@"Download %qu MB", size]; +// } +// else +// { +// size = (size + 999) / 1000; +// strTitle = [NSString stringWithFormat:@"%@", countryName]; +// strDownload = [NSString stringWithFormat:@"Download %qu kB", size]; +// } +// +// UIActionSheet * popupQuery = [[UIActionSheet alloc] +// initWithTitle: strTitle +// delegate: self +// cancelButtonTitle: @"Cancel" +// destructiveButtonTitle: strDownload +// otherButtonTitles: nil]; +// [popupQuery showFromRect: [cell frame] inView: tableView animated: YES]; +// [popupQuery release]; +//// g_pStorage->DownloadCountry(g_clickedIndex); +// } +// break; +// case EDownloading: +// { // display confirmation popup +// UIActionSheet * popupQuery = [[UIActionSheet alloc] +// initWithTitle: countryName +// delegate: self +// cancelButtonTitle: @"Do Nothing" +// destructiveButtonTitle: @"Cancel Download" +// otherButtonTitles: nil]; +// [popupQuery showFromRect: [cell frame] inView: tableView animated: YES]; +// [popupQuery release]; +// } +// break; +// case EInQueue: +// // cancel download +// g_pStorage->DeleteCountry(g_clickedIndex); +// break; +// } } - (void) OnDownloadFinished: (TIndex const &) index diff --git a/iphone/Maps/Settings/SettingsManager.mm b/iphone/Maps/Settings/SettingsManager.mm index bea9e2e7bd..e3f00f0fca 100644 --- a/iphone/Maps/Settings/SettingsManager.mm +++ b/iphone/Maps/Settings/SettingsManager.mm @@ -5,18 +5,32 @@ using namespace storage; -// Settings are always present globally -//static SettingsManager gInstance; +static void OnCountryChange(TIndex const & index) +{ +} + +static void OnCountryDownloadProgress(TIndex const & index, TDownloadProgress const & progress) +{ + +} + +static void OnUpdateCheck(int64_t size, char const * readme) +{ + +} + +// Settings are always present globally @implementation SettingsManager - CountriesViewController * m_countriesViewController = nil; + storage::Storage * g_storage = 0; + UINavigationController * g_navController = nil; // Destructor - (void) dealloc { - if (m_countriesViewController) - [m_countriesViewController release]; + if (g_navController) + [g_navController release]; [super dealloc]; } @@ -28,21 +42,28 @@ using namespace storage; // Currently displays only countries to download + (void) Show: (UIViewController *)parentController WithStorage: (Storage &)storage - { - if (!m_countriesViewController) - m_countriesViewController = [[CountriesViewController alloc] initWithStorage:storage]; + g_storage = &storage; + if (!g_navController) + { + CountriesViewController * rootViewController = [[CountriesViewController alloc] initWithStorage:storage + andIndex:TIndex() andHeader:@"Download"]; + g_navController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + + storage.Subscribe(&OnCountryChange, &OnCountryDownloadProgress, &OnUpdateCheck); + } - [parentController presentModalViewController:m_countriesViewController animated:YES]; + [parentController presentModalViewController:g_navController animated:YES]; } // Hides all opened settings windows + (void) Hide { - if (m_countriesViewController) + if (g_navController) { - [[m_countriesViewController parentViewController] dismissModalViewControllerAnimated:YES]; - m_countriesViewController = nil; + g_storage->Unsubscribe(); + [[g_navController parentViewController] dismissModalViewControllerAnimated:YES]; + g_navController = nil; } } diff --git a/storage/country.cpp b/storage/country.cpp index 1f05b8ff10..fc3beacd2e 100644 --- a/storage/country.cpp +++ b/storage/country.cpp @@ -146,7 +146,7 @@ namespace storage return false; } } - return true; + return countries.SiblingsCount() > 0; } void SaveTiles(string const & file, int32_t level, TDataFiles const & cellFiles, TCommonFiles const & commonFiles) diff --git a/storage/storage.cpp b/storage/storage.cpp index ebbe3850ce..73f8cf4ce5 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -243,9 +243,9 @@ namespace storage m_observerUpdateCheck = check; TTilesContainer tiles; - if (LoadTiles(tiles, GetPlatform().WritablePathForFile(UPDATE_CHECK_FILE), m_currentVersion)) + if (LoadTiles(tiles, GetPlatform().ReadPathForFile(UPDATE_CHECK_FILE), m_currentVersion)) { - if (!LoadCountries(GetPlatform().WritablePathForFile(COUNTRIES_FILE), tiles, m_countries)) + if (!LoadCountries(GetPlatform().ReadPathForFile(COUNTRIES_FILE), tiles, m_countries)) LOG(LWARNING, ("Can't load countries file", COUNTRIES_FILE)); } else