diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index 53958236..ee90dbbf 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -12,7 +12,7 @@ CrossPointSettings CrossPointSettings::instance; namespace { -constexpr uint8_t SETTINGS_FILE_VERSION = 1; +constexpr uint8_t SETTINGS_FILE_VERSION = 2; // Increment this when adding new persisted settings fields constexpr uint8_t SETTINGS_COUNT = 19; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; @@ -62,7 +62,7 @@ bool CrossPointSettings::loadFromFile() { uint8_t version; serialization::readPod(inputFile, version); - if (version != SETTINGS_FILE_VERSION) { + if (version != SETTINGS_FILE_VERSION && version != 1) { Serial.printf("[%lu] [CPS] Deserialization failed: Unknown version %u\n", millis(), version); inputFile.close(); return false; @@ -112,7 +112,13 @@ bool CrossPointSettings::loadFromFile() { } serialization::readPod(inputFile, textAntiAliasing); if (++settingsRead >= fileSettingsCount) break; - serialization::readPod(inputFile, readingSpeedWpm); + if (version == 1) { + uint8_t wpmV1; + serialization::readPod(inputFile, wpmV1); + readingSpeedWpm = wpmV1; + } else { + serialization::readPod(inputFile, readingSpeedWpm); + } if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, showTimeLeftInChapter); } while (false); diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index a71499db..8d66a3e0 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -62,7 +62,7 @@ class CrossPointSettings { uint8_t extraParagraphSpacing = 1; uint8_t textAntiAliasing = 1; // Reading speed (words per minute) for time-left estimate - uint8_t readingSpeedWpm = 200; + uint16_t readingSpeedWpm = 200; // Toggle to show time remaining in the current chapter uint8_t showTimeLeftInChapter = 0; // Duration of the power button press diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index bd306bff..d57107a5 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -35,7 +35,7 @@ const SettingInfo settingsList[settingsCount] = { SettingInfo::Value("Reader Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}), SettingInfo::Enum("Reader Paragraph Alignment", &CrossPointSettings::paragraphAlignment, {"Justify", "Left", "Center", "Right"}), - SettingInfo::Value("Reading Speed (WPM)", &CrossPointSettings::readingSpeedWpm, {150, 300, 10}), + SettingInfo::Value("Reading Speed (WPM)", &CrossPointSettings::readingSpeedWpm, {80, 300, 10}), SettingInfo::Toggle("Show Time Left", &CrossPointSettings::showTimeLeftInChapter), SettingInfo::Enum("Time to Sleep", &CrossPointSettings::sleepTimeout, {"1 min", "5 min", "10 min", "15 min", "30 min"}), @@ -129,14 +129,21 @@ void SettingsActivity::toggleCurrentSetting() { } else if (setting.type == SettingType::ENUM && setting.valuePtr != nullptr) { const uint8_t currentValue = SETTINGS.*(setting.valuePtr); SETTINGS.*(setting.valuePtr) = (currentValue + 1) % static_cast(setting.enumValues.size()); - } else if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) { + } else if (setting.type == SettingType::VALUE && setting.valuePtr16 != nullptr) { // Decreasing would also be nice for large ranges I think but oh well can't have everything - const int8_t currentValue = SETTINGS.*(setting.valuePtr); + const uint16_t currentValue = SETTINGS.*(setting.valuePtr16); // Wrap to minValue if exceeding setting value boundary if (currentValue + setting.valueRange.step > setting.valueRange.max) { - SETTINGS.*(setting.valuePtr) = setting.valueRange.min; + SETTINGS.*(setting.valuePtr16) = setting.valueRange.min; } else { - SETTINGS.*(setting.valuePtr) = currentValue + setting.valueRange.step; + SETTINGS.*(setting.valuePtr16) = currentValue + setting.valueRange.step; + } + } else if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) { + const uint16_t currentValue = SETTINGS.*(setting.valuePtr); + if (currentValue + setting.valueRange.step > setting.valueRange.max) { + SETTINGS.*(setting.valuePtr) = static_cast(setting.valueRange.min); + } else { + SETTINGS.*(setting.valuePtr) = static_cast(currentValue + setting.valueRange.step); } } else if (setting.type == SettingType::ACTION) { if (strcmp(setting.name, "Calibre Settings") == 0) { @@ -204,6 +211,8 @@ void SettingsActivity::render() const { } else if (settingsList[i].type == SettingType::ENUM && settingsList[i].valuePtr != nullptr) { const uint8_t value = SETTINGS.*(settingsList[i].valuePtr); valueText = settingsList[i].enumValues[value]; + } else if (settingsList[i].type == SettingType::VALUE && settingsList[i].valuePtr16 != nullptr) { + valueText = std::to_string(SETTINGS.*(settingsList[i].valuePtr16)); } else if (settingsList[i].type == SettingType::VALUE && settingsList[i].valuePtr != nullptr) { valueText = std::to_string(SETTINGS.*(settingsList[i].valuePtr)); } diff --git a/src/activities/settings/SettingsActivity.h b/src/activities/settings/SettingsActivity.h index 157689e3..e7313f64 100644 --- a/src/activities/settings/SettingsActivity.h +++ b/src/activities/settings/SettingsActivity.h @@ -17,30 +17,35 @@ enum class SettingType { TOGGLE, ENUM, ACTION, VALUE }; struct SettingInfo { const char* name; // Display name of the setting SettingType type; // Type of setting - uint8_t CrossPointSettings::* valuePtr; // Pointer to member in CrossPointSettings (for TOGGLE/ENUM/VALUE) + uint8_t CrossPointSettings::* valuePtr; // Pointer for 8-bit settings (TOGGLE/ENUM) + uint16_t CrossPointSettings::* valuePtr16; // Pointer for 16-bit VALUE settings std::vector enumValues; struct ValueRange { - uint8_t min; - uint8_t max; - uint8_t step; + uint16_t min; + uint16_t max; + uint16_t step; }; // Bounds/step for VALUE type settings ValueRange valueRange; // Static constructors static SettingInfo Toggle(const char* name, uint8_t CrossPointSettings::* ptr) { - return {name, SettingType::TOGGLE, ptr}; + return {name, SettingType::TOGGLE, ptr, nullptr}; } static SettingInfo Enum(const char* name, uint8_t CrossPointSettings::* ptr, std::vector values) { - return {name, SettingType::ENUM, ptr, std::move(values)}; + return {name, SettingType::ENUM, ptr, nullptr, std::move(values)}; } - static SettingInfo Action(const char* name) { return {name, SettingType::ACTION, nullptr}; } + static SettingInfo Action(const char* name) { return {name, SettingType::ACTION, nullptr, nullptr}; } + + static SettingInfo Value(const char* name, uint16_t CrossPointSettings::* ptr, const ValueRange valueRange) { + return {name, SettingType::VALUE, nullptr, ptr, {}, valueRange}; + } static SettingInfo Value(const char* name, uint8_t CrossPointSettings::* ptr, const ValueRange valueRange) { - return {name, SettingType::VALUE, ptr, {}, valueRange}; + return {name, SettingType::VALUE, ptr, nullptr, {}, valueRange}; } };