diff --git a/apps/global_preferences.cpp b/apps/global_preferences.cpp index c6644f5fd..5c6c4cd77 100644 --- a/apps/global_preferences.cpp +++ b/apps/global_preferences.cpp @@ -5,6 +5,11 @@ GlobalPreferences * GlobalPreferences::sharedGlobalPreferences() { return &globalPreferences; } +void GlobalPreferences::setCountry(I18n::Country country) { + m_country = country; + Poincare::Preferences::sharedPreferences()->setUnitFormat(unitFormat()); +} + GlobalPreferences::ExamMode GlobalPreferences::examMode() const { if (m_examMode == ExamMode::Unknown) { uint8_t mode = Ion::ExamMode::FetchExamMode(); diff --git a/apps/global_preferences.h b/apps/global_preferences.h index c6c20ff8b..b4471d008 100644 --- a/apps/global_preferences.h +++ b/apps/global_preferences.h @@ -15,7 +15,7 @@ public: I18n::Language language() const { return m_language; } void setLanguage(I18n::Language language) { m_language = language; } I18n::Country country() const { return m_country; } - void setCountry(I18n::Country country) { m_country = country; } + void setCountry(I18n::Country country); CountryPreferences::AvailableExamModes availableExamModes() const { return I18n::CountryPreferencesArray[static_cast(m_country)].availableExamModes(); } CountryPreferences::MethodForQuartiles methodForQuartiles() const { return I18n::CountryPreferencesArray[static_cast(m_country)].methodForQuartiles(); } Poincare::Preferences::UnitFormat unitFormat() const { return I18n::CountryPreferencesArray[static_cast(m_country)].unitFormat(); } diff --git a/apps/on_boarding/Makefile b/apps/on_boarding/Makefile index c65dbc633..b85d410e7 100644 --- a/apps/on_boarding/Makefile +++ b/apps/on_boarding/Makefile @@ -1,9 +1,8 @@ app_on_boarding_src = $(addprefix apps/on_boarding/,\ app.cpp \ - country_controller.cpp \ - language_controller.cpp \ logo_controller.cpp \ logo_view.cpp \ + localization_controller.cpp \ pop_up_controller.cpp \ power_on_self_test.cpp \ ) diff --git a/apps/on_boarding/app.cpp b/apps/on_boarding/app.cpp index ae12d0792..3e914f7d9 100644 --- a/apps/on_boarding/app.cpp +++ b/apps/on_boarding/app.cpp @@ -1,4 +1,5 @@ #include "app.h" +#include "../apps_container.h" #include namespace OnBoarding { @@ -13,10 +14,8 @@ App::Descriptor * App::Snapshot::descriptor() { } App::App(Snapshot * snapshot) : - ::App(snapshot, &m_stackController), - m_stackController(&m_modalViewController, &m_languageController), - m_languageController(&m_stackController), - m_countryController(&m_languageController), + ::App(snapshot, &m_localizationController), + m_localizationController(&m_modalViewController, Metric::CommonTopMargin, LocalizationController::Mode::Language), m_logoController() { } @@ -46,8 +45,7 @@ void App::didBecomeActive(Window * window) { } void App::reinitOnBoarding() { - m_languageController.resetSelection(); - m_countryController.resetSelection(); + m_localizationController.resetSelection(); displayModalViewController(&m_logoController, 0.5f, 0.5f); } diff --git a/apps/on_boarding/app.h b/apps/on_boarding/app.h index a965ce087..d58a0b1ad 100644 --- a/apps/on_boarding/app.h +++ b/apps/on_boarding/app.h @@ -2,9 +2,8 @@ #define ON_BOARDING_APP_H #include -#include "country_controller.h" -#include "language_controller.h" #include "logo_controller.h" +#include "localization_controller.h" namespace OnBoarding { @@ -16,11 +15,6 @@ public: Descriptor * descriptor() override; }; - static App * app() { - return static_cast(Container::activeApp()); - } - - CountryController * countryController() { return &m_countryController; } int numberOfTimers() override; Timer * timerAtIndex(int i) override; bool processEvent(Ion::Events::Event) override; @@ -28,9 +22,7 @@ public: private: App(Snapshot * snapshot); void reinitOnBoarding(); - StackViewController m_stackController; - LanguageController m_languageController; - CountryController m_countryController; + LocalizationController m_localizationController; LogoController m_logoController; }; diff --git a/apps/on_boarding/country_controller.cpp b/apps/on_boarding/country_controller.cpp deleted file mode 100644 index 29f04eec6..000000000 --- a/apps/on_boarding/country_controller.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "country_controller.h" -#include "../apps_container.h" -#include -#include - -namespace OnBoarding { - -CountryController::CountryController(Responder * parentResponder) : - Shared::CountryController( - parentResponder, - std::max( - static_cast(Metric::CommonLeftMargin), - (Ion::Display::Height - I18n::NumberOfCountries*Metric::ParameterCellHeight)/2)) -{ - static_cast(selectableTableView()->decorator()->indicatorAtIndex(1))->setMargin( - std::max( - static_cast(Metric::CommonLeftMargin), - (Ion::Display::Height - I18n::NumberOfCountries*Metric::ParameterCellHeight)/2)); -} - -void CountryController::resetSelection() { - selectableTableView()->deselectTable(); - /* The base ::CountryController behaviour is to highlight the previously - * chosen country. On boarding, we want the highlighted cell to be the first - * alphabetically, but with the default behaviour, it would be Canada, as it - * is the country of value t 0. */ - selectCellAtLocation(0, 0); -} - -bool CountryController::handleEvent(Ion::Events::Event event) { - if (Shared::CountryController::handleEvent(event)) { - AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); - if (appsContainer->promptController()) { - Container::activeApp()->displayModalViewController(appsContainer->promptController(), 0.5f, 0.5f); - } else { - appsContainer->switchTo(appsContainer->appSnapshotAtIndex(0)); - } - return true; - } - return false; -} - -} diff --git a/apps/on_boarding/country_controller.h b/apps/on_boarding/country_controller.h deleted file mode 100644 index 737770414..000000000 --- a/apps/on_boarding/country_controller.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef ON_BOARDING_COUNTRY_CONTROLLER_H -#define ON_BOARDING_COUNTRY_CONTROLLER_H - -#include -#include "../shared/country_controller.h" - -namespace OnBoarding { - -class CountryController : public Shared::CountryController { -public: - CountryController(Responder * parentResponder); - void resetSelection() override; - bool handleEvent(Ion::Events::Event event) override; - ViewController::DisplayParameter displayParameter() override { return ViewController::DisplayParameter::WantsMaximumSpace; } - -}; - -} - -#endif diff --git a/apps/on_boarding/language_controller.cpp b/apps/on_boarding/language_controller.cpp deleted file mode 100644 index cbe21962f..000000000 --- a/apps/on_boarding/language_controller.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "language_controller.h" -#include "../global_preferences.h" -#include "../apps_container.h" -#include "app.h" -#include "country_controller.h" -#include -#include - -namespace OnBoarding { - -LanguageController::LanguageController(Responder * parentResponder) : - Shared::LanguageController( - parentResponder, - std::max(static_cast(Metric::CommonLeftMargin), - (Ion::Display::Height - I18n::NumberOfLanguages*Metric::ParameterCellHeight)/2)) -{ - static_cast(m_selectableTableView.decorator()->indicatorAtIndex(1))->setMargin( - std::max(static_cast(Metric::CommonLeftMargin), - (Ion::Display::Height - I18n::NumberOfLanguages*Metric::ParameterCellHeight)/2)); -} - -bool LanguageController::handleEvent(Ion::Events::Event event) { - if (Shared::LanguageController::handleEvent(event)) { - AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); - if (appsContainer->promptController()) { - Container::activeApp()->displayModalViewController(appsContainer->promptController(), 0.5f, 0.5f); - } else { - stackController()->push(App::app()->countryController()); - } - return true; - } - if (event == Ion::Events::Back) { - return true; - } - return false; -} - -} diff --git a/apps/on_boarding/language_controller.h b/apps/on_boarding/language_controller.h deleted file mode 100644 index 08e23b26d..000000000 --- a/apps/on_boarding/language_controller.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ON_BOARDING_LANGUAGE_CONTROLLER_H -#define ON_BOARDING_LANGUAGE_CONTROLLER_H - -#include -#include "../shared/language_controller.h" - -namespace OnBoarding { - -class LanguageController : public Shared::LanguageController { -public: - LanguageController(Responder * parentResponder); - bool handleEvent(Ion::Events::Event event) override; - ViewController::DisplayParameter displayParameter() override { return ViewController::DisplayParameter::DoNotShowOwnTitle; } - -private: - StackViewController * stackController() { return static_cast(parentResponder()); } -}; - -} - -#endif diff --git a/apps/on_boarding/localization_controller.cpp b/apps/on_boarding/localization_controller.cpp new file mode 100644 index 000000000..bed17051f --- /dev/null +++ b/apps/on_boarding/localization_controller.cpp @@ -0,0 +1,33 @@ +#include "localization_controller.h" +#include +#include + +namespace OnBoarding { + +bool LocalizationController::handleEvent(Ion::Events::Event event) { + if (Shared::LocalizationController::handleEvent(event)) { + if (mode() == Mode::Language) { + setMode(Mode::Country); + viewWillAppear(); + } else { + assert(mode() == Mode::Country); + AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); + if (appsContainer->promptController()) { + Container::activeApp()->displayModalViewController(appsContainer->promptController(), 0.5f, 0.5f); + } else { + appsContainer->switchTo(appsContainer->appSnapshotAtIndex(0)); + } + } + return true; + } + if (event == Ion::Events::Back) { + if (mode() == Mode::Country) { + setMode(Mode::Language); + viewWillAppear(); + } + return true; + } + return false; +} + +} diff --git a/apps/on_boarding/localization_controller.h b/apps/on_boarding/localization_controller.h new file mode 100644 index 000000000..3f47a6fb0 --- /dev/null +++ b/apps/on_boarding/localization_controller.h @@ -0,0 +1,21 @@ +#ifndef ON_BOARDING_LOCALIZATION_CONTROLLER_H +#define ON_BOARDING_LOCALIZATION_CONTROLLER_H + +#include +#include + +namespace OnBoarding { + +class LocalizationController : public Shared::LocalizationController { +public: + using Shared::LocalizationController::LocalizationController; + + bool shouldDisplayTitle() override { return mode() == Mode::Country; } + bool shouldResetSelectionToTopCell() override { return true; } + + bool handleEvent(Ion::Events::Event event) override; +}; + +} + +#endif diff --git a/apps/settings/Makefile b/apps/settings/Makefile index 17b679bb2..0d38a7d18 100644 --- a/apps/settings/Makefile +++ b/apps/settings/Makefile @@ -12,13 +12,12 @@ app_settings_src = $(addprefix apps/settings/,\ sub_menu/about_controller.cpp \ sub_menu/about_controller_official.cpp:+official \ sub_menu/about_controller_non_official.cpp:-official \ - sub_menu/country_controller.cpp \ sub_menu/display_mode_controller.cpp \ sub_menu/exam_mode_controller_official.cpp:+official \ sub_menu/exam_mode_controller_non_official.cpp:-official \ sub_menu/exam_mode_controller.cpp \ sub_menu/generic_sub_controller.cpp \ - sub_menu/language_controller.cpp \ + sub_menu/localization_controller.cpp \ sub_menu/preferences_controller.cpp \ sub_menu/selectable_view_with_messages.cpp \ ) diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp index c15e67c15..d12cb186b 100644 --- a/apps/settings/main_controller.cpp +++ b/apps/settings/main_controller.cpp @@ -22,8 +22,7 @@ MainController::MainController(Responder * parentResponder, InputEventHandlerDel m_selectableTableView(this), m_preferencesController(this), m_displayModeController(this, inputEventHandlerDelegate), - m_languageController(this, Metric::CommonTopMargin), - m_countryController(this, Metric::CommonTopMargin), + m_localizationController(this, Metric::CommonTopMargin, LocalizationController::Mode::Language), m_examModeController(this), m_aboutController(this) { @@ -67,6 +66,12 @@ bool MainController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { assert(rowIndex != k_indexOfBrightnessCell); + + if (rowIndex == k_indexOfLanguageCell) { + m_localizationController.setMode(LocalizationController::Mode::Language); + } else if (rowIndex == k_indexOfCountryCell) { + m_localizationController.setMode(LocalizationController::Mode::Country); + } /* The About cell can either be found at index k_indexOfExamModeCell + 1 or * k_indexOfExamModeCell + 2, depending on whether there is a Pop-Up cell. * Since the Pop-Up cell has been handled above, we can use those two @@ -78,8 +83,8 @@ bool MainController::handleEvent(Ion::Events::Event event) { &m_preferencesController, nullptr, //&m_brightnessController &m_preferencesController, - &m_languageController, - &m_countryController, + &m_localizationController, + &m_localizationController, &m_examModeController, &m_aboutController, &m_aboutController diff --git a/apps/settings/main_controller.h b/apps/settings/main_controller.h index 4e887aa0f..f9675455f 100644 --- a/apps/settings/main_controller.h +++ b/apps/settings/main_controller.h @@ -5,10 +5,9 @@ #include #include "message_table_cell_with_gauge_with_separator.h" #include "sub_menu/about_controller.h" -#include "sub_menu/country_controller.h" #include "sub_menu/display_mode_controller.h" #include "sub_menu/exam_mode_controller.h" -#include "sub_menu/language_controller.h" +#include "sub_menu/localization_controller.h" #include "sub_menu/preferences_controller.h" namespace Settings { @@ -65,8 +64,7 @@ private: SelectableTableView m_selectableTableView; PreferencesController m_preferencesController; DisplayModeController m_displayModeController; - LanguageController m_languageController; - CountryController m_countryController; + LocalizationController m_localizationController; ExamModeController m_examModeController; AboutController m_aboutController; diff --git a/apps/settings/sub_menu/country_controller.cpp b/apps/settings/sub_menu/country_controller.cpp deleted file mode 100644 index 8b709b369..000000000 --- a/apps/settings/sub_menu/country_controller.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "country_controller.h" - -namespace Settings { - -CountryController::CountryController(Responder * parentResponder, KDCoordinate verticalMargin) : - Shared::CountryController(parentResponder, verticalMargin) -{ - m_contentView.shouldDisplayTitle(false); -} - - -bool CountryController::handleEvent(Ion::Events::Event event) { - if (Shared::CountryController::handleEvent(event) || event == Ion::Events::Left) { - static_cast(parentResponder())->pop(); - return true; - } - return false; -} - -} diff --git a/apps/settings/sub_menu/country_controller.h b/apps/settings/sub_menu/country_controller.h deleted file mode 100644 index a75b0f962..000000000 --- a/apps/settings/sub_menu/country_controller.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef SETTING_COUNTRY_CONTROLLER_H -#define SETTING_COUNTRY_CONTROLLER_H - -#include -#include "../../shared/country_controller.h" - -namespace Settings { - -class CountryController : public Shared::CountryController { -public: - CountryController(Responder * parentResponder, KDCoordinate verticalMargin); - bool handleEvent(Ion::Events::Event event) override; -}; - -} - -#endif diff --git a/apps/settings/sub_menu/language_controller.cpp b/apps/settings/sub_menu/language_controller.cpp deleted file mode 100644 index 9edb1857a..000000000 --- a/apps/settings/sub_menu/language_controller.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "language_controller.h" - -namespace Settings { - -bool LanguageController::handleEvent(Ion::Events::Event event) { - if (Shared::LanguageController::handleEvent(event) || event == Ion::Events::Left) { - static_cast(parentResponder())->pop(); - return true; - } - return false; -} - -} diff --git a/apps/settings/sub_menu/language_controller.h b/apps/settings/sub_menu/language_controller.h deleted file mode 100644 index e0e358aca..000000000 --- a/apps/settings/sub_menu/language_controller.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SETTINGS_LANGUAGE_CONTROLLER_H -#define SETTINGS_LANGUAGE_CONTROLLER_H - -#include -#include "../../shared/language_controller.h" - -namespace Settings { - -class LanguageController : public Shared::LanguageController { -public: - using Shared::LanguageController::LanguageController; - bool handleEvent(Ion::Events::Event event) override; - TELEMETRY_ID("Language"); -}; - -} - -#endif diff --git a/apps/settings/sub_menu/localization_controller.cpp b/apps/settings/sub_menu/localization_controller.cpp new file mode 100644 index 000000000..b77981c8e --- /dev/null +++ b/apps/settings/sub_menu/localization_controller.cpp @@ -0,0 +1,13 @@ +#include "localization_controller.h" + +namespace Settings { + +bool LocalizationController::handleEvent(Ion::Events::Event event) { + if (Shared::LocalizationController::handleEvent(event) || event == Ion::Events::Left) { + static_cast(parentResponder())->pop(); + return true; + } + return false; +} + +} diff --git a/apps/settings/sub_menu/localization_controller.h b/apps/settings/sub_menu/localization_controller.h new file mode 100644 index 000000000..7fee93862 --- /dev/null +++ b/apps/settings/sub_menu/localization_controller.h @@ -0,0 +1,21 @@ +#ifndef SETTING_LOCALIZATION_CONTROLLER_H +#define SETTING_LOCALIZATION_CONTROLLER_H + +#include +#include + +namespace Settings { + +class LocalizationController : public Shared::LocalizationController { +public: + using Shared::LocalizationController::LocalizationController; + + bool shouldDisplayTitle() override { return false; } + bool shouldResetSelectionToTopCell() override { return false; } + + bool handleEvent(Ion::Events::Event event) override; + TELEMETRY_ID("Localization"); +}; +} + +#endif diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 481c962e0..c90ce2973 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -26,7 +26,6 @@ app_shared_src = $(addprefix apps/shared/,\ buffer_function_title_cell.cpp \ buffer_text_view_with_text_field.cpp \ button_with_separator.cpp \ - country_controller.cpp \ cursor_view.cpp \ editable_cell_table_view_controller.cpp \ expression_field_delegate_app.cpp \ @@ -51,9 +50,9 @@ app_shared_src = $(addprefix apps/shared/,\ interactive_curve_view_controller.cpp \ interval.cpp \ interval_parameter_controller.cpp \ - language_controller.cpp \ layout_field_delegate.cpp \ list_parameter_controller.cpp \ + localization_controller.cpp \ message_view.cpp \ ok_view.cpp \ parameter_text_field_delegate.cpp \ diff --git a/apps/shared/country_controller.cpp b/apps/shared/country_controller.cpp deleted file mode 100644 index 7678d23ec..000000000 --- a/apps/shared/country_controller.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "country_controller.h" -#include "../global_preferences.h" -#include "../apps_container.h" -#include -#include - -namespace Shared { - -// CountryController::ContentView -constexpr int CountryController::ContentView::k_numberOfTextLines; - -CountryController::ContentView::ContentView(CountryController * controller, SelectableTableViewDataSource * dataSource) : - m_selectableTableView(controller, controller, dataSource), - m_titleMessage(KDFont::LargeFont, I18n::Message::Country), - m_displayTitle(true) -{ - m_titleMessage.setBackgroundColor(Palette::WallScreen); - m_titleMessage.setAlignment(0.5f, 0.5f); - I18n::Message textMessages[k_numberOfTextLines] = {I18n::Message::CountryWarning1, I18n::Message::CountryWarning2}; - for (int i = 0; i < k_numberOfTextLines; i++) { - m_messageLines[i].setBackgroundColor(Palette::WallScreen); - m_messageLines[i].setFont(KDFont::SmallFont); - m_messageLines[i].setAlignment(0.5f, 0.5f); - m_messageLines[i].setMessage(textMessages[i]); - } -} - -void CountryController::ContentView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), Palette::WallScreen); -} - -View * CountryController::ContentView::subviewAtIndex(int i) { - assert(i < numberOfSubviews()); - switch (i) { - case 0: - return &m_selectableTableView; - case 1: - return &m_titleMessage; - default: - return &m_messageLines[i - 2]; - } -} - -void CountryController::ContentView::layoutSubviews(bool force) { - KDCoordinate origin = Metric::CommonTopMargin; - if (m_displayTitle) { - origin = layoutTitleSubview(force, origin) + Metric::CommonSmallMargin; - } - origin = layoutSubtitleSubview(force, origin) + Metric::CommonTopMargin; - origin = layoutTableSubview(force, origin); - assert(origin <= bounds().height()); -} - -KDCoordinate CountryController::ContentView::layoutTitleSubview(bool force, KDCoordinate verticalOrigin) { - KDCoordinate titleHeight = m_titleMessage.font()->glyphSize().height(); - m_titleMessage.setFrame(KDRect(0, verticalOrigin, bounds().width(), titleHeight), force); - return verticalOrigin + titleHeight; -} - -KDCoordinate CountryController::ContentView::layoutSubtitleSubview(bool force, KDCoordinate verticalOrigin) { - assert(k_numberOfTextLines > 0); - KDCoordinate textHeight = m_messageLines[0].font()->glyphSize().height(); - for (int i = 0; i < k_numberOfTextLines; i++) { - m_messageLines[i].setFrame(KDRect(0, verticalOrigin, bounds().width(), textHeight), force); - verticalOrigin += textHeight; - } - return verticalOrigin; -} - -KDCoordinate CountryController::ContentView::layoutTableSubview(bool force, KDCoordinate verticalOrigin) { - KDCoordinate tableHeight = std::min( - bounds().height() - verticalOrigin, - m_selectableTableView.minimalSizeForOptimalDisplay().height()); - m_selectableTableView.setFrame(KDRect(0, verticalOrigin, bounds().width(), tableHeight), force); - return verticalOrigin + tableHeight; -} - -// CountryController -int CountryController::IndexOfCountry(I18n::Country country) { - /* As we want to order the countries alphabetically in the selected language, - * the index of a country in the table is the number of other countries that - * go before it in alphabetical order. */ - int res = 0; - for (int c = 0; c < I18n::NumberOfCountries; c++) { - if (country != static_cast(c) && strcmp(I18n::translate(I18n::CountryNames[static_cast(country)]), I18n::translate(I18n::CountryNames[c])) > 0) { - res += 1; - } - } - return res; -} - -I18n::Country CountryController::CountryAtIndex(int i) { - /* This method is called for each country one after the other, so we could - * save a lot of computations by memoizing the IndexInTableOfCountry. - * However, since the number of countries is fairly small, and the country - * menu is unlikely to be used more than once or twice in the device's - * lifespan, we skim on memory usage here.*/ - for (int c = 0; c < I18n::NumberOfCountries; c++) { - I18n::Country country = static_cast(c); - if (i == IndexOfCountry(country)) { - return country; - } - } - assert(false); - return (I18n::Country)0; -} - -CountryController::CountryController(Responder * parentResponder, KDCoordinate verticalMargin) : - ViewController(parentResponder), - m_contentView(this, this) -{ - selectableTableView()->setTopMargin(0); - selectableTableView()->setBottomMargin(verticalMargin); - for (int i = 0; i < I18n::NumberOfCountries; i++) { - m_cells[i].setMessageFont(KDFont::LargeFont); - } -} - -void CountryController::resetSelection() { - selectableTableView()->deselectTable(); - selectCellAtLocation(0, IndexOfCountry(GlobalPreferences::sharedGlobalPreferences()->country())); -} - - -void CountryController::viewWillAppear() { - ViewController::viewWillAppear(); - resetSelection(); - /* FIXME : When selecting a country, changing the language, then coming back - * to select a country, some countries' names will be cropped. We force the - * TableView to refresh to prevent that. */ - selectableTableView()->reloadData(); -} - -bool CountryController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::OK || event == Ion::Events::EXE) { - /* FIXME : Changing the unit format should perhaps be done in setCountry.*/ - I18n::Country country = CountryAtIndex(selectedRow()); - GlobalPreferences::sharedGlobalPreferences()->setCountry(country); - Poincare::Preferences::sharedPreferences()->setUnitFormat(GlobalPreferences::sharedGlobalPreferences()->unitFormat()); - return true; - } - return false; -} - -void CountryController::willDisplayCellForIndex(HighlightCell * cell, int index) { - static_cast(cell)->setMessage(I18n::CountryNames[static_cast(CountryAtIndex(index))]); -} - -} diff --git a/apps/shared/country_controller.h b/apps/shared/country_controller.h deleted file mode 100644 index 624802f86..000000000 --- a/apps/shared/country_controller.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef SHARED_COUNTRY_CONTROLLER_H -#define SHARED_COUNTRY_CONTROLLER_H - -#include -#include - -namespace Shared { - -class CountryController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { -public: - static int IndexOfCountry(I18n::Country country); - static I18n::Country CountryAtIndex(int i); - - CountryController(Responder * parentResponder, KDCoordinate verticalMargin); - virtual void resetSelection(); - - View * view() override { return &m_contentView; } - const char * title() override { return I18n::translate(I18n::Message::Country); } - void didBecomeFirstResponder() override { Container::activeApp()->setFirstResponder(selectableTableView()); } - void viewWillAppear() override; - bool handleEvent(Ion::Events::Event event) override; - - int numberOfRows() const override { return I18n::NumberOfCountries; } - KDCoordinate cellHeight() override { return Metric::ParameterCellHeight; } - HighlightCell * reusableCell(int index) override { return &m_cells[index]; } - int reusableCellCount() const override { return I18n::NumberOfCountries; } - - void willDisplayCellForIndex(HighlightCell * cell, int index) override; - -protected: - class ContentView : public View { - public: - ContentView(CountryController * controller, SelectableTableViewDataSource * dataSource); - SelectableTableView * selectableTableView() { return &m_selectableTableView; } - void drawRect(KDContext * ctx, KDRect rect) const override; - void shouldDisplayTitle(bool flag) { m_displayTitle = flag; } - protected: - void layoutSubviews(bool force = false) override; - KDCoordinate layoutTitleSubview(bool force, KDCoordinate verticalOrigin); - KDCoordinate layoutSubtitleSubview(bool force, KDCoordinate verticalOrigin); - KDCoordinate layoutTableSubview(bool force, KDCoordinate verticalOrigin); - private: - constexpr static int k_numberOfTextLines = 2; - int numberOfSubviews() const override { return 1 + 1 + k_numberOfTextLines; } - View * subviewAtIndex(int i) override; - SelectableTableView m_selectableTableView; - MessageTextView m_titleMessage; - MessageTextView m_messageLines[k_numberOfTextLines]; - bool m_displayTitle; - }; - - SelectableTableView * selectableTableView() { return m_contentView.selectableTableView(); } - ContentView m_contentView; - -private: - MessageTableCell m_cells[I18n::NumberOfCountries]; -}; - -} - -#endif diff --git a/apps/shared/language_controller.cpp b/apps/shared/language_controller.cpp deleted file mode 100644 index 5c0897f53..000000000 --- a/apps/shared/language_controller.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "language_controller.h" -#include "../global_preferences.h" -#include "../apps_container.h" -#include - -namespace Shared { - -LanguageController::LanguageController(Responder * parentResponder, KDCoordinate verticalMargin) : - ViewController(parentResponder), - m_selectableTableView(this, this, this) -{ - m_selectableTableView.setTopMargin(verticalMargin); - m_selectableTableView.setBottomMargin(verticalMargin); - for (int i = 0; i < I18n::NumberOfLanguages; i++) { - m_cells[i].setMessageFont(KDFont::LargeFont); - } -} - -void LanguageController::resetSelection() { - m_selectableTableView.deselectTable(); - selectCellAtLocation(0, (int)(GlobalPreferences::sharedGlobalPreferences()->language())); -} - -const char * LanguageController::title() { - return I18n::translate(I18n::Message::Language); -} - -View * LanguageController::view() { - return &m_selectableTableView; -} - -void LanguageController::didBecomeFirstResponder() { - Container::activeApp()->setFirstResponder(&m_selectableTableView); -} - -void LanguageController::viewWillAppear() { - ViewController::viewWillAppear(); - resetSelection(); -} - -bool LanguageController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::OK || event == Ion::Events::EXE) { - GlobalPreferences::sharedGlobalPreferences()->setLanguage((I18n::Language)selectedRow()); - /* We need to reload the whole title bar in order to translate both the - * "Settings" title and the degree preference. */ - AppsContainer::sharedAppsContainer()->reloadTitleBarView(); - return true; - } - return false; -} - -int LanguageController::numberOfRows() const { - return I18n::NumberOfLanguages; -} - -KDCoordinate LanguageController::cellHeight() { - return Metric::ParameterCellHeight; -} - -HighlightCell * LanguageController::reusableCell(int index) { - return &m_cells[index]; -} - -int LanguageController::reusableCellCount() const { - return I18n::NumberOfLanguages; -} - -void LanguageController::willDisplayCellForIndex(HighlightCell * cell, int index) { - static_cast(cell)->setMessage(I18n::LanguageNames[index]); -} - -} diff --git a/apps/shared/language_controller.h b/apps/shared/language_controller.h deleted file mode 100644 index a3ab284e2..000000000 --- a/apps/shared/language_controller.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef SHARED_LANGUAGE_CONTROLLER_H -#define SHARED_LANGUAGE_CONTROLLER_H - -#include -#include - -namespace Shared { - -class LanguageController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { -public: - LanguageController(Responder * parentResponder, KDCoordinate verticalMargin); - void resetSelection(); - - View * view() override; - const char * title() override; - void didBecomeFirstResponder() override; - void viewWillAppear() override; - bool handleEvent(Ion::Events::Event event) override; - - int numberOfRows() const override; - KDCoordinate cellHeight() override; - HighlightCell * reusableCell(int index) override; - int reusableCellCount() const override; - - void willDisplayCellForIndex(HighlightCell * cell, int index) override; - -protected: - SelectableTableView m_selectableTableView; - -private: - MessageTableCell m_cells[I18n::NumberOfLanguages]; -}; - -} - -#endif diff --git a/apps/shared/localization_controller.cpp b/apps/shared/localization_controller.cpp new file mode 100644 index 000000000..ba433b95f --- /dev/null +++ b/apps/shared/localization_controller.cpp @@ -0,0 +1,176 @@ +#include "localization_controller.h" +#include +#include + +namespace Shared { + +// ContentView +constexpr int LocalizationController::ContentView::k_numberOfCountryWarningLines; + +LocalizationController::ContentView::ContentView(LocalizationController * controller, SelectableTableViewDataSource * dataSource) : + m_controller(controller), + m_selectableTableView(controller, controller, dataSource), + m_countryTitleMessage(KDFont::LargeFont, I18n::Message::Country) +{ + m_countryTitleMessage.setBackgroundColor(Palette::WallScreen); + m_countryTitleMessage.setAlignment(0.5f, 0.5f); + I18n::Message textMessages[k_numberOfCountryWarningLines] = {I18n::Message::CountryWarning1, I18n::Message::CountryWarning2}; + for (int i = 0; i < k_numberOfCountryWarningLines; i++) { + m_countryWarningLines[i].setBackgroundColor(Palette::WallScreen); + m_countryWarningLines[i].setFont(KDFont::SmallFont); + m_countryWarningLines[i].setAlignment(0.5f, 0.5f); + m_countryWarningLines[i].setMessage(textMessages[i]); + } +} + +int LocalizationController::ContentView::numberOfSubviews() const { + return 1 + m_controller->shouldDisplayTitle() + k_numberOfCountryWarningLines * m_controller->shouldDisplayWarning(); +} + +View * LocalizationController::ContentView::subviewAtIndex(int i) { + assert(i < numberOfSubviews()); + /* FIXME : This relies on the fact that the title is never displayed without the warning. */ + switch (i) { + case 0: + return &m_selectableTableView; + case 3: + return &m_countryTitleMessage; + default: + return &m_countryWarningLines[i-1]; + } +} + +void LocalizationController::ContentView::modeHasChanged() { + layoutSubviews(); + markRectAsDirty(bounds()); +} + +void LocalizationController::ContentView::layoutSubviews(bool force) { + KDCoordinate origin = 0; + if (m_controller->shouldDisplayTitle()) { + origin = layoutTitleSubview(force, Metric::CommonTopMargin + origin); + } + if (m_controller->shouldDisplayWarning()) { + origin = layoutWarningSubview(force, Metric::CommonTopMargin + origin) + Metric::CommonTopMargin; + } + origin = layoutTableSubview(force, origin); + assert(origin <= bounds().height()); +} + +KDCoordinate LocalizationController::ContentView::layoutTitleSubview(bool force, KDCoordinate verticalOrigin) { + KDCoordinate titleHeight = m_countryTitleMessage.font()->glyphSize().height(); + m_countryTitleMessage.setFrame(KDRect(0, verticalOrigin, bounds().width(), titleHeight), force); + return verticalOrigin + titleHeight; +} + +KDCoordinate LocalizationController::ContentView::layoutWarningSubview(bool force, KDCoordinate verticalOrigin) { + assert(k_numberOfCountryWarningLines > 0); + KDCoordinate textHeight = m_countryWarningLines[0].font()->glyphSize().height(); + for (int i = 0; i < k_numberOfCountryWarningLines; i++) { + m_countryWarningLines[i].setFrame(KDRect(0, verticalOrigin, bounds().width(), textHeight), force); + verticalOrigin += textHeight; + } + return verticalOrigin; +} + +KDCoordinate LocalizationController::ContentView::layoutTableSubview(bool force, KDCoordinate verticalOrigin) { + KDCoordinate tableHeight = std::min( + bounds().height() - verticalOrigin, + m_selectableTableView.minimalSizeForOptimalDisplay().height()); + m_selectableTableView.setFrame(KDRect(0, verticalOrigin, bounds().width(), tableHeight), force); + return verticalOrigin + tableHeight; +} + +// LocalizationController +constexpr int LocalizationController::k_numberOfCells; + +int LocalizationController::IndexOfCountry(I18n::Country country) { + /* As we want to order the countries alphabetically in the selected language, + * the index of a country in the table is the number of other countries that + * go before it in alphabetical order. */ + int res = 0; + for (int c = 0; c < I18n::NumberOfCountries; c++) { + if (country != static_cast(c) && strcmp(I18n::translate(I18n::CountryNames[static_cast(country)]), I18n::translate(I18n::CountryNames[c])) > 0) { + res += 1; + } + } + return res; +} + +I18n::Country LocalizationController::CountryAtIndex(int i) { + /* This method is called for each country one after the other, so we could + * save a lot of computations by memoizing the IndexInTableOfCountry. + * However, since the number of countries is fairly small, and the country + * menu is unlikely to be used more than once or twice in the device's + * lifespan, we skim on memory usage here.*/ + for (int c = 0; c < I18n::NumberOfCountries; c++) { + I18n::Country country = static_cast(c); + if (i == IndexOfCountry(country)) { + return country; + } + } + assert(false); + return (I18n::Country)0; +} + +LocalizationController::LocalizationController(Responder * parentResponder, KDCoordinate verticalMargin, LocalizationController::Mode mode) : + ViewController(parentResponder), + m_contentView(this, this), + m_mode(mode) +{ + selectableTableView()->setTopMargin((shouldDisplayWarning()) ? 0 : verticalMargin); + selectableTableView()->setBottomMargin(verticalMargin); + for (int i = 0; i < k_numberOfCells; i++) { + m_cells[i].setMessageFont(KDFont::LargeFont); + } +} + +void LocalizationController::resetSelection() { + selectableTableView()->deselectTable(); + selectCellAtLocation(0, (shouldResetSelectionToTopCell()) ? 0 : (mode() == Mode::Language) ? static_cast(GlobalPreferences::sharedGlobalPreferences()->language()) : IndexOfCountry(GlobalPreferences::sharedGlobalPreferences()->country())); +} + +void LocalizationController::setMode(LocalizationController::Mode mode) { + selectableTableView()->deselectTable(); + m_mode = mode; + selectableTableView()->setTopMargin((shouldDisplayWarning()) ? 0 : selectableTableView()->bottomMargin()); + m_contentView.modeHasChanged(); +} + +const char * LocalizationController::title() { + if (mode() == Mode::Language) { + return I18n::translate(I18n::Message::Language); + } + assert(mode() == Mode::Country); + return I18n::translate(I18n::Message::Country); +} + +void LocalizationController::viewWillAppear() { + ViewController::viewWillAppear(); + resetSelection(); + selectableTableView()->reloadData(); +} + +bool LocalizationController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + if (mode() == Mode::Language) { + GlobalPreferences::sharedGlobalPreferences()->setLanguage(static_cast(selectedRow())); + AppsContainer::sharedAppsContainer()->reloadTitleBarView(); + } else { + assert(mode() == Mode::Country); + GlobalPreferences::sharedGlobalPreferences()->setCountry(CountryAtIndex(selectedRow())); + } + return true; + } + return false; +} + +void LocalizationController::willDisplayCellForIndex(HighlightCell * cell, int index) { + if (mode() == Mode::Language) { + static_cast(cell)->setMessage(I18n::LanguageNames[index]); + return; + } + assert(mode() == Mode::Country); + static_cast(cell)->setMessage(I18n::CountryNames[static_cast(CountryAtIndex(index))]); +} +} diff --git a/apps/shared/localization_controller.h b/apps/shared/localization_controller.h new file mode 100644 index 000000000..224ca7c37 --- /dev/null +++ b/apps/shared/localization_controller.h @@ -0,0 +1,79 @@ +#ifndef LOCALIZATION_CONTROLLER_H +#define LOCALIZATION_CONTROLLER_H + +#include +#include +#include + +namespace Shared { + +class LocalizationController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { +public: + static int IndexOfCountry(I18n::Country country); + static I18n::Country CountryAtIndex(int i); + + enum class Mode : uint8_t { + Language, + Country + }; + + LocalizationController(Responder * parentResponder, KDCoordinate verticalMargin, Mode mode); + void resetSelection(); + Mode mode() const { return m_mode; } + void setMode(Mode mode); + + virtual bool shouldDisplayTitle() = 0; + virtual bool shouldResetSelectionToTopCell() = 0; + bool shouldDisplayWarning() { return mode() == Mode::Country; } + + View * view() override { return &m_contentView; } + const char * title() override; + void didBecomeFirstResponder() override { Container::activeApp()->setFirstResponder(selectableTableView()); } + void viewWillAppear() override; + bool handleEvent(Ion::Events::Event event) override; + + int numberOfRows() const override { return (mode() == Mode::Country) ? I18n::NumberOfCountries : I18n::NumberOfLanguages; } + KDCoordinate cellHeight() override { return Metric::ParameterCellHeight; } + HighlightCell * reusableCell(int index) override { return &m_cells[index]; } + int reusableCellCount() const override { return (mode() == Mode::Country) ? I18n::NumberOfCountries : I18n::NumberOfLanguages; } + + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + +protected: + class ContentView : public View { + public: + ContentView(LocalizationController * controller, SelectableTableViewDataSource * dataSource); + + SelectableTableView * selectableTableView() { return &m_selectableTableView; } + void drawRect(KDContext * ctx, KDRect rect) const override { ctx->fillRect(bounds(), Palette::WallScreen); } + void modeHasChanged(); + + private: + constexpr static int k_numberOfCountryWarningLines = 2; + + void layoutSubviews(bool force = false) override; + KDCoordinate layoutTitleSubview(bool force, KDCoordinate verticalOrigin); + KDCoordinate layoutWarningSubview(bool force, KDCoordinate verticalOrigin); + KDCoordinate layoutTableSubview(bool force, KDCoordinate verticalOrigin); + int numberOfSubviews() const override; + View * subviewAtIndex(int i) override; + + LocalizationController * m_controller; + SelectableTableView m_selectableTableView; + MessageTextView m_countryTitleMessage; + MessageTextView m_countryWarningLines[k_numberOfCountryWarningLines]; + }; + + SelectableTableView * selectableTableView() { return m_contentView.selectableTableView(); } + + ContentView m_contentView; + +private: + static constexpr int k_numberOfCells = I18n::NumberOfLanguages > I18n::NumberOfCountries ? I18n::NumberOfLanguages : I18n::NumberOfCountries; + MessageTableCell m_cells[k_numberOfCells]; + Mode m_mode; +}; + +} + +#endif