Rearrange menus + fixes

This commit is contained in:
jpirnay
2026-05-14 23:44:30 +02:00
parent fc02ec67d9
commit 3dfcdd002f
5 changed files with 58 additions and 50 deletions
+16 -14
View File
@@ -92,33 +92,35 @@ inline const std::vector<SettingInfo> list = {
SettingInfo::Enum(StrId::STR_ORIENTATION, &CrossPointSettings::orientation, SettingInfo::Enum(StrId::STR_ORIENTATION, &CrossPointSettings::orientation,
{StrId::STR_PORTRAIT, StrId::STR_LANDSCAPE_CW, StrId::STR_INVERTED, StrId::STR_LANDSCAPE_CCW}, {StrId::STR_PORTRAIT, StrId::STR_LANDSCAPE_CW, StrId::STR_INVERTED, StrId::STR_LANDSCAPE_CCW},
"orientation", StrId::STR_CAT_READER), "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 // side (SettingsActivity / CrossPointWebServer enrich enumLabels before
// iterating). The built-in StrIds are kept as a fallback for code paths that // iterating). The built-in StrIds are kept as a fallback for code paths that
// don't enrich enumLabels. // don't enrich enumLabels.
SettingInfo::DynamicEnum(StrId::STR_FONT_FAMILY, {StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS}, SettingInfo::DynamicEnum(StrId::STR_FONT_FAMILY, {StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS},
fontFamilyDynamicGetter, fontFamilyDynamicSetter, "fontFamily", StrId::STR_CAT_READER) 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, SettingInfo::Enum(StrId::STR_FONT_SIZE, &CrossPointSettings::fontSize,
{StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE, StrId::STR_TINY}, {StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE, StrId::STR_TINY},
"fontSize", StrId::STR_CAT_READER) "fontSize", StrId::STR_CAT_READER)
.withSubmenu(StrId::STR_MENU_READER_FONT_SETTINGS), .withSubmenu(StrId::STR_MENU_READER_FONT),
// 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),
SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing", SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing",
StrId::STR_CAT_READER) 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, 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_NORMAL, StrId::STR_DARK, StrId::STR_EXTRA_DARK, StrId::STR_MAX_DARK}, "textDarkness",
StrId::STR_CAT_READER) 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 // Formatting settings
SettingInfo::Enum( SettingInfo::Enum(
@@ -6,28 +6,12 @@
#include "MappedInputManager.h" #include "MappedInputManager.h"
#include "SdCardFontGlobals.h" #include "SdCardFontGlobals.h"
#include "components/UITheme.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<int>(families.size()); i++) {
if (families[i].name == SETTINGS.sdFontFamilyName) {
return static_cast<uint8_t>(CrossPointSettings::BUILTIN_FONT_COUNT + i);
}
}
}
return SETTINGS.fontFamily < CrossPointSettings::BUILTIN_FONT_COUNT ? SETTINGS.fontFamily : 0;
}
} // namespace
void FontSelectionActivity::onEnter() { void FontSelectionActivity::onEnter() {
Activity::onEnter(); Activity::onEnter();
fontCount = fontFamilyOptionCount(); fontCount = fontFamilyOptionCount();
selectedIndex = currentFontIndex(); selectedIndex =
static_cast<int>(target == Target::TXT ? txtFontFamilyDynamicGetter(nullptr) : fontFamilyDynamicGetter(nullptr));
if (selectedIndex >= fontCount) selectedIndex = 0; if (selectedIndex >= fontCount) selectedIndex = 0;
requestUpdate(); requestUpdate();
} }
@@ -50,7 +34,11 @@ void FontSelectionActivity::loop() {
} }
void FontSelectionActivity::handleSelection() { void FontSelectionActivity::handleSelection() {
fontFamilyDynamicSetter(nullptr, static_cast<uint8_t>(selectedIndex)); if (target == Target::TXT) {
txtFontFamilyDynamicSetter(nullptr, static_cast<uint8_t>(selectedIndex));
} else {
fontFamilyDynamicSetter(nullptr, static_cast<uint8_t>(selectedIndex));
}
finish(); finish();
} }
@@ -60,13 +48,15 @@ void FontSelectionActivity::render(RenderLock&&) {
const auto& metrics = UITheme::getInstance().getMetrics(); const auto& metrics = UITheme::getInstance().getMetrics();
const Rect contentRect = UITheme::getContentRect(renderer, true, false); 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}, 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 contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing; const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing;
const uint8_t activeIndex = currentFontIndex(); const uint8_t activeIndex = static_cast<uint8_t>(target == Target::TXT ? txtFontFamilyDynamicGetter(nullptr)
: fontFamilyDynamicGetter(nullptr));
GUI.drawList( GUI.drawList(
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, fontCount, selectedIndex, renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, fontCount, selectedIndex,
[](int index) { return fontFamilyOptionLabel(static_cast<uint8_t>(index)); }, nullptr, nullptr, [](int index) { return fontFamilyOptionLabel(static_cast<uint8_t>(index)); }, nullptr, nullptr,
@@ -11,8 +11,10 @@ class MappedInputManager;
/// Replaces in-place enum cycling for the Reader Font Family setting. /// Replaces in-place enum cycling for the Reader Font Family setting.
class FontSelectionActivity final : public Activity { class FontSelectionActivity final : public Activity {
public: public:
explicit FontSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput) enum class Target { EPUB, TXT };
: Activity("FontSelect", renderer, mappedInput) {}
explicit FontSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, Target target = Target::EPUB)
: Activity("FontSelect", renderer, mappedInput), target(target) {}
void onEnter() override; void onEnter() override;
void onExit() override; void onExit() override;
@@ -25,4 +27,5 @@ class FontSelectionActivity final : public Activity {
ButtonNavigator buttonNavigator; ButtonNavigator buttonNavigator;
int selectedIndex = 0; int selectedIndex = 0;
uint8_t fontCount = 0; uint8_t fontCount = 0;
Target target;
}; };
+20 -9
View File
@@ -81,10 +81,11 @@ void SettingsActivity::onEnter() {
setting.nameId == StrId::STR_TIMEZONE)) { setting.nameId == StrId::STR_TIMEZONE)) {
continue; 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. // The list itself is a namespace-static; we only mutate our local copy here.
SettingInfo enriched = setting; 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(); const uint8_t n = fontFamilyOptionCount();
enriched.enumLabels.clear(); enriched.enumLabels.clear();
enriched.enumLabels.reserve(n); enriched.enumLabels.reserve(n);
@@ -96,8 +97,7 @@ void SettingsActivity::onEnter() {
continue; continue;
} }
const bool isReaderFontEntry = const bool isReaderFontEntry =
enriched.category == StrId::STR_CAT_READER && (enriched.subcategory == StrId::STR_MENU_READER_FONT || enriched.category == StrId::STR_CAT_READER && enriched.submenu == StrId::STR_MENU_READER_FONT;
enriched.submenu == StrId::STR_MENU_READER_FONT_SETTINGS);
if (!insertedFontDownload && sawReaderFontSection && !isReaderFontEntry) { if (!insertedFontDownload && sawReaderFontSection && !isReaderFontEntry) {
insertFontDownloadBelowFontSection(); insertFontDownloadBelowFontSection();
@@ -278,11 +278,22 @@ void SettingsActivity::toggleCurrentSetting() {
if (setting.isSeparator) return; if (setting.isSeparator) return;
if (setting.type == SettingType::ENUM && setting.nameId == StrId::STR_FONT_FAMILY) { if (setting.type == SettingType::ENUM && setting.nameId == StrId::STR_FONT_FAMILY) {
startActivityForResult(std::make_unique<FontSelectionActivity>(renderer, mappedInput), startActivityForResult(
[this](const ActivityResult&) { std::make_unique<FontSelectionActivity>(renderer, mappedInput, FontSelectionActivity::Target::EPUB),
SETTINGS.saveToFile(); [this](const ActivityResult&) {
needsHalfRefresh = true; SETTINGS.saveToFile();
}); needsHalfRefresh = true;
});
return;
}
if (setting.type == SettingType::ENUM && setting.nameId == StrId::STR_TXT_FONT_FAMILY) {
startActivityForResult(
std::make_unique<FontSelectionActivity>(renderer, mappedInput, FontSelectionActivity::Target::TXT),
[this](const ActivityResult&) {
SETTINGS.saveToFile();
needsHalfRefresh = true;
});
return; return;
} }
+6 -4
View File
@@ -1257,10 +1257,10 @@ void CrossPointWebServer::handleGetSettings() const {
for (const auto& sBase : settings) { for (const auto& sBase : settings) {
if (!sBase.key) continue; // Skip ACTION-only entries 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; SettingInfo sLocal;
const SettingInfo* sPtr = &sBase; 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; sLocal = sBase;
const uint8_t n = fontFamilyOptionCount(); const uint8_t n = fontFamilyOptionCount();
sLocal.enumLabels.clear(); sLocal.enumLabels.clear();
@@ -1380,9 +1380,11 @@ void CrossPointWebServer::handlePostSettings() {
} }
case SettingType::ENUM: { case SettingType::ENUM: {
const int val = doc[s.key].as<int>(); const int val = doc[s.key].as<int>();
// 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. // (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<int>(fontFamilyOptionCount()) ? static_cast<int>(fontFamilyOptionCount())
: static_cast<int>(s.enumLabels.empty() ? s.enumValues.size() : s.enumLabels.size()); : static_cast<int>(s.enumLabels.empty() ? s.enumValues.size() : s.enumLabels.size());
if (val >= 0 && val < count) { if (val >= 0 && val < count) {