ThemeManager.h
1 #pragma once 2 3 #include <string> 4 #include <unordered_map> 5 #include <vector> 6 7 #include "Theme.h" 8 9 /// Maximum number of themes that can be loaded/displayed 10 constexpr int MAX_CACHED_THEMES = 16; 11 12 /** 13 * Singleton manager for theme loading and application. 14 * 15 * Loads themes from /themes/*.theme files on SD card. 16 * Falls back to builtin themes when files are missing. 17 * 18 * Usage: 19 * THEME_MANAGER.loadTheme("dark"); 20 * renderer.fillRect(x, y, w, h, THEME.selectionFillBlack); 21 */ 22 class ThemeManager { 23 public: 24 static ThemeManager& instance(); 25 26 /** 27 * Load a theme by name. 28 * Looks for /themes/<name>.theme on SD card. 29 * Falls back to builtin theme if file not found. 30 * 31 * @param themeName Name of the theme (without .theme extension) 32 * @return true if loaded from file, false if using builtin fallback 33 */ 34 bool loadTheme(const char* themeName); 35 36 /** 37 * Save current theme to file. 38 * @param themeName Name for the theme file 39 * @return true if saved successfully 40 */ 41 bool saveTheme(const char* themeName); 42 43 /** 44 * Get the currently active theme. 45 */ 46 const Theme& current() const { return activeTheme; } 47 48 /** 49 * Get mutable reference to current theme for modifications. 50 */ 51 Theme& mutableCurrent() { return activeTheme; } 52 53 /** 54 * Apply builtin light theme. 55 */ 56 void applyLightTheme(); 57 58 /** 59 * Apply builtin dark theme. 60 */ 61 void applyDarkTheme(); 62 63 /** 64 * List available theme files on SD card. 65 * Also pre-caches theme configurations for instant switching. 66 * @param forceRefresh If true, clears cache and reloads all themes from disk 67 * @return Vector of theme names (without .theme extension) 68 */ 69 std::vector<std::string> listAvailableThemes(bool forceRefresh = false); 70 71 /** 72 * Apply a cached theme instantly (no file I/O). 73 * Use after listAvailableThemes() has been called. 74 * @param themeName Name of the theme 75 * @return true if theme was found in cache and applied 76 */ 77 bool applyCachedTheme(const char* themeName); 78 79 /** 80 * Check if a theme is cached. 81 */ 82 bool isThemeCached(const char* themeName) const; 83 84 /** 85 * Clear the theme cache to free memory. 86 * Call before entering memory-intensive states. 87 */ 88 void clearCache() { themeCache.clear(); } 89 90 /** 91 * Create default theme files on SD card if they don't exist. 92 * Called during boot to give users template files to edit. 93 */ 94 void createDefaultThemeFiles(); 95 96 /** 97 * Get the current theme name. 98 */ 99 const char* currentThemeName() const { return themeName; } 100 101 private: 102 ThemeManager(); 103 ~ThemeManager() = default; 104 ThemeManager(const ThemeManager&) = delete; 105 ThemeManager& operator=(const ThemeManager&) = delete; 106 107 bool loadFromFile(const char* path); 108 bool loadFromFileToTheme(const char* path, Theme& theme); 109 bool saveToFile(const char* path, const Theme& theme); 110 111 Theme activeTheme; 112 char themeName[32]; 113 std::unordered_map<std::string, Theme> themeCache; 114 }; 115 116 // Convenience macros 117 #define THEME_MANAGER ThemeManager::instance() 118 #define THEME ThemeManager::instance().current()