diff --git a/src/SettingsList.h b/src/SettingsList.h index f92460ce..c9a5c147 100644 --- a/src/SettingsList.h +++ b/src/SettingsList.h @@ -92,33 +92,35 @@ inline const std::vector list = { SettingInfo::Enum(StrId::STR_ORIENTATION, &CrossPointSettings::orientation, {StrId::STR_PORTRAIT, StrId::STR_LANDSCAPE_CW, StrId::STR_INVERTED, StrId::STR_LANDSCAPE_CCW}, "orientation", StrId::STR_CAT_READER), - // EPUB font — DynamicEnum so SD card font families can be appended at the consumer + // EPUB font submenu — family first, then size/AA/darkness. + // DynamicEnum so SD card font families can be appended at the consumer // side (SettingsActivity / CrossPointWebServer enrich enumLabels before // iterating). The built-in StrIds are kept as a fallback for code paths that // don't enrich enumLabels. SettingInfo::DynamicEnum(StrId::STR_FONT_FAMILY, {StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS}, fontFamilyDynamicGetter, fontFamilyDynamicSetter, "fontFamily", StrId::STR_CAT_READER) - .withSubcategory(StrId::STR_MENU_READER_FONT), + .withSubcategory(StrId::STR_MENU_READER_FONT) + .withSubmenu(StrId::STR_MENU_READER_FONT), SettingInfo::Enum(StrId::STR_FONT_SIZE, &CrossPointSettings::fontSize, {StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE, StrId::STR_TINY}, "fontSize", StrId::STR_CAT_READER) - .withSubmenu(StrId::STR_MENU_READER_FONT_SETTINGS), - // TXT/MD font — same dynamic structure as the EPUB font entry above. - SettingInfo::DynamicEnum(StrId::STR_TXT_FONT_FAMILY, {StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS}, - txtFontFamilyDynamicGetter, txtFontFamilyDynamicSetter, "txtFontFamily", - StrId::STR_CAT_READER) - .withSubcategory(StrId::STR_MENU_TXT_FONT), - SettingInfo::Enum(StrId::STR_TXT_FONT_SIZE, &CrossPointSettings::txtFontSize, - {StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE, StrId::STR_TINY}, - "txtFontSize", StrId::STR_CAT_READER) - .withSubcategory(StrId::STR_MENU_TXT_FONT), + .withSubmenu(StrId::STR_MENU_READER_FONT), SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing", StrId::STR_CAT_READER) - .withSubmenu(StrId::STR_MENU_READER_FONT_SETTINGS), + .withSubmenu(StrId::STR_MENU_READER_FONT), SettingInfo::Enum(StrId::STR_TEXT_DARKNESS, &CrossPointSettings::textDarkness, {StrId::STR_NORMAL, StrId::STR_DARK, StrId::STR_EXTRA_DARK, StrId::STR_MAX_DARK}, "textDarkness", StrId::STR_CAT_READER) - .withSubmenu(StrId::STR_MENU_READER_FONT_SETTINGS), + .withSubmenu(StrId::STR_MENU_READER_FONT), + // TXT/MD font submenu — same dynamic structure as EPUB, includes SD card fonts. + SettingInfo::DynamicEnum(StrId::STR_TXT_FONT_FAMILY, {StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS}, + txtFontFamilyDynamicGetter, txtFontFamilyDynamicSetter, "txtFontFamily", + StrId::STR_CAT_READER) + .withSubmenu(StrId::STR_MENU_TXT_FONT), + SettingInfo::Enum(StrId::STR_TXT_FONT_SIZE, &CrossPointSettings::txtFontSize, + {StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE, StrId::STR_TINY}, + "txtFontSize", StrId::STR_CAT_READER) + .withSubmenu(StrId::STR_MENU_TXT_FONT), // Formatting settings SettingInfo::Enum( diff --git a/src/activities/settings/FontSelectionActivity.cpp b/src/activities/settings/FontSelectionActivity.cpp index bd609b6d..c3b1f583 100644 --- a/src/activities/settings/FontSelectionActivity.cpp +++ b/src/activities/settings/FontSelectionActivity.cpp @@ -6,28 +6,12 @@ #include "MappedInputManager.h" #include "SdCardFontGlobals.h" #include "components/UITheme.h" -#include "fontIds.h" - -namespace { - -uint8_t currentFontIndex() { - if (SETTINGS.sdFontFamilyName[0] != '\0') { - const auto& families = sdFontSystem.registry().getFamilies(); - for (int i = 0; i < static_cast(families.size()); i++) { - if (families[i].name == SETTINGS.sdFontFamilyName) { - return static_cast(CrossPointSettings::BUILTIN_FONT_COUNT + i); - } - } - } - return SETTINGS.fontFamily < CrossPointSettings::BUILTIN_FONT_COUNT ? SETTINGS.fontFamily : 0; -} - -} // namespace void FontSelectionActivity::onEnter() { Activity::onEnter(); fontCount = fontFamilyOptionCount(); - selectedIndex = currentFontIndex(); + selectedIndex = + static_cast(target == Target::TXT ? txtFontFamilyDynamicGetter(nullptr) : fontFamilyDynamicGetter(nullptr)); if (selectedIndex >= fontCount) selectedIndex = 0; requestUpdate(); } @@ -50,7 +34,11 @@ void FontSelectionActivity::loop() { } void FontSelectionActivity::handleSelection() { - fontFamilyDynamicSetter(nullptr, static_cast(selectedIndex)); + if (target == Target::TXT) { + txtFontFamilyDynamicSetter(nullptr, static_cast(selectedIndex)); + } else { + fontFamilyDynamicSetter(nullptr, static_cast(selectedIndex)); + } finish(); } @@ -60,13 +48,15 @@ void FontSelectionActivity::render(RenderLock&&) { const auto& metrics = UITheme::getInstance().getMetrics(); const Rect contentRect = UITheme::getContentRect(renderer, true, false); + const StrId headerStr = target == Target::TXT ? StrId::STR_TXT_FONT_FAMILY : StrId::STR_FONT_FAMILY; GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight}, - tr(STR_FONT_FAMILY)); + I18N.get(headerStr)); const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing; const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing; - const uint8_t activeIndex = currentFontIndex(); + const uint8_t activeIndex = static_cast(target == Target::TXT ? txtFontFamilyDynamicGetter(nullptr) + : fontFamilyDynamicGetter(nullptr)); GUI.drawList( renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, fontCount, selectedIndex, [](int index) { return fontFamilyOptionLabel(static_cast(index)); }, nullptr, nullptr, diff --git a/src/activities/settings/FontSelectionActivity.h b/src/activities/settings/FontSelectionActivity.h index 4ab0cf14..01b98cb5 100644 --- a/src/activities/settings/FontSelectionActivity.h +++ b/src/activities/settings/FontSelectionActivity.h @@ -11,8 +11,10 @@ class MappedInputManager; /// Replaces in-place enum cycling for the Reader Font Family setting. class FontSelectionActivity final : public Activity { public: - explicit FontSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput) - : Activity("FontSelect", renderer, mappedInput) {} + enum class Target { EPUB, TXT }; + + explicit FontSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, Target target = Target::EPUB) + : Activity("FontSelect", renderer, mappedInput), target(target) {} void onEnter() override; void onExit() override; @@ -25,4 +27,5 @@ class FontSelectionActivity final : public Activity { ButtonNavigator buttonNavigator; int selectedIndex = 0; uint8_t fontCount = 0; + Target target; }; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index dbac7bd2..85e6b8ae 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -81,10 +81,11 @@ void SettingsActivity::onEnter() { setting.nameId == StrId::STR_TIMEZONE)) { continue; } - // Enrich the font-family entry with SD card families discovered at boot. + // Enrich font-family entries with SD card families discovered at boot. // The list itself is a namespace-static; we only mutate our local copy here. SettingInfo enriched = setting; - if (setting.key && std::strcmp(setting.key, "fontFamily") == 0) { + if (setting.key && + (std::strcmp(setting.key, "fontFamily") == 0 || std::strcmp(setting.key, "txtFontFamily") == 0)) { const uint8_t n = fontFamilyOptionCount(); enriched.enumLabels.clear(); enriched.enumLabels.reserve(n); @@ -96,8 +97,7 @@ void SettingsActivity::onEnter() { continue; } const bool isReaderFontEntry = - enriched.category == StrId::STR_CAT_READER && (enriched.subcategory == StrId::STR_MENU_READER_FONT || - enriched.submenu == StrId::STR_MENU_READER_FONT_SETTINGS); + enriched.category == StrId::STR_CAT_READER && enriched.submenu == StrId::STR_MENU_READER_FONT; if (!insertedFontDownload && sawReaderFontSection && !isReaderFontEntry) { insertFontDownloadBelowFontSection(); @@ -278,11 +278,22 @@ void SettingsActivity::toggleCurrentSetting() { if (setting.isSeparator) return; if (setting.type == SettingType::ENUM && setting.nameId == StrId::STR_FONT_FAMILY) { - startActivityForResult(std::make_unique(renderer, mappedInput), - [this](const ActivityResult&) { - SETTINGS.saveToFile(); - needsHalfRefresh = true; - }); + startActivityForResult( + std::make_unique(renderer, mappedInput, FontSelectionActivity::Target::EPUB), + [this](const ActivityResult&) { + SETTINGS.saveToFile(); + needsHalfRefresh = true; + }); + return; + } + + if (setting.type == SettingType::ENUM && setting.nameId == StrId::STR_TXT_FONT_FAMILY) { + startActivityForResult( + std::make_unique(renderer, mappedInput, FontSelectionActivity::Target::TXT), + [this](const ActivityResult&) { + SETTINGS.saveToFile(); + needsHalfRefresh = true; + }); return; } diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index 15f3e9e9..9d63b9eb 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -1257,10 +1257,10 @@ void CrossPointWebServer::handleGetSettings() const { for (const auto& sBase : settings) { if (!sBase.key) continue; // Skip ACTION-only entries - // Enrich the font-family entry with current SD card families. + // Enrich font-family entries with current SD card families. SettingInfo sLocal; const SettingInfo* sPtr = &sBase; - if (std::strcmp(sBase.key, "fontFamily") == 0) { + if (sBase.key && (std::strcmp(sBase.key, "fontFamily") == 0 || std::strcmp(sBase.key, "txtFontFamily") == 0)) { sLocal = sBase; const uint8_t n = fontFamilyOptionCount(); sLocal.enumLabels.clear(); @@ -1380,9 +1380,11 @@ void CrossPointWebServer::handlePostSettings() { } case SettingType::ENUM: { const int val = doc[s.key].as(); - // For fontFamily the enumLabels in the static list are empty by design + // For font-family keys the enumLabels in the static list are empty by design // (built lazily by handleGetSettings); use the dynamic option count instead. - const int count = (std::strcmp(s.key, "fontFamily") == 0) + const bool isFontFamilyKey = + s.key && (std::strcmp(s.key, "fontFamily") == 0 || std::strcmp(s.key, "txtFontFamily") == 0); + const int count = isFontFamilyKey ? static_cast(fontFamilyOptionCount()) : static_cast(s.enumLabels.empty() ? s.enumValues.size() : s.enumLabels.size()); if (val >= 0 && val < count) {