feat: Slim dictionary (#2583)

Co-authored-by: Ryan Hitchman <hitchmanr@gmail.com>
Co-authored-by: Kurtis Grant <kurtis.b.grant@gmail.com>
Co-authored-by: kemonine <kemonine@kemonine.info>
Co-authored-by: DustinHu <hu.dustin@gmail.com>
Co-authored-by: Justin Mitchell <justin@jmitch.com>
This commit is contained in:
Uri Tauber
2026-07-19 17:57:16 +03:00
committed by GitHub
co-authored by Ryan Hitchman Kurtis Grant kemonine DustinHu Justin Mitchell
parent 5ba1d5747f
commit b1d1d757ba
27 changed files with 1919 additions and 10 deletions
@@ -20,6 +20,7 @@
#include "BookmarkEntry.h"
#include "CrossPointSettings.h"
#include "CrossPointState.h"
#include "DictionaryWordSelectActivity.h"
#include "EpubReaderBookmarksActivity.h"
#include "EpubReaderChapterSelectionActivity.h"
#include "EpubReaderFootnotesActivity.h"
@@ -257,6 +258,29 @@ void EpubReaderActivity::openReaderMenu() {
});
}
void EpubReaderActivity::openDictionaryWordSelect() {
if (SETTINGS.dictionaryName[0] == '\0') {
showDictionaryMessage = true;
dictionaryMessageTime = millis();
requestUpdate();
return;
}
if (!section) return;
auto page = section->loadPage(section->currentPage);
if (!page) return;
// Word geometry must match render(): viewable-area margins plus screen margin.
int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft;
renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom,
&orientedMarginLeft);
orientedMarginTop += SETTINGS.screenMargin;
orientedMarginLeft += SETTINGS.screenMargin;
startActivityForResult(std::make_unique<DictionaryWordSelectActivity>(renderer, mappedInput, std::move(page),
orientedMarginLeft, orientedMarginTop),
[this](const ActivityResult&) { requestUpdate(); });
}
void EpubReaderActivity::loop() {
if (!epub) {
// Should never happen
@@ -379,6 +403,11 @@ void EpubReaderActivity::loop() {
requestUpdate();
}
if (showDictionaryMessage && (millis() - dictionaryMessageTime) >= ReaderUtils::BOOKMARK_MESSAGE_DURATION_MS) {
showDictionaryMessage = false;
requestUpdate();
}
// While the end screen suggestion menu is showing it owns Confirm/Back/navigation
// input. Anything it doesn't handle (e.g. long-press Back to the file browser) falls
// through to the regular handlers below; page turns are absorbed by the end-of-book
@@ -442,6 +471,14 @@ void EpubReaderActivity::loop() {
}
}
break;
case CrossPointSettings::LP_MENU_DICTIONARY:
// Hold ~0.4s starts dictionary word selection on the current page.
if (mappedInput.getHeldTime() >= ReaderUtils::BOOKMARK_HOLD_MS && !showDictionaryMessage) {
ignoreNextConfirmRelease = true; // Prevent menu open on the release that follows
openDictionaryWordSelect();
return;
}
break;
case CrossPointSettings::LP_MENU_DISABLED:
default:
break;
@@ -710,6 +747,10 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction
});
break;
}
case EpubReaderMenuActivity::MenuAction::DICTIONARY: {
openDictionaryWordSelect();
break;
}
case EpubReaderMenuActivity::MenuAction::DISPLAY_QR: {
if (section && section->currentPage >= 0 && section->currentPage < section->pageCount) {
std::string fullText = section->getTextFromSectionFile();
@@ -1300,6 +1341,10 @@ void EpubReaderActivity::render(RenderLock&& lock) {
if (showBookmarkMessage) {
GUI.drawPopup(renderer, bookmarkRemoved ? tr(STR_BOOKMARK_REMOVED) : tr(STR_BOOKMARK_ADDED));
}
if (showDictionaryMessage) {
GUI.drawPopup(renderer, tr(STR_DICT_NO_DICT_SET));
}
}
bool EpubReaderActivity::applyDeferredReposition() {