diff --git a/lib/I18n/translations/english.yaml b/lib/I18n/translations/english.yaml index 23253403..53514c4f 100644 --- a/lib/I18n/translations/english.yaml +++ b/lib/I18n/translations/english.yaml @@ -474,4 +474,7 @@ STR_WEATHER_MOON_INFO: "Moon" STR_WEATHER_SUN_INFO: "Sun" STR_READER_TOOLS: "Tools" STR_READER_NAVIGATION: "Navigation" -STR_READER_APPEARANCE: "Appearance" \ No newline at end of file +STR_READER_APPEARANCE: "Appearance" +STR_MENU_SYS_SYSTEM: "System" +STR_MENU_SYS_NETWORK: "Network" +STR_MENU_SYS_TOOLS: "Tools" \ No newline at end of file diff --git a/src/activities/reader/EpubReaderMenuActivity.cpp b/src/activities/reader/EpubReaderMenuActivity.cpp index 15641b46..a047c6e9 100644 --- a/src/activities/reader/EpubReaderMenuActivity.cpp +++ b/src/activities/reader/EpubReaderMenuActivity.cpp @@ -67,8 +67,8 @@ std::vector EpubReaderMenuActivity::buildMenuI void EpubReaderMenuActivity::onEnter() { Activity::onEnter(); - const auto pred = UITheme::makeSelectablePredicate( - static_cast(menuItems.size()), [this](int i) { return menuItems[i].getTitle(); }); + const auto pred = UITheme::makeSelectablePredicate(static_cast(menuItems.size()), + [this](int i) { return menuItems[i].getTitle(); }); buttonNavigator.setSelectablePredicate(pred, static_cast(menuItems.size())); if (!pred(selectedIndex)) { selectedIndex = buttonNavigator.nextIndex(selectedIndex); @@ -187,9 +187,7 @@ void EpubReaderMenuActivity::render(RenderLock&&) { GUI.drawList( renderer, Rect{contentRect.x, startY, contentRect.width, listHeight}, static_cast(menuItems.size()), - selectedIndex, - [this](int index) { return menuItems[index].getTitle(); }, - nullptr, nullptr, + selectedIndex, [this](int index) { return menuItems[index].getTitle(); }, nullptr, nullptr, [this](int index) { const auto& item = menuItems[index]; switch (item.action) { diff --git a/src/activities/settings/ClockSettingsActivity.cpp b/src/activities/settings/ClockSettingsActivity.cpp index 4b01adfe..681f2ade 100644 --- a/src/activities/settings/ClockSettingsActivity.cpp +++ b/src/activities/settings/ClockSettingsActivity.cpp @@ -42,8 +42,8 @@ std::vector ClockSettingsActivity::buildMenuIte void ClockSettingsActivity::onEnter() { Activity::onEnter(); - const auto pred = UITheme::makeSelectablePredicate( - static_cast(menuItems.size()), [this](int i) { return menuItems[i].getTitle(); }); + const auto pred = UITheme::makeSelectablePredicate(static_cast(menuItems.size()), + [this](int i) { return menuItems[i].getTitle(); }); buttonNavigator.setSelectablePredicate(pred, static_cast(menuItems.size())); if (!pred(selectedIndex)) { selectedIndex = buttonNavigator.nextIndex(selectedIndex); @@ -126,8 +126,7 @@ void ClockSettingsActivity::render(RenderLock&&) { GUI.drawList( renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast(menuItems.size()), selectedIndex, - [this](int index) { return menuItems[index].getTitle(); }, - nullptr, nullptr, + [this](int index) { return menuItems[index].getTitle(); }, nullptr, nullptr, [this](int index) { const auto action = menuItems[index].action; switch (action) { diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index d64ed44f..d03f6c6e 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -26,6 +26,15 @@ const StrId SettingsActivity::categoryNames[categoryCount] = {StrId::STR_CAT_DISPLAY, StrId::STR_CAT_READER, StrId::STR_CAT_CONTROLS, StrId::STR_CAT_SYSTEM}; +std::string SettingInfo::getTitle() const { + const auto t = I18N.get(nameId); + return isSeparator ? UITheme::makeSeparatorTitle(t) : t; +} + +bool SettingsActivity::isListItemSelectable(int settingIdx) const { + return settingIdx >= 0 && settingIdx < settingsCount && !(*currentSettings)[settingIdx].isSeparator; +} + void SettingsActivity::onEnter() { Activity::onEnter(); @@ -57,15 +66,23 @@ void SettingsActivity::onEnter() { // Append device-only ACTION items controlsSettings.insert(controlsSettings.begin(), SettingInfo::Action(StrId::STR_REMAP_FRONT_BUTTONS, SettingAction::RemapFrontButtons)); - systemSettings.push_back(SettingInfo::Action(StrId::STR_CLOCK_SETTINGS, SettingAction::ClockSettings)); + + systemSettings.push_back(SettingInfo::Action(StrId::STR_LANGUAGE, SettingAction::Language)); + // Network section + systemSettings.push_back(SettingInfo::Separator(StrId::STR_MENU_SYS_NETWORK)); systemSettings.push_back(SettingInfo::Action(StrId::STR_WIFI_NETWORKS, SettingAction::Network)); systemSettings.push_back(SettingInfo::Action(StrId::STR_KOREADER_SYNC, SettingAction::KOReaderSync)); systemSettings.push_back(SettingInfo::Action(StrId::STR_OPDS_BROWSER, SettingAction::OPDSBrowser)); + // Tools section + systemSettings.push_back(SettingInfo::Separator(StrId::STR_MENU_SYS_TOOLS)); + systemSettings.push_back(SettingInfo::Action(StrId::STR_CLOCK_SETTINGS, SettingAction::ClockSettings)); + systemSettings.push_back(SettingInfo::Action(StrId::STR_WEATHER_SETTINGS, SettingAction::Weather)); + // System section + systemSettings.push_back(SettingInfo::Separator(StrId::STR_MENU_SYS_SYSTEM)); systemSettings.push_back(SettingInfo::Action(StrId::STR_CLEAR_READING_CACHE, SettingAction::ClearCache)); systemSettings.push_back(SettingInfo::Action(StrId::STR_CHECK_UPDATES, SettingAction::CheckForUpdates)); - systemSettings.push_back(SettingInfo::Action(StrId::STR_LANGUAGE, SettingAction::Language)); systemSettings.push_back(SettingInfo::Action(StrId::STR_SYSTEM_INFO, SettingAction::SystemInfo)); - systemSettings.push_back(SettingInfo::Action(StrId::STR_WEATHER_SETTINGS, SettingAction::Weather)); + readerSettings.push_back(SettingInfo::Action(StrId::STR_CUSTOMISE_STATUS_BAR, SettingAction::CustomiseStatusBar)); // Reset selection to first category @@ -115,12 +132,14 @@ void SettingsActivity::loop() { // Handle navigation buttonNavigator.onNextRelease([this] { - selectedSettingIndex = ButtonNavigator::nextIndex(selectedSettingIndex, settingsCount + 1); + selectedSettingIndex = ButtonNavigator::nextIndex(selectedSettingIndex, settingsCount + 1, + [this](int i) { return i == 0 || isListItemSelectable(i - 1); }); requestUpdate(); }); buttonNavigator.onPreviousRelease([this] { - selectedSettingIndex = ButtonNavigator::previousIndex(selectedSettingIndex, settingsCount + 1); + selectedSettingIndex = ButtonNavigator::previousIndex( + selectedSettingIndex, settingsCount + 1, [this](int i) { return i == 0 || isListItemSelectable(i - 1); }); requestUpdate(); }); @@ -163,6 +182,7 @@ void SettingsActivity::toggleCurrentSetting() { } const auto& setting = (*currentSettings)[selectedSetting]; + if (setting.isSeparator) return; if (setting.type == SettingType::TOGGLE && setting.valuePtr != nullptr) { // Toggle the boolean value using the member pointer @@ -258,8 +278,8 @@ void SettingsActivity::render(RenderLock&&) { Rect{contentRect.x, contentTop, contentRect.width, contentRect.height - (metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing * 2)}, - settingsCount, selectedSettingIndex - 1, - [&settings](int index) { return std::string(I18N.get(settings[index].nameId)); }, nullptr, nullptr, + settingsCount, selectedSettingIndex - 1, [&settings](int index) { return settings[index].getTitle(); }, nullptr, + nullptr, [&settings](int i) { const auto& setting = settings[i]; std::string valueText = ""; diff --git a/src/activities/settings/SettingsActivity.h b/src/activities/settings/SettingsActivity.h index 1a1bf5f6..589b2c39 100644 --- a/src/activities/settings/SettingsActivity.h +++ b/src/activities/settings/SettingsActivity.h @@ -142,6 +142,17 @@ struct SettingInfo { s.category = category; return s; } + + static SettingInfo Separator(StrId nameId) { + SettingInfo s; + s.nameId = nameId; + s.type = SettingType::ACTION; + s.isSeparator = true; + return s; + } + + bool isSeparator = false; + [[nodiscard]] std::string getTitle() const; }; class SettingsActivity final : public Activity { @@ -163,6 +174,7 @@ class SettingsActivity final : public Activity { void enterCategory(int categoryIndex); void toggleCurrentSetting(); + [[nodiscard]] bool isListItemSelectable(int settingIdx) const; public: explicit SettingsActivity(GfxRenderer& renderer, MappedInputManager& mappedInput) diff --git a/src/components/UITheme.cpp b/src/components/UITheme.cpp index 6b92df15..d4ec15ad 100644 --- a/src/components/UITheme.cpp +++ b/src/components/UITheme.cpp @@ -108,11 +108,9 @@ std::string UITheme::stripSeparatorTitle(const std::string& title) { return isSeparatorTitle(title) ? title.substr(2) : title; } -std::function UITheme::makeSelectablePredicate(int total, - std::function titleGetter) { - return [total, titleGetter](int index) { - return index >= 0 && index < total && !isSeparatorTitle(titleGetter(index)); - }; +std::function UITheme::makeSelectablePredicate(int total, std::function titleGetter) { + return + [total, titleGetter](int index) { return index >= 0 && index < total && !isSeparatorTitle(titleGetter(index)); }; } std::string UITheme::getCoverThumbPath(std::string coverBmpPath, int coverHeight) {