mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-04 22:57:50 +03:00
Detect long-press and skip chapter immediately
This commit is contained in:
parent
4824247137
commit
de92710627
@ -162,6 +162,28 @@ void EpubReaderActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Detect long-press and schedule skip immediately
|
||||
const bool prevPressed = mappedInput.isPressed(MappedInputManager::Button::PageBack) ||
|
||||
mappedInput.isPressed(MappedInputManager::Button::Left);
|
||||
const bool nextPressed = mappedInput.isPressed(MappedInputManager::Button::PageForward) ||
|
||||
(SETTINGS.shortPwrBtn == CrossPointSettings::SHORT_PWRBTN::PAGE_TURN &&
|
||||
mappedInput.isPressed(MappedInputManager::Button::Power)) ||
|
||||
mappedInput.isPressed(MappedInputManager::Button::Right);
|
||||
|
||||
if (SETTINGS.longPressChapterSkip && (prevPressed || nextPressed) &&
|
||||
mappedInput.getHeldTime() >= SETTINGS.getLongPressDurationMs() && !delayedSkipPending &&
|
||||
!awaitingReleaseAfterSkip) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
showSkipPopup("Skipping");
|
||||
delayedSkipPending = true;
|
||||
delayedSkipDir = nextPressed ? +1 : -1;
|
||||
delayedSkipExecuteAtMs = millis() + 500;
|
||||
xSemaphoreGive(renderingMutex);
|
||||
// Block release-based page change until unpressed
|
||||
awaitingReleaseAfterSkip = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const bool prevReleased = mappedInput.wasReleased(MappedInputManager::Button::PageBack) ||
|
||||
mappedInput.wasReleased(MappedInputManager::Button::Left);
|
||||
const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
|
||||
@ -173,6 +195,12 @@ void EpubReaderActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (awaitingReleaseAfterSkip) {
|
||||
awaitingReleaseAfterSkip = false;
|
||||
skipUnpressed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// any botton press when at end of the book goes back to the last page
|
||||
if (currentSpineIndex > 0 && currentSpineIndex >= epub->getSpineItemsCount()) {
|
||||
currentSpineIndex = epub->getSpineItemsCount() - 1;
|
||||
@ -181,20 +209,6 @@ void EpubReaderActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool skipChapter = SETTINGS.longPressChapterSkip && mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs();
|
||||
|
||||
if (skipChapter) {
|
||||
// We don't want to delete the section mid-render, so grab the semaphore
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
// Show immediate feedback for long-press skip, then schedule delayed action (500ms)
|
||||
showSkipPopup("Skipping");
|
||||
delayedSkipPending = true;
|
||||
delayedSkipDir = nextReleased ? +1 : -1;
|
||||
delayedSkipExecuteAtMs = millis() + 500;
|
||||
xSemaphoreGive(renderingMutex);
|
||||
// Do not perform the skip immediately; it will be executed in display loop after delay
|
||||
return;
|
||||
}
|
||||
|
||||
// No current section, attempt to rerender the book
|
||||
if (!section) {
|
||||
|
||||
@ -19,6 +19,8 @@ class EpubReaderActivity final : public ActivityWithSubactivity {
|
||||
bool delayedSkipPending = false;
|
||||
int delayedSkipDir = 0;
|
||||
uint32_t delayedSkipExecuteAtMs = 0;
|
||||
bool awaitingReleaseAfterSkip = false;
|
||||
bool skipUnpressed = false;
|
||||
const std::function<void()> onGoBack;
|
||||
const std::function<void()> onGoHome;
|
||||
|
||||
|
||||
@ -110,6 +110,29 @@ void XtcReaderActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Detect long-press and schedule skip immediately
|
||||
const bool prevPressed = mappedInput.isPressed(MappedInputManager::Button::PageBack) ||
|
||||
mappedInput.isPressed(MappedInputManager::Button::Left);
|
||||
const bool nextPressed = mappedInput.isPressed(MappedInputManager::Button::PageForward) ||
|
||||
(SETTINGS.shortPwrBtn == CrossPointSettings::SHORT_PWRBTN::PAGE_TURN &&
|
||||
mappedInput.isPressed(MappedInputManager::Button::Power)) ||
|
||||
mappedInput.isPressed(MappedInputManager::Button::Right);
|
||||
|
||||
if (SETTINGS.longPressChapterSkip && (prevPressed || nextPressed) &&
|
||||
mappedInput.getHeldTime() >= SETTINGS.getLongPressDurationMs() && !delayedSkipPending &&
|
||||
!awaitingReleaseAfterSkip) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
showSkipPopup("Skipping");
|
||||
delayedSkipPending = true;
|
||||
delayedSkipDir = nextPressed ? +1 : -1;
|
||||
delayedSkipAmount = 10; // long-press skip amount
|
||||
delayedSkipExecuteAtMs = millis() + 500;
|
||||
xSemaphoreGive(renderingMutex);
|
||||
// Block release-based page change until unpressed
|
||||
awaitingReleaseAfterSkip = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const bool prevReleased = mappedInput.wasReleased(MappedInputManager::Button::PageBack) ||
|
||||
mappedInput.wasReleased(MappedInputManager::Button::Left);
|
||||
const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
|
||||
@ -121,6 +144,12 @@ void XtcReaderActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (awaitingReleaseAfterSkip) {
|
||||
awaitingReleaseAfterSkip = false;
|
||||
skipUnpressed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle end of book
|
||||
if (currentPage >= xtc->getPageCount()) {
|
||||
currentPage = xtc->getPageCount() - 1;
|
||||
@ -128,38 +157,17 @@ void XtcReaderActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool skipPages = SETTINGS.longPressChapterSkip && mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs();
|
||||
const int skipAmount = skipPages ? 10 : 1;
|
||||
|
||||
if (prevReleased) {
|
||||
if (skipPages) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
showSkipPopup("Skipping");
|
||||
delayedSkipPending = true;
|
||||
delayedSkipDir = -1;
|
||||
delayedSkipAmount = skipAmount;
|
||||
delayedSkipExecuteAtMs = millis() + 500;
|
||||
xSemaphoreGive(renderingMutex);
|
||||
return;
|
||||
}
|
||||
if (currentPage >= static_cast<uint32_t>(skipAmount)) {
|
||||
currentPage -= skipAmount;
|
||||
// Short press: single page back
|
||||
if (currentPage >= 1) {
|
||||
currentPage -= 1;
|
||||
} else {
|
||||
currentPage = 0;
|
||||
}
|
||||
updateRequired = true;
|
||||
} else if (nextReleased) {
|
||||
if (skipPages) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
showSkipPopup("Skipping");
|
||||
delayedSkipPending = true;
|
||||
delayedSkipDir = +1;
|
||||
delayedSkipAmount = skipAmount;
|
||||
delayedSkipExecuteAtMs = millis() + 500;
|
||||
xSemaphoreGive(renderingMutex);
|
||||
return;
|
||||
}
|
||||
currentPage += skipAmount;
|
||||
// Short press: single page forward
|
||||
currentPage += 1;
|
||||
if (currentPage >= xtc->getPageCount()) {
|
||||
currentPage = xtc->getPageCount(); // Allow showing "End of book"
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ class XtcReaderActivity final : public ActivityWithSubactivity {
|
||||
int delayedSkipDir = 0;
|
||||
uint32_t delayedSkipExecuteAtMs = 0;
|
||||
uint32_t delayedSkipAmount = 0;
|
||||
bool awaitingReleaseAfterSkip = false;
|
||||
bool skipUnpressed = false;
|
||||
const std::function<void()> onGoBack;
|
||||
const std::function<void()> onGoHome;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user