diff --git a/README.md b/README.md index d59df835..8a473e5a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ This project is **not affiliated with Xteink**; it's built as a community projec - [ ] User provided fonts - [ ] Full UTF support - [x] Screen rotation +- [x] Adjustable auto-sleep timeout (2, 5, 10, 15, 20, 30, 60 minutes, or Never) See [the user guide](./USER_GUIDE.md) for instructions on operating CrossPoint. diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index cd8b56f7..9d8b5fc8 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -40,7 +40,7 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, fontSize); serialization::writePod(outputFile, lineSpacing); serialization::writePod(outputFile, paragraphAlignment); - serialization::writePod(outputFile, sleepTimeout); + serialization::writePod(outputFile, autoSleepMinutes); serialization::writePod(outputFile, refreshFrequency); serialization::writePod(outputFile, screenMargin); serialization::writePod(outputFile, sleepScreenCoverMode); @@ -94,7 +94,7 @@ bool CrossPointSettings::loadFromFile() { if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, paragraphAlignment); if (++settingsRead >= fileSettingsCount) break; - serialization::readPod(inputFile, sleepTimeout); + serialization::readPod(inputFile, autoSleepMinutes); if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, refreshFrequency); if (++settingsRead >= fileSettingsCount) break; @@ -153,22 +153,6 @@ float CrossPointSettings::getReaderLineCompression() const { } } -unsigned long CrossPointSettings::getSleepTimeoutMs() const { - switch (sleepTimeout) { - case SLEEP_1_MIN: - return 1UL * 60 * 1000; - case SLEEP_5_MIN: - return 5UL * 60 * 1000; - case SLEEP_10_MIN: - default: - return 10UL * 60 * 1000; - case SLEEP_15_MIN: - return 15UL * 60 * 1000; - case SLEEP_30_MIN: - return 30UL * 60 * 1000; - } -} - int CrossPointSettings::getRefreshFrequency() const { switch (refreshFrequency) { case REFRESH_1: diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 3a2a3503..b16626ca 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -46,8 +46,8 @@ class CrossPointSettings { enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2 }; enum PARAGRAPH_ALIGNMENT { JUSTIFIED = 0, LEFT_ALIGN = 1, CENTER_ALIGN = 2, RIGHT_ALIGN = 3 }; - // Auto-sleep timeout options (in minutes) - enum SLEEP_TIMEOUT { SLEEP_1_MIN = 0, SLEEP_5_MIN = 1, SLEEP_10_MIN = 2, SLEEP_15_MIN = 3, SLEEP_30_MIN = 4 }; + // Auto-sleep timeout options (enum index to minutes: 0=2min, 1=5min, 2=10min, 3=15min, 4=20min, 5=30min, 6=60min, + // 7=Never) // E-ink refresh frequency (pages between full refreshes) enum REFRESH_FREQUENCY { REFRESH_1 = 0, REFRESH_5 = 1, REFRESH_10 = 2, REFRESH_15 = 3, REFRESH_30 = 4 }; @@ -74,8 +74,8 @@ class CrossPointSettings { uint8_t fontSize = MEDIUM; uint8_t lineSpacing = NORMAL; uint8_t paragraphAlignment = JUSTIFIED; - // Auto-sleep timeout setting (default 10 minutes) - uint8_t sleepTimeout = SLEEP_10_MIN; + // Auto-sleep timeout (enum index: 0=2min, 1=5min, 2=10min, 3=15min, 4=20min, 5=30min, 6=60min, 7=Never) + uint8_t autoSleepMinutes = 1; // Default to 5 minutes // E-ink refresh frequency (default 15 pages) uint8_t refreshFrequency = REFRESH_15; // Reader screen margin settings @@ -95,7 +95,20 @@ class CrossPointSettings { bool loadFromFile(); float getReaderLineCompression() const; - unsigned long getSleepTimeoutMs() const; + unsigned long getAutoSleepTimeoutMs() const { + // Map enum index to milliseconds: 0=2min, 1=5min, 2=10min, 3=15min, 4=20min, 5=30min, 6=60min, 7=Never(0) + constexpr unsigned long timeouts[] = { + 2UL * 60UL * 1000UL, // 0: 2 minutes + 5UL * 60UL * 1000UL, // 1: 5 minutes (default) + 10UL * 60UL * 1000UL, // 2: 10 minutes + 15UL * 60UL * 1000UL, // 3: 15 minutes + 20UL * 60UL * 1000UL, // 4: 20 minutes + 30UL * 60UL * 1000UL, // 5: 30 minutes + 60UL * 60UL * 1000UL, // 6: 60 minutes + 0UL // 7: Never (disabled) + }; + return (autoSleepMinutes < 8) ? timeouts[autoSleepMinutes] : timeouts[2]; + } int getRefreshFrequency() const; }; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 702db172..a1f83edf 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -16,31 +16,42 @@ namespace { constexpr int settingsCount = 18; const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE - SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), - SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), - SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}), - SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing), - SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing), - SettingInfo::Toggle("Short Power Button Click", &CrossPointSettings::shortPwrBtn), - SettingInfo::Enum("Reading Orientation", &CrossPointSettings::orientation, - {"Portrait", "Landscape CW", "Inverted", "Landscape CCW"}), - SettingInfo::Enum("Front Button Layout", &CrossPointSettings::frontButtonLayout, - {"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}), - SettingInfo::Enum("Side Button Layout (reader)", &CrossPointSettings::sideButtonLayout, - {"Prev, Next", "Next, Prev"}), - SettingInfo::Enum("Reader Font Family", &CrossPointSettings::fontFamily, - {"Bookerly", "Noto Sans", "Open Dyslexic"}), - SettingInfo::Enum("Reader Font Size", &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}), - SettingInfo::Enum("Reader Line Spacing", &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}), - SettingInfo::Value("Reader Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}), - SettingInfo::Enum("Reader Paragraph Alignment", &CrossPointSettings::paragraphAlignment, - {"Justify", "Left", "Center", "Right"}), - SettingInfo::Enum("Time to Sleep", &CrossPointSettings::sleepTimeout, - {"1 min", "5 min", "10 min", "15 min", "30 min"}), - SettingInfo::Enum("Refresh Frequency", &CrossPointSettings::refreshFrequency, - {"1 page", "5 pages", "10 pages", "15 pages", "30 pages"}), - SettingInfo::Action("Calibre Settings"), - SettingInfo::Action("Check for updates")}; + {"Sleep Screen", SettingType::ENUM, &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover"}}, + {"Status Bar", SettingType::ENUM, &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}}, + {"Extra Paragraph Spacing", SettingType::TOGGLE, &CrossPointSettings::extraParagraphSpacing, {}}, + {"Short Power Button Click", SettingType::TOGGLE, &CrossPointSettings::shortPwrBtn, {}}, + {"Reading Orientation", + SettingType::ENUM, + &CrossPointSettings::orientation, + {"Portrait", "Landscape CW", "Inverted", "Landscape CCW"}}, + {"Front Button Layout", + SettingType::ENUM, + &CrossPointSettings::frontButtonLayout, + {"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}}, + {"Side Button Layout (reader)", + SettingType::ENUM, + &CrossPointSettings::sideButtonLayout, + {"Prev, Next", "Next, Prev"}}, + {"Reader Font Family", + SettingType::ENUM, + &CrossPointSettings::fontFamily, + {"Bookerly", "Noto Sans", "Open Dyslexic"}}, + {"Reader Font Size", SettingType::ENUM, &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}}, + {"Reader Line Spacing", SettingType::ENUM, &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}}, + {"Reader Paragraph Alignment", + SettingType::ENUM, + &CrossPointSettings::paragraphAlignment, + {"Justify", "Left", "Center", "Right"}}, + {"Auto Sleep Timeout", + SettingType::ENUM, + &CrossPointSettings::autoSleepMinutes, + {"2 min", "5 min", "10 min", "15 min", "20 min", "30 min", "60 min", "Never"}}, + {"Refresh Frequency", + SettingType::ENUM, + &CrossPointSettings::refreshFrequency, + {"1 page", "5 pages", "10 pages", "15 pages", "30 pages"}}, + {"Check for updates", SettingType::ACTION, nullptr, {}}, +}; } // namespace void SettingsActivity::taskTrampoline(void* param) { diff --git a/src/main.cpp b/src/main.cpp index 5261df3d..af9992df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -324,16 +324,16 @@ void loop() { lastMemPrint = millis(); } - // Check for any user activity (button press or release) or active background work + // Check for any user activity (button press or release) static unsigned long lastActivityTime = millis(); - if (inputManager.wasAnyPressed() || inputManager.wasAnyReleased() || - (currentActivity && currentActivity->preventAutoSleep())) { + if (inputManager.wasAnyPressed() || inputManager.wasAnyReleased()) { lastActivityTime = millis(); // Reset inactivity timer } - const unsigned long sleepTimeoutMs = SETTINGS.getSleepTimeoutMs(); - if (millis() - lastActivityTime >= sleepTimeoutMs) { - Serial.printf("[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", millis(), sleepTimeoutMs); + // Check auto-sleep timeout (if enabled - 0 means never sleep) + const unsigned long autoSleepTimeout = SETTINGS.getAutoSleepTimeoutMs(); + if (autoSleepTimeout > 0 && millis() - lastActivityTime >= autoSleepTimeout) { + Serial.printf("[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", millis(), autoSleepTimeout); enterDeepSleep(); // This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start return;