Fixing submenus

This commit is contained in:
jpirnay
2026-04-24 14:17:50 +02:00
parent ec36670485
commit 9a72409826
7 changed files with 120 additions and 11 deletions
+1
View File
@@ -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;
+1 -1
View File
@@ -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);
@@ -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<int>(action), pendingOrientation, selectedPageTurnOption,
setResult(MenuResult{static_cast<int>(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<size_t>(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<size_t>(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<size_t>(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<SettingsSubmenuActivity>(renderer, mappedInput, submenuEntry.nameId,
it->items, std::move(itemValueStringOverride)),
[this](const ActivityResult& result) {
if (!result.isCancelled) {
const auto* menuResult = std::get_if<MenuResult>(&result.data);
if (menuResult && menuResult->nameId != -1) {
const auto action = actionForNameId(static_cast<StrId>(menuResult->nameId));
if (action != MenuAction::NONE) {
finishWithAction(action);
return;
}
}
}
requestUpdate();
});
}
void EpubReaderMenuActivity::toggleCurrentItem() {
if (selectedIndex < 0 || selectedIndex >= static_cast<int>(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&&) {
@@ -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);
+10 -1
View File
@@ -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<MenuResult>(&result.data);
if (menuResult && menuResult->action != -1) {
auto activity = createActivityForAction(static_cast<SettingAction>(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(),
@@ -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<int>(setting.action);
} else {
menuResult.nameId = static_cast<int>(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(); }
@@ -1,6 +1,7 @@
#pragma once
#include <I18n.h>
#include <functional>
#include <vector>
#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<std::string(const SettingInfo&)> 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<SettingInfo> items)
: MenuListActivity("SettingsSubmenu", renderer, mappedInput), titleId(titleId) {
std::vector<SettingInfo> items,
std::function<std::string(const SettingInfo&)> itemValueStringOverride = {})
: MenuListActivity("SettingsSubmenu", renderer, mappedInput),
titleId(titleId),
itemValueStringOverride(std::move(itemValueStringOverride)) {
menuItems = std::move(items);
}