mod: add clock settings tab, timezone support, and clock size option

Fix clock persistence bug caused by stale legacy read in settings
deserialization. Add clock size setting (Small/Medium/Large) and
timezone selection with North American presets plus custom UTC offset.
Move all clock-related settings into a dedicated Clock tab, rename
"Home Screen Clock" to "Clock", and move minute-change detection to
main loop so the header clock updates on every screen.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
cottongin
2026-02-17 03:46:06 -05:00
parent 38a87298f3
commit 966fbef3d1
22 changed files with 435 additions and 42 deletions

View File

@@ -4,6 +4,7 @@
#include <Logging.h>
#include <Serialization.h>
#include <cstdio>
#include <cstring>
#include <string>
@@ -138,7 +139,10 @@ uint8_t CrossPointSettings::writeSettings(FsFile& file, bool count_only) const {
// New fields added at end for backward compatibility
writer.writeItem(file, preferredPortrait);
writer.writeItem(file, preferredLandscape);
writer.writeItem(file, homeScreenClock);
writer.writeItem(file, clockFormat);
writer.writeItem(file, clockSize);
writer.writeItem(file, timezone);
writer.writeItem(file, timezoneOffsetHours);
return writer.item_count;
}
@@ -267,14 +271,19 @@ bool CrossPointSettings::loadFromFile() {
if (++settingsRead >= fileSettingsCount) break;
readAndValidate(inputFile, sleepScreenLetterboxFill, SLEEP_SCREEN_LETTERBOX_FILL_COUNT);
if (++settingsRead >= fileSettingsCount) break;
{ uint8_t _ignore; serialization::readPod(inputFile, _ignore); } // legacy: sleepScreenGradientDir
if (++settingsRead >= fileSettingsCount) break;
// New fields added at end for backward compatibility
readAndValidate(inputFile, preferredPortrait, ORIENTATION_COUNT);
if (++settingsRead >= fileSettingsCount) break;
readAndValidate(inputFile, preferredLandscape, ORIENTATION_COUNT);
if (++settingsRead >= fileSettingsCount) break;
readAndValidate(inputFile, homeScreenClock, CLOCK_FORMAT_COUNT);
readAndValidate(inputFile, clockFormat, CLOCK_FORMAT_COUNT);
if (++settingsRead >= fileSettingsCount) break;
readAndValidate(inputFile, clockSize, CLOCK_SIZE_COUNT);
if (++settingsRead >= fileSettingsCount) break;
readAndValidate(inputFile, timezone, TZ_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, timezoneOffsetHours);
if (timezoneOffsetHours < -12 || timezoneOffsetHours > 14) timezoneOffsetHours = 0;
if (++settingsRead >= fileSettingsCount) break;
} while (false);
@@ -442,3 +451,31 @@ int CrossPointSettings::getReaderFontId() const {
#endif
}
}
const char* CrossPointSettings::getTimezonePosixStr() const {
switch (timezone) {
case TZ_EASTERN:
return "EST5EDT,M3.2.0,M11.1.0";
case TZ_CENTRAL:
return "CST6CDT,M3.2.0,M11.1.0";
case TZ_MOUNTAIN:
return "MST7MDT,M3.2.0,M11.1.0";
case TZ_PACIFIC:
return "PST8PDT,M3.2.0,M11.1.0";
case TZ_ALASKA:
return "AKST9AKDT,M3.2.0,M11.1.0";
case TZ_HAWAII:
return "HST10";
case TZ_CUSTOM: {
// Build "UTC<offset>" string where offset sign is inverted per POSIX convention
// POSIX TZ: positive = west of UTC, so we negate the user-facing offset
static char buf[16];
int posixOffset = -timezoneOffsetHours;
snprintf(buf, sizeof(buf), "UTC%d", posixOffset);
return buf;
}
case TZ_UTC:
default:
return "UTC0";
}
}