mod: overhaul reader menu with long-press actions and quick toggles

Consolidate dictionary items: remove "Lookup Word History" and
"Delete Dictionary Cache" from the menu. Long-press on "Lookup Word"
opens history; delete-dict-cache is now a sentinel entry at the bottom
of the history list.

Replace "Reading Orientation" with "Toggle Portrait/Landscape" that
toggles between two configurable preferred orientations (new settings:
Preferred Portrait, Preferred Landscape). Long-press opens a manual
4-option orientation sub-menu.

Add "Toggle Font Size" menu item that cycles through font sizes and
applies on menu exit (with section re-layout).

Rename "Letterbox Fill" to "Override Letterbox Fill" and
"Sync Progress" to "Sync Reading Progress" in reader menu.

All long-press flows use ignoreNextConfirmRelease to prevent the
button release from triggering actions on the subsequent screen.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
cottongin
2026-02-16 18:45:46 -05:00
parent 61fb11cae3
commit 1d7971ae60
11 changed files with 248 additions and 48 deletions

View File

@@ -250,8 +250,8 @@ void EpubReaderActivity::loop() {
exitActivity();
enterNewActivity(new EpubReaderMenuActivity(
this->renderer, this->mappedInput, epub->getTitle(), currentPage, totalPages, bookProgressPercent,
SETTINGS.orientation, hasDictionary, isBookmarked, epub->getCachePath(),
[this](const uint8_t orientation) { onReaderMenuBack(orientation); },
SETTINGS.orientation, SETTINGS.fontSize, hasDictionary, isBookmarked, epub->getCachePath(),
[this](const uint8_t orientation, const uint8_t fontSize) { onReaderMenuBack(orientation, fontSize); },
[this](EpubReaderMenuActivity::MenuAction action) { onReaderMenuConfirm(action); }));
}
@@ -342,11 +342,13 @@ void EpubReaderActivity::loop() {
}
}
void EpubReaderActivity::onReaderMenuBack(const uint8_t orientation) {
void EpubReaderActivity::onReaderMenuBack(const uint8_t orientation, const uint8_t fontSize) {
exitActivity();
// Apply the user-selected orientation when the menu is dismissed.
// This ensures the menu can be navigated without immediately rotating the screen.
applyOrientation(orientation);
// Apply font size change (no-op if unchanged).
applyFontSize(fontSize);
// Force a half refresh on the next render to clear menu/popup artifacts
pagesUntilFullRefresh = 1;
requestUpdate();
@@ -563,24 +565,6 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction
}));
break;
}
case EpubReaderMenuActivity::MenuAction::DELETE_DICT_CACHE: {
if (Dictionary::cacheExists()) {
Dictionary::deleteCache();
{
RenderLock lock(*this);
GUI.drawPopup(renderer, tr(STR_DICT_CACHE_DELETED));
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
}
} else {
{
RenderLock lock(*this);
GUI.drawPopup(renderer, tr(STR_NO_CACHE_TO_DELETE));
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
}
}
vTaskDelay(1500 / portTICK_PERIOD_MS);
break;
}
case EpubReaderMenuActivity::MenuAction::SELECT_CHAPTER: {
// Calculate values BEFORE we start destroying things
const int currentP = section ? section->currentPage : 0;
@@ -706,7 +690,8 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction
exitActivity();
enterNewActivity(new LookedUpWordsActivity(
renderer, mappedInput, epub->getCachePath(), SETTINGS.getReaderFontId(), SETTINGS.orientation,
[this]() { pendingSubactivityExit = true; }, [this]() { pendingSubactivityExit = true; }));
[this]() { pendingSubactivityExit = true; }, [this]() { pendingSubactivityExit = true; },
true)); // initialSkipRelease: consumed the long-press that triggered this
break;
}
case EpubReaderMenuActivity::MenuAction::GO_HOME: {
@@ -766,6 +751,7 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction
}
// Handled locally in the menu activity (cycle on Confirm, never dispatched here)
case EpubReaderMenuActivity::MenuAction::ROTATE_SCREEN:
case EpubReaderMenuActivity::MenuAction::TOGGLE_FONT_SIZE:
case EpubReaderMenuActivity::MenuAction::LETTERBOX_FILL:
break;
}
@@ -798,6 +784,28 @@ void EpubReaderActivity::applyOrientation(const uint8_t orientation) {
}
}
void EpubReaderActivity::applyFontSize(const uint8_t fontSize) {
if (SETTINGS.fontSize == fontSize) {
return;
}
// Preserve current reading position so we can restore after reflow.
{
RenderLock lock(*this);
if (section) {
cachedSpineIndex = currentSpineIndex;
cachedChapterTotalPageCount = section->pageCount;
nextPageNumber = section->currentPage;
}
SETTINGS.fontSize = fontSize;
SETTINGS.saveToFile();
// Reset section to force re-layout with the new font size.
section.reset();
}
}
// TODO: Failure handling
void EpubReaderActivity::render(Activity::RenderLock&& lock) {
if (!epub) {