413 lines
15 KiB
C++
413 lines
15 KiB
C++
#pragma once
|
||
#include <HalStorage.h>
|
||
|
||
#include <cstdint>
|
||
#include <iosfwd>
|
||
|
||
class CrossPointSettings {
|
||
private:
|
||
// 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;
|
||
|
||
enum SLEEP_SCREEN_MODE {
|
||
DARK = 0,
|
||
LIGHT = 1,
|
||
CUSTOM = 2,
|
||
COVER = 3,
|
||
BLANK = 4,
|
||
COVER_CUSTOM = 5,
|
||
OVERLAY = 6,
|
||
QUICK_RESUME = 7,
|
||
SLEEP_SCREEN_MODE_COUNT
|
||
};
|
||
enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, SLEEP_SCREEN_COVER_MODE_COUNT };
|
||
enum SLEEP_IMAGE_PICK_MODE { PICK_RANDOM = 0, PICK_SEQUENTIAL = 1, SLEEP_IMAGE_PICK_MODE_COUNT };
|
||
enum SLEEP_SCREEN_COVER_FILTER {
|
||
NO_FILTER = 0,
|
||
BLACK_AND_WHITE = 1,
|
||
INVERTED_BLACK_AND_WHITE = 2,
|
||
SLEEP_SCREEN_COVER_FILTER_COUNT
|
||
};
|
||
enum QUICK_RESUME_SLEEP_SCREEN {
|
||
QUICK_RESUME_NEVER = 0,
|
||
QUICK_RESUME_AFTER_TIMEOUT = 1,
|
||
QUICK_RESUME_SLEEP_SCREEN_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 STATUS_BAR_ITEMS_POSITION {
|
||
STATUS_BAR_ITEMS_TOP = 0,
|
||
STATUS_BAR_ITEMS_BOTTOM = 1,
|
||
STATUS_BAR_ITEMS_POSITION_COUNT
|
||
};
|
||
|
||
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
|
||
};
|
||
|
||
// Font family options (built-in fonts only; SD card fonts use sdFontFamilyName)
|
||
enum FONT_FAMILY { BOOKERLY = 0, NOTOSANS = 1, FONT_FAMILY_COUNT };
|
||
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, TINY = 4, 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
|
||
};
|
||
|
||
// Hide battery percentage
|
||
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2, HIDE_BATTERY_PERCENTAGE_COUNT };
|
||
|
||
// UI Theme
|
||
enum UI_THEME { CLASSIC = 0, LYRA = 1, LYRA_3_COVERS = 2, LYRA_CAROUSEL = 3 };
|
||
|
||
// Image rendering in EPUB reader
|
||
enum IMAGE_RENDERING { IMAGES_DISPLAY = 0, IMAGES_PLACEHOLDER = 1, IMAGES_SUPPRESS = 2, IMAGE_RENDERING_COUNT };
|
||
|
||
// Action mapped to each tilt gesture direction.
|
||
enum TILT_GESTURE_ACTION {
|
||
TILT_ACT_NONE = 0,
|
||
TILT_ACT_NEXT_PAGE = 1,
|
||
TILT_ACT_PREV_PAGE = 2,
|
||
TILT_GESTURE_ACTION_COUNT
|
||
};
|
||
|
||
// Text darkness for AA glyph rendering (forwarded to GfxRenderer::setTextDarkness)
|
||
enum TEXT_DARKNESS {
|
||
DARKNESS_NORMAL = 0, // true 4-level AA
|
||
DARKNESS_DARK = 1, // historical default — bolder dark-gray AA
|
||
DARKNESS_EXTRA_DARK = 2, // both AA shades pushed to darkest gray state
|
||
DARKNESS_MAXIMUM = 3, // skip grayscale passes — AA pixels stay solid black from BW pass
|
||
TEXT_DARKNESS_COUNT
|
||
};
|
||
#ifdef ENABLE_IMAGE_DITHERING_EXTENSION
|
||
enum IMAGE_DITHERING {
|
||
IMAGE_DITHER_BAYER = 0,
|
||
IMAGE_DITHER_ATKINSON = 1,
|
||
IMAGE_DITHER_DIFFUSED_BAYER = 2,
|
||
IMAGE_DITHERING_COUNT
|
||
};
|
||
#else
|
||
enum IMAGE_DITHERING { IMAGE_DITHER_BAYER = 0, IMAGE_DITHERING_COUNT };
|
||
#endif
|
||
|
||
// Timezone options (POSIX TZ rules for DST support)
|
||
enum TIMEZONE {
|
||
TZ_UTC = 0,
|
||
TZ_CET = 1,
|
||
TZ_EET = 2,
|
||
TZ_MSK = 3,
|
||
TZ_UTC_PLUS4 = 4,
|
||
TZ_IST = 5,
|
||
TZ_UTC_PLUS7 = 6,
|
||
TZ_UTC_PLUS8 = 7,
|
||
TZ_UTC_PLUS9 = 8,
|
||
TZ_AEST = 9,
|
||
TZ_NZST = 10,
|
||
TZ_UTC_MINUS3 = 11,
|
||
TZ_EST = 12,
|
||
TZ_CST = 13,
|
||
TZ_MST = 14,
|
||
TZ_PST = 15,
|
||
TZ_AST_ADT = 16,
|
||
TZ_ACST_ACDT = 17,
|
||
TZ_AKST_AKDT = 18,
|
||
TIMEZONE_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;
|
||
// Apply information overlay with reading progress on sleep cover
|
||
uint8_t sleepCoverOverlay = 0;
|
||
// Sleep image pick mode (random vs sequential walk-through)
|
||
uint8_t sleepImagePickMode = PICK_RANDOM;
|
||
// Quick Resume on Timeout: keep current page on display with a moon icon when sleeping by timeout,
|
||
// and on wake restore the page directly (skipping the boot screen).
|
||
uint8_t quickResumeSleepScreen = QUICK_RESUME_NEVER;
|
||
// Status bar settings (statusBar, statusBarProgressBar, statusBarProgressBarThickness 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 statusBarUpperProgressBar = HIDE_PROGRESS;
|
||
uint8_t statusBarUpperProgressBarThickness = PROGRESS_BAR_NORMAL;
|
||
uint8_t statusBarLowerProgressBar = HIDE_PROGRESS;
|
||
uint8_t statusBarLowerProgressBarThickness = PROGRESS_BAR_NORMAL;
|
||
uint8_t statusBarItemsPosition = STATUS_BAR_ITEMS_BOTTOM;
|
||
uint8_t statusBarTitle = CHAPTER_TITLE;
|
||
uint8_t statusBarBattery = 1;
|
||
// Text rendering settings
|
||
uint8_t extraParagraphSpacing = 1;
|
||
uint8_t textAntiAliasing = 1;
|
||
// X3-only: when on, the AA refresh uses the 7-frame community grayscale LUT
|
||
// (~130 ms panel time) instead of the OEM 53-frame LUT (~2.4 s). Mid-tones
|
||
// run slightly darker than X4. Matches what papyrix-reader has shipped since
|
||
// 2025-11. Default on — the 2.2 s/page win dwarfs the subtle mid-tone shift.
|
||
// No effect on X4.
|
||
//
|
||
// JSON key was bumped from "fastAntiAliasing" to "fastAntiAliasingV2" when
|
||
// the default flipped to 1: existing settings files with the old key are
|
||
// ignored, so every device picks up the new C++ default on next load.
|
||
uint8_t fastAntiAliasing = 1;
|
||
// Text darkness (0 = normal, 1 = dark, 2 = extra dark). Default 1 preserves
|
||
// historical AA rendering (both grayscale shades drawn in the MSB pass).
|
||
uint8_t textDarkness = DARKNESS_DARK;
|
||
// 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;
|
||
// 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 (EPUB)
|
||
uint8_t fontFamily = BOOKERLY;
|
||
// SD card font family name (empty = use built-in fontFamily)
|
||
char sdFontFamilyName[32] = "";
|
||
uint8_t fontSize = MEDIUM;
|
||
// Reader font settings (TXT / MD) — defaults to EPUB settings when not explicitly set
|
||
uint8_t txtFontFamily = NOTOSANS;
|
||
char txtSdFontFamilyName[32] = "";
|
||
uint8_t txtFontSize = MEDIUM;
|
||
uint8_t lineSpacing = NORMAL;
|
||
uint8_t paragraphAlignment = JUSTIFIED;
|
||
// Auto-sleep timeout setting (default 10 minutes)
|
||
uint8_t sleepTimeout = SLEEP_10_MIN;
|
||
// E-ink refresh frequency (default 15 pages)
|
||
uint8_t refreshFrequency = REFRESH_15;
|
||
// Perform a half refresh on the page immediately following an EPUB page that displayed images.
|
||
uint8_t halfRefreshAfterImagePage = 1;
|
||
uint8_t hyphenationEnabled = 0;
|
||
|
||
// Reader screen margin settings
|
||
uint8_t screenMargin = 5;
|
||
// OPDS browser settings
|
||
char opdsServerUrl[128] = "";
|
||
char opdsUsername[64] = "";
|
||
char opdsPassword[64] = "";
|
||
// Hide battery percentage
|
||
uint8_t hideBatteryPercentage = HIDE_NEVER;
|
||
// UI Theme
|
||
uint8_t uiTheme = LYRA;
|
||
// Sunlight fading compensation
|
||
uint8_t fadingFix = 0;
|
||
// Use book's embedded CSS styles for EPUB rendering (1 = enabled, 0 = disabled)
|
||
uint8_t embeddedStyle = 1;
|
||
// Show hidden files/directories (starting with '.') in the file browser (0 = hidden, 1 = show)
|
||
uint8_t showHiddenFiles = 0;
|
||
// Show file extensions in the file browser (0 = hidden, 1 = show)
|
||
uint8_t showFileExtensions = 0;
|
||
// Image rendering mode in EPUB reader
|
||
uint8_t imageRendering = IMAGES_DISPLAY;
|
||
// Show a placeholder for large images (>800×600 source pixels) instead of decoding immediately.
|
||
// The user can press OK on the placeholder page to decode the image on demand.
|
||
uint8_t largeImagePlaceholder = 1;
|
||
// Dithering mode for decoded images (EPUB/JPG/PNG)
|
||
uint8_t imageDithering = IMAGE_DITHER_BAYER;
|
||
// Tilt-based page turning (X3 only — requires QMI8658 IMU)
|
||
uint8_t tiltPageTurn = 0;
|
||
// Action when the computed tilt value crosses the positive threshold.
|
||
uint8_t tiltPositiveAction = TILT_ACT_NEXT_PAGE;
|
||
// Action when the computed tilt value crosses the negative threshold.
|
||
uint8_t tiltNegativeAction = TILT_ACT_PREV_PAGE;
|
||
// Enable synthetic TOC fallback for malformed/sparse TOC books (1 = enabled, 0 = disabled)
|
||
uint8_t syntheticTocFallback = 1;
|
||
// Default bionic reading in EPUB pages when no per-book override is set (1 = enabled, 0 = disabled)
|
||
uint8_t bionicReading = 0;
|
||
// Automatically push reading progress to the KOReader sync server when leaving the reader
|
||
// (1 = enabled, 0 = disabled). The push only fires when credentials are configured and the
|
||
// reader session advanced at least 3 pages, and is skipped when remote progress is already ahead.
|
||
uint8_t koSyncOnBookClose = 0;
|
||
// Move finished book to /COMPLETED when the end-of-book screen action is selected.
|
||
uint8_t moveFinishedBooksToCompleted = 0;
|
||
// Remove finished book from Recent Books when the end-of-book screen action is selected.
|
||
uint8_t removeFinishedBooksFromRecents = 0;
|
||
// Show clock in the reader status bar
|
||
uint8_t statusBarClock = 0;
|
||
// Clock format: 0 = 24h (14:00), 1 = 12h (2:00pm)
|
||
uint8_t clockFormat12h = 0;
|
||
// Timezone selection (applies POSIX TZ rules for DST)
|
||
uint8_t timeZone = TZ_UTC;
|
||
// Use clock and keep the LP timer running during deep sleep (GPIO13 HIGH)
|
||
// so time can be accurately restored on wake. Increases sleep current by ~3-4 mA.
|
||
uint8_t useClock = 0;
|
||
// Show the Weather home screen menu item (1 = enabled, 0 = hidden)
|
||
uint8_t useWeather = 1;
|
||
// Include release candidate builds when checking for OTA updates.
|
||
uint8_t includeBetaUpdates = 0;
|
||
|
||
// Configurable actions for short / double / long press on each logical button.
|
||
// BTN_DEFAULT means "use the button's normal built-in behaviour".
|
||
enum BUTTON_ACTION {
|
||
BTN_DEFAULT = 0,
|
||
BTN_PAGE_FORWARD,
|
||
BTN_PAGE_BACK,
|
||
BTN_PAGE_FORWARD_10,
|
||
BTN_PAGE_BACK_10,
|
||
BTN_GO_HOME,
|
||
BTN_SLEEP,
|
||
BTN_FORCE_REFRESH,
|
||
BTN_FORCE_FAST_REFRESH,
|
||
BTN_OPEN_TOC,
|
||
BTN_OPEN_BOOKMARKS,
|
||
BTN_STAR_PAGE,
|
||
BTN_FOOTNOTES,
|
||
BTN_NEXT_SECTION,
|
||
BTN_PREV_SECTION,
|
||
BTN_EXIT_READER,
|
||
BTN_READER_MENU,
|
||
BTN_TOGGLE_BIONIC_READING,
|
||
BTN_KOREADER_SYNC,
|
||
BTN_CYCLE_FONT_SIZE,
|
||
BTN_CYCLE_ORIENTATION,
|
||
BTN_QUICK_OVERRIDES,
|
||
BUTTON_ACTION_COUNT
|
||
};
|
||
|
||
// Short-press actions (default: built-in)
|
||
uint8_t btnShortBack = BTN_DEFAULT;
|
||
uint8_t btnShortConfirm = BTN_DEFAULT;
|
||
uint8_t btnShortLeft = BTN_DEFAULT;
|
||
uint8_t btnShortRight = BTN_DEFAULT;
|
||
uint8_t btnShortPageBack = BTN_DEFAULT;
|
||
uint8_t btnShortPageForward = BTN_DEFAULT;
|
||
uint8_t btnShortPower = BTN_DEFAULT;
|
||
|
||
// Double-press actions (default: BTN_DEFAULT = disabled, no disambiguation wait)
|
||
uint8_t btnDoubleBack = BTN_DEFAULT;
|
||
uint8_t btnDoubleConfirm = BTN_DEFAULT;
|
||
uint8_t btnDoubleLeft = BTN_DEFAULT;
|
||
uint8_t btnDoubleRight = BTN_DEFAULT;
|
||
uint8_t btnDoublePageBack = BTN_DEFAULT;
|
||
uint8_t btnDoublePageForward = BTN_DEFAULT;
|
||
uint8_t btnDoublePower = BTN_DEFAULT;
|
||
|
||
// Long-press actions (default: built-in)
|
||
uint8_t btnLongBack = BTN_DEFAULT;
|
||
uint8_t btnLongConfirm = BTN_DEFAULT;
|
||
uint8_t btnLongLeft = BTN_DEFAULT;
|
||
uint8_t btnLongRight = BTN_DEFAULT;
|
||
uint8_t btnLongPageBack = BTN_DEFAULT;
|
||
uint8_t btnLongPageForward = BTN_DEFAULT;
|
||
uint8_t btnLongPower = BTN_DEFAULT;
|
||
|
||
~CrossPointSettings() = default;
|
||
|
||
// Get singleton instance
|
||
static CrossPointSettings& getInstance() { return instance; }
|
||
|
||
static constexpr uint16_t getPowerButtonDuration() { return 400; }
|
||
int getReaderFontId() const;
|
||
int getTxtReaderFontId() const;
|
||
// Pure built-in lookup (size enum + family enum -> font ID). Independent of
|
||
// SD-card font selection. Used by the per-book fontFamilyOverride path so
|
||
// an override forces back to a known built-in even when an SD font is the
|
||
// global default.
|
||
static int getBuiltinReaderFontId(uint8_t family, uint8_t size);
|
||
|
||
bool saveToFile() const;
|
||
bool loadFromFile();
|
||
void loadStartupFromNvs();
|
||
void saveStartupToNvs() const;
|
||
|
||
static void validateFrontButtonMapping(CrossPointSettings& settings);
|
||
|
||
// Enforce settings whose values depend on others (e.g. sleepScreen=QUICK_RESUME implies
|
||
// quickResumeSleepScreen=ON). Call after any setting mutation that could invalidate the pair.
|
||
static void normalizeDependentSettings(CrossPointSettings& settings);
|
||
|
||
float getReaderLineCompression() const;
|
||
unsigned long getSleepTimeoutMs() const;
|
||
int getRefreshFrequency() const;
|
||
};
|
||
|
||
// Helper macro to access settings
|
||
#define SETTINGS CrossPointSettings::getInstance()
|