diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index f5e8ded5..06213f45 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -14,7 +14,7 @@ CrossPointSettings CrossPointSettings::instance; namespace { constexpr uint8_t SETTINGS_FILE_VERSION = 1; // Increment this when adding new persisted settings fields -constexpr uint8_t SETTINGS_COUNT = 20; +constexpr uint8_t SETTINGS_COUNT = 21; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; } // namespace @@ -49,6 +49,7 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, hideBatteryPercentage); serialization::writePod(outputFile, longPressChapterSkip); serialization::writePod(outputFile, hyphenationEnabled); + serialization::writePod(outputFile, longPressDuration); outputFile.close(); Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); @@ -120,6 +121,8 @@ bool CrossPointSettings::loadFromFile() { if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, hyphenationEnabled); if (++settingsRead >= fileSettingsCount) break; + serialization::readPod(inputFile, longPressDuration); + if (++settingsRead >= fileSettingsCount) break; } while (false); inputFile.close(); @@ -195,6 +198,22 @@ int CrossPointSettings::getRefreshFrequency() const { } } +unsigned long CrossPointSettings::getLongPressDurationMs() const { + switch (longPressDuration) { + case LONG_PRESS_DURATION::LP_1S: + return 1UL * 1000; + case LONG_PRESS_DURATION::LP_2S: + default: + return 2UL * 1000; + case LONG_PRESS_DURATION::LP_3S: + return 3UL * 1000; + case LONG_PRESS_DURATION::LP_5S: + return 5UL * 1000; + case LONG_PRESS_DURATION::LP_10S: + return 10UL * 1000; + } +} + int CrossPointSettings::getReaderFontId() const { switch (fontFamily) { case BOOKERLY: diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 8ce32a2c..25c4b631 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -55,6 +55,9 @@ class CrossPointSettings { // Short power button press actions enum SHORT_PWRBTN { IGNORE = 0, SLEEP = 1, PAGE_TURN = 2 }; + // Long-press duration options + enum LONG_PRESS_DURATION { LP_1S = 0, LP_2S = 1, LP_3S = 2, LP_5S = 3, LP_10S = 4 }; + // Hide battery percentage enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2 }; @@ -94,6 +97,7 @@ class CrossPointSettings { uint8_t hideBatteryPercentage = HIDE_NEVER; // Long-press chapter skip on side buttons uint8_t longPressChapterSkip = 1; + uint8_t longPressDuration = LP_2S; ~CrossPointSettings() = default; @@ -111,6 +115,7 @@ class CrossPointSettings { float getReaderLineCompression() const; unsigned long getSleepTimeoutMs() const; int getRefreshFrequency() const; + unsigned long getLongPressDurationMs() const; }; // Helper macro to access settings diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index 555cba91..0d7503c4 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -17,7 +17,6 @@ namespace { constexpr int PAGE_ITEMS = 23; -constexpr int SKIP_PAGE_MS = 700; constexpr char OPDS_ROOT_PATH[] = "opds"; // No leading slash - relative to server URL } // namespace @@ -123,7 +122,7 @@ void OpdsBookBrowserActivity::loop() { mappedInput.wasReleased(MappedInputManager::Button::Left); const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::Down) || mappedInput.wasReleased(MappedInputManager::Button::Right); - const bool skipPage = mappedInput.getHeldTime() > SKIP_PAGE_MS; + const bool skipPage = mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs(); if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) { if (!entries.empty()) { diff --git a/src/activities/home/MyLibraryActivity.cpp b/src/activities/home/MyLibraryActivity.cpp index 9e6f3734..134451dd 100644 --- a/src/activities/home/MyLibraryActivity.cpp +++ b/src/activities/home/MyLibraryActivity.cpp @@ -6,6 +6,7 @@ #include #include "MappedInputManager.h" +#include "CrossPointSettings.h" #include "RecentBooksStore.h" #include "ScreenComponents.h" #include "fontIds.h" @@ -20,7 +21,6 @@ constexpr int LEFT_MARGIN = 20; constexpr int RIGHT_MARGIN = 40; // Extra space for scroll indicator // Timing thresholds -constexpr int SKIP_PAGE_MS = 700; constexpr unsigned long GO_HOME_MS = 1000; void sortFileList(std::vector& strs) { @@ -201,7 +201,7 @@ void MyLibraryActivity::loop() { const bool leftReleased = mappedInput.wasReleased(MappedInputManager::Button::Left); const bool rightReleased = mappedInput.wasReleased(MappedInputManager::Button::Right); - const bool skipPage = mappedInput.getHeldTime() > SKIP_PAGE_MS; + const bool skipPage = mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs(); // Confirm button - open selected item if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) { diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 6ff39c5e..55b20ee6 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -15,7 +15,6 @@ namespace { // pagesPerRefresh now comes from SETTINGS.getRefreshFrequency() -constexpr unsigned long skipChapterMs = 700; constexpr unsigned long goHomeMs = 1000; constexpr int statusBarMargin = 19; } // namespace @@ -182,7 +181,7 @@ void EpubReaderActivity::loop() { return; } - const bool skipChapter = SETTINGS.longPressChapterSkip && mappedInput.getHeldTime() > skipChapterMs; + 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 diff --git a/src/activities/reader/EpubReaderChapterSelectionActivity.cpp b/src/activities/reader/EpubReaderChapterSelectionActivity.cpp index ad4dd2ff..d34d8577 100644 --- a/src/activities/reader/EpubReaderChapterSelectionActivity.cpp +++ b/src/activities/reader/EpubReaderChapterSelectionActivity.cpp @@ -4,12 +4,11 @@ #include "KOReaderCredentialStore.h" #include "KOReaderSyncActivity.h" +#include "CrossPointSettings.h" #include "MappedInputManager.h" #include "fontIds.h" namespace { -// Time threshold for treating a long press as a page-up/page-down -constexpr int SKIP_PAGE_MS = 700; } // namespace bool EpubReaderChapterSelectionActivity::hasSyncOption() const { return KOREADER_STORE.hasCredentials(); } @@ -124,7 +123,7 @@ void EpubReaderChapterSelectionActivity::loop() { const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::Down) || mappedInput.wasReleased(MappedInputManager::Button::Right); - const bool skipPage = mappedInput.getHeldTime() > SKIP_PAGE_MS; + const bool skipPage = mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs(); const int pageItems = getPageItems(); const int totalItems = getTotalItems(); diff --git a/src/activities/reader/XtcReaderActivity.cpp b/src/activities/reader/XtcReaderActivity.cpp index 0a58d7b3..fe444da3 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -19,7 +19,6 @@ #include "fontIds.h" namespace { -constexpr unsigned long skipPageMs = 700; constexpr unsigned long goHomeMs = 1000; } // namespace @@ -129,7 +128,7 @@ void XtcReaderActivity::loop() { return; } - const bool skipPages = SETTINGS.longPressChapterSkip && mappedInput.getHeldTime() > skipPageMs; + const bool skipPages = SETTINGS.longPressChapterSkip && mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs(); const int skipAmount = skipPages ? 10 : 1; if (prevReleased) { diff --git a/src/activities/reader/XtcReaderChapterSelectionActivity.cpp b/src/activities/reader/XtcReaderChapterSelectionActivity.cpp index b2cfecaa..bb31aa44 100644 --- a/src/activities/reader/XtcReaderChapterSelectionActivity.cpp +++ b/src/activities/reader/XtcReaderChapterSelectionActivity.cpp @@ -2,11 +2,11 @@ #include +#include "CrossPointSettings.h" #include "MappedInputManager.h" #include "fontIds.h" namespace { -constexpr int SKIP_PAGE_MS = 700; } // namespace int XtcReaderChapterSelectionActivity::getPageItems() const { @@ -80,7 +80,7 @@ void XtcReaderChapterSelectionActivity::loop() { const bool nextReleased = mappedInput.wasReleased(MappedInputManager::Button::Down) || mappedInput.wasReleased(MappedInputManager::Button::Right); - const bool skipPage = mappedInput.getHeldTime() > SKIP_PAGE_MS; + const bool skipPage = mappedInput.getHeldTime() > SETTINGS.getLongPressDurationMs(); const int pageItems = getPageItems(); if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) { diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 943fdb4c..0b53eb94 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -35,13 +35,14 @@ const SettingInfo readerSettings[readerSettingsCount] = { SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing), SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing)}; -constexpr int controlsSettingsCount = 4; +constexpr int controlsSettingsCount = 5; const SettingInfo controlsSettings[controlsSettingsCount] = { SettingInfo::Enum("Front Button Layout", &CrossPointSettings::frontButtonLayout, {"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}), SettingInfo::Enum("Side Button Layout (reader)", &CrossPointSettings::sideButtonLayout, {"Prev, Next", "Next, Prev"}), SettingInfo::Toggle("Long-press Chapter Skip", &CrossPointSettings::longPressChapterSkip), + SettingInfo::Enum("Long-press Duration", &CrossPointSettings::longPressDuration, {"1s", "2s", "3s", "5s", "10s"}), SettingInfo::Enum("Short Power Button Click", &CrossPointSettings::shortPwrBtn, {"Ignore", "Sleep", "Page Turn"})}; constexpr int systemSettingsCount = 5;