mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 15:17:37 +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;
|
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) ||
|
const bool prevReleased = mappedInput.wasReleased(MappedInputManager::Button::PageBack) ||
|
||||||
mappedInput.wasReleased(MappedInputManager::Button::Left);
|
mappedInput.wasReleased(MappedInputManager::Button::Left);
|
||||||
const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
|
const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
|
||||||
@ -173,6 +195,12 @@ void EpubReaderActivity::loop() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (awaitingReleaseAfterSkip) {
|
||||||
|
awaitingReleaseAfterSkip = false;
|
||||||
|
skipUnpressed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// any botton press when at end of the book goes back to the last page
|
// any botton press when at end of the book goes back to the last page
|
||||||
if (currentSpineIndex > 0 && currentSpineIndex >= epub->getSpineItemsCount()) {
|
if (currentSpineIndex > 0 && currentSpineIndex >= epub->getSpineItemsCount()) {
|
||||||
currentSpineIndex = epub->getSpineItemsCount() - 1;
|
currentSpineIndex = epub->getSpineItemsCount() - 1;
|
||||||
@ -181,20 +209,6 @@ void EpubReaderActivity::loop() {
|
|||||||
return;
|
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
|
// No current section, attempt to rerender the book
|
||||||
if (!section) {
|
if (!section) {
|
||||||
|
|||||||
@ -19,6 +19,8 @@ class EpubReaderActivity final : public ActivityWithSubactivity {
|
|||||||
bool delayedSkipPending = false;
|
bool delayedSkipPending = false;
|
||||||
int delayedSkipDir = 0;
|
int delayedSkipDir = 0;
|
||||||
uint32_t delayedSkipExecuteAtMs = 0;
|
uint32_t delayedSkipExecuteAtMs = 0;
|
||||||
|
bool awaitingReleaseAfterSkip = false;
|
||||||
|
bool skipUnpressed = false;
|
||||||
const std::function<void()> onGoBack;
|
const std::function<void()> onGoBack;
|
||||||
const std::function<void()> onGoHome;
|
const std::function<void()> onGoHome;
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,29 @@ void XtcReaderActivity::loop() {
|
|||||||
return;
|
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) ||
|
const bool prevReleased = mappedInput.wasReleased(MappedInputManager::Button::PageBack) ||
|
||||||
mappedInput.wasReleased(MappedInputManager::Button::Left);
|
mappedInput.wasReleased(MappedInputManager::Button::Left);
|
||||||
const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
|
const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::PageForward) ||
|
||||||
@ -121,6 +144,12 @@ void XtcReaderActivity::loop() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (awaitingReleaseAfterSkip) {
|
||||||
|
awaitingReleaseAfterSkip = false;
|
||||||
|
skipUnpressed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle end of book
|
// Handle end of book
|
||||||
if (currentPage >= xtc->getPageCount()) {
|
if (currentPage >= xtc->getPageCount()) {
|
||||||
currentPage = xtc->getPageCount() - 1;
|
currentPage = xtc->getPageCount() - 1;
|
||||||
@ -128,38 +157,17 @@ void XtcReaderActivity::loop() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool skipPages = SETTINGS.longPressChapterSkip && mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs();
|
|
||||||
const int skipAmount = skipPages ? 10 : 1;
|
|
||||||
|
|
||||||
if (prevReleased) {
|
if (prevReleased) {
|
||||||
if (skipPages) {
|
// Short press: single page back
|
||||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
if (currentPage >= 1) {
|
||||||
showSkipPopup("Skipping");
|
currentPage -= 1;
|
||||||
delayedSkipPending = true;
|
|
||||||
delayedSkipDir = -1;
|
|
||||||
delayedSkipAmount = skipAmount;
|
|
||||||
delayedSkipExecuteAtMs = millis() + 500;
|
|
||||||
xSemaphoreGive(renderingMutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (currentPage >= static_cast<uint32_t>(skipAmount)) {
|
|
||||||
currentPage -= skipAmount;
|
|
||||||
} else {
|
} else {
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
}
|
}
|
||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
} else if (nextReleased) {
|
} else if (nextReleased) {
|
||||||
if (skipPages) {
|
// Short press: single page forward
|
||||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
currentPage += 1;
|
||||||
showSkipPopup("Skipping");
|
|
||||||
delayedSkipPending = true;
|
|
||||||
delayedSkipDir = +1;
|
|
||||||
delayedSkipAmount = skipAmount;
|
|
||||||
delayedSkipExecuteAtMs = millis() + 500;
|
|
||||||
xSemaphoreGive(renderingMutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currentPage += skipAmount;
|
|
||||||
if (currentPage >= xtc->getPageCount()) {
|
if (currentPage >= xtc->getPageCount()) {
|
||||||
currentPage = xtc->getPageCount(); // Allow showing "End of book"
|
currentPage = xtc->getPageCount(); // Allow showing "End of book"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,8 @@ class XtcReaderActivity final : public ActivityWithSubactivity {
|
|||||||
int delayedSkipDir = 0;
|
int delayedSkipDir = 0;
|
||||||
uint32_t delayedSkipExecuteAtMs = 0;
|
uint32_t delayedSkipExecuteAtMs = 0;
|
||||||
uint32_t delayedSkipAmount = 0;
|
uint32_t delayedSkipAmount = 0;
|
||||||
|
bool awaitingReleaseAfterSkip = false;
|
||||||
|
bool skipUnpressed = false;
|
||||||
const std::function<void()> onGoBack;
|
const std::function<void()> onGoBack;
|
||||||
const std::function<void()> onGoHome;
|
const std::function<void()> onGoHome;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user