diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 58668c68..1094d3b2 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -17,6 +17,7 @@ namespace { // pagesPerRefresh now comes from SETTINGS.getRefreshFrequency() constexpr unsigned long skipChapterMs = 700; constexpr unsigned long goHomeMs = 1000; +constexpr unsigned long rotateScreenMs = 1000; constexpr int statusBarMargin = 19; constexpr int progressBarMarginTop = 1; @@ -123,8 +124,14 @@ void EpubReaderActivity::loop() { return; } + // Long press CONFIRM (1s+) rotates the screen + if (mappedInput.wasReleased(MappedInputManager::Button::Confirm) && mappedInput.getHeldTime() >= rotateScreenMs) { + rotateScreen(); + return; + } + // Enter chapter selection activity - if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) { + if (mappedInput.wasReleased(MappedInputManager::Button::Confirm) && mappedInput.getHeldTime() < rotateScreenMs) { // Don't start activity transition while rendering xSemaphoreTake(renderingMutex, portMAX_DELAY); const int currentPage = section ? section->currentPage : 0; @@ -553,3 +560,48 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in title.c_str()); } } + +void EpubReaderActivity::rotateScreen() { + // We don't want to change orientation mid-render, so grab the semaphore + xSemaphoreTake(renderingMutex, portMAX_DELAY); + + // If a section is loaded, preserve the current page number + if (section) { + nextPageNumber = section->currentPage; + } + + // + // Cycle to next orientation + // + uint8_t newOrientation = (SETTINGS.orientation + 1) % 4; + SETTINGS.orientation = newOrientation; + SETTINGS.saveToFile(); + + // + // Apply orientation to renderer + // + switch (SETTINGS.orientation) { + case CrossPointSettings::ORIENTATION::PORTRAIT: + renderer.setOrientation(GfxRenderer::Orientation::Portrait); + break; + case CrossPointSettings::ORIENTATION::LANDSCAPE_CW: + renderer.setOrientation(GfxRenderer::Orientation::LandscapeClockwise); + break; + case CrossPointSettings::ORIENTATION::INVERTED: + renderer.setOrientation(GfxRenderer::Orientation::PortraitInverted); + break; + case CrossPointSettings::ORIENTATION::LANDSCAPE_CCW: + renderer.setOrientation(GfxRenderer::Orientation::LandscapeCounterClockwise); + break; + default: + break; + } + + // + // Force a redraw + // + section.reset(); + updateRequired = true; + + xSemaphoreGive(renderingMutex); +} diff --git a/src/activities/reader/EpubReaderActivity.h b/src/activities/reader/EpubReaderActivity.h index ab4aff2d..482501cd 100644 --- a/src/activities/reader/EpubReaderActivity.h +++ b/src/activities/reader/EpubReaderActivity.h @@ -27,6 +27,7 @@ class EpubReaderActivity final : public ActivityWithSubactivity { void renderContents(std::unique_ptr page, int orientedMarginTop, int orientedMarginRight, int orientedMarginBottom, int orientedMarginLeft); void renderStatusBar(int orientedMarginRight, int orientedMarginBottom, int orientedMarginLeft) const; + void rotateScreen(); public: explicit EpubReaderActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, std::unique_ptr epub,