refactor: Simplify XtcReaderActivity with detectPageTurn (#1837)

## Summary

Simplify duplicated code in `XtcReaderActivity` to use
`ReaderUtils::detectPageTurn`. This implementation is now shared with
`EpubReaderActivity` and `TxtReaderActivity`. Also deduplicated the
chapter skip time constant.

---

### 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? _**PARTIALLY**_
This commit is contained in:
Zach Nelson
2026-05-06 09:57:06 -05:00
committed by GitHub
parent 4ea938b709
commit cfe3a948a0
5 changed files with 13 additions and 52 deletions
+2 -3
View File
@@ -30,7 +30,6 @@
namespace { namespace {
// pagesPerRefresh now comes from SETTINGS.getRefreshFrequency() // pagesPerRefresh now comes from SETTINGS.getRefreshFrequency()
constexpr unsigned long skipChapterMs = 700;
// pages per minute, first item is 1 to prevent division by zero if accessed // pages per minute, first item is 1 to prevent division by zero if accessed
constexpr int PAGE_TURN_RATES[] = {1, 1, 3, 6, 12}; constexpr int PAGE_TURN_RATES[] = {1, 1, 3, 6, 12};
@@ -185,7 +184,7 @@ void EpubReaderActivity::loop() {
return; return;
} }
auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput); const auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput);
if (!prevTriggered && !nextTriggered) { if (!prevTriggered && !nextTriggered) {
return; return;
} }
@@ -203,7 +202,7 @@ void EpubReaderActivity::loop() {
return; return;
} }
const bool longPress = !fromTilt && mappedInput.getHeldTime() > skipChapterMs; const bool longPress = !fromTilt && mappedInput.getHeldTime() > ReaderUtils::SKIP_HOLD_MS;
// Don't skip chapter after screenshot // Don't skip chapter after screenshot
if (gpio.wasReleased(HalGPIO::BTN_POWER) && gpio.wasReleased(HalGPIO::BTN_DOWN)) { if (gpio.wasReleased(HalGPIO::BTN_POWER) && gpio.wasReleased(HalGPIO::BTN_DOWN)) {
+1
View File
@@ -10,6 +10,7 @@
namespace ReaderUtils { namespace ReaderUtils {
constexpr unsigned long GO_HOME_MS = 1000; constexpr unsigned long GO_HOME_MS = 1000;
constexpr unsigned long SKIP_HOLD_MS = 700;
inline void applyOrientation(GfxRenderer& renderer, const uint8_t orientation) { inline void applyOrientation(GfxRenderer& renderer, const uint8_t orientation) {
switch (orientation) { switch (orientation) {
+1 -1
View File
@@ -71,7 +71,7 @@ void TxtReaderActivity::loop() {
return; return;
} }
auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput); const auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput);
if (!prevTriggered && !nextTriggered) { if (!prevTriggered && !nextTriggered) {
return; return;
} }
+9 -44
View File
@@ -10,22 +10,17 @@
#include <FsHelpers.h> #include <FsHelpers.h>
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <HalStorage.h> #include <HalStorage.h>
#include <HalTiltSensor.h>
#include <I18n.h> #include <I18n.h>
#include "CrossPointSettings.h" #include "CrossPointSettings.h"
#include "CrossPointState.h" #include "CrossPointState.h"
#include "MappedInputManager.h" #include "MappedInputManager.h"
#include "ReaderUtils.h"
#include "RecentBooksStore.h" #include "RecentBooksStore.h"
#include "XtcReaderChapterSelectionActivity.h" #include "XtcReaderChapterSelectionActivity.h"
#include "components/UITheme.h" #include "components/UITheme.h"
#include "fontIds.h" #include "fontIds.h"
namespace {
constexpr unsigned long skipPageMs = 700;
constexpr unsigned long goHomeMs = 1000;
} // namespace
void XtcReaderActivity::onEnter() { void XtcReaderActivity::onEnter() {
Activity::onEnter(); Activity::onEnter();
@@ -70,34 +65,19 @@ void XtcReaderActivity::loop() {
} }
// Long press BACK (1s+) goes to file selection // Long press BACK (1s+) goes to file selection
if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= goHomeMs) { if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= ReaderUtils::GO_HOME_MS) {
activityManager.goToFileBrowser(xtc ? xtc->getPath() : ""); activityManager.goToFileBrowser(xtc ? xtc->getPath() : "");
return; return;
} }
// Short press BACK goes directly to home // Short press BACK goes directly to home
if (mappedInput.wasReleased(MappedInputManager::Button::Back) && mappedInput.getHeldTime() < goHomeMs) { if (mappedInput.wasReleased(MappedInputManager::Button::Back) &&
mappedInput.getHeldTime() < ReaderUtils::GO_HOME_MS) {
onGoHome(); onGoHome();
return; return;
} }
// When long-press chapter skip is disabled, turn pages on press instead of release. const auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput);
const bool usePressForPageTurn = SETTINGS.longPressButtonBehavior == SETTINGS.OFF;
const bool tiltNext = SETTINGS.tiltPageTurn && halTiltSensor.wasTiltedForward();
const bool tiltPrev = SETTINGS.tiltPageTurn && halTiltSensor.wasTiltedBack();
const bool prevTriggered =
tiltPrev || (usePressForPageTurn ? (mappedInput.wasPressed(MappedInputManager::Button::PageBack) ||
mappedInput.wasPressed(MappedInputManager::Button::Left))
: (mappedInput.wasReleased(MappedInputManager::Button::PageBack) ||
mappedInput.wasReleased(MappedInputManager::Button::Left)));
const bool powerPageTurn = SETTINGS.shortPwrBtn == CrossPointSettings::SHORT_PWRBTN::PAGE_TURN &&
mappedInput.wasReleased(MappedInputManager::Button::Power);
const bool nextTriggered =
tiltNext || (usePressForPageTurn ? (mappedInput.wasPressed(MappedInputManager::Button::PageForward) ||
powerPageTurn || mappedInput.wasPressed(MappedInputManager::Button::Right))
: (mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
powerPageTurn || mappedInput.wasReleased(MappedInputManager::Button::Right)));
if (!prevTriggered && !nextTriggered) { if (!prevTriggered && !nextTriggered) {
return; return;
} }
@@ -113,9 +93,8 @@ void XtcReaderActivity::loop() {
return; return;
} }
const bool fromTilt = tiltPrev || tiltNext; const bool skipPages = !fromTilt && SETTINGS.longPressButtonBehavior == SETTINGS.CHAPTER_SKIP &&
const bool skipPages = mappedInput.getHeldTime() > ReaderUtils::SKIP_HOLD_MS;
!fromTilt && SETTINGS.longPressButtonBehavior == SETTINGS.CHAPTER_SKIP && mappedInput.getHeldTime() > skipPageMs;
const int skipAmount = skipPages ? 10 : 1; const int skipAmount = skipPages ? 10 : 1;
if (prevTriggered) { if (prevTriggered) {
@@ -242,14 +221,7 @@ void XtcReaderActivity::renderPage() {
} }
} }
// Display BW with conditional refresh based on pagesUntilFullRefresh ReaderUtils::displayWithRefreshCycle(renderer, pagesUntilFullRefresh);
if (pagesUntilFullRefresh <= 1) {
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
pagesUntilFullRefresh = SETTINGS.getRefreshFrequency();
} else {
renderer.displayBuffer();
pagesUntilFullRefresh--;
}
// Pass 2: LSB buffer - mark DARK gray only (XTH value 1) // Pass 2: LSB buffer - mark DARK gray only (XTH value 1)
// In LUT: 0 bit = apply gray effect, 1 bit = untouched // In LUT: 0 bit = apply gray effect, 1 bit = untouched
@@ -321,14 +293,7 @@ void XtcReaderActivity::renderPage() {
// XTC pages already have status bar pre-rendered, no need to add our own // XTC pages already have status bar pre-rendered, no need to add our own
// Display with appropriate refresh ReaderUtils::displayWithRefreshCycle(renderer, pagesUntilFullRefresh);
if (pagesUntilFullRefresh <= 1) {
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
pagesUntilFullRefresh = SETTINGS.getRefreshFrequency();
} else {
renderer.displayBuffer();
pagesUntilFullRefresh--;
}
LOG_DBG("XTR", "Rendered page %lu/%lu (%u-bit)", currentPage + 1, xtc->getPageCount(), bitDepth); LOG_DBG("XTR", "Rendered page %lu/%lu (%u-bit)", currentPage + 1, xtc->getPageCount(), bitDepth);
} }
-4
View File
@@ -13,10 +13,6 @@
#include "components/themes/lyra/LyraTheme.h" #include "components/themes/lyra/LyraTheme.h"
#include "components/themes/roundedraff/RoundedRaffTheme.h" #include "components/themes/roundedraff/RoundedRaffTheme.h"
namespace {
constexpr int SKIP_PAGE_MS = 700;
} // namespace
UITheme UITheme::instance; UITheme UITheme::instance;
UITheme::UITheme() { UITheme::UITheme() {