diff --git a/src/activities/ActivityResult.h b/src/activities/ActivityResult.h index ae163500..151137b6 100644 --- a/src/activities/ActivityResult.h +++ b/src/activities/ActivityResult.h @@ -20,6 +20,7 @@ struct KeyboardResult { struct MenuResult { int action = -1; + int nameId = -1; uint8_t orientation = 0; uint8_t pageTurnOption = 0; int8_t embeddedStyleOverride = -1; diff --git a/src/activities/MenuListActivity.h b/src/activities/MenuListActivity.h index 719f43d8..9d501fed 100644 --- a/src/activities/MenuListActivity.h +++ b/src/activities/MenuListActivity.h @@ -86,7 +86,7 @@ class MenuListActivity : public Activity { void handleNavigation(); // Toggle/cycle the currently selected item. For ACTION items, delegates to onActionSelected(). - void toggleCurrentItem(); + virtual void toggleCurrentItem(); // Draw the list into the given rect using GUI.drawList(). void drawMenuList(const Rect& rect); diff --git a/src/activities/reader/EpubReaderMenuActivity.cpp b/src/activities/reader/EpubReaderMenuActivity.cpp index 5bcc9568..271d3beb 100644 --- a/src/activities/reader/EpubReaderMenuActivity.cpp +++ b/src/activities/reader/EpubReaderMenuActivity.cpp @@ -5,6 +5,7 @@ #include "KOReaderCredentialStore.h" #include "MappedInputManager.h" +#include "activities/settings/SettingsSubmenuActivity.h" #include "components/UITheme.h" #include "fontIds.h" @@ -202,7 +203,7 @@ EpubReaderMenuActivity::MenuAction EpubReaderMenuActivity::actionForNameId(StrId } void EpubReaderMenuActivity::finishWithAction(MenuAction action) { - setResult(MenuResult{static_cast(action), pendingOrientation, selectedPageTurnOption, + setResult(MenuResult{static_cast(action), -1, pendingOrientation, selectedPageTurnOption, pendingEmbeddedStyleOverride, pendingImageRenderingOverride, pendingFontFamilyOverride, pendingFontSizeOverride, pendingTextDarkness}); finish(); @@ -230,6 +231,7 @@ void EpubReaderMenuActivity::onBackPressed() { ActivityResult result; result.isCancelled = true; result.data = MenuResult{-1, + -1, pendingOrientation, selectedPageTurnOption, pendingEmbeddedStyleOverride, @@ -255,10 +257,10 @@ std::string EpubReaderMenuActivity::getItemValueString(int index) const { return currentPageStarred ? std::string(tr(STR_STATE_ON)) : std::string(tr(STR_STATE_OFF)); } - // Plain ACTION items (select chapter, screenshot, etc.) show no value. - // Submenu placeholders should still show the standard submenu indicator. if (item.type == SettingType::ACTION) { - if (item.action == SettingAction::Submenu) return MenuListActivity::getItemValueString(index); + if (item.action == SettingAction::Submenu) { + return MenuListActivity::getItemValueString(index); + } return {}; } @@ -291,6 +293,73 @@ std::string EpubReaderMenuActivity::getItemValueString(int index) const { return MenuListActivity::getItemValueString(index); } +void EpubReaderMenuActivity::openSubmenu(const SettingInfo& submenuEntry) { + auto it = std::find_if(submenuData.begin(), submenuData.end(), + [&submenuEntry](const SettingInfo::SubmenuData& d) { return d.id == submenuEntry.nameId; }); + if (it == submenuData.end()) return; + + auto itemValueStringOverride = [this](const SettingInfo& item) -> std::string { + if (item.nameId == StrId::STR_EMBEDDED_STYLE && pendingEmbeddedStyleOverride < 0) { + const auto defaultEffective = (SETTINGS.embeddedStyle != 0) ? tr(STR_STATE_ON) : tr(STR_STATE_OFF); + return std::string(tr(STR_DEFAULT_VALUE)) + " (" + defaultEffective + ")"; + } + if (item.nameId == StrId::STR_IMAGES && pendingImageRenderingOverride < 0) { + const auto valueIndex = static_cast(SETTINGS.imageRendering + 1); + if (valueIndex < item.enumValues.size()) { + return std::string(tr(STR_DEFAULT_VALUE)) + " (" + I18N.get(item.enumValues[valueIndex]) + ")"; + } + } + if (item.nameId == StrId::STR_FONT_FAMILY && pendingFontFamilyOverride < 0) { + const auto valueIndex = static_cast(SETTINGS.fontFamily + 1); + if (valueIndex < item.enumValues.size()) { + return std::string(tr(STR_DEFAULT_VALUE)) + " (" + I18N.get(item.enumValues[valueIndex]) + ")"; + } + } + if (item.nameId == StrId::STR_FONT_SIZE && pendingFontSizeOverride < 0) { + const auto valueIndex = static_cast(SETTINGS.fontSize + 1); + if (valueIndex < item.enumValues.size()) { + return std::string(tr(STR_DEFAULT_VALUE)) + " (" + I18N.get(item.enumValues[valueIndex]) + ")"; + } + } + return item.getDisplayValue(); + }; + + startActivityForResult(std::make_unique(renderer, mappedInput, submenuEntry.nameId, + it->items, std::move(itemValueStringOverride)), + [this](const ActivityResult& result) { + if (!result.isCancelled) { + const auto* menuResult = std::get_if(&result.data); + if (menuResult && menuResult->nameId != -1) { + const auto action = actionForNameId(static_cast(menuResult->nameId)); + if (action != MenuAction::NONE) { + finishWithAction(action); + return; + } + } + } + requestUpdate(); + }); +} + +void EpubReaderMenuActivity::toggleCurrentItem() { + if (selectedIndex < 0 || selectedIndex >= static_cast(menuItems.size())) return; + const auto& item = menuItems[selectedIndex]; + if (item.isSeparator) return; + + if (item.type == SettingType::ACTION) { + if (item.action == SettingAction::Submenu) { + openSubmenu(item); + return; + } + onActionSelected(selectedIndex); + return; + } + + menuItems[selectedIndex].toggleValue(); + onSettingToggled(selectedIndex); + requestUpdate(); +} + void EpubReaderMenuActivity::onEnter() { MenuListActivity::onEnter(); } void EpubReaderMenuActivity::render(RenderLock&&) { diff --git a/src/activities/reader/EpubReaderMenuActivity.h b/src/activities/reader/EpubReaderMenuActivity.h index b052714f..368d39eb 100644 --- a/src/activities/reader/EpubReaderMenuActivity.h +++ b/src/activities/reader/EpubReaderMenuActivity.h @@ -53,6 +53,8 @@ class EpubReaderMenuActivity final : public MenuListActivity { void onActionSelected(int index) override; void onBackPressed() override; void onSettingToggled(int index) override; + void toggleCurrentItem() override; + void openSubmenu(const SettingInfo& submenuEntry); // Map from StrId to MenuAction for result passing static MenuAction actionForNameId(StrId nameId); diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 87d606e5..01020f65 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -213,7 +213,16 @@ void SettingsActivity::toggleCurrentSetting() { if (setting.isSeparator) return; if (setting.type == SettingType::ACTION) { - auto resultHandler = [this](const ActivityResult&) { SETTINGS.saveToFile(); }; + auto resultHandler = [this](const ActivityResult& result) { + SETTINGS.saveToFile(); + const auto* menuResult = std::get_if(&result.data); + if (menuResult && menuResult->action != -1) { + auto activity = createActivityForAction(static_cast(menuResult->action), renderer, mappedInput); + if (activity) { + startActivityForResult(std::move(activity), [this](const ActivityResult&) { SETTINGS.saveToFile(); }); + } + } + }; if (setting.action == SettingAction::Submenu) { auto it = std::find_if(submenuData.begin(), submenuData.end(), diff --git a/src/activities/settings/SettingsSubmenuActivity.cpp b/src/activities/settings/SettingsSubmenuActivity.cpp index d3d5262a..0fc68ff0 100644 --- a/src/activities/settings/SettingsSubmenuActivity.cpp +++ b/src/activities/settings/SettingsSubmenuActivity.cpp @@ -17,10 +17,32 @@ void SettingsSubmenuActivity::onEnter() { void SettingsSubmenuActivity::onActionSelected(int index) { const auto& setting = menuItems[index]; - auto resultHandler = [this](const ActivityResult&) { SETTINGS.saveToFile(); }; + if (setting.isSeparator) return; - auto activity = createActivityForAction(setting.action, renderer, mappedInput); - if (activity) startActivityForResult(std::move(activity), resultHandler); + if (setting.type == SettingType::ACTION) { + MenuResult menuResult; + if (setting.action != SettingAction::None) { + menuResult.action = static_cast(setting.action); + } else { + menuResult.nameId = static_cast(setting.nameId); + } + setResult(ActivityResult(menuResult)); + finish(); + return; + } + + onSettingToggled(index); +} + +std::string SettingsSubmenuActivity::getItemValueString(int index) const { + const auto& item = menuItems[index]; + if (item.type == SettingType::ACTION && item.action != SettingAction::Submenu) { + return {}; + } + if (itemValueStringOverride) { + return itemValueStringOverride(item); + } + return MenuListActivity::getItemValueString(index); } void SettingsSubmenuActivity::onSettingToggled(int /*index*/) { SETTINGS.saveToFile(); } diff --git a/src/activities/settings/SettingsSubmenuActivity.h b/src/activities/settings/SettingsSubmenuActivity.h index c8288dda..32618941 100644 --- a/src/activities/settings/SettingsSubmenuActivity.h +++ b/src/activities/settings/SettingsSubmenuActivity.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "SettingInfo.h" @@ -10,16 +11,21 @@ // Supports subcategory separators (withSubcategory) exactly as the parent settings tabs do. class SettingsSubmenuActivity final : public MenuListActivity { StrId titleId; + std::function itemValueStringOverride; // MenuListActivity overrides void onEnter() override; void onActionSelected(int index) override; void onSettingToggled(int index) override; + std::string getItemValueString(int index) const override; public: explicit SettingsSubmenuActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, StrId titleId, - std::vector items) - : MenuListActivity("SettingsSubmenu", renderer, mappedInput), titleId(titleId) { + std::vector items, + std::function itemValueStringOverride = {}) + : MenuListActivity("SettingsSubmenu", renderer, mappedInput), + titleId(titleId), + itemValueStringOverride(std::move(itemValueStringOverride)) { menuItems = std::move(items); }