Add submenus
This commit is contained in:
@@ -481,3 +481,8 @@ STR_MENU_SYS_TOOLS: "Tools"
|
|||||||
STR_MENU_DISP_SLEEP: "Sleepscreen"
|
STR_MENU_DISP_SLEEP: "Sleepscreen"
|
||||||
STR_MENU_DISP_BATTERY: "Battery symbol"
|
STR_MENU_DISP_BATTERY: "Battery symbol"
|
||||||
STR_MENU_DISP_REFRESH: "Screen refresh"
|
STR_MENU_DISP_REFRESH: "Screen refresh"
|
||||||
|
STR_MENU_READER_FONT: "Reader Font"
|
||||||
|
STR_MENU_READER_FONT_SETTINGS: "Font Settings"
|
||||||
|
STR_MENU_READER_LAYOUT: "Layout Settings"
|
||||||
|
STR_MENU_READER_TWEAKS: "Reader Tweaks"
|
||||||
|
STR_MENU_READER_SPACING: "Spacing"
|
||||||
+51
-29
@@ -27,8 +27,14 @@
|
|||||||
//
|
//
|
||||||
// ACTION-type entries and entries without a key are device-only and are added directly
|
// ACTION-type entries and entries without a key are device-only and are added directly
|
||||||
// in SettingsActivity::onEnter(), not here.
|
// in SettingsActivity::onEnter(), not here.
|
||||||
inline const std::vector<SettingInfo>& getSettingsList() {
|
//
|
||||||
static const std::vector<SettingInfo> list = {
|
// Implementation note: the list is a namespace-level static (not a function-local static) so
|
||||||
|
// it is initialised during the global-static phase before setup() runs. A function-local
|
||||||
|
// static would trigger __cxa_guard_acquire on the first call, which creates a FreeRTOS mutex
|
||||||
|
// deep inside the heap allocator chain — enough stack to overflow the 8 KB loop task stack
|
||||||
|
// when called from inside SETTINGS.loadFromFile() at boot time.
|
||||||
|
namespace SettingsListDetail {
|
||||||
|
inline const std::vector<SettingInfo> list = {
|
||||||
// --- Display ---
|
// --- Display ---
|
||||||
SettingInfo::Enum(StrId::STR_TIME_TO_SLEEP, &CrossPointSettings::sleepTimeout,
|
SettingInfo::Enum(StrId::STR_TIME_TO_SLEEP, &CrossPointSettings::sleepTimeout,
|
||||||
{StrId::STR_MIN_1, StrId::STR_MIN_5, StrId::STR_MIN_10, StrId::STR_MIN_15, StrId::STR_MIN_30},
|
{StrId::STR_MIN_1, StrId::STR_MIN_5, StrId::STR_MIN_10, StrId::STR_MIN_15, StrId::STR_MIN_30},
|
||||||
@@ -41,8 +47,8 @@ inline const std::vector<SettingInfo>& getSettingsList() {
|
|||||||
SettingInfo::Enum(StrId::STR_SLEEP_COVER_MODE, &CrossPointSettings::sleepScreenCoverMode,
|
SettingInfo::Enum(StrId::STR_SLEEP_COVER_MODE, &CrossPointSettings::sleepScreenCoverMode,
|
||||||
{StrId::STR_FIT, StrId::STR_CROP}, "sleepScreenCoverMode", StrId::STR_CAT_DISPLAY),
|
{StrId::STR_FIT, StrId::STR_CROP}, "sleepScreenCoverMode", StrId::STR_CAT_DISPLAY),
|
||||||
SettingInfo::Enum(StrId::STR_SLEEP_COVER_FILTER, &CrossPointSettings::sleepScreenCoverFilter,
|
SettingInfo::Enum(StrId::STR_SLEEP_COVER_FILTER, &CrossPointSettings::sleepScreenCoverFilter,
|
||||||
{StrId::STR_NONE_OPT, StrId::STR_FILTER_CONTRAST, StrId::STR_INVERTED},
|
{StrId::STR_NONE_OPT, StrId::STR_FILTER_CONTRAST, StrId::STR_INVERTED}, "sleepScreenCoverFilter",
|
||||||
"sleepScreenCoverFilter", StrId::STR_CAT_DISPLAY),
|
StrId::STR_CAT_DISPLAY),
|
||||||
SettingInfo::Enum(
|
SettingInfo::Enum(
|
||||||
StrId::STR_SLEEP_COVER_OVERLAY, &CrossPointSettings::sleepCoverOverlay,
|
StrId::STR_SLEEP_COVER_OVERLAY, &CrossPointSettings::sleepCoverOverlay,
|
||||||
{StrId::STR_OVERLAY_OFF, StrId::STR_OVERLAY_WHITE, StrId::STR_OVERLAY_GRAY, StrId::STR_OVERLAY_BLACK},
|
{StrId::STR_OVERLAY_OFF, StrId::STR_OVERLAY_WHITE, StrId::STR_OVERLAY_GRAY, StrId::STR_OVERLAY_BLACK},
|
||||||
@@ -65,39 +71,54 @@ inline const std::vector<SettingInfo>& getSettingsList() {
|
|||||||
StrId::STR_CAT_DISPLAY),
|
StrId::STR_CAT_DISPLAY),
|
||||||
|
|
||||||
// --- Reader ---
|
// --- Reader ---
|
||||||
|
// General reader settings
|
||||||
|
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),
|
||||||
|
// Font
|
||||||
SettingInfo::Enum(StrId::STR_FONT_FAMILY, &CrossPointSettings::fontFamily,
|
SettingInfo::Enum(StrId::STR_FONT_FAMILY, &CrossPointSettings::fontFamily,
|
||||||
{StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS, StrId::STR_OPEN_DYSLEXIC}, "fontFamily",
|
{StrId::STR_BOOKERLY, StrId::STR_NOTO_SANS, StrId::STR_OPEN_DYSLEXIC}, "fontFamily",
|
||||||
StrId::STR_CAT_READER),
|
StrId::STR_CAT_READER)
|
||||||
|
.withSubcategory(StrId::STR_FONT_FAMILY),
|
||||||
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}, "fontSize",
|
{StrId::STR_SMALL, StrId::STR_MEDIUM, StrId::STR_LARGE, StrId::STR_X_LARGE}, "fontSize",
|
||||||
StrId::STR_CAT_READER),
|
StrId::STR_CAT_READER)
|
||||||
SettingInfo::Enum(StrId::STR_LINE_SPACING, &CrossPointSettings::lineSpacing,
|
.withSubmenu(StrId::STR_MENU_READER_FONT),
|
||||||
{StrId::STR_TIGHT, StrId::STR_NORMAL, StrId::STR_WIDE}, "lineSpacing", StrId::STR_CAT_READER),
|
SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing",
|
||||||
SettingInfo::Value(StrId::STR_SCREEN_MARGIN, &CrossPointSettings::screenMargin, {5, 40, 5}, "screenMargin",
|
StrId::STR_CAT_READER)
|
||||||
StrId::STR_CAT_READER),
|
.withSubmenu(StrId::STR_MENU_READER_FONT),
|
||||||
SettingInfo::Enum(StrId::STR_PARA_ALIGNMENT, &CrossPointSettings::paragraphAlignment,
|
SettingInfo::Enum(StrId::STR_TEXT_DARKNESS, &CrossPointSettings::textDarkness,
|
||||||
{StrId::STR_JUSTIFY, StrId::STR_ALIGN_LEFT, StrId::STR_CENTER, StrId::STR_ALIGN_RIGHT,
|
{StrId::STR_NORMAL, StrId::STR_DARK, StrId::STR_EXTRA_DARK, StrId::STR_MAX_DARK}, "textDarkness",
|
||||||
StrId::STR_BOOK_S_STYLE},
|
StrId::STR_CAT_READER)
|
||||||
"paragraphAlignment", StrId::STR_CAT_READER),
|
.withSubmenu(StrId::STR_MENU_READER_FONT),
|
||||||
|
|
||||||
|
// Formatting settings
|
||||||
|
SettingInfo::Enum(
|
||||||
|
StrId::STR_PARA_ALIGNMENT, &CrossPointSettings::paragraphAlignment,
|
||||||
|
{StrId::STR_JUSTIFY, StrId::STR_ALIGN_LEFT, StrId::STR_CENTER, StrId::STR_ALIGN_RIGHT, StrId::STR_BOOK_S_STYLE},
|
||||||
|
"paragraphAlignment", StrId::STR_CAT_READER)
|
||||||
|
.withSubcategory(StrId::STR_MENU_READER_LAYOUT),
|
||||||
SettingInfo::Toggle(StrId::STR_EMBEDDED_STYLE, &CrossPointSettings::embeddedStyle, "embeddedStyle",
|
SettingInfo::Toggle(StrId::STR_EMBEDDED_STYLE, &CrossPointSettings::embeddedStyle, "embeddedStyle",
|
||||||
StrId::STR_CAT_READER),
|
StrId::STR_CAT_READER),
|
||||||
SettingInfo::Toggle(StrId::STR_HYPHENATION, &CrossPointSettings::hyphenationEnabled, "hyphenationEnabled",
|
SettingInfo::Toggle(StrId::STR_HYPHENATION, &CrossPointSettings::hyphenationEnabled, "hyphenationEnabled",
|
||||||
StrId::STR_CAT_READER),
|
StrId::STR_CAT_READER),
|
||||||
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),
|
|
||||||
SettingInfo::Toggle(StrId::STR_EXTRA_SPACING, &CrossPointSettings::extraParagraphSpacing, "extraParagraphSpacing",
|
|
||||||
StrId::STR_CAT_READER),
|
|
||||||
SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing",
|
|
||||||
StrId::STR_CAT_READER),
|
|
||||||
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),
|
|
||||||
SettingInfo::Enum(StrId::STR_IMAGES, &CrossPointSettings::imageRendering,
|
SettingInfo::Enum(StrId::STR_IMAGES, &CrossPointSettings::imageRendering,
|
||||||
{StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER, StrId::STR_IMAGES_SUPPRESS},
|
{StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER, StrId::STR_IMAGES_SUPPRESS},
|
||||||
"imageRendering", StrId::STR_CAT_READER),
|
"imageRendering", StrId::STR_CAT_READER),
|
||||||
|
SettingInfo::Value(StrId::STR_SCREEN_MARGIN, &CrossPointSettings::screenMargin, {5, 40, 5}, "screenMargin",
|
||||||
|
StrId::STR_CAT_READER)
|
||||||
|
.withSubmenu(StrId::STR_MENU_READER_SPACING),
|
||||||
|
SettingInfo::Enum(StrId::STR_LINE_SPACING, &CrossPointSettings::lineSpacing,
|
||||||
|
{StrId::STR_TIGHT, StrId::STR_NORMAL, StrId::STR_WIDE}, "lineSpacing", StrId::STR_CAT_READER)
|
||||||
|
.withSubmenu(StrId::STR_MENU_READER_SPACING),
|
||||||
|
SettingInfo::Toggle(StrId::STR_EXTRA_SPACING, &CrossPointSettings::extraParagraphSpacing, "extraParagraphSpacing",
|
||||||
|
StrId::STR_CAT_READER)
|
||||||
|
.withSubmenu(StrId::STR_MENU_READER_SPACING),
|
||||||
|
// Generic reader settings
|
||||||
SettingInfo::Toggle(StrId::STR_CREATE_FALLBACK_FOR_INVALID_TOC, &CrossPointSettings::syntheticTocFallback,
|
SettingInfo::Toggle(StrId::STR_CREATE_FALLBACK_FOR_INVALID_TOC, &CrossPointSettings::syntheticTocFallback,
|
||||||
"syntheticTocFallback", StrId::STR_CAT_READER),
|
"syntheticTocFallback", StrId::STR_CAT_READER)
|
||||||
|
.withSubcategory(StrId::STR_MENU_READER_TWEAKS),
|
||||||
|
|
||||||
// --- Controls ---
|
// --- Controls ---
|
||||||
SettingInfo::Enum(StrId::STR_SIDE_BTN_LAYOUT, &CrossPointSettings::sideButtonLayout,
|
SettingInfo::Enum(StrId::STR_SIDE_BTN_LAYOUT, &CrossPointSettings::sideButtonLayout,
|
||||||
{StrId::STR_PREV_NEXT, StrId::STR_NEXT_PREV}, "sideButtonLayout", StrId::STR_CAT_CONTROLS),
|
{StrId::STR_PREV_NEXT, StrId::STR_NEXT_PREV}, "sideButtonLayout", StrId::STR_CAT_CONTROLS),
|
||||||
@@ -110,8 +131,8 @@ inline const std::vector<SettingInfo>& getSettingsList() {
|
|||||||
// --- System ---
|
// --- System ---
|
||||||
SettingInfo::Toggle(StrId::STR_SHOW_HIDDEN_FILES, &CrossPointSettings::showHiddenFiles, "showHiddenFiles",
|
SettingInfo::Toggle(StrId::STR_SHOW_HIDDEN_FILES, &CrossPointSettings::showHiddenFiles, "showHiddenFiles",
|
||||||
StrId::STR_CAT_SYSTEM),
|
StrId::STR_CAT_SYSTEM),
|
||||||
SettingInfo::Toggle(StrId::STR_SHOW_FILE_EXTENSIONS, &CrossPointSettings::showFileExtensions,
|
SettingInfo::Toggle(StrId::STR_SHOW_FILE_EXTENSIONS, &CrossPointSettings::showFileExtensions, "showFileExtensions",
|
||||||
"showFileExtensions", StrId::STR_CAT_SYSTEM),
|
StrId::STR_CAT_SYSTEM),
|
||||||
SettingInfo::Enum(StrId::STR_CLOCK_FORMAT, &CrossPointSettings::clockFormat12h, {StrId::STR_24H, StrId::STR_12H},
|
SettingInfo::Enum(StrId::STR_CLOCK_FORMAT, &CrossPointSettings::clockFormat12h, {StrId::STR_24H, StrId::STR_12H},
|
||||||
"clockFormat12h", StrId::STR_CAT_SYSTEM),
|
"clockFormat12h", StrId::STR_CAT_SYSTEM),
|
||||||
SettingInfo::Enum(StrId::STR_TIMEZONE, &CrossPointSettings::timeZone,
|
SettingInfo::Enum(StrId::STR_TIMEZONE, &CrossPointSettings::timeZone,
|
||||||
@@ -180,5 +201,6 @@ inline const std::vector<SettingInfo>& getSettingsList() {
|
|||||||
SettingInfo::Toggle(StrId::STR_CLOCK, &CrossPointSettings::statusBarClock, "statusBarClock",
|
SettingInfo::Toggle(StrId::STR_CLOCK, &CrossPointSettings::statusBarClock, "statusBarClock",
|
||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
};
|
};
|
||||||
return list;
|
} // namespace SettingsListDetail
|
||||||
}
|
|
||||||
|
inline const std::vector<SettingInfo>& getSettingsList() { return SettingsListDetail::list; }
|
||||||
|
|||||||
@@ -333,17 +333,21 @@ void SettingsActivity::render(RenderLock&&) {
|
|||||||
nullptr,
|
nullptr,
|
||||||
[&settings](int i) {
|
[&settings](int i) {
|
||||||
const auto& setting = settings[i];
|
const auto& setting = settings[i];
|
||||||
std::string valueText = "";
|
|
||||||
if (setting.type == SettingType::TOGGLE && setting.valuePtr != nullptr) {
|
if (setting.type == SettingType::TOGGLE && setting.valuePtr != nullptr) {
|
||||||
const bool value = SETTINGS.*(setting.valuePtr);
|
const bool value = SETTINGS.*(setting.valuePtr);
|
||||||
valueText = value ? tr(STR_STATE_ON) : tr(STR_STATE_OFF);
|
return std::string(value ? tr(STR_STATE_ON) : tr(STR_STATE_OFF));
|
||||||
} else if (setting.type == SettingType::ENUM && setting.valuePtr != nullptr) {
|
|
||||||
const uint8_t value = SETTINGS.*(setting.valuePtr);
|
|
||||||
valueText = I18N.get(setting.enumValues[value]);
|
|
||||||
} else if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) {
|
|
||||||
valueText = std::to_string(SETTINGS.*(setting.valuePtr));
|
|
||||||
}
|
}
|
||||||
return valueText;
|
if (setting.type == SettingType::ENUM && setting.valuePtr != nullptr) {
|
||||||
|
const uint8_t value = SETTINGS.*(setting.valuePtr);
|
||||||
|
return std::string(I18N.get(setting.enumValues[value]));
|
||||||
|
}
|
||||||
|
if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) {
|
||||||
|
return std::to_string(SETTINGS.*(setting.valuePtr));
|
||||||
|
}
|
||||||
|
if (setting.type == SettingType::ACTION && !setting.isSeparator) {
|
||||||
|
return std::string(">>");
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
void SettingsSubmenuActivity::onEnter() {
|
void SettingsSubmenuActivity::onEnter() {
|
||||||
Activity::onEnter();
|
Activity::onEnter();
|
||||||
itemCount = static_cast<int>(items.size());
|
itemCount = static_cast<int>(items.size());
|
||||||
const auto pred = UITheme::makeSelectablePredicate(itemCount,
|
const auto pred = UITheme::makeSelectablePredicate(itemCount, [this](int i) { return items[i].getTitle(); });
|
||||||
[this](int i) { return items[i].getTitle(); });
|
|
||||||
buttonNavigator.setSelectablePredicate(pred, itemCount);
|
buttonNavigator.setSelectablePredicate(pred, itemCount);
|
||||||
if (!pred(selectedIndex)) {
|
if (!pred(selectedIndex)) {
|
||||||
selectedIndex = buttonNavigator.nextIndex(selectedIndex);
|
selectedIndex = buttonNavigator.nextIndex(selectedIndex);
|
||||||
@@ -151,6 +150,9 @@ void SettingsSubmenuActivity::render(RenderLock&&) {
|
|||||||
if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) {
|
if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) {
|
||||||
return std::to_string(SETTINGS.*(setting.valuePtr));
|
return std::to_string(SETTINGS.*(setting.valuePtr));
|
||||||
}
|
}
|
||||||
|
if (setting.type == SettingType::ACTION && !setting.isSeparator) {
|
||||||
|
return std::string(">>");
|
||||||
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
|
|||||||
+3
-1
@@ -204,10 +204,12 @@ void setup() {
|
|||||||
|
|
||||||
HalSystem::checkPanic();
|
HalSystem::checkPanic();
|
||||||
HalSystem::clearPanic(); // TODO: move this to an activity when we have one to display the panic info
|
HalSystem::clearPanic(); // TODO: move this to an activity when we have one to display the panic info
|
||||||
|
LOG_DBG("MAIN", "System initialized, now setting up environment, millis=%lu", millis());
|
||||||
SETTINGS.loadFromFile();
|
SETTINGS.loadFromFile();
|
||||||
|
LOG_DBG("MAIN", "Settings loaded, now setting up clock and localization, millis=%lu", millis());
|
||||||
HalClock::applyTimezone(SETTINGS.timeZone);
|
HalClock::applyTimezone(SETTINGS.timeZone);
|
||||||
I18N.loadSettings();
|
I18N.loadSettings();
|
||||||
|
LOG_DBG("MAIN", "Localization loaded, now setting up theme and button navigation, millis=%lu", millis());
|
||||||
KOREADER_STORE.loadFromFile();
|
KOREADER_STORE.loadFromFile();
|
||||||
WEATHER_SETTINGS.loadFromFile();
|
WEATHER_SETTINGS.loadFromFile();
|
||||||
UITheme::getInstance().reload();
|
UITheme::getInstance().reload();
|
||||||
|
|||||||
Reference in New Issue
Block a user