diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index f5e8ded5..2395e4fc 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -14,7 +14,7 @@ CrossPointSettings CrossPointSettings::instance; namespace { constexpr uint8_t SETTINGS_FILE_VERSION = 1; // Increment this when adding new persisted settings fields -constexpr uint8_t SETTINGS_COUNT = 20; +constexpr uint8_t SETTINGS_COUNT = 21; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; } // namespace @@ -30,6 +30,7 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, SETTINGS_FILE_VERSION); serialization::writePod(outputFile, SETTINGS_COUNT); serialization::writePod(outputFile, sleepScreen); + serialization::writePod(outputFile, showSleepScreen); serialization::writePod(outputFile, extraParagraphSpacing); serialization::writePod(outputFile, shortPwrBtn); serialization::writePod(outputFile, statusBar); @@ -77,6 +78,8 @@ bool CrossPointSettings::loadFromFile() { do { serialization::readPod(inputFile, sleepScreen); if (++settingsRead >= fileSettingsCount) break; + serialization::readPod(inputFile, showSleepScreen); + if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, extraParagraphSpacing); if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, shortPwrBtn); diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 2c33beb3..2be8e131 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -17,6 +17,7 @@ class CrossPointSettings { // Should match with SettingsActivity text enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4 }; + enum SHOW_SLEEP_SCREEN { ALWAYS = 0, EXCEPT_TIMEOUT = 1, NEVER = 2 }; enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1 }; // Status bar display type enum @@ -65,6 +66,8 @@ class CrossPointSettings { // Sleep screen settings uint8_t sleepScreen = DARK; + // Show sleep screen settings + uint8_t showSleepScreen = ALWAYS; // Sleep screen cover mode settings uint8_t sleepScreenCoverMode = FIT; // Status bar settings diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index 40341e5f..68599846 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -10,11 +10,20 @@ #include "CrossPointState.h" #include "fontIds.h" #include "images/CrossLarge.h" +#include "images/MoonIcon.h" #include "util/StringUtils.h" void SleepActivity::onEnter() { + const bool SHOW_SLEEP_SCREEN = + SETTINGS.showSleepScreen == CrossPointSettings::SHOW_SLEEP_SCREEN::ALWAYS || + (!fromTimeout && SETTINGS.showSleepScreen == CrossPointSettings::SHOW_SLEEP_SCREEN::EXCEPT_TIMEOUT); + Activity::onEnter(); - renderPopup("Entering Sleep..."); + if (SHOW_SLEEP_SCREEN) { + renderPopup("Entering Sleep..."); + } else { + return renderLastScreenSleepScreen(); + } if (SETTINGS.sleepScreen == CrossPointSettings::SLEEP_SCREEN_MODE::BLANK) { return renderBlankSleepScreen(); @@ -269,6 +278,13 @@ void SleepActivity::renderCoverSleepScreen() const { renderDefaultSleepScreen(); } +void SleepActivity::renderLastScreenSleepScreen() const { + const auto pageHeight = renderer.getScreenHeight(); + + renderer.drawImage(MoonIcon, 48, pageHeight - 48, 48, 48); + renderer.displayBuffer(EInkDisplay::HALF_REFRESH); +} + void SleepActivity::renderBlankSleepScreen() const { renderer.clearScreen(); renderer.displayBuffer(EInkDisplay::HALF_REFRESH); diff --git a/src/activities/boot_sleep/SleepActivity.h b/src/activities/boot_sleep/SleepActivity.h index 283220ce..01263311 100644 --- a/src/activities/boot_sleep/SleepActivity.h +++ b/src/activities/boot_sleep/SleepActivity.h @@ -5,8 +5,8 @@ class Bitmap; class SleepActivity final : public Activity { public: - explicit SleepActivity(GfxRenderer& renderer, MappedInputManager& mappedInput) - : Activity("Sleep", renderer, mappedInput) {} + explicit SleepActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, bool fromTimeout) + : Activity("Sleep", renderer, mappedInput), fromTimeout(fromTimeout) {} void onEnter() override; private: @@ -15,5 +15,8 @@ class SleepActivity final : public Activity { void renderCustomSleepScreen() const; void renderCoverSleepScreen() const; void renderBitmapSleepScreen(const Bitmap& bitmap) const; + void renderLastScreenSleepScreen() const; void renderBlankSleepScreen() const; + + bool fromTimeout = false; }; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 45b7a12d..82f2827f 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -11,10 +11,11 @@ const char* SettingsActivity::categoryNames[categoryCount] = {"Display", "Reader", "Controls", "System"}; namespace { -constexpr int displaySettingsCount = 5; +constexpr int displaySettingsCount = 6; const SettingInfo displaySettings[displaySettingsCount] = { // Should match with SLEEP_SCREEN_MODE SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), + SettingInfo::Enum("Show Sleep Screen", &CrossPointSettings::showSleepScreen, {"Always", "Except Timeout", "Never"}), SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}), SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}), diff --git a/src/images/MoonIcon.h b/src/images/MoonIcon.h new file mode 100644 index 00000000..34e617ba --- /dev/null +++ b/src/images/MoonIcon.h @@ -0,0 +1,24 @@ +#pragma once +#include + +// Image dimensions: 48x48 +#define MOONICON_WIDTH 48 +#define MOONICON_HEIGHT 48 + +static const uint8_t MoonIcon[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xF0, 0xFF, 0xFF, + 0xFF, 0xC0, 0x1F, 0xF0, 0x3F, 0xFF, 0xFF, 0x00, 0x1F, 0xF8, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFC, 0x07, 0xFF, + 0xFF, 0xF9, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xF9, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xF9, 0xFF, 0xFE, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFC, 0x00, 0xFF, + 0xFF, 0xC7, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xC3, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xC3, 0xFF, 0xF0, 0x00, 0x7F, + 0xFF, 0xC1, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x7F, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index c0222e0d..301d2180 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -198,9 +198,9 @@ void waitForPowerRelease() { } // Enter deep sleep mode -void enterDeepSleep() { +void enterDeepSleep(bool fromTimeout) { exitActivity(); - enterNewActivity(new SleepActivity(renderer, mappedInputManager)); + enterNewActivity(new SleepActivity(renderer, mappedInputManager, fromTimeout)); einkDisplay.deepSleep(); Serial.printf("[%lu] [ ] Power button press calibration value: %lu ms\n", millis(), t2 - t1); @@ -376,14 +376,14 @@ void loop() { 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); - enterDeepSleep(); + enterDeepSleep(true); // This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start return; } if (inputManager.isPressed(InputManager::BTN_POWER) && inputManager.getHeldTime() > SETTINGS.getPowerButtonDuration()) { - enterDeepSleep(); + enterDeepSleep(false); // This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start return; }