feat: add power button short press for quick access to footnotes (#1658)
This commit is contained in:
@@ -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
|
- "Ignore" (default) - Require a long press to turn off the device
|
||||||
- "Sleep" - A short press puts the device into sleep mode
|
- "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
|
- "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
|
- "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
|
#### 3.6.4 System
|
||||||
|
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ STR_BOOK_S_STYLE: "Book's Style"
|
|||||||
STR_EMBEDDED_STYLE: "Embedded Style"
|
STR_EMBEDDED_STYLE: "Embedded Style"
|
||||||
STR_FOCUS_READING: "Focus Reading"
|
STR_FOCUS_READING: "Focus Reading"
|
||||||
STR_OPDS_SERVER_URL: "OPDS Server URL"
|
STR_OPDS_SERVER_URL: "OPDS Server URL"
|
||||||
|
STR_PWR_BTN_FOOTNOTE_BACK: "Quick-return from footnotes"
|
||||||
STR_SET_SLEEP_COVER: "Set Cover"
|
STR_SET_SLEEP_COVER: "Set Cover"
|
||||||
STR_FOOTNOTES: "Footnotes"
|
STR_FOOTNOTES: "Footnotes"
|
||||||
STR_NO_FOOTNOTES: "No footnotes on this page"
|
STR_NO_FOOTNOTES: "No footnotes on this page"
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class CrossPointSettings {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Short power button press actions
|
// 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
|
// Hide battery percentage
|
||||||
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2, HIDE_BATTERY_PERCENTAGE_COUNT };
|
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;
|
uint8_t uiTheme = LYRA;
|
||||||
// Sunlight fading compensation
|
// Sunlight fading compensation
|
||||||
uint8_t fadingFix = 0;
|
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)
|
// Use book's embedded CSS styles for EPUB rendering (1 = enabled, 0 = disabled)
|
||||||
uint8_t embeddedStyle = 1;
|
uint8_t embeddedStyle = 1;
|
||||||
// Focus Reading - emphasizes the first part of words with bold
|
// Focus Reading - emphasizes the first part of words with bold
|
||||||
|
|||||||
+5
-3
@@ -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_OFF, StrId::STR_LONG_PRESS_BEHAVIOR_SKIP,
|
||||||
StrId::STR_LONG_PRESS_BEHAVIOR_ORIENTATION},
|
StrId::STR_LONG_PRESS_BEHAVIOR_ORIENTATION},
|
||||||
"longPressButtonBehavior", StrId::STR_CAT_CONTROLS),
|
"longPressButtonBehavior", StrId::STR_CAT_CONTROLS),
|
||||||
SettingInfo::Enum(StrId::STR_SHORT_PWR_BTN, &CrossPointSettings::shortPwrBtn,
|
SettingInfo::Enum(
|
||||||
{StrId::STR_IGNORE, StrId::STR_SLEEP, StrId::STR_PAGE_TURN, StrId::STR_FORCE_REFRESH},
|
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),
|
"shortPwrBtn", StrId::STR_CAT_CONTROLS),
|
||||||
|
SettingInfo::Toggle(StrId::STR_PWR_BTN_FOOTNOTE_BACK, &CrossPointSettings::pwrBtnFootnoteBack,
|
||||||
|
"pwrBtnFootnoteBack", StrId::STR_CAT_CONTROLS),
|
||||||
// --- System ---
|
// --- System ---
|
||||||
SettingInfo::Value(
|
SettingInfo::Value(
|
||||||
StrId::STR_TIME_TO_SLEEP, &CrossPointSettings::sleepTimeoutMinutes,
|
StrId::STR_TIME_TO_SLEEP, &CrossPointSettings::sleepTimeoutMinutes,
|
||||||
|
|||||||
@@ -312,6 +312,32 @@ void EpubReaderActivity::loop() {
|
|||||||
return;
|
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);
|
const auto [prevTriggered, nextTriggered, fromTilt] = ReaderUtils::detectPageTurn(mappedInput);
|
||||||
if (!prevTriggered && !nextTriggered) {
|
if (!prevTriggered && !nextTriggered) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ void EpubReaderFootnotesActivity::loop() {
|
|||||||
return;
|
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())) {
|
if (selectedIndex >= 0 && selectedIndex < static_cast<int>(footnotes.size())) {
|
||||||
setResult(FootnoteResult{footnotes[selectedIndex].href});
|
setResult(FootnoteResult{footnotes[selectedIndex].href});
|
||||||
finish();
|
finish();
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ void SettingsActivity::rebuildSettingsLists() {
|
|||||||
} else if (setting.category == StrId::STR_CAT_READER) {
|
} else if (setting.category == StrId::STR_CAT_READER) {
|
||||||
readerSettings.push_back(setting);
|
readerSettings.push_back(setting);
|
||||||
} else if (setting.category == StrId::STR_CAT_CONTROLS) {
|
} else if (setting.category == StrId::STR_CAT_CONTROLS) {
|
||||||
|
if (setting.valuePtr == &CrossPointSettings::pwrBtnFootnoteBack &&
|
||||||
|
SETTINGS.shortPwrBtn != CrossPointSettings::SHORT_PWRBTN::FOOTNOTES) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
controlsSettings.push_back(setting);
|
controlsSettings.push_back(setting);
|
||||||
} else if (setting.category == StrId::STR_CAT_SYSTEM) {
|
} else if (setting.category == StrId::STR_CAT_SYSTEM) {
|
||||||
systemSettings.push_back(setting);
|
systemSettings.push_back(setting);
|
||||||
@@ -271,6 +275,8 @@ void SettingsActivity::toggleCurrentSetting() {
|
|||||||
|
|
||||||
syncQuickResumeTimeoutForSleepScreen(sleepScreenChanged, quickResumeTimeoutChanged);
|
syncQuickResumeTimeoutForSleepScreen(sleepScreenChanged, quickResumeTimeoutChanged);
|
||||||
SETTINGS.saveToFile();
|
SETTINGS.saveToFile();
|
||||||
|
rebuildSettingsLists();
|
||||||
|
selectedSettingIndex = std::min(selectedSettingIndex, settingsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsActivity::syncQuickResumeTimeoutForSleepScreen(bool sleepScreenChanged, bool quickResumeTimeoutChanged) {
|
void SettingsActivity::syncQuickResumeTimeoutForSleepScreen(bool sleepScreenChanged, bool quickResumeTimeoutChanged) {
|
||||||
|
|||||||
@@ -479,8 +479,23 @@
|
|||||||
return changed;
|
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) {
|
function handleSettingChanged(key) {
|
||||||
syncQuickResumeTimeoutForSleepScreen(key === 'sleepScreen', key === 'quickResumeSleepScreen');
|
syncQuickResumeTimeoutForSleepScreen(key === 'sleepScreen', key === 'quickResumeSleepScreen');
|
||||||
|
if (key === 'shortPwrBtn') {
|
||||||
|
updateSettingsVisibility();
|
||||||
|
}
|
||||||
markChanged();
|
markChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +526,7 @@
|
|||||||
for (const category in groups) {
|
for (const category in groups) {
|
||||||
html += '<div class="card"><h2>' + escapeHtml(category) + '</h2>';
|
html += '<div class="card"><h2>' + escapeHtml(category) + '</h2>';
|
||||||
groups[category].forEach(function(s) {
|
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-name">' + escapeHtml(s.name) + '</span>' +
|
||||||
'<span class="setting-control">' + renderControl(s) + '</span>' +
|
'<span class="setting-control">' + renderControl(s) + '</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
@@ -520,6 +535,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
|
updateSettingsVisibility();
|
||||||
document.getElementById('save-container').style.display = '';
|
document.getElementById('save-container').style.display = '';
|
||||||
document.getElementById('saveBtn').disabled = true;
|
document.getElementById('saveBtn').disabled = true;
|
||||||
preserveQuickResumeTimeoutOn = getControlValue('quickResumeSleepScreen') === 1;
|
preserveQuickResumeTimeoutOn = getControlValue('quickResumeSleepScreen') === 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user