[ios] Implemented TTS UI.

This commit is contained in:
v.mikhaylenko 2015-11-12 15:15:59 +03:00
parent 9c5202e67f
commit a4f980fc55
16 changed files with 429 additions and 74 deletions

View file

@ -72,24 +72,6 @@ static inline NSString * formattedSize(uint64_t size)
return [sizeString uppercaseString];
}
static inline NSString * bcp47ToTwineLanguage(NSString const * bcp47LangName)
{
if (bcp47LangName == nil || [bcp47LangName length] < 2)
return nil;
if ([bcp47LangName isEqualToString:@"zh-CN"] || [bcp47LangName isEqualToString:@"zh-CHS"]
|| [bcp47LangName isEqualToString:@"zh-SG"])
{
return @"zh-Hans"; // Chinese simplified
}
if ([bcp47LangName hasPrefix:@"zh"])
return @"zh-Hant"; // Chinese traditional
// Taking two first symbols of a language name. For example ru-RU -> ru
return [bcp47LangName substringToIndex:2];
}
// Use only for screen dimensions CGFloat comparison
static inline BOOL equalScreenDimensions(CGFloat left, CGFloat right)
{

View file

@ -37,7 +37,6 @@
#pragma mark - MWMNavigationDashboardManager
- (void)setupRoutingDashboard:(location::FollowingInfo const &)info;
- (void)playTurnNotifications;
- (void)routingHidden;
- (void)routingReady;
- (void)routingPrepare;

View file

@ -322,11 +322,6 @@ extern NSString * const kAlohalyticsTapEventKey;
[self.menuController setStreetName:@(info.m_sourceName.c_str())];
}
- (void)playTurnNotifications
{
[self.navigationManager playTurnNotifications];
}
- (void)handleRoutingError
{
self.navigationManager.state = MWMNavigationDashboardStateError;

View file

@ -51,8 +51,13 @@ using namespace routing::turns;
// _lanes = info.m_lanes;
_nextTurnImage = image(info.m_nextTurn, true);
}
_turnImage = image(info.m_turn, false);
if (info.m_turn == TurnDirection::EnterRoundAbout || info.m_turn == TurnDirection::LeaveRoundAbout)
TurnDirection const turn = info.m_turn;
_turnImage = image(turn, false);
BOOL const isRound = turn == TurnDirection::EnterRoundAbout ||
turn == TurnDirection::StayOnRoundAbout ||
turn == TurnDirection::LeaveRoundAbout;
if (isRound)
_roundExitNumber = info.m_exitNum;
else
_roundExitNumber = 0;

View file

@ -43,7 +43,6 @@ typedef NS_ENUM(NSUInteger, MWMNavigationDashboardState)
- (instancetype)initWithParentView:(UIView *)view delegate:(id<MWMNavigationDashboardManagerProtocol, MWMRoutePreviewDataSource>)delegate;
- (void)setupDashboard:(location::FollowingInfo const &)info;
- (void)updateDashboard;
- (void)playTurnNotifications;
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation;
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;

View file

@ -32,7 +32,6 @@ static NSString * const kNavigationDashboardIPADXibName = @"MWMNiPadNavigationDa
@property (weak, nonatomic) UIView * ownerView;
@property (nonatomic) MWMNavigationDashboardEntity * entity;
@property (nonatomic) MWMTextToSpeech * tts;
//@property (nonatomic) MWMLanesPanel * lanesPanel;
@property (nonatomic) MWMNextTurnPanel * nextTurnPanel;
@property (nonatomic) MWMRouteHelperPanelsDrawer * drawer;
@ -78,12 +77,26 @@ static NSString * const kNavigationDashboardIPADXibName = @"MWMNiPadNavigationDa
_navigationDashboard = isPortrait ? _navigationDashboardPortrait : _navigationDashboardLandscape;
_navigationDashboardPortrait.delegate = _navigationDashboardLandscape.delegate = delegate;
}
_tts = [[MWMTextToSpeech alloc] init];
_helperPanels = [NSMutableArray array];
}
return self;
}
- (void)changedTTSStatus:(NSNotification *)notification
{
if (self.state != MWMNavigationDashboardStateNavigation)
return;
NSDictionary<NSString *, NSNumber *> * userInfo = notification.userInfo;
BOOL const enabled = userInfo[@"on"].boolValue;
self.navigationDashboardPortrait.soundButton.selected = enabled;
self.navigationDashboardLandscape.soundButton.selected = enabled;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Layout
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
@ -142,12 +155,6 @@ static NSString * const kNavigationDashboardIPADXibName = @"MWMNiPadNavigationDa
[self updateDashboard];
}
- (void)playTurnNotifications
{
if (self.state == MWMNavigationDashboardStateNavigation)
[self.tts playTurnNotifications];
}
- (void)handleError
{
[self.routePreview stateError];
@ -192,10 +199,7 @@ static NSString * const kNavigationDashboardIPADXibName = @"MWMNiPadNavigationDa
return;
case 1:
if (![self.helperPanels.firstObject isKindOfClass:panel.class])
{
[self.helperPanels addObject:panel];
return;
}
return;
case 2:
for (MWMRouteHelperPanel * p in self.helperPanels)
@ -272,6 +276,17 @@ static NSString * const kNavigationDashboardIPADXibName = @"MWMNiPadNavigationDa
[self.delegate didCancelRouting];
}
- (IBAction)soundTap:(UIButton *)sender
{
BOOL const isEnable = !sender.selected;
MWMTextToSpeech * tts = [MWMTextToSpeech tts];
if (isEnable)
[tts enable];
else
[tts disable];
sender.selected = isEnable;
}
#pragma mark - MWMNavigationGo
- (IBAction)navigationGoPressed:(UIButton *)sender
@ -316,6 +331,13 @@ static NSString * const kNavigationDashboardIPADXibName = @"MWMNiPadNavigationDa
- (void)showStateNavigation
{
[self.routePreview remove];
MWMTextToSpeech * tts = [MWMTextToSpeech tts];
BOOL const isNeedToEnable = tts.isNeedToEnable;
self.navigationDashboardPortrait.soundButton.selected = isNeedToEnable;
self.navigationDashboardLandscape.soundButton.selected = isNeedToEnable;
if (isNeedToEnable) {
[tts enable];
}
[self.navigationDashboard addToView:self.ownerView];
}

View file

@ -1,14 +1,33 @@
#import <Foundation/Foundation.h>
#include "std/string.hpp"
#include "std/vector.hpp"
@interface MWMTextToSpeech : NSObject
- (instancetype)init;
+ (instancetype)tts;
- (vector<std::pair<string, string>>)availableLanguages;
- (NSString *)savedLanguage;
- (void)setNotificationsLocale:(string const &)locale;
- (BOOL)isNeedToEnable;
- (void)setNeedToEnable:(BOOL)need;
- (BOOL)isEnable;
- (void)enable;
- (void)disable;
- (void)playTurnNotifications;
- (instancetype)init __attribute__((unavailable("call tts instead")));
- (instancetype)copy __attribute__((unavailable("call tts instead")));
- (instancetype)copyWithZone:(NSZone *)zone __attribute__((unavailable("call tts instead")));
+ (instancetype)alloc __attribute__((unavailable("call tts instead")));
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable("call tts instead")));
+ (instancetype)new __attribute__((unavailable("call tts instead")));
@end
namespace tts
{
string bcp47ToTwineLanguage(NSString const * bcp47LangName);
string translatedTwine(string const & twine);
} // namespace tts

View file

@ -1,21 +1,38 @@
#import <AVFoundation/AVFoundation.h>
#import "Common.h"
#import <AVFoundation/AVFoundation.h>
#import "MWMTextToSpeech.h"
#include "Framework.h"
#include "sound/tts/languages.hpp"
extern NSString * const kMwmTextToSpeechEnable = @"MWMTEXTTOSPEECH_ENABLE";
extern NSString * const kMwmTextToSpeechDisable = @"MWMTEXTTOSPEECH_DISABLE";
extern NSString * const kUserDefaultsTTSLanguage = @"UserDefaultsTTSLanguage";
extern NSString * const kUserDafaultsNeedToEnableTTS = @"UserDefaultsNeedToEnableTTS";
@interface MWMTextToSpeech()
{
vector<pair<string, string>> _availableLanguages;
}
@property (nonatomic) AVSpeechSynthesizer * speechSynthesizer;
@property (nonatomic) AVSpeechSynthesisVoice * speechVoice;
@property (nonatomic) float speechRate;
@end
@implementation MWMTextToSpeech
- (instancetype)init
+ (instancetype)tts
{
static dispatch_once_t onceToken;
static MWMTextToSpeech * tts = nil;
dispatch_once(&onceToken, ^
{
tts = [[super alloc] initTTS];
});
return tts;
}
- (instancetype)initTTS
{
self = [super init];
if (self)
@ -27,27 +44,40 @@ extern NSString * const kMwmTextToSpeechDisable = @"MWMTEXTTOSPEECH_DISABLE";
LOG(LWARNING, ("[ setCategory]] error.", [err localizedDescription]));
if (![audioSession setActive:YES error:&err])
LOG(LWARNING, ("[[AVAudioSession sharedInstance] setActive]] error.", [err localizedDescription]));
_availableLanguages = availableLanguages();
NSString * saved = self.savedLanguage;
string preferedLanguage ;
if (saved.length)
preferedLanguage = saved.UTF8String;
else
preferedLanguage = tts::bcp47ToTwineLanguage([AVSpeechSynthesisVoice currentLanguageCode]);
pair<string, string> const lan {preferedLanguage, tts::translatedTwine(preferedLanguage)};
if (find(_availableLanguages.begin(), _availableLanguages.end(), lan) != _availableLanguages.end())
[self setNotificationsLocale:preferedLanguage];
else
[self setNotificationsLocale:"en"];
// Before 9.0 version iOS has an issue with speechRate. AVSpeechUtteranceDefaultSpeechRate does not work correctly.
// It's a work around for iOS 7.x and 8.x.
self.speechRate = isIOSVersionLessThan(@"7.1.1") ? 0.3 : (isIOSVersionLessThan(@"9.0.0") ? 0.15 : AVSpeechUtteranceDefaultSpeechRate);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(enable)
name:kMwmTextToSpeechEnable
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(disable)
name:kMwmTextToSpeechDisable
object:nil];
_speechRate = isIOSVersionLessThan(@"7.1.1") ? 0.3 : (isIOSVersionLessThan(@"9.0.0") ? 0.15 : AVSpeechUtteranceDefaultSpeechRate);
}
return self;
}
-(void)dealloc
- (vector<pair<string, string>>)availableLanguages
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
return _availableLanguages;
}
- (void)setNotificationsLocale:(string const &)locale
{
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];
[ud setObject:@(locale.c_str()) forKey:kUserDefaultsTTSLanguage];
GetFramework().SetTurnNotificationsLocale(locale);
[ud synchronize];
}
- (BOOL)isValid
@ -55,16 +85,32 @@ extern NSString * const kMwmTextToSpeechDisable = @"MWMTEXTTOSPEECH_DISABLE";
return _speechSynthesizer != nil && _speechVoice != nil;
}
- (BOOL)isNeedToEnable
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kUserDafaultsNeedToEnableTTS];
}
- (void)setNeedToEnable:(BOOL)need
{
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];
[ud setBool:need forKey:kUserDafaultsNeedToEnableTTS];
[ud synchronize];
}
- (void)enable
{
if (![self isValid])
[self createSynthesizer];
GetFramework().EnableTurnNotifications(true);
[self setNeedToEnable:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
if (![self isValid])
[self createSynthesizer];
GetFramework().EnableTurnNotifications(true);
});
}
- (void)disable
{
[self setNeedToEnable:NO];
GetFramework().EnableTurnNotifications(false);
}
@ -73,13 +119,17 @@ extern NSString * const kMwmTextToSpeechDisable = @"MWMTEXTTOSPEECH_DISABLE";
return GetFramework().AreTurnNotificationsEnabled() ? YES : NO;
}
- (NSString *)savedLanguage
{
return [[NSUserDefaults standardUserDefaults] stringForKey:kUserDefaultsTTSLanguage];
}
- (void)createSynthesizer
{
self.speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
[self createVoice:self.savedLanguage];
// TODO(vbykoianko) Use [NSLocale preferredLanguages] instead of [AVSpeechSynthesisVoice currentLanguageCode].
// [AVSpeechSynthesisVoice currentLanguageCode] is used now because of we need a language code in BCP-47.
[self createVoice:[AVSpeechSynthesisVoice currentLanguageCode]];
}
- (void)createVoice:(NSString *)locale
@ -113,13 +163,13 @@ extern NSString * const kMwmTextToSpeechDisable = @"MWMTEXTTOSPEECH_DISABLE";
}
self.speechVoice = [AVSpeechSynthesisVoice voiceWithLanguage:locale];
NSString const * twineLang = bcp47ToTwineLanguage(locale);
if (twineLang == nil)
string const twineLang = tts::bcp47ToTwineLanguage(locale);
if (twineLang.empty())
{
LOG(LERROR, ("Cannot convert UI locale or default locale to twine language. MWMTestToSpeech is invalid."));
return; // self is not valid.
}
GetFramework().SetTurnNotificationsLocale([twineLang UTF8String]);
GetFramework().SetTurnNotificationsLocale(twineLang);
}
- (void)speakOneString:(NSString *)textToSpeak
@ -150,4 +200,59 @@ extern NSString * const kMwmTextToSpeechDisable = @"MWMTEXTTOSPEECH_DISABLE";
[self speakOneString:@(text.c_str())];
}
static vector<pair<string, string>> availableLanguages()
{
NSArray<AVSpeechSynthesisVoice *> * voices = [AVSpeechSynthesisVoice speechVoices];
vector<string> native(voices.count);
for (AVSpeechSynthesisVoice * v in voices)
native.push_back(tts::bcp47ToTwineLanguage(v.language));
sort(native.begin(), native.end());
using namespace routing::turns::sound;
vector<pair<string, string>> result;
for (auto const & p : kLanguageList)
{
if (find(native.begin(), native.end(), p.first) != native.end())
result.push_back(p);
}
return result;
}
@end
namespace tts
{
string bcp47ToTwineLanguage(NSString const * bcp47LangName)
{
if (bcp47LangName == nil || [bcp47LangName length] < 2)
return nil;
if ([bcp47LangName isEqualToString:@"zh-CN"] || [bcp47LangName isEqualToString:@"zh-CHS"]
|| [bcp47LangName isEqualToString:@"zh-SG"])
{
return "zh-Hans"; // Chinese simplified
}
if ([bcp47LangName hasPrefix:@"zh"])
return "zh-Hant"; // Chinese traditional
// Taking two first symbols of a language name. For example ru-RU -> ru
return [[bcp47LangName substringToIndex:2] UTF8String];
}
string translatedTwine(string const & twine)
{
auto const & list = routing::turns::sound::kLanguageList;
auto const it = find_if(list.begin(), list.end(), [&twine](pair<string, string> const & pair)
{
return pair.first == twine;
});
if (it != list.end())
return it->second;
else
return "";
}
} // namespace tts

View file

@ -12,6 +12,7 @@
@property (weak, nonatomic) IBOutlet UILabel * arrivalsTimeLabel;
@property (weak, nonatomic) IBOutlet UILabel * roundRoadLabel;
@property (weak, nonatomic) IBOutlet UILabel * streetLabel;
@property (weak, nonatomic) IBOutlet UIButton * soundButton;
@property (weak, nonatomic) IBOutlet UISlider * progress;
- (void)configureWithEntity:(MWMNavigationDashboardEntity *)entity;

View file

@ -6,6 +6,7 @@
#import "MWMAPIBar.h"
#import "MWMMapViewControlsManager.h"
#import "RouteState.h"
#import "MWMTextToSpeech.h"
#import "UIFont+MapsMeFonts.h"
#import "UIViewController+Navigation.h"
@ -143,7 +144,7 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction)
if (res.IsValid())
[self.controlsManager setupRoutingDashboard:res];
[self.controlsManager playTurnNotifications];
[[MWMTextToSpeech tts] playTurnNotifications];
}
- (void)onCompassUpdate:(location::CompassInfo const &)info

View file

@ -47,6 +47,8 @@ static NSString * const kBundleVersion = @"BundleVersion";
extern string const kCountryCodeKey;
extern string const kUniqueIdKey;
extern string const kLanguageKey;
extern NSString * const kUserDefaultsTTSLanguage;
extern NSString * const kUserDafaultsNeedToEnableTTS;
/// Adds needed localized strings to C++ code
/// @TODO Refactor localization mechanism to make it simpler
@ -202,11 +204,13 @@ void InitLocalizedStrings()
[self incrementSessionCount];
[self showAlertIfRequired];
}
Framework & f = GetFramework();
application.applicationIconBadgeNumber = f.GetCountryTree().GetActiveMapLayout().GetOutOfDateCount();
f.GetLocationState()->InvalidatePosition();
[self enableTTSForTheFirstTime];
return returnValue;
}
@ -529,6 +533,17 @@ void InitLocalizedStrings()
[RouteState remove];
}
#pragma mark - TTS
- (void)enableTTSForTheFirstTime
{
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];
if ([ud stringForKey:kUserDefaultsTTSLanguage].length)
return;
[ud setBool:YES forKey:kUserDafaultsNeedToEnableTTS];
[ud synchronize];
}
#pragma mark - Standby
- (void)enableStandby

View file

@ -0,0 +1,5 @@
#import "TableViewController.h"
@interface MWMTTSLanguageViewController : TableViewController
@end

View file

@ -0,0 +1,39 @@
#import "MWMTextToSpeech.h"
#import "MWMTTSLanguageViewController.h"
#import "MWMTTSSettingsViewController.h"
#import "SelectableCell.h"
static NSString * const kUnwingSegueIdentifier = @"UnwindToTTSSettings";
@implementation MWMTTSLanguageViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = L(@"pref_tts_other_section_title");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(SelectableCell *)sender
{
if (![segue.identifier isEqualToString:kUnwingSegueIdentifier])
return;
MWMTTSSettingsViewController * dest = segue.destinationViewController;
NSUInteger const row = [self.tableView indexPathForCell:sender].row;
[dest setAdditionalTTSLanguage:[[MWMTextToSpeech tts] availableLanguages][row]];
}
#pragma mark - UITableViewDataSource && UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[MWMTextToSpeech tts] availableLanguages].size();
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SelectableCell * cell = (SelectableCell *)[tableView dequeueReusableCellWithIdentifier:[SelectableCell className]];
cell.titleLabel.text = @([[MWMTextToSpeech tts] availableLanguages][indexPath.row].second.c_str());
return cell;
}
@end

View file

@ -0,0 +1,7 @@
#import "TableViewController.h"
@interface MWMTTSSettingsViewController : TableViewController
- (void)setAdditionalTTSLanguage:(std::pair<string, string> const &)l;
@end

View file

@ -0,0 +1,134 @@
#import <AVFoundation/AVFoundation.h>
#import "LinkCell.h"
#import "MWMTextToSpeech.h"
#import "MWMTTSSettingsViewController.h"
#import "SelectableCell.h"
static NSString * kSelectTTSLanguageSegueName = @"TTSLanguage";
using namespace std;
@interface MWMTTSSettingsViewController ()
{
pair<string, string> _additionalTTSLanguage;
vector<pair<string, string>> _languages;
}
@property (nonatomic) BOOL isLocaleLanguageAbsent;
@end
@implementation MWMTTSSettingsViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = L(@"pref_tts_language_title");
MWMTextToSpeech * tts = [MWMTextToSpeech tts];
_languages.reserve(3);
auto const & v = tts.availableLanguages;
pair<string, string> const standart = v.front();
_languages.push_back(standart);
using namespace tts;
string const current = bcp47ToTwineLanguage([AVSpeechSynthesisVoice currentLanguageCode]);
if (current != standart.first && !current.empty())
{
string const translated = translatedTwine(current);
pair<string, string> const cur {current, translated};
if (translated.empty() || find(v.begin(), v.end(), cur) != v.end())
_languages.push_back(cur);
else
self.isLocaleLanguageAbsent = YES;
}
string const savedLanguage = tts.savedLanguage.UTF8String;
if (savedLanguage != current && savedLanguage != standart.first && !savedLanguage.empty())
_languages.push_back({savedLanguage, translatedTwine(savedLanguage)});
}
- (IBAction)unwind:(id)sender
{
size_t const size = _languages.size();
switch (size)
{
case 1:
_languages.push_back(_additionalTTSLanguage);
break;
case 2:
if (self.isLocaleLanguageAbsent)
_languages[size - 1] = _additionalTTSLanguage;
else
_languages.push_back(_additionalTTSLanguage);
break;
case 3:
_languages[size - 1] = _additionalTTSLanguage;
break;
default:
NSAssert(false, @"Incorrect language's count");
break;
}
[self.tableView reloadData];
}
- (void)setAdditionalTTSLanguage:(pair<string, string> const &)l
{
[[MWMTextToSpeech tts] setNotificationsLocale:l.first];
_additionalTTSLanguage = l;
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
return _languages.size() + 1;
else
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row != _languages.size())
{
SelectableCell * cell = (SelectableCell *)[tableView dequeueReusableCellWithIdentifier:[SelectableCell className]];
pair<string, string> const p = _languages[indexPath.row];
cell.titleLabel.text = @(p.second.c_str());
BOOL const isSelected = [@(p.first.c_str()) isEqualToString:[[MWMTextToSpeech tts] savedLanguage]];
cell.accessoryType = isSelected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
else
{
LinkCell * cell = (LinkCell *)[tableView dequeueReusableCellWithIdentifier:[LinkCell className]];
cell.titleLabel.text = indexPath.section == 0 ? L(@"pref_tts_other_section_title") : L(@"pref_tts_how_to_set_up_voice");
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
if (indexPath.row == _languages.size())
{
[self performSegueWithIdentifier:kSelectTTSLanguageSegueName sender:nil];
}
else
{
[[MWMTextToSpeech tts] setNotificationsLocale:_languages[indexPath.row].first];
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}
}
else
{
#warning need to add help
}
}
@end

View file

@ -1,4 +1,3 @@
#import "SettingsViewController.h"
#import "SwitchCell.h"
#import "SelectableCell.h"
@ -8,6 +7,7 @@
#import "MapsAppDelegate.h"
#import "Statistics.h"
#import "MWMMapViewControlsManager.h"
#import "MWMTextToSpeech.h"
#include "Framework.h"
@ -16,14 +16,16 @@
#include "platform/preferred_languages.hpp"
extern char const * kStatisticsEnabledSettingsKey;
extern NSString * const kTTSStatusWasChangedNotification = @"TTFStatusWasChangedFromSettingsNotification";
typedef NS_ENUM(NSUInteger, Section)
{
SectionMetrics,
SectionZoomButtons,
SectionRouting,
SectionCalibration,
SectionStatistics,
SectionCount
SectionCount // Must be latest value!
};
@interface SettingsViewController () <SwitchCellDelegate>
@ -60,7 +62,7 @@ typedef NS_ENUM(NSUInteger, Section)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == SectionMetrics)
if (section == SectionMetrics || section == SectionRouting)
return 2;
else
return 1;
@ -110,7 +112,23 @@ typedef NS_ENUM(NSUInteger, Section)
customCell.titleLabel.text = L(@"pref_calibration_title");
customCell.delegate = self;
}
else if (indexPath.section == SectionRouting)
{
if (indexPath.row == 0)
{
cell = [tableView dequeueReusableCellWithIdentifier:[SwitchCell className]];
SwitchCell * customCell = (SwitchCell *)cell;
customCell.switchButton.on = [[MWMTextToSpeech tts] isNeedToEnable];
customCell.titleLabel.text = L(@"pref_tts_enable_title");
customCell.delegate = self;
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:[LinkCell className]];
LinkCell * customCell = (LinkCell *)cell;
customCell.titleLabel.text = L(@"pref_tts_language_title");
}
}
return cell;
}
@ -144,6 +162,13 @@ typedef NS_ENUM(NSUInteger, Section)
{
Settings::Set("CompassCalibrationEnabled", (bool)value);
}
else if (indexPath.section == SectionRouting)
{
[[MWMTextToSpeech tts] setNeedToEnable:value];
[[NSNotificationCenter defaultCenter] postNotificationName:kTTSStatusWasChangedNotification
object:nil
userInfo:@{@"on" : @(value)}];
}
}
Settings::Units unitsForIndex(NSInteger index)
@ -166,6 +191,8 @@ Settings::Units unitsForIndex(NSInteger index)
{
if (section == SectionMetrics)
return L(@"measurement_units");
else if (section == SectionRouting)
return L(@"prefs_group_route");
else
return nil;
}