333 lines
12 KiB
C++
333 lines
12 KiB
C++
#pragma once
|
|
#include <HalStorage.h>
|
|
|
|
#include <cstdint>
|
|
#include <iosfwd>
|
|
#include <mutex>
|
|
|
|
class CrossPointSettings {
|
|
private:
|
|
mutable std::mutex _mutex;
|
|
|
|
// Private constructor for singleton
|
|
CrossPointSettings() = default;
|
|
|
|
// Static instance
|
|
static CrossPointSettings instance;
|
|
|
|
public:
|
|
// Delete copy constructor and assignment
|
|
CrossPointSettings(const CrossPointSettings&) = delete;
|
|
CrossPointSettings& operator=(const CrossPointSettings&) = delete;
|
|
|
|
// Access the settings mutex for protecting multi-field reads/writes from other cores.
|
|
// Callers must not re-enter SETTINGS methods that lock _mutex while holding it.
|
|
std::mutex& getMutex() const { return _mutex; }
|
|
|
|
enum SLEEP_SCREEN_MODE {
|
|
DARK = 0,
|
|
LIGHT = 1,
|
|
CUSTOM = 2,
|
|
COVER = 3,
|
|
COVER_CUSTOM = 4,
|
|
BLANK = 5,
|
|
QUICK_RESUME = 6,
|
|
SLEEP_SCREEN_MODE_COUNT
|
|
};
|
|
enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, SLEEP_SCREEN_COVER_MODE_COUNT };
|
|
enum SLEEP_SCREEN_COVER_FILTER {
|
|
NO_FILTER = 0,
|
|
BLACK_AND_WHITE = 1,
|
|
INVERTED_BLACK_AND_WHITE = 2,
|
|
SLEEP_SCREEN_COVER_FILTER_COUNT
|
|
};
|
|
|
|
// Status bar enum - legacy
|
|
enum STATUS_BAR_MODE {
|
|
NONE = 0,
|
|
NO_PROGRESS = 1,
|
|
FULL = 2,
|
|
BOOK_PROGRESS_BAR = 3,
|
|
ONLY_BOOK_PROGRESS_BAR = 4,
|
|
CHAPTER_PROGRESS_BAR = 5,
|
|
STATUS_BAR_MODE_COUNT
|
|
};
|
|
enum STATUS_BAR_PROGRESS_BAR {
|
|
BOOK_PROGRESS = 0,
|
|
CHAPTER_PROGRESS = 1,
|
|
HIDE_PROGRESS = 2,
|
|
STATUS_BAR_PROGRESS_BAR_COUNT
|
|
};
|
|
enum STATUS_BAR_PROGRESS_BAR_THICKNESS {
|
|
PROGRESS_BAR_THIN = 0,
|
|
PROGRESS_BAR_NORMAL = 1,
|
|
PROGRESS_BAR_THICK = 2,
|
|
STATUS_BAR_PROGRESS_BAR_THICKNESS_COUNT
|
|
};
|
|
enum STATUS_BAR_TITLE { BOOK_TITLE = 0, CHAPTER_TITLE = 1, HIDE_TITLE = 2, STATUS_BAR_TITLE_COUNT };
|
|
enum XTC_STATUS_BAR_MODE {
|
|
XTC_STATUS_BAR_HIDE = 0,
|
|
XTC_STATUS_BAR_BOTTOM = 1,
|
|
XTC_STATUS_BAR_TOP = 2,
|
|
XTC_STATUS_BAR_MODE_COUNT
|
|
};
|
|
|
|
enum STATUS_BAR_CLOCK_MODE { STATUS_BAR_CLOCK_HIDE = 0, STATUS_BAR_CLOCK_RIGHT = 1, STATUS_BAR_CLOCK_LEFT = 2 };
|
|
|
|
enum ORIENTATION {
|
|
PORTRAIT = 0, // 480x800 logical coordinates (current default)
|
|
LANDSCAPE_CW = 1, // 800x480 logical coordinates, rotated 180° (swap top/bottom)
|
|
INVERTED = 2, // 480x800 logical coordinates, inverted
|
|
LANDSCAPE_CCW = 3, // 800x480 logical coordinates, native panel orientation
|
|
ORIENTATION_COUNT
|
|
};
|
|
|
|
// Front button layout options (legacy)
|
|
// Default: Back, Confirm, Left, Right
|
|
// Swapped: Left, Right, Back, Confirm
|
|
enum FRONT_BUTTON_LAYOUT {
|
|
BACK_CONFIRM_LEFT_RIGHT = 0,
|
|
LEFT_RIGHT_BACK_CONFIRM = 1,
|
|
LEFT_BACK_CONFIRM_RIGHT = 2,
|
|
BACK_CONFIRM_RIGHT_LEFT = 3,
|
|
FRONT_BUTTON_LAYOUT_COUNT
|
|
};
|
|
|
|
// Front button hardware identifiers (for remapping)
|
|
enum FRONT_BUTTON_HARDWARE {
|
|
FRONT_HW_BACK = 0,
|
|
FRONT_HW_CONFIRM = 1,
|
|
FRONT_HW_LEFT = 2,
|
|
FRONT_HW_RIGHT = 3,
|
|
FRONT_BUTTON_HARDWARE_COUNT
|
|
};
|
|
|
|
// Side button layout options
|
|
// Default: Up = Previous, Down = Next
|
|
enum SIDE_BUTTON_LAYOUT { PREV_NEXT = 0, NEXT_PREV = 1, SIDE_BUTTONS_DISABLED = 2, SIDE_BUTTON_LAYOUT_COUNT };
|
|
|
|
// Font family options (built-in fonts only; SD card fonts use sdFontFamilyName)
|
|
enum FONT_FAMILY { NOTOSERIF = 0, NOTOSANS = 1, FONT_FAMILY_COUNT };
|
|
static constexpr uint8_t LEGACY_OPENDYSLEXIC = 2;
|
|
static constexpr uint8_t BUILTIN_FONT_COUNT = FONT_FAMILY_COUNT;
|
|
// Font size options
|
|
enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3, FONT_SIZE_COUNT };
|
|
enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2, LINE_COMPRESSION_COUNT };
|
|
enum PARAGRAPH_ALIGNMENT {
|
|
JUSTIFIED = 0,
|
|
LEFT_ALIGN = 1,
|
|
CENTER_ALIGN = 2,
|
|
RIGHT_ALIGN = 3,
|
|
BOOK_STYLE = 4,
|
|
PARAGRAPH_ALIGNMENT_COUNT
|
|
};
|
|
|
|
// Auto-sleep timeout options (in minutes)
|
|
enum SLEEP_TIMEOUT {
|
|
SLEEP_1_MIN = 0,
|
|
SLEEP_5_MIN = 1,
|
|
SLEEP_10_MIN = 2,
|
|
SLEEP_15_MIN = 3,
|
|
SLEEP_30_MIN = 4,
|
|
SLEEP_TIMEOUT_COUNT
|
|
};
|
|
|
|
// E-ink refresh frequency (pages between full refreshes)
|
|
enum REFRESH_FREQUENCY {
|
|
REFRESH_1 = 0,
|
|
REFRESH_5 = 1,
|
|
REFRESH_10 = 2,
|
|
REFRESH_15 = 3,
|
|
REFRESH_30 = 4,
|
|
REFRESH_FREQUENCY_COUNT
|
|
};
|
|
|
|
// Short power button press actions
|
|
enum SHORT_PWRBTN { IGNORE = 0, SLEEP = 1, PAGE_TURN = 2, FORCE_REFRESH = 3, FOOTNOTES = 4, SHORT_PWRBTN_COUNT };
|
|
|
|
// Long-press Confirm action while reading an EPUB. The setting cycles through these values.
|
|
// Persisted in settings.json by index: any new function (e.g. dictionary, bookmark) MUST use a
|
|
// value >= 2 and be appended at the END of the enumValues array in SettingsList.h, otherwise the
|
|
// stored indices shift and existing saves are silently misinterpreted.
|
|
enum LONG_PRESS_MENU_FUNCTION {
|
|
LP_MENU_KOSYNC = 0,
|
|
LP_MENU_DISABLED = 1,
|
|
LP_MENU_BOOKMARK = 2,
|
|
LP_MENU_DICTIONARY = 3,
|
|
LONG_PRESS_MENU_FUNCTION_COUNT
|
|
};
|
|
|
|
// Hide battery percentage
|
|
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2, HIDE_BATTERY_PERCENTAGE_COUNT };
|
|
|
|
// Page turn button long press behavior
|
|
enum LONG_PRESS_BUTTON_BEHAVIOR {
|
|
OFF = 0,
|
|
CHAPTER_SKIP = 1,
|
|
ORIENTATION_CHANGE = 2,
|
|
LONG_PRESS_BUTTON_BEHAVIOR_COUNT
|
|
};
|
|
|
|
// UI Theme
|
|
enum UI_THEME { CLASSIC = 0, LYRA = 1, LYRA_3_COVERS = 2, ROUNDEDRAFF = 3 };
|
|
|
|
// Image rendering in EPUB reader
|
|
enum IMAGE_RENDERING { IMAGES_DISPLAY = 0, IMAGES_PLACEHOLDER = 1, IMAGES_SUPPRESS = 2, IMAGE_RENDERING_COUNT };
|
|
|
|
enum TILT_PAGE_TURN { TILT_OFF = 0, TILT_NORMAL = 1, TILT_NVERTED = 2, TILT_PAGE_TURN_COUNT };
|
|
|
|
enum TOUCH_READER_CONTROLS { TOUCH_READER_OFF = 0, TOUCH_READER_ON = 1, TOUCH_READER_CONTROLS_COUNT };
|
|
|
|
enum QUICK_RESUME_SLEEP_SCREEN {
|
|
QUICK_RESUME_NEVER = 0,
|
|
QUICK_RESUME_AFTER_TIMEOUT = 1,
|
|
QUICK_RESUME_SLEEP_SCREEN_COUNT
|
|
};
|
|
|
|
// Sleep screen settings
|
|
uint8_t sleepScreen = DARK;
|
|
// Sleep screen cover mode settings
|
|
uint8_t sleepScreenCoverMode = FIT;
|
|
// Sleep screen cover filter
|
|
uint8_t sleepScreenCoverFilter = NO_FILTER;
|
|
// Status bar settings (statusBar retained for migration only)
|
|
uint8_t statusBar = FULL;
|
|
uint8_t statusBarChapterPageCount = 1;
|
|
uint8_t statusBarBookProgressPercentage = 1;
|
|
uint8_t statusBarProgressBar = HIDE_PROGRESS;
|
|
uint8_t statusBarProgressBarThickness = PROGRESS_BAR_NORMAL;
|
|
uint8_t statusBarTitle = CHAPTER_TITLE;
|
|
uint8_t statusBarBattery = 1;
|
|
uint8_t xtcStatusBarMode = XTC_STATUS_BAR_HIDE;
|
|
// Clock display in status bar (X3 only, requires DS3231 RTC)
|
|
uint8_t statusBarClock = STATUS_BAR_CLOCK_HIDE;
|
|
// Clock UTC offset in quarter-hour steps, biased by 48 so it fits in uint8_t.
|
|
// Value 48 = UTC+0, 0 = UTC-12:00, 104 = UTC+14:00.
|
|
// Quarter-hour granularity supports oddball zones like Nepal (+5:45) and Chatham (+12:45).
|
|
uint8_t clockUtcOffsetQ = 48;
|
|
// Clock display format: 0 = 24-hour, 1 = 12-hour
|
|
uint8_t clockFormat = 0;
|
|
// Set once an NTP sync succeeds. Used to skip re-syncing on every WiFi connect.
|
|
// Resetting to 0 (e.g. via the web UI) forces a re-sync on next WiFi connect.
|
|
uint8_t clockHasBeenSynced = 0;
|
|
// Text rendering settings
|
|
uint8_t extraParagraphSpacing = 1;
|
|
uint8_t textAntiAliasing = 1;
|
|
// Short power button click behaviour
|
|
uint8_t shortPwrBtn = IGNORE;
|
|
// EPUB reading orientation settings
|
|
// 0 = portrait (default), 1 = landscape clockwise, 2 = inverted, 3 = landscape counter-clockwise
|
|
uint8_t orientation = PORTRAIT;
|
|
// Button layouts (front layout retained for migration only)
|
|
uint8_t frontButtonLayout = BACK_CONFIRM_LEFT_RIGHT;
|
|
uint8_t sideButtonLayout = PREV_NEXT;
|
|
uint8_t frontButtonFollowOrientation = 0;
|
|
// Front button remap (logical -> hardware)
|
|
// Used by MappedInputManager to translate logical buttons into physical front buttons.
|
|
uint8_t frontButtonBack = FRONT_HW_BACK;
|
|
uint8_t frontButtonConfirm = FRONT_HW_CONFIRM;
|
|
uint8_t frontButtonLeft = FRONT_HW_LEFT;
|
|
uint8_t frontButtonRight = FRONT_HW_RIGHT;
|
|
// Reader font settings
|
|
uint8_t fontFamily = NOTOSERIF;
|
|
uint8_t fontSize = MEDIUM;
|
|
uint8_t lineSpacing = NORMAL;
|
|
uint8_t paragraphAlignment = JUSTIFIED;
|
|
// Auto-sleep timeout setting (default 10 minutes). Legacy sleepTimeout enum values are migration-only.
|
|
uint8_t sleepTimeoutMinutes = 10;
|
|
// E-ink refresh frequency (default 15 pages)
|
|
uint8_t refreshFrequency = REFRESH_15;
|
|
uint8_t hyphenationEnabled = 0;
|
|
|
|
// Reader screen margin settings
|
|
uint8_t screenMargin = 5;
|
|
// OPDS download destination folder ("" = SD root). Global; edited from the
|
|
// OPDS server list. Persisted via a category-less SettingInfo::String in
|
|
// SettingsList.h, so it stays out of the on-device Settings screen.
|
|
char opdsDownloadFolder[64] = "";
|
|
// On-disk filename format for OPDS downloads (0=Author-Title default, 1=Title-Author,
|
|
// 2=Title). See OpdsFilenameFormat. Persisted via a category-less SettingInfo::Enum,
|
|
// edited from the OPDS server list; hidden from the on-device Settings screen.
|
|
uint8_t opdsFilenameFormat = 0;
|
|
// Hide battery percentage
|
|
uint8_t hideBatteryPercentage = HIDE_NEVER;
|
|
// Long-press page turn button behavior
|
|
uint8_t longPressButtonBehavior = OFF;
|
|
// Long-press Confirm function in EPUB reader (cycles through LONG_PRESS_MENU_FUNCTION values).
|
|
// Defaults to Disabled so shortcut-based bookmark toggling remains opt-in.
|
|
uint8_t longPressMenuFunction = LP_MENU_DISABLED;
|
|
// UI Theme
|
|
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
|
|
uint8_t focusReadingEnabled = 0;
|
|
// SD card font family name (empty = use built-in fontFamily)
|
|
char sdFontFamilyName[32] = "";
|
|
// Dictionary folder name under /dictionaries (empty = no dictionary)
|
|
char dictionaryName[32] = "";
|
|
// Show hidden files/directories (starting with '.') in the file browser (0 = hidden, 1 = show)
|
|
uint8_t showHiddenFiles = 0;
|
|
// Remove a book from the Recent Books list when its End-of-Book screen is reached (0 = off, 1 = on)
|
|
uint8_t removeReadBooksFromRecents = 0;
|
|
// Move epub to /Read/ folder on SD card when finished (0 = disabled, 1 = enabled)
|
|
uint8_t moveFinishedToReadFolder = 0;
|
|
// Short press Back goes to file browser instead of home (0 = disabled, 1 = enabled)
|
|
uint8_t backShortToFileBrowser = 0;
|
|
// Image rendering mode in EPUB reader
|
|
uint8_t imageRendering = IMAGES_DISPLAY;
|
|
// Tilt-based page turning (X3 only — requires QMI8658 IMU)
|
|
uint8_t tiltPageTurn = TILT_OFF;
|
|
// Touch screen reader zones/gestures on boards with a touch controller.
|
|
uint8_t touchReaderControls = TOUCH_READER_ON;
|
|
// Language setting (Language enum index, default 0 = EN)
|
|
uint8_t language = 0;
|
|
// Quick Resume: keep current content visible with moon icon instead of showing a static sleep screen.
|
|
uint8_t quickResumeSleepScreen = QUICK_RESUME_NEVER;
|
|
|
|
~CrossPointSettings() = default;
|
|
|
|
// Get singleton instance
|
|
static CrossPointSettings& getInstance() { return instance; }
|
|
|
|
static constexpr uint8_t MIN_SLEEP_TIMEOUT_MINUTES = 1;
|
|
static constexpr uint8_t SLEEP_TIMEOUT_NEVER_MINUTES = 31;
|
|
static constexpr uint8_t MAX_SLEEP_TIMEOUT_MINUTES = SLEEP_TIMEOUT_NEVER_MINUTES;
|
|
|
|
// Callback to resolve SD card font IDs. Set by SdCardFontSystem::begin().
|
|
// Returns font ID or 0 if not found.
|
|
using SdFontIdResolver = int (*)(void* ctx, const char* familyName, uint8_t fontSize);
|
|
SdFontIdResolver sdFontIdResolver = nullptr;
|
|
void* sdFontResolverCtx = nullptr;
|
|
|
|
uint16_t getPowerButtonDuration() const {
|
|
return (shortPwrBtn == CrossPointSettings::SHORT_PWRBTN::SLEEP) ? 10 : 400;
|
|
}
|
|
int getReaderFontId() const;
|
|
|
|
// If count_only is true, returns the number of settings items that would be written.
|
|
uint8_t writeSettings(HalFile& file, bool count_only = false) const;
|
|
|
|
bool saveToFile() const;
|
|
bool loadFromFile();
|
|
|
|
static void validateFrontButtonMapping(CrossPointSettings& settings);
|
|
static uint8_t sleepTimeoutEnumToMinutes(uint8_t legacyValue);
|
|
|
|
private:
|
|
bool loadFromBinaryFile();
|
|
bool migrateLanguageBinaryFile();
|
|
|
|
public:
|
|
float getReaderLineCompression() const;
|
|
unsigned long getSleepTimeoutMs() const;
|
|
int getRefreshFrequency() const;
|
|
};
|
|
|
|
// Helper macro to access settings
|
|
#define SETTINGS CrossPointSettings::getInstance()
|