From cced77783fb76ded480771114d42fb6fa9921665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B3=D0=BE=D1=80=20=D0=9C=D0=B0=D1=80=D1=82=D1=8B?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= Date: Wed, 15 Apr 2026 05:21:55 +0700 Subject: [PATCH] feat: add orientation-aware popups for reader activities (#1428) ## Summary Make popups (like "Going to sleep") respect the current screen orientation when shown from reader activities. **What changes are included?** - Apply reader orientation in SleepActivity before showing popup when `lastSleepFromReader` is true - Make popup Y-position proportional to screen height (7.5% for BaseTheme, 16.5% for LyraTheme) instead of hardcoded pixel values, ensuring correct positioning in both portrait and landscape modes. - Add `isReaderActivity()` override to all reader sub-screens (menu, chapter selection, percent selection, footnotes, QR display, KOReader sync), so sleep popups rotate correctly when entering sleep from any reader context. ## Additional Context --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**YES**_ (Claude Opus 4.5) --- src/activities/boot_sleep/SleepActivity.cpp | 11 ++++++++++- .../reader/EpubReaderChapterSelectionActivity.h | 1 + src/activities/reader/EpubReaderFootnotesActivity.h | 1 + src/activities/reader/EpubReaderMenuActivity.h | 1 + .../reader/EpubReaderPercentSelectionActivity.h | 1 + src/activities/reader/KOReaderSyncActivity.h | 1 + src/activities/reader/QrDisplayActivity.h | 1 + src/components/themes/BaseTheme.cpp | 3 ++- src/components/themes/lyra/LyraTheme.cpp | 3 ++- 9 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index 64fa11d91..88a15aa13 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -10,13 +10,22 @@ #include "CrossPointSettings.h" #include "CrossPointState.h" +#include "activities/reader/ReaderUtils.h" #include "components/UITheme.h" #include "fontIds.h" #include "images/Logo120.h" void SleepActivity::onEnter() { Activity::onEnter(); - GUI.drawPopup(renderer, tr(STR_ENTERING_SLEEP)); + + // Show popup with reader orientation only when going to sleep from reader + if (APP_STATE.lastSleepFromReader) { + ReaderUtils::applyOrientation(renderer, SETTINGS.orientation); + GUI.drawPopup(renderer, tr(STR_ENTERING_SLEEP)); + renderer.setOrientation(GfxRenderer::Orientation::Portrait); + } else { + GUI.drawPopup(renderer, tr(STR_ENTERING_SLEEP)); + } switch (SETTINGS.sleepScreen) { case (CrossPointSettings::SLEEP_SCREEN_MODE::BLANK): diff --git a/src/activities/reader/EpubReaderChapterSelectionActivity.h b/src/activities/reader/EpubReaderChapterSelectionActivity.h index 20b53aa43..216eadf46 100644 --- a/src/activities/reader/EpubReaderChapterSelectionActivity.h +++ b/src/activities/reader/EpubReaderChapterSelectionActivity.h @@ -32,4 +32,5 @@ class EpubReaderChapterSelectionActivity final : public Activity { void onExit() override; void loop() override; void render(RenderLock&&) override; + bool isReaderActivity() const override { return true; } }; diff --git a/src/activities/reader/EpubReaderFootnotesActivity.h b/src/activities/reader/EpubReaderFootnotesActivity.h index 7336d038c..85fe692d1 100644 --- a/src/activities/reader/EpubReaderFootnotesActivity.h +++ b/src/activities/reader/EpubReaderFootnotesActivity.h @@ -19,6 +19,7 @@ class EpubReaderFootnotesActivity final : public Activity { void onExit() override; void loop() override; void render(RenderLock&&) override; + bool isReaderActivity() const override { return true; } private: const std::vector& footnotes; diff --git a/src/activities/reader/EpubReaderMenuActivity.h b/src/activities/reader/EpubReaderMenuActivity.h index 9ddba93db..3937d62c7 100644 --- a/src/activities/reader/EpubReaderMenuActivity.h +++ b/src/activities/reader/EpubReaderMenuActivity.h @@ -32,6 +32,7 @@ class EpubReaderMenuActivity final : public Activity { void onExit() override; void loop() override; void render(RenderLock&&) override; + bool isReaderActivity() const override { return true; } private: struct MenuItem { diff --git a/src/activities/reader/EpubReaderPercentSelectionActivity.h b/src/activities/reader/EpubReaderPercentSelectionActivity.h index 8cba8664f..ad68fc32c 100644 --- a/src/activities/reader/EpubReaderPercentSelectionActivity.h +++ b/src/activities/reader/EpubReaderPercentSelectionActivity.h @@ -15,6 +15,7 @@ class EpubReaderPercentSelectionActivity final : public Activity { void onExit() override; void loop() override; void render(RenderLock&&) override; + bool isReaderActivity() const override { return true; } private: // Current percent value (0-100) shown on the slider. diff --git a/src/activities/reader/KOReaderSyncActivity.h b/src/activities/reader/KOReaderSyncActivity.h index 71bdbf2f4..afd331ece 100644 --- a/src/activities/reader/KOReaderSyncActivity.h +++ b/src/activities/reader/KOReaderSyncActivity.h @@ -38,6 +38,7 @@ class KOReaderSyncActivity final : public Activity { void loop() override; void render(RenderLock&&) override; bool preventAutoSleep() override { return state == CONNECTING || state == SYNCING; } + bool isReaderActivity() const override { return true; } private: enum State { diff --git a/src/activities/reader/QrDisplayActivity.h b/src/activities/reader/QrDisplayActivity.h index 3cfdb6b37..d6ff236a4 100644 --- a/src/activities/reader/QrDisplayActivity.h +++ b/src/activities/reader/QrDisplayActivity.h @@ -14,6 +14,7 @@ class QrDisplayActivity final : public Activity { void onExit() override; void loop() override; void render(RenderLock&&) override; + bool isReaderActivity() const override { return true; } private: std::string textPayload; diff --git a/src/components/themes/BaseTheme.cpp b/src/components/themes/BaseTheme.cpp index 0d6dcd336..dff5ec065 100644 --- a/src/components/themes/BaseTheme.cpp +++ b/src/components/themes/BaseTheme.cpp @@ -648,7 +648,8 @@ void BaseTheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount Rect BaseTheme::drawPopup(const GfxRenderer& renderer, const char* message) const { constexpr int margin = 15; - constexpr int y = 60; + // Scale y position proportionally to screen height (7.5% from top) + const int y = static_cast(renderer.getScreenHeight() * 0.075f); const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD); const int textHeight = renderer.getLineHeight(UI_12_FONT_ID); const int w = textWidth + margin * 2; diff --git a/src/components/themes/lyra/LyraTheme.cpp b/src/components/themes/lyra/LyraTheme.cpp index e2451f684..56903f892 100644 --- a/src/components/themes/lyra/LyraTheme.cpp +++ b/src/components/themes/lyra/LyraTheme.cpp @@ -541,7 +541,8 @@ void LyraTheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount } Rect LyraTheme::drawPopup(const GfxRenderer& renderer, const char* message) const { - constexpr int y = 132; + // Scale y position proportionally to screen height (16.5% from top) + const int y = static_cast(renderer.getScreenHeight() * 0.165f); constexpr int outline = 2; const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::REGULAR); const int textHeight = renderer.getLineHeight(UI_12_FONT_ID);