#pragma once #include #include #include #include #include "activities/Activity.h" #include "util/ButtonNavigator.h" class CrossPointSettings; enum class SettingType { TOGGLE, ENUM, ACTION, VALUE, STRING }; enum class SettingAction { None, RemapFrontButtons, CustomiseStatusBar, KOReaderSync, OPDSBrowser, Network, ClearCache, CheckForUpdates, Language, }; struct SettingInfo { StrId nameId; SettingType type; uint8_t CrossPointSettings::* valuePtr = nullptr; std::vector enumValues; SettingAction action = SettingAction::None; struct ValueRange { uint8_t min; uint8_t max; uint8_t step; }; ValueRange valueRange = {}; const char* key = nullptr; // JSON API key (nullptr for ACTION types) StrId category = StrId::STR_NONE_OPT; // Category for web UI grouping // Direct char[] string fields (for settings stored in CrossPointSettings) char* stringPtr = nullptr; size_t stringMaxLen = 0; // Dynamic accessors (for settings stored outside CrossPointSettings, e.g. KOReaderCredentialStore) std::function valueGetter; std::function valueSetter; std::function stringGetter; std::function stringSetter; static SettingInfo Toggle(StrId nameId, uint8_t CrossPointSettings::* ptr, const char* key = nullptr, StrId category = StrId::STR_NONE_OPT) { SettingInfo s; s.nameId = nameId; s.type = SettingType::TOGGLE; s.valuePtr = ptr; s.key = key; s.category = category; return s; } static SettingInfo Enum(StrId nameId, uint8_t CrossPointSettings::* ptr, std::vector values, const char* key = nullptr, StrId category = StrId::STR_NONE_OPT) { SettingInfo s; s.nameId = nameId; s.type = SettingType::ENUM; s.valuePtr = ptr; s.enumValues = std::move(values); s.key = key; s.category = category; return s; } static SettingInfo Action(StrId nameId, SettingAction action) { SettingInfo s; s.nameId = nameId; s.type = SettingType::ACTION; s.action = action; return s; } static SettingInfo Value(StrId nameId, uint8_t CrossPointSettings::* ptr, const ValueRange valueRange, const char* key = nullptr, StrId category = StrId::STR_NONE_OPT) { SettingInfo s; s.nameId = nameId; s.type = SettingType::VALUE; s.valuePtr = ptr; s.valueRange = valueRange; s.key = key; s.category = category; return s; } static SettingInfo String(StrId nameId, char* ptr, size_t maxLen, const char* key = nullptr, StrId category = StrId::STR_NONE_OPT) { SettingInfo s; s.nameId = nameId; s.type = SettingType::STRING; s.stringPtr = ptr; s.stringMaxLen = maxLen; s.key = key; s.category = category; return s; } static SettingInfo DynamicEnum(StrId nameId, std::vector values, std::function getter, std::function setter, const char* key = nullptr, StrId category = StrId::STR_NONE_OPT) { SettingInfo s; s.nameId = nameId; s.type = SettingType::ENUM; s.enumValues = std::move(values); s.valueGetter = std::move(getter); s.valueSetter = std::move(setter); s.key = key; s.category = category; return s; } static SettingInfo DynamicString(StrId nameId, std::function getter, std::function setter, const char* key = nullptr, StrId category = StrId::STR_NONE_OPT) { SettingInfo s; s.nameId = nameId; s.type = SettingType::STRING; s.stringGetter = std::move(getter); s.stringSetter = std::move(setter); s.key = key; s.category = category; return s; } }; class SettingsActivity final : public Activity { ButtonNavigator buttonNavigator; int selectedCategoryIndex = 0; // Currently selected category int selectedSettingIndex = 0; int settingsCount = 0; // Per-category settings derived from shared list + device-only actions std::vector displaySettings; std::vector readerSettings; std::vector controlsSettings; std::vector systemSettings; const std::vector* currentSettings = nullptr; static constexpr int categoryCount = 4; static const StrId categoryNames[categoryCount]; void enterCategory(int categoryIndex); void toggleCurrentSetting(); public: explicit SettingsActivity(GfxRenderer& renderer, MappedInputManager& mappedInput) : Activity("Settings", renderer, mappedInput) {} void onEnter() override; void onExit() override; void loop() override; void render(RenderLock&&) override; };