Updates for better setting grouping

This commit is contained in:
jpirnay
2026-03-26 19:55:56 +01:00
parent 6e8254b815
commit cfd79d32ca
13 changed files with 183 additions and 24 deletions
+2 -1
View File
@@ -82,7 +82,8 @@ STR_PARA_ALIGNMENT: "Reader Paragraph Alignment"
STR_HYPHENATION: "Hyphenation" STR_HYPHENATION: "Hyphenation"
STR_TIME_TO_SLEEP: "Time to Sleep" STR_TIME_TO_SLEEP: "Time to Sleep"
STR_SHOW_HIDDEN_FILES: "Show Hidden Files" STR_SHOW_HIDDEN_FILES: "Show Hidden Files"
STR_KEEP_CLOCK_ALIVE: "Keep Clock Alive" STR_USE_CLOCK: "Use Clock"
STR_CLOCK_SETTINGS: "Clock Settings"
STR_CLOCK: "Clock" STR_CLOCK: "Clock"
STR_CLOCK_FORMAT: "Clock Format" STR_CLOCK_FORMAT: "Clock Format"
STR_TIMEZONE: "Timezone" STR_TIMEZONE: "Timezone"
+3 -3
View File
@@ -226,9 +226,9 @@ class CrossPointSettings {
uint8_t clockFormat12h = 0; uint8_t clockFormat12h = 0;
// Timezone selection (applies POSIX TZ rules for DST) // Timezone selection (applies POSIX TZ rules for DST)
uint8_t timeZone = TZ_UTC; uint8_t timeZone = TZ_UTC;
// Keep the LP timer running during deep sleep (GPIO13 HIGH) so the clock // Use clock and keep the LP timer running during deep sleep (GPIO13 HIGH)
// can be accurately restored on wake. Increases sleep current by ~3-4 mA. // so time can be accurately restored on wake. Increases sleep current by ~3-4 mA.
uint8_t keepClockAlive = 0; uint8_t useClock = 0;
~CrossPointSettings() = default; ~CrossPointSettings() = default;
+1 -2
View File
@@ -88,8 +88,7 @@ inline const std::vector<SettingInfo>& getSettingsList() {
StrId::STR_TZ_UTC_PLUS9, StrId::STR_TZ_AEST, StrId::STR_TZ_NZST, StrId::STR_TZ_UTC_MINUS3, StrId::STR_TZ_UTC_PLUS9, StrId::STR_TZ_AEST, StrId::STR_TZ_NZST, StrId::STR_TZ_UTC_MINUS3,
StrId::STR_TZ_EST, StrId::STR_TZ_CST, StrId::STR_TZ_MST, StrId::STR_TZ_PST}, StrId::STR_TZ_EST, StrId::STR_TZ_CST, StrId::STR_TZ_MST, StrId::STR_TZ_PST},
"timeZone", StrId::STR_CAT_SYSTEM), "timeZone", StrId::STR_CAT_SYSTEM),
SettingInfo::Toggle(StrId::STR_KEEP_CLOCK_ALIVE, &CrossPointSettings::keepClockAlive, "keepClockAlive", SettingInfo::Toggle(StrId::STR_USE_CLOCK, &CrossPointSettings::useClock, "useClock", StrId::STR_CAT_SYSTEM),
StrId::STR_CAT_SYSTEM),
// --- KOReader Sync (web-only, uses KOReaderCredentialStore) --- // --- KOReader Sync (web-only, uses KOReaderCredentialStore) ---
SettingInfo::DynamicString( SettingInfo::DynamicString(
+5 -4
View File
@@ -1,5 +1,6 @@
#include "ActivityManager.h" #include "ActivityManager.h"
#include <Arduino.h>
#include <HalClock.h> #include <HalClock.h>
#include <HalPowerManager.h> #include <HalPowerManager.h>
@@ -57,13 +58,13 @@ void ActivityManager::loop() {
currentActivity->loop(); currentActivity->loop();
} }
if (SETTINGS.statusBarClock && HalClock::isSynced()) { if (SETTINGS.useClock && HalClock::isSynced()) {
static time_t lastClockMinute = 0; static time_t lastMinute = -1;
time_t now = HalClock::now(); time_t now = HalClock::now();
if (now > 0) { if (now > 0) {
time_t minute = now / 60; time_t minute = now / 60;
if (minute != lastClockMinute) { if (minute != lastMinute) {
lastClockMinute = minute; lastMinute = minute;
requestUpdate(); requestUpdate();
} }
} }
@@ -0,0 +1,117 @@
#include "ClockSettingsActivity.h"
#include <GfxRenderer.h>
#include <HalClock.h>
#include <I18n.h>
#include "CrossPointSettings.h"
#include "DetectTimezoneActivity.h"
#include "MappedInputManager.h"
#include "SyncTimeActivity.h"
#include "components/UITheme.h"
#include "fontIds.h"
namespace {
constexpr int MENU_ITEMS = 5;
const StrId menuNames[MENU_ITEMS] = {StrId::STR_USE_CLOCK, StrId::STR_CLOCK_FORMAT, StrId::STR_TIMEZONE,
StrId::STR_SYNC_TIME, StrId::STR_DETECT_TIMEZONE};
const StrId timeZoneNames[CrossPointSettings::TIMEZONE_COUNT] = {
StrId::STR_TZ_UTC, StrId::STR_TZ_CET, StrId::STR_TZ_EET, StrId::STR_TZ_MSK,
StrId::STR_TZ_UTC_PLUS4, StrId::STR_TZ_IST, StrId::STR_TZ_UTC_PLUS7, StrId::STR_TZ_UTC_PLUS8,
StrId::STR_TZ_UTC_PLUS9, StrId::STR_TZ_AEST, StrId::STR_TZ_NZST, StrId::STR_TZ_UTC_MINUS3,
StrId::STR_TZ_EST, StrId::STR_TZ_CST, StrId::STR_TZ_MST, StrId::STR_TZ_PST};
} // namespace
void ClockSettingsActivity::onEnter() {
Activity::onEnter();
selectedIndex = 0;
requestUpdate();
}
void ClockSettingsActivity::onExit() { Activity::onExit(); }
void ClockSettingsActivity::loop() {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
finish();
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
handleSelection();
requestUpdate();
return;
}
buttonNavigator.onNextRelease([this] {
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, MENU_ITEMS);
requestUpdate();
});
buttonNavigator.onPreviousRelease([this] {
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, MENU_ITEMS);
requestUpdate();
});
}
void ClockSettingsActivity::handleSelection() {
if (selectedIndex == 0) {
SETTINGS.useClock = (SETTINGS.useClock + 1) % 2;
if (!SETTINGS.useClock) {
SETTINGS.statusBarClock = 0;
}
SETTINGS.saveToFile();
} else if (selectedIndex == 1) {
SETTINGS.clockFormat12h = (SETTINGS.clockFormat12h + 1) % 2;
SETTINGS.saveToFile();
} else if (selectedIndex == 2) {
SETTINGS.timeZone = (SETTINGS.timeZone + 1) % CrossPointSettings::TIMEZONE_COUNT;
HalClock::applyTimezone(SETTINGS.timeZone);
SETTINGS.saveToFile();
} else if (selectedIndex == 3) {
auto resultHandler = [](const ActivityResult&) { SETTINGS.saveToFile(); };
startActivityForResult(std::make_unique<SyncTimeActivity>(renderer, mappedInput), resultHandler);
} else if (selectedIndex == 4) {
auto resultHandler = [](const ActivityResult&) { SETTINGS.saveToFile(); };
startActivityForResult(std::make_unique<DetectTimezoneActivity>(renderer, mappedInput), resultHandler);
}
}
void ClockSettingsActivity::render(RenderLock&&) {
renderer.clearScreen();
const auto& metrics = UITheme::getInstance().getMetrics();
const auto pageWidth = renderer.getScreenWidth();
const auto pageHeight = renderer.getScreenHeight();
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_CLOCK_SETTINGS));
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
GUI.drawList(
renderer, Rect{0, contentTop, pageWidth, contentHeight}, MENU_ITEMS, selectedIndex,
[](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr, nullptr,
[](int index) {
if (index == 0) {
return std::string(SETTINGS.useClock ? tr(STR_STATE_ON) : tr(STR_STATE_OFF));
}
if (index == 1) {
return std::string(SETTINGS.clockFormat12h ? tr(STR_12H) : tr(STR_24H));
}
if (index == 2) {
const auto tzIndex = static_cast<size_t>(SETTINGS.timeZone);
if (tzIndex < (sizeof(timeZoneNames) / sizeof(timeZoneNames[0]))) {
return std::string(I18N.get(timeZoneNames[tzIndex]));
}
return std::string(tr(STR_TZ_UTC));
}
return std::string("");
},
true);
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
renderer.displayBuffer();
}
@@ -0,0 +1,20 @@
#pragma once
#include <I18n.h>
#include "activities/Activity.h"
#include "util/ButtonNavigator.h"
class ClockSettingsActivity final : public Activity {
ButtonNavigator buttonNavigator;
int selectedIndex = 0;
void handleSelection();
public:
explicit ClockSettingsActivity(GfxRenderer& renderer, MappedInputManager& mappedInput)
: Activity("ClockSettings", renderer, mappedInput) {}
void onEnter() override;
void onExit() override;
void loop() override;
void render(RenderLock&&) override;
};
+14 -2
View File
@@ -7,6 +7,7 @@
#include "ButtonRemapActivity.h" #include "ButtonRemapActivity.h"
#include "CalibreSettingsActivity.h" #include "CalibreSettingsActivity.h"
#include "ClearCacheActivity.h" #include "ClearCacheActivity.h"
#include "ClockSettingsActivity.h"
#include "CrossPointSettings.h" #include "CrossPointSettings.h"
#include "DetectTimezoneActivity.h" #include "DetectTimezoneActivity.h"
#include "KOReaderSettingsActivity.h" #include "KOReaderSettingsActivity.h"
@@ -34,6 +35,11 @@ void SettingsActivity::onEnter() {
for (const auto& setting : getSettingsList()) { for (const auto& setting : getSettingsList()) {
if (setting.category == StrId::STR_NONE_OPT) continue; if (setting.category == StrId::STR_NONE_OPT) continue;
if (setting.category == StrId::STR_CAT_SYSTEM &&
(setting.nameId == StrId::STR_USE_CLOCK || setting.nameId == StrId::STR_CLOCK_FORMAT ||
setting.nameId == StrId::STR_TIMEZONE)) {
continue;
}
if (setting.category == StrId::STR_CAT_DISPLAY) { if (setting.category == StrId::STR_CAT_DISPLAY) {
displaySettings.push_back(setting); displaySettings.push_back(setting);
} else if (setting.category == StrId::STR_CAT_READER) { } else if (setting.category == StrId::STR_CAT_READER) {
@@ -49,8 +55,7 @@ void SettingsActivity::onEnter() {
// Append device-only ACTION items // Append device-only ACTION items
controlsSettings.insert(controlsSettings.begin(), controlsSettings.insert(controlsSettings.begin(),
SettingInfo::Action(StrId::STR_REMAP_FRONT_BUTTONS, SettingAction::RemapFrontButtons)); SettingInfo::Action(StrId::STR_REMAP_FRONT_BUTTONS, SettingAction::RemapFrontButtons));
systemSettings.push_back(SettingInfo::Action(StrId::STR_SYNC_TIME, SettingAction::SyncTime)); systemSettings.push_back(SettingInfo::Action(StrId::STR_CLOCK_SETTINGS, SettingAction::ClockSettings));
systemSettings.push_back(SettingInfo::Action(StrId::STR_DETECT_TIMEZONE, SettingAction::DetectTimezone));
systemSettings.push_back(SettingInfo::Action(StrId::STR_WIFI_NETWORKS, SettingAction::Network)); systemSettings.push_back(SettingInfo::Action(StrId::STR_WIFI_NETWORKS, SettingAction::Network));
systemSettings.push_back(SettingInfo::Action(StrId::STR_KOREADER_SYNC, SettingAction::KOReaderSync)); systemSettings.push_back(SettingInfo::Action(StrId::STR_KOREADER_SYNC, SettingAction::KOReaderSync));
systemSettings.push_back(SettingInfo::Action(StrId::STR_OPDS_BROWSER, SettingAction::OPDSBrowser)); systemSettings.push_back(SettingInfo::Action(StrId::STR_OPDS_BROWSER, SettingAction::OPDSBrowser));
@@ -179,6 +184,9 @@ void SettingsActivity::toggleCurrentSetting() {
case SettingAction::CustomiseStatusBar: case SettingAction::CustomiseStatusBar:
startActivityForResult(std::make_unique<StatusBarSettingsActivity>(renderer, mappedInput), resultHandler); startActivityForResult(std::make_unique<StatusBarSettingsActivity>(renderer, mappedInput), resultHandler);
break; break;
case SettingAction::ClockSettings:
startActivityForResult(std::make_unique<ClockSettingsActivity>(renderer, mappedInput), resultHandler);
break;
case SettingAction::KOReaderSync: case SettingAction::KOReaderSync:
startActivityForResult(std::make_unique<KOReaderSettingsActivity>(renderer, mappedInput), resultHandler); startActivityForResult(std::make_unique<KOReaderSettingsActivity>(renderer, mappedInput), resultHandler);
break; break;
@@ -216,6 +224,10 @@ void SettingsActivity::toggleCurrentSetting() {
HalClock::applyTimezone(SETTINGS.timeZone); HalClock::applyTimezone(SETTINGS.timeZone);
} }
if (setting.nameId == StrId::STR_USE_CLOCK && !SETTINGS.useClock) {
SETTINGS.statusBarClock = 0;
}
SETTINGS.saveToFile(); SETTINGS.saveToFile();
} }
@@ -15,6 +15,7 @@ enum class SettingAction {
None, None,
RemapFrontButtons, RemapFrontButtons,
CustomiseStatusBar, CustomiseStatusBar,
ClockSettings,
KOReaderSync, KOReaderSync,
OPDSBrowser, OPDSBrowser,
Network, Network,
@@ -38,6 +38,9 @@ void StatusBarSettingsActivity::onEnter() {
Activity::onEnter(); Activity::onEnter();
selectedIndex = 0; selectedIndex = 0;
if (!SETTINGS.useClock && selectedIndex >= MENU_ITEMS - 1) {
selectedIndex = 0;
}
// Clamp statusBarProgressBar and statusBarTitle in case of corrupt/migrated data // Clamp statusBarProgressBar and statusBarTitle in case of corrupt/migrated data
if (SETTINGS.statusBarProgressBar >= PROGRESS_BAR_ITEMS) { if (SETTINGS.statusBarProgressBar >= PROGRESS_BAR_ITEMS) {
@@ -71,22 +74,26 @@ void StatusBarSettingsActivity::loop() {
// Handle navigation // Handle navigation
buttonNavigator.onNextRelease([this] { buttonNavigator.onNextRelease([this] {
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, MENU_ITEMS); const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, menuCount);
requestUpdate(); requestUpdate();
}); });
buttonNavigator.onPreviousRelease([this] { buttonNavigator.onPreviousRelease([this] {
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, MENU_ITEMS); const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, menuCount);
requestUpdate(); requestUpdate();
}); });
buttonNavigator.onNextContinuous([this] { buttonNavigator.onNextContinuous([this] {
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, MENU_ITEMS); const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
selectedIndex = ButtonNavigator::nextIndex(selectedIndex, menuCount);
requestUpdate(); requestUpdate();
}); });
buttonNavigator.onPreviousContinuous([this] { buttonNavigator.onPreviousContinuous([this] {
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, MENU_ITEMS); const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
selectedIndex = ButtonNavigator::previousIndex(selectedIndex, menuCount);
requestUpdate(); requestUpdate();
}); });
} }
@@ -111,7 +118,7 @@ void StatusBarSettingsActivity::handleSelection() {
} else if (selectedIndex == 5) { } else if (selectedIndex == 5) {
// Show Battery // Show Battery
SETTINGS.statusBarBattery = (SETTINGS.statusBarBattery + 1) % 2; SETTINGS.statusBarBattery = (SETTINGS.statusBarBattery + 1) % 2;
} else if (selectedIndex == 6) { } else if (selectedIndex == 6 && SETTINGS.useClock) {
// Show Clock // Show Clock
SETTINGS.statusBarClock = (SETTINGS.statusBarClock + 1) % 2; SETTINGS.statusBarClock = (SETTINGS.statusBarClock + 1) % 2;
} }
@@ -129,8 +136,9 @@ void StatusBarSettingsActivity::render(RenderLock&&) {
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing; const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2; const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
const int menuCount = SETTINGS.useClock ? MENU_ITEMS : MENU_ITEMS - 1;
GUI.drawList( GUI.drawList(
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(MENU_ITEMS), renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(menuCount),
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr, static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
nullptr, nullptr,
[this](int index) { [this](int index) {
+1 -1
View File
@@ -96,7 +96,7 @@ int UITheme::getStatusBarHeight() {
// Add status bar margin // Add status bar margin
const bool showStatusBar = SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage || const bool showStatusBar = SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage ||
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE || SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
SETTINGS.statusBarBattery || SETTINGS.statusBarClock; SETTINGS.statusBarBattery || (SETTINGS.useClock && SETTINGS.statusBarClock);
const bool showProgressBar = const bool showProgressBar =
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS; SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
return (showStatusBar ? (metrics.statusBarVerticalMargin) : 0) + return (showStatusBar ? (metrics.statusBarVerticalMargin) : 0) +
+2 -2
View File
@@ -296,7 +296,7 @@ void BaseTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* t
showBatteryPercentage); showBatteryPercentage);
// Draw clock in header // Draw clock in header
{ if (SETTINGS.useClock) {
char clockStr[16]; char clockStr[16];
HalClock::formatTime(clockStr, sizeof(clockStr), !SETTINGS.clockFormat12h); HalClock::formatTime(clockStr, sizeof(clockStr), !SETTINGS.clockFormat12h);
renderer.drawText(SMALL_FONT_ID, rect.x + BaseMetrics::values.contentSidePadding, rect.y + 5, clockStr); renderer.drawText(SMALL_FONT_ID, rect.x + BaseMetrics::values.contentSidePadding, rect.y + 5, clockStr);
@@ -725,7 +725,7 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
// Draw Clock // Draw Clock
int clockTextWidth = 0; int clockTextWidth = 0;
if (SETTINGS.statusBarClock) { if (SETTINGS.useClock && SETTINGS.statusBarClock) {
char clockStr[16]; char clockStr[16];
HalClock::formatTime(clockStr, sizeof(clockStr), !SETTINGS.clockFormat12h); HalClock::formatTime(clockStr, sizeof(clockStr), !SETTINGS.clockFormat12h);
clockTextWidth = renderer.getTextWidth(SMALL_FONT_ID, clockStr); clockTextWidth = renderer.getTextWidth(SMALL_FONT_ID, clockStr);
+1 -1
View File
@@ -169,7 +169,7 @@ void LyraTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* t
showBatteryPercentage); showBatteryPercentage);
// Draw clock in header // Draw clock in header
{ if (SETTINGS.useClock) {
char clockStr[16]; char clockStr[16];
HalClock::formatTime(clockStr, sizeof(clockStr), !SETTINGS.clockFormat12h); HalClock::formatTime(clockStr, sizeof(clockStr), !SETTINGS.clockFormat12h);
renderer.drawText(SMALL_FONT_ID, rect.x + LyraMetrics::values.contentSidePadding, rect.y + 5, clockStr); renderer.drawText(SMALL_FONT_ID, rect.x + LyraMetrics::values.contentSidePadding, rect.y + 5, clockStr);
+2 -2
View File
@@ -185,7 +185,7 @@ void waitForPowerRelease() {
void enterDeepSleep() { void enterDeepSleep() {
HalPowerManager::Lock powerLock; // Ensure we are at normal CPU frequency for sleep preparation HalPowerManager::Lock powerLock; // Ensure we are at normal CPU frequency for sleep preparation
APP_STATE.lastSleepFromReader = activityManager.isReaderActivity(); APP_STATE.lastSleepFromReader = activityManager.isReaderActivity();
HalClock::saveBeforeSleep(SETTINGS.keepClockAlive); HalClock::saveBeforeSleep(SETTINGS.useClock);
APP_STATE.saveToFile(); APP_STATE.saveToFile();
activityManager.goToSleep(); activityManager.goToSleep();
@@ -194,7 +194,7 @@ void enterDeepSleep() {
LOG_DBG("MAIN", "Power button press calibration value: %lu ms", t2 - t1); LOG_DBG("MAIN", "Power button press calibration value: %lu ms", t2 - t1);
LOG_DBG("MAIN", "Entering deep sleep"); LOG_DBG("MAIN", "Entering deep sleep");
powerManager.startDeepSleep(gpio, SETTINGS.keepClockAlive); powerManager.startDeepSleep(gpio, SETTINGS.useClock);
} }
void setupDisplayAndFonts() { void setupDisplayAndFonts() {