fix: theme switching works and restarts

This commit is contained in:
Brackyt 2026-01-25 16:41:31 +01:00
parent 7a5c1e8e0e
commit 84d08684a2
2 changed files with 47 additions and 29 deletions

View File

@ -474,11 +474,10 @@ uint32_t ThemeManager::computeContextHash(const ThemeContext &context,
void ThemeManager::loadTheme(const std::string &themeName) { void ThemeManager::loadTheme(const std::string &themeName) {
unloadTheme(); unloadTheme();
currentThemeName = themeName; currentThemeName = themeName;
Serial.printf("[ThemeManager] Loading theme: %s\n", themeName.c_str());
std::map<std::string, std::map<std::string, std::string>> sections; std::map<std::string, std::map<std::string, std::string>> sections;
if (themeName == "Default") { if (themeName == "Default" || themeName.empty()) {
std::string path = "/themes/Default/theme.ini"; std::string path = "/themes/Default/theme.ini";
if (SdMan.exists(path.c_str())) { if (SdMan.exists(path.c_str())) {
FsFile file; FsFile file;
@ -489,21 +488,30 @@ void ThemeManager::loadTheme(const std::string &themeName) {
} }
} else { } else {
Serial.println("[ThemeManager] Using embedded Default theme"); Serial.println("[ThemeManager] Using embedded Default theme");
sections = IniParser::parseString(DEFAULT_THEME_INI); sections = IniParser::parseString(getDefaultThemeIni());
} }
currentThemeName = "Default";
} else { } else {
std::string path = "/themes/" + themeName + "/theme.ini"; std::string path = "/themes/" + themeName + "/theme.ini";
FsFile file; Serial.printf("[ThemeManager] Checking path: %s\n", path.c_str());
if (SdMan.openFileForRead("Theme", path, file)) {
sections = IniParser::parse(file); if (!SdMan.exists(path.c_str())) {
file.close(); Serial.printf("[ThemeManager] Theme %s not found, using Default\n", themeName.c_str());
Serial.printf("[ThemeManager] Loaded theme: %s\n", themeName.c_str()); sections = IniParser::parseString(getDefaultThemeIni());
} else {
Serial.printf("[ThemeManager] ERR: Could not load theme %s, falling back "
"to Default\n",
themeName.c_str());
sections = IniParser::parseString(DEFAULT_THEME_INI);
currentThemeName = "Default"; currentThemeName = "Default";
} else {
FsFile file;
if (SdMan.openFileForRead("Theme", path, file)) {
Serial.printf("[ThemeManager] Parsing theme file...\n");
sections = IniParser::parse(file);
file.close();
Serial.printf("[ThemeManager] Parsed %d sections from %s\n",
(int)sections.size(), themeName.c_str());
} else {
Serial.printf("[ThemeManager] Failed to open %s, using Default\n", path.c_str());
sections = IniParser::parseString(getDefaultThemeIni());
currentThemeName = "Default";
}
} }
} }

View File

@ -1,11 +1,11 @@
#include "ThemeSelectionActivity.h" #include "ThemeSelectionActivity.h"
#include "CrossPointSettings.h" #include "CrossPointSettings.h"
#include "MappedInputManager.h" #include "MappedInputManager.h"
#include "ThemeManager.h"
#include "fontIds.h" #include "fontIds.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <SDCardManager.h> #include <SDCardManager.h>
#include <cstring> #include <cstring>
#include <esp_system.h>
void ThemeSelectionActivity::taskTrampoline(void *param) { void ThemeSelectionActivity::taskTrampoline(void *param) {
auto *self = static_cast<ThemeSelectionActivity *>(param); auto *self = static_cast<ThemeSelectionActivity *>(param);
@ -69,13 +69,28 @@ void ThemeSelectionActivity::loop() {
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) { if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
if (selectedIndex >= 0 && selectedIndex < themeNames.size()) { if (selectedIndex >= 0 && selectedIndex < themeNames.size()) {
std::string selected = themeNames[selectedIndex]; std::string selected = themeNames[selectedIndex];
strncpy(SETTINGS.themeName, selected.c_str(),
sizeof(SETTINGS.themeName) - 1);
SETTINGS.themeName[sizeof(SETTINGS.themeName) - 1] = '\0';
SETTINGS.saveToFile();
// Load the new theme immediately // Only reboot if theme actually changed
ThemeEngine::ThemeManager::get().loadTheme(selected); if (selected != std::string(SETTINGS.themeName)) {
strncpy(SETTINGS.themeName, selected.c_str(),
sizeof(SETTINGS.themeName) - 1);
SETTINGS.themeName[sizeof(SETTINGS.themeName) - 1] = '\0';
SETTINGS.saveToFile();
// Show reboot message
renderer.clearScreen();
renderer.drawCenteredText(UI_12_FONT_ID, renderer.getScreenHeight() / 2 - 20,
"Applying theme...", true);
renderer.drawCenteredText(UI_10_FONT_ID, renderer.getScreenHeight() / 2 + 10,
"Device will restart", true);
renderer.displayBuffer();
// Small delay to ensure display updates
vTaskDelay(500 / portTICK_PERIOD_MS);
esp_restart();
return;
}
} }
onGoBack(); onGoBack();
return; return;
@ -150,14 +165,11 @@ void ThemeSelectionActivity::render() const {
int y = startY + i * entryHeight; int y = startY + i * entryHeight;
bool isSelected = (idx == selectedIndex); bool isSelected = (idx == selectedIndex);
renderer.drawText(UI_10_FONT_ID, 20, y, themeNames[idx].c_str(), std::string displayName = themeNames[idx];
!isSelected);
// Mark current active theme if different from selected
if (themeNames[idx] == std::string(SETTINGS.themeName)) { if (themeNames[idx] == std::string(SETTINGS.themeName)) {
renderer.drawText(UI_10_FONT_ID, pageWidth - 80, y, "(Current)", displayName = "* " + displayName;
!isSelected);
} }
renderer.drawText(UI_10_FONT_ID, 20, y, displayName.c_str(), !isSelected);
} }
// Scrollbar if needed // Scrollbar if needed
@ -166,12 +178,10 @@ void ThemeSelectionActivity::render() const {
int thumbHeight = barHeight * maxVisible / themeNames.size(); int thumbHeight = barHeight * maxVisible / themeNames.size();
int thumbY = startY + (barHeight - thumbHeight) * startIdx / int thumbY = startY + (barHeight - thumbHeight) * startIdx /
(themeNames.size() - maxVisible); (themeNames.size() - maxVisible);
renderer.fillRect(pageWidth - 5, startY, 2, barHeight, renderer.fillRect(pageWidth - 5, startY, 2, barHeight, 0);
0); // Track logic? No just draw thumb
renderer.fillRect(pageWidth - 7, thumbY, 6, thumbHeight, 1); renderer.fillRect(pageWidth - 7, thumbY, 6, thumbHeight, 1);
} }
// Hints
const auto labels = mappedInput.mapLabels("Cancel", "Select", "", ""); const auto labels = mappedInput.mapLabels("Cancel", "Select", "", "");
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3,
labels.btn4); labels.btn4);