diff --git a/src/activities/reader/EpubReaderChapterSelectionActivity.cpp b/src/activities/reader/EpubReaderChapterSelectionActivity.cpp index 1b35e143..3ead68ca 100644 --- a/src/activities/reader/EpubReaderChapterSelectionActivity.cpp +++ b/src/activities/reader/EpubReaderChapterSelectionActivity.cpp @@ -7,11 +7,6 @@ #include "MappedInputManager.h" #include "fontIds.h" -namespace { -// Time threshold for treating a long press as a page-up/page-down -constexpr int SKIP_PAGE_MS = 700; -} // namespace - bool EpubReaderChapterSelectionActivity::hasSyncOption() const { return KOREADER_STORE.hasCredentials(); } int EpubReaderChapterSelectionActivity::getTotalItems() const { @@ -119,12 +114,6 @@ void EpubReaderChapterSelectionActivity::loop() { return; } - const bool prevReleased = mappedInput.wasReleased(MappedInputManager::Button::Up) || - mappedInput.wasReleased(MappedInputManager::Button::Left); - const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::Down) || - mappedInput.wasReleased(MappedInputManager::Button::Right); - - const bool skipPage = mappedInput.getHeldTime() > SKIP_PAGE_MS; const int pageItems = getPageItems(); const int totalItems = getTotalItems(); @@ -145,21 +134,27 @@ void EpubReaderChapterSelectionActivity::loop() { } } else if (mappedInput.wasReleased(MappedInputManager::Button::Back)) { onGoBack(); - } else if (prevReleased) { - if (skipPage) { - selectorIndex = ((selectorIndex / pageItems - 1) * pageItems + totalItems) % totalItems; - } else { - selectorIndex = (selectorIndex + totalItems - 1) % totalItems; - } - updateRequired = true; - } else if (nextReleased) { - if (skipPage) { - selectorIndex = ((selectorIndex / pageItems + 1) * pageItems) % totalItems; - } else { - selectorIndex = (selectorIndex + 1) % totalItems; - } - updateRequired = true; } + + buttonNavigator.onNextRelease([this, totalItems] { + selectorIndex = ButtonNavigator::nextIndex(selectorIndex, totalItems); + updateRequired = true; + }); + + buttonNavigator.onPreviousRelease([this, totalItems] { + selectorIndex = ButtonNavigator::previousIndex(selectorIndex, totalItems); + updateRequired = true; + }); + + buttonNavigator.onNextContinuous([this, totalItems, pageItems] { + selectorIndex = ButtonNavigator::nextPageIndex(selectorIndex, totalItems, pageItems); + updateRequired = true; + }); + + buttonNavigator.onPreviousContinuous([this, totalItems, pageItems] { + selectorIndex = ButtonNavigator::previousPageIndex(selectorIndex, totalItems, pageItems); + updateRequired = true; + }); } void EpubReaderChapterSelectionActivity::displayTaskLoop() { diff --git a/src/activities/reader/EpubReaderChapterSelectionActivity.h b/src/activities/reader/EpubReaderChapterSelectionActivity.h index 255f0cea..5ddb324b 100644 --- a/src/activities/reader/EpubReaderChapterSelectionActivity.h +++ b/src/activities/reader/EpubReaderChapterSelectionActivity.h @@ -7,12 +7,14 @@ #include #include "../ActivityWithSubactivity.h" +#include "util/ButtonNavigator.h" class EpubReaderChapterSelectionActivity final : public ActivityWithSubactivity { std::shared_ptr epub; std::string epubPath; TaskHandle_t displayTaskHandle = nullptr; SemaphoreHandle_t renderingMutex = nullptr; + ButtonNavigator buttonNavigator; int currentSpineIndex = 0; int currentPage = 0; int totalPagesInSpine = 0; diff --git a/src/util/ButtonNavigator.cpp b/src/util/ButtonNavigator.cpp index f7006ca5..531722ca 100644 --- a/src/util/ButtonNavigator.cpp +++ b/src/util/ButtonNavigator.cpp @@ -15,6 +15,10 @@ void ButtonNavigator::onNextPress(const Callback& callback) { onPress(getNextBut void ButtonNavigator::onPreviousPress(const Callback& callback) { onPress(getPreviousButtons(), callback); } +void ButtonNavigator::onNextRelease(const Callback& callback) const { onRelease(getNextButtons(), callback); } + +void ButtonNavigator::onPreviousRelease(const Callback& callback) const { onRelease(getPreviousButtons(), callback); } + void ButtonNavigator::onNextContinuous(const Callback& callback) { onContinuous(getNextButtons(), callback); } void ButtonNavigator::onPreviousContinuous(const Callback& callback) { onContinuous(getPreviousButtons(), callback); } @@ -34,6 +38,21 @@ void ButtonNavigator::onPress(const Buttons& buttons, const Callback& callback) callback(); } } +void ButtonNavigator::onRelease(const Buttons& buttons, const Callback& callback) const { + if (!mappedInput) return; + + bool buttonReleased = false; + for (const MappedInputManager::Button button : buttons) { + if (mappedInput->wasReleased(button)) { + buttonReleased = true; + break; + } + } + + if (buttonReleased && !recentlyNavigatedContinuously()) { + callback(); + } +} void ButtonNavigator::onContinuous(const Buttons& buttons, const Callback& callback) { if (!mappedInput) return; @@ -82,4 +101,30 @@ int ButtonNavigator::previousIndex(const int currentIndex, const int totalItems) // Calculate the previous index with wrap-around return (currentIndex + totalItems - 1) % totalItems; -} \ No newline at end of file +} + +int ButtonNavigator::nextPageIndex(const int currentIndex, const int totalItems, const int itemsPerPage) { + if (totalItems <= 0 || itemsPerPage <= 0) return 0; + + const int lastPageIndex = (totalItems - 1) / itemsPerPage; + const int currentPageIndex = currentIndex / itemsPerPage; + + if (currentPageIndex < lastPageIndex) { + return (currentPageIndex + 1) * itemsPerPage; + } + + return 0; +} + +int ButtonNavigator::previousPageIndex(const int currentIndex, const int totalItems, const int itemsPerPage) { + if (totalItems <= 0 || itemsPerPage <= 0) return 0; + + const int lastPageIndex = (totalItems - 1) / itemsPerPage; + const int currentPageIndex = currentIndex / itemsPerPage; + + if (currentPageIndex > 0) { + return (currentPageIndex - 1) * itemsPerPage; + } + + return lastPageIndex * itemsPerPage; +} diff --git a/src/util/ButtonNavigator.h b/src/util/ButtonNavigator.h index 14a1d928..0b08d85c 100644 --- a/src/util/ButtonNavigator.h +++ b/src/util/ButtonNavigator.h @@ -38,10 +38,17 @@ class ButtonNavigator final { void onPreviousPress(const Callback& callback); void onPress(const Buttons& buttons, const Callback& callback); + void onNextRelease(const Callback& callback) const; + void onPreviousRelease(const Callback& callback) const; + void onRelease(const Buttons& buttons, const Callback& callback) const; + void onNextContinuous(const Callback& callback); void onPreviousContinuous(const Callback& callback); void onContinuous(const Buttons& buttons, const Callback& callback); [[nodiscard]] static int nextIndex(int currentIndex, int totalItems); [[nodiscard]] static int previousIndex(int currentIndex, int totalItems); + + [[nodiscard]] static int nextPageIndex(int currentIndex, int totalItems, int itemsPerPage); + [[nodiscard]] static int previousPageIndex(int currentIndex, int totalItems, int itemsPerPage); }; \ No newline at end of file