feat: add power button short press for quick access to footnotes (#1658)

This commit is contained in:
Lorenzo Santini
2026-06-08 14:45:41 -04:00
committed by GitHub
parent 7f01eab62e
commit 9c12b90737
8 changed files with 63 additions and 7 deletions
+2
View File
@@ -247,7 +247,9 @@ The Settings screen allows you to configure the device's behavior. There are a f
- "Ignore" (default) - Require a long press to turn off the device
- "Sleep" - A short press puts the device into sleep mode
- "Page Turn" - A short press in reading mode turns to the next page; a long press turns the device off
- "Footnotes" - A short press in reading mode opens the footnotes submenu; if only one footnote is present on the page, the referenced page is opened directly. The short press on the power button can be used to select the footnote in the submenu, and to go back to the original page after finish reading the footnote (like the back button).
- "Refresh" - A short press triggers a manual full-screen refresh, useful for clearing ghosting
- **Quick-return from footnotes**: Toggles on and off the quick return functionality from the footnotes. When the functionality it's active, a short press of the power button will act as the back button from the footnotes page.
#### 3.6.4 System
+1
View File
@@ -318,6 +318,7 @@ STR_BOOK_S_STYLE: "Book's Style"
STR_EMBEDDED_STYLE: "Embedded Style"
STR_FOCUS_READING: "Focus Reading"
STR_OPDS_SERVER_URL: "OPDS Server URL"
STR_PWR_BTN_FOOTNOTE_BACK: "Quick-return from footnotes"
STR_SET_SLEEP_COVER: "Set Cover"
STR_FOOTNOTES: "Footnotes"
STR_NO_FOOTNOTES: "No footnotes on this page"
+3 -1
View File
@@ -134,7 +134,7 @@ class CrossPointSettings {
};
// Short power button press actions
enum SHORT_PWRBTN { IGNORE = 0, SLEEP = 1, PAGE_TURN = 2, FORCE_REFRESH = 3, SHORT_PWRBTN_COUNT };
enum SHORT_PWRBTN { IGNORE = 0, SLEEP = 1, PAGE_TURN = 2, FORCE_REFRESH = 3, FOOTNOTES = 4, SHORT_PWRBTN_COUNT };
// Hide battery percentage
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2, HIDE_BATTERY_PERCENTAGE_COUNT };
@@ -230,6 +230,8 @@ class CrossPointSettings {
uint8_t uiTheme = LYRA;
// Sunlight fading compensation
uint8_t fadingFix = 0;
// Power button return from footnotes (1 = enabled, 0 = disabled)
uint8_t pwrBtnFootnoteBack = 1;
// Use book's embedded CSS styles for EPUB rendering (1 = enabled, 0 = disabled)
uint8_t embeddedStyle = 1;
// Focus Reading - emphasizes the first part of words with bold
+6 -4
View File
@@ -171,10 +171,12 @@ inline std::vector<SettingInfo> getSettingsList(const SdCardFontRegistry* regist
{StrId::STR_LONG_PRESS_BEHAVIOR_OFF, StrId::STR_LONG_PRESS_BEHAVIOR_SKIP,
StrId::STR_LONG_PRESS_BEHAVIOR_ORIENTATION},
"longPressButtonBehavior", StrId::STR_CAT_CONTROLS),
SettingInfo::Enum(StrId::STR_SHORT_PWR_BTN, &CrossPointSettings::shortPwrBtn,
{StrId::STR_IGNORE, StrId::STR_SLEEP, StrId::STR_PAGE_TURN, StrId::STR_FORCE_REFRESH},
"shortPwrBtn", StrId::STR_CAT_CONTROLS),
SettingInfo::Enum(
StrId::STR_SHORT_PWR_BTN, &CrossPointSettings::shortPwrBtn,
{StrId::STR_IGNORE, StrId::STR_SLEEP, StrId::STR_PAGE_TURN, StrId::STR_FORCE_REFRESH, StrId::STR_FOOTNOTES},
"shortPwrBtn", StrId::STR_CAT_CONTROLS),
SettingInfo::Toggle(StrId::STR_PWR_BTN_FOOTNOTE_BACK, &CrossPointSettings::pwrBtnFootnoteBack,
"pwrBtnFootnoteBack", StrId::STR_CAT_CONTROLS),
// --- System ---
SettingInfo::Value(
StrId::STR_TIME_TO_SLEEP, &CrossPointSettings::sleepTimeoutMinutes,
@@ -312,6 +312,32 @@ void EpubReaderActivity::loop() {
return;
}
// auto [prevTriggered, nextTriggered] = ReaderUtils::detectPageTurn(mappedInput);
// Handle short power button press for footnotes
if (SETTINGS.shortPwrBtn == CrossPointSettings::SHORT_PWRBTN::FOOTNOTES &&
mappedInput.wasReleased(MappedInputManager::Button::Power) &&
!mappedInput.wasReleased(MappedInputManager::Button::Down)) {
if (footnoteDepth > 0) {
restoreSavedPosition();
} else {
if (currentPageFootnotes.size() == 1) {
navigateToHref(currentPageFootnotes[0].href, true);
} else if (currentPageFootnotes.size() > 1) {
startActivityForResult(
std::make_unique<EpubReaderFootnotesActivity>(renderer, mappedInput, currentPageFootnotes),
[this](const ActivityResult& result) {
if (!result.isCancelled) {
const auto& footnoteResult = std::get<FootnoteResult>(result.data);
navigateToHref(footnoteResult.href, true);
}
requestUpdate();
});
}
}
return;
}
const auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput);
if (!prevTriggered && !nextTriggered) {
return;
@@ -26,7 +26,8 @@ void EpubReaderFootnotesActivity::loop() {
return;
}
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm) ||
mappedInput.wasReleased(MappedInputManager::Button::Power)) {
if (selectedIndex >= 0 && selectedIndex < static_cast<int>(footnotes.size())) {
setResult(FootnoteResult{footnotes[selectedIndex].href});
finish();
@@ -46,6 +46,10 @@ void SettingsActivity::rebuildSettingsLists() {
} else if (setting.category == StrId::STR_CAT_READER) {
readerSettings.push_back(setting);
} else if (setting.category == StrId::STR_CAT_CONTROLS) {
if (setting.valuePtr == &CrossPointSettings::pwrBtnFootnoteBack &&
SETTINGS.shortPwrBtn != CrossPointSettings::SHORT_PWRBTN::FOOTNOTES) {
continue;
}
controlsSettings.push_back(setting);
} else if (setting.category == StrId::STR_CAT_SYSTEM) {
systemSettings.push_back(setting);
@@ -271,6 +275,8 @@ void SettingsActivity::toggleCurrentSetting() {
syncQuickResumeTimeoutForSleepScreen(sleepScreenChanged, quickResumeTimeoutChanged);
SETTINGS.saveToFile();
rebuildSettingsLists();
selectedSettingIndex = std::min(selectedSettingIndex, settingsCount);
}
void SettingsActivity::syncQuickResumeTimeoutForSleepScreen(bool sleepScreenChanged, bool quickResumeTimeoutChanged) {
+17 -1
View File
@@ -479,8 +479,23 @@
return changed;
}
function updateSettingsVisibility() {
const shortPwrBtnVal = getControlValue('shortPwrBtn');
const pwrBtnFootnoteBackRow = document.getElementById('row-setting-pwrBtnFootnoteBack');
if (pwrBtnFootnoteBackRow) {
if (shortPwrBtnVal === 4) {
pwrBtnFootnoteBackRow.style.display = '';
} else {
pwrBtnFootnoteBackRow.style.display = 'none';
}
}
}
function handleSettingChanged(key) {
syncQuickResumeTimeoutForSleepScreen(key === 'sleepScreen', key === 'quickResumeSleepScreen');
if (key === 'shortPwrBtn') {
updateSettingsVisibility();
}
markChanged();
}
@@ -511,7 +526,7 @@
for (const category in groups) {
html += '<div class="card"><h2>' + escapeHtml(category) + '</h2>';
groups[category].forEach(function(s) {
html += '<div class="setting-row">' +
html += '<div class="setting-row" id="row-setting-' + s.key + '">' +
'<span class="setting-name">' + escapeHtml(s.name) + '</span>' +
'<span class="setting-control">' + renderControl(s) + '</span>' +
'</div>';
@@ -520,6 +535,7 @@
}
container.innerHTML = html;
updateSettingsVisibility();
document.getElementById('save-container').style.display = '';
document.getElementById('saveBtn').disabled = true;
preserveQuickResumeTimeoutOn = getControlValue('quickResumeSleepScreen') === 1;