From 8349ea8c9f32d43e2d64ca3d333d3e10f49f827d Mon Sep 17 00:00:00 2001 From: mrtnvgr Date: Wed, 28 Jan 2026 10:48:17 +0700 Subject: [PATCH] feat(settings): add "Cover + Custom" sleep screen mode --- USER_GUIDE.md | 1 + src/CrossPointSettings.h | 10 ++++++- src/activities/boot_sleep/SleepActivity.cpp | 29 ++++++++++++++------ src/activities/settings/SettingsActivity.cpp | 3 +- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 06973c92..6ab2a089 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -102,6 +102,7 @@ The Settings screen allows you to configure the device's behavior. There are a f - "Custom" - Custom images from the SD card; see [Sleep Screen](#36-sleep-screen) below for more information - "Cover" - The book cover image (Note: this is experimental and may not work as expected) - "None" - A blank screen + - "Cover + Custom" - The book cover image, fallbacks to "Custom" behavior - **Sleep Screen Cover Mode**: How to display the book cover when "Cover" sleep screen is selected: - "Fit" (default) - Scale the image down to fit centered on the screen, padding with white borders as necessary - "Crop" - Scale the image down and crop as necessary to try to to fill the screen (Note: this is experimental and may not work as expected) diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index c450d348..c9e64af7 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -15,7 +15,15 @@ class CrossPointSettings { CrossPointSettings(const CrossPointSettings&) = delete; CrossPointSettings& operator=(const CrossPointSettings&) = delete; - enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4, SLEEP_SCREEN_MODE_COUNT }; + enum SLEEP_SCREEN_MODE { + DARK = 0, + LIGHT = 1, + CUSTOM = 2, + COVER = 3, + BLANK = 4, + COVER_CUSTOM = 5, + SLEEP_SCREEN_MODE_COUNT + }; enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, SLEEP_SCREEN_COVER_MODE_COUNT }; enum SLEEP_SCREEN_COVER_FILTER { NO_FILTER = 0, diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index cc276edb..9bfa5598 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -22,6 +22,7 @@ void SleepActivity::onEnter() { case (CrossPointSettings::SLEEP_SCREEN_MODE::CUSTOM): return renderCustomSleepScreen(); case (CrossPointSettings::SLEEP_SCREEN_MODE::COVER): + case (CrossPointSettings::SLEEP_SCREEN_MODE::COVER_CUSTOM): return renderCoverSleepScreen(); default: return renderDefaultSleepScreen(); @@ -207,8 +208,18 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap) const { } void SleepActivity::renderCoverSleepScreen() const { + void (SleepActivity::*renderNoCoverSleepScreen)() const; + switch (SETTINGS.sleepScreen) { + case (CrossPointSettings::SLEEP_SCREEN_MODE::COVER_CUSTOM): + renderNoCoverSleepScreen = &SleepActivity::renderCustomSleepScreen; + break; + default: + renderNoCoverSleepScreen = &SleepActivity::renderDefaultSleepScreen; + break; + } + if (APP_STATE.openEpubPath.empty()) { - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } std::string coverBmpPath; @@ -221,12 +232,12 @@ void SleepActivity::renderCoverSleepScreen() const { Xtc lastXtc(APP_STATE.openEpubPath, "/.crosspoint"); if (!lastXtc.load()) { Serial.println("[SLP] Failed to load last XTC"); - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } if (!lastXtc.generateCoverBmp()) { Serial.println("[SLP] Failed to generate XTC cover bmp"); - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } coverBmpPath = lastXtc.getCoverBmpPath(); @@ -235,12 +246,12 @@ void SleepActivity::renderCoverSleepScreen() const { Txt lastTxt(APP_STATE.openEpubPath, "/.crosspoint"); if (!lastTxt.load()) { Serial.println("[SLP] Failed to load last TXT"); - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } if (!lastTxt.generateCoverBmp()) { Serial.println("[SLP] No cover image found for TXT file"); - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } coverBmpPath = lastTxt.getCoverBmpPath(); @@ -249,17 +260,17 @@ void SleepActivity::renderCoverSleepScreen() const { Epub lastEpub(APP_STATE.openEpubPath, "/.crosspoint"); if (!lastEpub.load()) { Serial.println("[SLP] Failed to load last epub"); - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } if (!lastEpub.generateCoverBmp(cropped)) { Serial.println("[SLP] Failed to generate cover bmp"); - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } coverBmpPath = lastEpub.getCoverBmpPath(cropped); } else { - return renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } FsFile file; @@ -272,7 +283,7 @@ void SleepActivity::renderCoverSleepScreen() const { } } - renderDefaultSleepScreen(); + return (this->*renderNoCoverSleepScreen)(); } void SleepActivity::renderBlankSleepScreen() const { diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 7316db05..f0b938e2 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -14,7 +14,8 @@ namespace { 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("Sleep Screen", &CrossPointSettings::sleepScreen, + {"Dark", "Light", "Custom", "Cover", "None", "Cover + Custom"}), SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), SettingInfo::Enum("Sleep Screen Cover Filter", &CrossPointSettings::sleepScreenCoverFilter, {"None", "Contrast", "Inverted"}),