[Deprecated] Restore old themeManager behavior for 3.0.2 release.

This commit is contained in:
Lukas Brübach 2026-06-26 10:29:28 -04:00
parent cfc6d5dfed
commit fcb4c4589a
10 changed files with 255 additions and 418 deletions

View file

@ -74,7 +74,7 @@ endif()
# A project name is needed for CPack # A project name is needed for CPack
# Version can be overriden by git tags, see cmake/getversion.cmake # Version can be overriden by git tags, see cmake/getversion.cmake
project("Cockatrice" VERSION 3.1.0) project("Cockatrice" VERSION 3.0.2)
# Set release name if not provided via env/cmake var # Set release name if not provided via env/cmake var
if(NOT DEFINED GIT_TAG_RELEASENAME) if(NOT DEFINED GIT_TAG_RELEASENAME)

View file

@ -25,7 +25,7 @@ PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QSt
// Load both scheme configs upfront so switching is instant // Load both scheme configs upfront so switching is instant
loadSchemes(); loadSchemes();
loadedScheme = themeManager->isDarkMode(themeDirPath) ? "Dark" : "Light"; //loadedScheme = themeManager->isDarkMode(themeDirPath) ? "Dark" : "Light";
schemeComboBox->blockSignals(true); schemeComboBox->blockSignals(true);
schemeComboBox->setCurrentText(loadedScheme); schemeComboBox->setCurrentText(loadedScheme);
@ -247,7 +247,7 @@ void PaletteEditorDialog::onGenerateFromAccent(const QColor &accent, int intensi
void PaletteEditorDialog::onApply() void PaletteEditorDialog::onApply()
{ {
themeManager->previewPalette(paletteGrid->currentPaletteConfig(), loadedScheme); //themeManager->previewPalette(paletteGrid->currentPaletteConfig(), loadedScheme);
} }
void PaletteEditorDialog::onSave() void PaletteEditorDialog::onSave()
@ -258,11 +258,11 @@ void PaletteEditorDialog::onSave()
PaletteConfig cfg = paletteGrid->currentPaletteConfig(); PaletteConfig cfg = paletteGrid->currentPaletteConfig();
if (!ThemeManager::savePaletteConfig(themeDirPath, loadedScheme, cfg)) { /*if (!ThemeManager::savePaletteConfig(themeDirPath, loadedScheme, cfg)) {
QMessageBox::warning(this, tr("Save failed"), QMessageBox::warning(this, tr("Save failed"),
tr("Could not write %1 to:\n%2").arg(PaletteConfig::fileName(loadedScheme), themeDirPath)); tr("Could not write %1 to:\n%2").arg(PaletteConfig::fileName(loadedScheme), themeDirPath));
return; return;
} }*/
ThemeConfig globalCfg = ThemeConfig::fromThemeDir(themeDirPath); ThemeConfig globalCfg = ThemeConfig::fromThemeDir(themeDirPath);
globalCfg.colorScheme = loadedScheme; globalCfg.colorScheme = loadedScheme;
@ -270,7 +270,7 @@ void PaletteEditorDialog::onSave()
savedConfig[loadedScheme] = cfg; savedConfig[loadedScheme] = cfg;
workingConfig[loadedScheme] = cfg; workingConfig[loadedScheme] = cfg;
themeManager->reloadCurrentTheme(); //themeManager->reloadCurrentTheme();
accept(); accept();
} }

View file

@ -19,7 +19,9 @@
#include <Qt> #include <Qt>
#define NONE_THEME_NAME "Default" #define NONE_THEME_NAME "Default"
#define FUSION_THEME_NAME "Fusion" #define FUSION_THEME_NAME "Fusion (System Default)"
#define FUSION_THEME_NAME_LIGHT "Fusion (Light)"
#define FUSION_THEME_NAME_DARK "Fusion (Dark)"
#define STYLE_CSS_NAME "style.css" #define STYLE_CSS_NAME "style.css"
#define HANDZONE_BG_NAME "handzone" #define HANDZONE_BG_NAME "handzone"
#define PLAYERZONE_BG_NAME "playerzone" #define PLAYERZONE_BG_NAME "playerzone"
@ -49,9 +51,8 @@ struct PaletteColorInfo
// Iterate through all color roles (excluding NoRole and NColorRoles) // Iterate through all color roles (excluding NoRole and NColorRoles)
for (int r = 0; r < QPalette::NColorRoles; ++r) { for (int r = 0; r < QPalette::NColorRoles; ++r) {
auto role = static_cast<QPalette::ColorRole>(r); auto role = static_cast<QPalette::ColorRole>(r);
if (role == QPalette::NoRole) { if (role == QPalette::NoRole)
continue; continue;
}
PaletteColorInfo info; PaletteColorInfo info;
info.group = group; info.group = group;
@ -77,9 +78,8 @@ struct PaletteColorInfo
for (int r = 0; r < QPalette::NColorRoles; ++r) { for (int r = 0; r < QPalette::NColorRoles; ++r) {
auto role = static_cast<QPalette::ColorRole>(r); auto role = static_cast<QPalette::ColorRole>(r);
if (role == QPalette::NoRole) { if (role == QPalette::NoRole)
continue; continue;
}
QColor color = palette.color(group, role); QColor color = palette.color(group, role);
qInfo().nospace() << qPrintable(QString("%1").arg(roleEnum.valueToKey(role), -20)) << " : " qInfo().nospace() << qPrintable(QString("%1").arg(roleEnum.valueToKey(role), -20)) << " : "
@ -92,7 +92,7 @@ struct PaletteColorInfo
ThemeManager::ThemeManager(QObject *parent) : QObject(parent) ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
{ {
defaultStyleName = qApp->style()->objectName(); defaultStyleName = qApp->style()->objectName();
//! \todo Workaround for windows11 style being broken. // FIXME workaround for windows11 style being broken
if (defaultStyleName == "windows11") { if (defaultStyleName == "windows11") {
defaultStyleName = "windowsvista"; defaultStyleName = "windowsvista";
} }
@ -113,28 +113,37 @@ void ThemeManager::ensureThemeDirectoryExists()
} }
} }
bool ThemeManager::isDarkMode(const QString &themeDirPath) bool ThemeManager::isDarkMode()
{ {
ThemeConfig themeConfig = ThemeConfig::fromThemeDir(themeDirPath); auto themeName = SettingsCache::instance().getThemeName();
if (themeConfig.colorScheme.compare("Dark", Qt::CaseInsensitive) == 0) { // Explicit Dark Mode
return true; if (themeName == FUSION_THEME_NAME_LIGHT || themeName.endsWith("(Light)")) {
} else if (themeConfig.colorScheme.compare("Light", Qt::CaseInsensitive) == 0) {
return false; return false;
} else {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
bool osDark = (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark);
#else
bool osDark = false;
#endif
return osDark;
} }
// Explicit Light Mode
if (themeName == FUSION_THEME_NAME_DARK || themeName.endsWith("(Dark)")) {
return true;
}
// Auto detection on compatible Qt versions
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark &&
(themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME || themeName.endsWith("(System Default)"))) {
return true;
} else {
return false;
}
#endif
// Default to light mode
return false;
} }
bool ThemeManager::isBuiltInTheme() bool ThemeManager::isBuiltInTheme()
{ {
const auto themeName = SettingsCache::instance().getThemeName(); const auto themeName = SettingsCache::instance().getThemeName();
return themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME; return themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME || themeName == FUSION_THEME_NAME_LIGHT ||
themeName == FUSION_THEME_NAME_DARK;
} }
QStringMap &ThemeManager::getAvailableThemes() QStringMap &ThemeManager::getAvailableThemes()
@ -142,13 +151,15 @@ QStringMap &ThemeManager::getAvailableThemes()
QDir dir; QDir dir;
availableThemes.clear(); availableThemes.clear();
// add default value
availableThemes.insert(NONE_THEME_NAME, QString());
// load themes from user profile dir // load themes from user profile dir
dir.setPath(SettingsCache::instance().getThemesPath()); dir.setPath(SettingsCache::instance().getThemesPath());
// add default value availableThemes.insert(FUSION_THEME_NAME, dir.filePath("Fusion (System Default)"));
availableThemes.insert(NONE_THEME_NAME, dir.absoluteFilePath("Default")); availableThemes.insert(FUSION_THEME_NAME_LIGHT, dir.filePath("Fusion (Light)"));
availableThemes.insert(FUSION_THEME_NAME_DARK, dir.filePath("Fusion (Dark)"));
availableThemes.insert(FUSION_THEME_NAME, dir.absoluteFilePath("Fusion"));
for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) { for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
if (!availableThemes.contains(themeName)) { if (!availableThemes.contains(themeName)) {
@ -204,112 +215,192 @@ QBrush ThemeManager::loadExtraBrush(QString fileName, QBrush &fallbackBrush)
return brush; return brush;
} }
ThemeConfig ThemeManager::loadGlobalConfig(const QString &themeDirPath) static inline QPalette createDarkGreenFusionPalette()
{ {
return ThemeConfig::fromThemeDir(themeDirPath); QPalette p = QStyleFactory::create("Fusion")->standardPalette();
}
bool ThemeManager::saveGlobalConfig(const QString &themeDirPath, const ThemeConfig &cfg) // ---------- Core backgrounds ----------
{ p.setColor(QPalette::Window, QColor(30, 30, 30)); // #ff1e1e1e
return cfg.save(themeDirPath); p.setColor(QPalette::Base, QColor(45, 45, 45)); // #ff2d2d2d
} p.setColor(QPalette::AlternateBase, QColor(53, 53, 53)); // #ff353535
p.setColor(QPalette::Button, QColor(60, 60, 60)); // #ff3c3c3c
p.setColor(QPalette::ToolTipBase, QColor(60, 60, 60)); // #ff3c3c3c
PaletteConfig ThemeManager::loadPaletteConfig(const QString &themeDirPath, const QString &colorScheme) // ---------- Core text ----------
{ p.setColor(QPalette::WindowText, Qt::white); // #ffffffff
if (themeDirPath.isEmpty()) { p.setColor(QPalette::Text, Qt::white); // #ffffffff
return {}; p.setColor(QPalette::ButtonText, Qt::white); // #ffffffff
} p.setColor(QPalette::ToolTipText, QColor(212, 212, 212)); // #ffd4d4d4
return PaletteConfig::fromScheme(themeDirPath, colorScheme); p.setColor(QPalette::PlaceholderText, QColor(255, 255, 255, 128)); // #80ffffff
}
bool ThemeManager::savePaletteConfig(const QString &themeDirPath, const QString &colorScheme, const PaletteConfig &cfg) // ---------- Selection / focus ----------
{ const QColor highlight(20, 140, 60); // #ff148c3c
if (themeDirPath.isEmpty()) { p.setColor(QPalette::Highlight, highlight);
return false; p.setColor(QPalette::HighlightedText, Qt::white); // #ffffffff
}
QDir dir(themeDirPath); // ---------- Links ----------
if (!dir.exists()) { p.setColor(QPalette::Link, QColor(0, 246, 82)); // #ff00f652
dir.mkpath("."); p.setColor(QPalette::LinkVisited, QColor(0, 211, 70)); // #ff00d346
}
QFile f(dir.absoluteFilePath(PaletteConfig::fileName(colorScheme))); // ---------- Accent (Qt 6) ----------
if (!f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
return false; p.setColor(QPalette::Accent, QColor(0, 211, 70)); // #ff00d346
}
QTextStream(&f) << cfg.toToml();
return true;
}
void ThemeManager::setColorScheme(const QString &scheme)
{
const QString dirPath = getAvailableThemes().value(SettingsCache::instance().getThemeName());
ThemeConfig cfg = ThemeConfig::fromThemeDir(dirPath);
cfg.colorScheme = scheme;
cfg.save(dirPath);
reloadCurrentTheme();
}
void ThemeManager::reloadCurrentTheme()
{
themeChangedSlot();
}
void ThemeManager::previewPalette(const PaletteConfig &cfg, const QString &scheme)
{
const QString themeName = SettingsCache::instance().getThemeName();
const QString dirPath = getAvailableThemes().value(themeName);
const ThemeConfig themeCfg = ThemeConfig::fromThemeDir(dirPath);
applyStyleAndPalette(themeName, themeCfg, cfg, scheme);
}
void ThemeManager::applyStyleAndPalette(const QString &themeName,
const ThemeConfig &themeCfg,
const PaletteConfig &palCfg,
const QString &activeScheme)
{
QString styleName = themeCfg.styleName;
if (styleName.isEmpty() || styleName.compare("Default", Qt::CaseInsensitive) == 0) {
if (themeName == FUSION_THEME_NAME) {
styleName = "Fusion";
} else {
styleName = defaultStyleName;
}
}
QStyle *style = QStyleFactory::create(styleName);
if (!style) {
style = QStyleFactory::create(defaultStyleName);
}
// Base palette
QPalette base;
if (styleName.compare("Fusion", Qt::CaseInsensitive) == 0) {
base = style->standardPalette();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
if (activeScheme == "Dark") {
base.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
}
#endif #endif
// ---------- Bright text ----------
p.setColor(QPalette::BrightText, QColor(0, 246, 82)); // #ff00f652
// ---------- 3D / frame shading ----------
p.setColor(QPalette::Light, QColor(120, 120, 120)); // #ff787878
p.setColor(QPalette::Midlight, QColor(90, 90, 90)); // #ff5a5a5a
p.setColor(QPalette::Mid, QColor(40, 40, 40)); // #ff282828
p.setColor(QPalette::Dark, QColor(30, 30, 30)); // #ff1e1e1e
p.setColor(QPalette::Shadow, Qt::black); // #ff000000
// ---------- Disabled state ----------
const QColor disabledText(157, 157, 157); // #ff9d9d9d
p.setColor(QPalette::Disabled, QPalette::WindowText, disabledText);
p.setColor(QPalette::Disabled, QPalette::Text, disabledText);
p.setColor(QPalette::Disabled, QPalette::ButtonText, disabledText);
p.setColor(QPalette::Disabled, QPalette::Base, QColor(30, 30, 30));
p.setColor(QPalette::Disabled, QPalette::Window, QColor(30, 30, 30));
p.setColor(QPalette::Disabled, QPalette::Link, QColor(48, 140, 198)); // #ff308cc6
p.setColor(QPalette::Disabled, QPalette::LinkVisited, QColor(255, 0, 255)); // #ffff00ff
p.setColor(QPalette::Disabled, QPalette::ToolTipBase, QColor(255, 255, 220));
p.setColor(QPalette::Disabled, QPalette::ToolTipText, Qt::black);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
p.setColor(QPalette::Disabled, QPalette::Accent, disabledText);
#endif
// ---------- Inactive state ----------
p.setColor(QPalette::Inactive, QPalette::Highlight, QColor(30, 30, 30));
p.setColor(QPalette::Inactive, QPalette::HighlightedText, Qt::white);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
p.setColor(QPalette::Inactive, QPalette::Accent, QColor(30, 30, 30));
#endif
return p;
}
static inline QPalette createLightGreenFusionPalette()
{
QPalette p = QStyleFactory::create("Fusion")->standardPalette();
// ---------- Core backgrounds ----------
p.setColor(QPalette::Window, QColor(240, 240, 240)); // #fff0f0f0
p.setColor(QPalette::Base, Qt::white); // #ffffffff
p.setColor(QPalette::AlternateBase, QColor(233, 231, 227)); // #ffe9e7e3
p.setColor(QPalette::Button, QColor(240, 240, 240)); // #fff0f0f0
p.setColor(QPalette::ToolTipBase, QColor(255, 255, 220)); // #ffffffdc
// ---------- Core text ----------
p.setColor(QPalette::WindowText, Qt::black); // #ff000000
p.setColor(QPalette::Text, Qt::black); // #ff000000
p.setColor(QPalette::ButtonText, Qt::black); // #ff000000
p.setColor(QPalette::ToolTipText, Qt::black); // #ff000000
p.setColor(QPalette::PlaceholderText, QColor(0, 0, 0, 128)); // #80000000
// ---------- Selection / focus ----------
const QColor highlight(20, 140, 60); // #ff148c3c
p.setColor(QPalette::Highlight, highlight);
p.setColor(QPalette::HighlightedText, Qt::white); // #ffffffff
// ---------- Links ----------
p.setColor(QPalette::Link, QColor(13, 95, 40)); // #ff0d5f28
p.setColor(QPalette::LinkVisited, QColor(8, 64, 27)); // #ff08401b
// ---------- Accent (Qt 6) ----------
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
p.setColor(QPalette::Accent, QColor(16, 117, 50)); // #ff107532
#endif
// ---------- Bright text ----------
p.setColor(QPalette::BrightText, Qt::white); // #ffffffff
// ---------- 3D / frame shading ----------
p.setColor(QPalette::Light, Qt::white); // #ffffffff
p.setColor(QPalette::Midlight, QColor(227, 227, 227)); // #ffe3e3e3
p.setColor(QPalette::Mid, QColor(160, 160, 160)); // #ffa0a0a0
p.setColor(QPalette::Dark, QColor(160, 160, 160)); // #ffa0a0a0
p.setColor(QPalette::Shadow, QColor(105, 105, 105)); // #ff696969
// ---------- Disabled state ----------
const QColor disabledText(120, 120, 120); // #ff787878
p.setColor(QPalette::Disabled, QPalette::WindowText, disabledText);
p.setColor(QPalette::Disabled, QPalette::Text, disabledText);
p.setColor(QPalette::Disabled, QPalette::ButtonText, disabledText);
p.setColor(QPalette::Disabled, QPalette::Base, QColor(240, 240, 240));
p.setColor(QPalette::Disabled, QPalette::Window, QColor(240, 240, 240));
p.setColor(QPalette::Disabled, QPalette::Midlight, QColor(247, 247, 247));
p.setColor(QPalette::Disabled, QPalette::AlternateBase, QColor(247, 247, 247));
p.setColor(QPalette::Disabled, QPalette::Shadow, Qt::black);
p.setColor(QPalette::Disabled, QPalette::Link, QColor(0, 0, 255));
p.setColor(QPalette::Disabled, QPalette::LinkVisited, QColor(255, 0, 255));
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
p.setColor(QPalette::Disabled, QPalette::Accent, disabledText);
#endif
// ---------- Inactive state ----------
p.setColor(QPalette::Inactive, QPalette::Highlight, QColor(240, 240, 240));
p.setColor(QPalette::Inactive, QPalette::HighlightedText, Qt::black);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
p.setColor(QPalette::Inactive, QPalette::Accent, QColor(240, 240, 240));
#endif
return p;
}
void ThemeManager::themeChangedSlot()
{
QString themeName = SettingsCache::instance().getThemeName();
qCInfo(ThemeManagerLog) << "Theme changed:" << themeName;
QString dirPath = getAvailableThemes().value(themeName);
QDir dir = dirPath;
// css
if (!dirPath.isEmpty() && dir.exists(STYLE_CSS_NAME)) {
qApp->setStyleSheet("file:///" + dir.absoluteFilePath(STYLE_CSS_NAME));
} else { } else {
base = qApp->palette(); qApp->setStyleSheet("");
} }
// Overlay custom palette colours QStyle *newStyle = nullptr;
if (palCfg.hasPalette()) { QPalette newPalette;
base = palCfg.apply(base);
if (themeName == FUSION_THEME_NAME) {
newStyle = QStyleFactory::create("Fusion");
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
// Start from Fusion's own palette so dark mode is handled correctly,
// then apply any tweaks on top of it.
newPalette = newStyle->standardPalette();
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark) {
newPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
}
#else
newPalette = qApp->palette();
#endif
} else if (themeName == FUSION_THEME_NAME_LIGHT) {
newStyle = QStyleFactory::create("Fusion");
newPalette = createLightGreenFusionPalette();
} else if (themeName == FUSION_THEME_NAME_DARK) {
newStyle = QStyleFactory::create("Fusion");
newPalette = createDarkGreenFusionPalette();
} else {
newStyle = QStyleFactory::create(defaultStyleName);
// Use the style's default palette.
newPalette = newStyle->standardPalette();
} }
// Palette BEFORE style — setStyle() triggers a synchronous repolish of all // Apply palette FIRST.
// widgets immediately. If the palette isn't set yet at that point, every qApp->setPalette(newPalette);
// widget gets polished against the stale colours, requiring a second apply // Then apply style.
// to fully resolve. Setting palette first means setStyle's repolish cascade qApp->setStyle(newStyle);
// already sees the correct colours.
qApp->setPalette(base);
qApp->setStyle(style);
// Force every widget to re-polish and repaint immediately rather than // Force every widget to re-polish and repaint immediately rather than
// waiting for natural expose events, which produces a patchwork of old // waiting for natural expose events, which produces a patchwork of old
@ -319,57 +410,34 @@ void ThemeManager::applyStyleAndPalette(const QString &themeName,
// palette (WA_SetPalette not set). Calling it unconditionally would clobber // palette (WA_SetPalette not set). Calling it unconditionally would clobber
// intentional per-widget palette customisations across the whole app. // intentional per-widget palette customisations across the whole app.
for (QWidget *widget : qApp->allWidgets()) { for (QWidget *widget : qApp->allWidgets()) {
style->unpolish(widget); if (widget->isVisible()) {
style->polish(widget); newStyle->unpolish(widget);
newStyle->polish(widget);
widget->update(); widget->update();
} }
} }
void ThemeManager::themeChangedSlot() if (dirPath.isEmpty()) {
{ // set default values
QString themeName = SettingsCache::instance().getThemeName(); QDir::setSearchPaths("theme", DEFAULT_RESOURCE_PATHS);
QString dirPath = getAvailableThemes().value(themeName); brushes[Role::Hand] = HANDZONE_BG_DEFAULT;
currentThemePath = dirPath; brushes[Role::Table] = TABLEZONE_BG_DEFAULT;
QDir dir(dirPath); brushes[Role::Player] = PLAYERZONE_BG_DEFAULT;
brushes[Role::Stack] = STACKZONE_BG_DEFAULT;
// CSS
if (!dirPath.isEmpty() && dir.exists(STYLE_CSS_NAME)) {
qApp->setStyleSheet("file:///" + dir.absoluteFilePath(STYLE_CSS_NAME));
} else { } else {
qApp->setStyleSheet(""); // resources
}
// load theme.cfg for style + scheme preference
ThemeConfig themeCfg = ThemeConfig::fromThemeDir(dirPath);
// Resolve active scheme:
// theme.cfg says Dark/Light → use that
// theme.cfg says System or is absent → follow the OS
QString activeScheme = isDarkMode(dirPath) ? "Dark" : "Light";
// ── Load palette: custom first, then theme default ────────────────────
PaletteConfig palette = PaletteConfig::fromScheme(dirPath, activeScheme);
if (!palette.hasPalette()) {
palette = PaletteConfig::fromDefault(dirPath, activeScheme);
}
applyStyleAndPalette(themeName, themeCfg, palette, activeScheme);
QStringList resources; QStringList resources;
if (!dirPath.isEmpty()) { resources << dir.absolutePath() << DEFAULT_RESOURCE_PATHS;
resources << dir.absolutePath();
}
resources << DEFAULT_RESOURCE_PATHS;
QDir::setSearchPaths("theme", resources); QDir::setSearchPaths("theme", resources);
// zones bg
dir.cd("zones");
brushes[Role::Hand] = loadBrush(HANDZONE_BG_NAME, HANDZONE_BG_DEFAULT); brushes[Role::Hand] = loadBrush(HANDZONE_BG_NAME, HANDZONE_BG_DEFAULT);
brushes[Role::Table] = loadBrush(TABLEZONE_BG_NAME, TABLEZONE_BG_DEFAULT); brushes[Role::Table] = loadBrush(TABLEZONE_BG_NAME, TABLEZONE_BG_DEFAULT);
brushes[Role::Player] = loadBrush(PLAYERZONE_BG_NAME, PLAYERZONE_BG_DEFAULT); brushes[Role::Player] = loadBrush(PLAYERZONE_BG_NAME, PLAYERZONE_BG_DEFAULT);
brushes[Role::Stack] = loadBrush(STACKZONE_BG_NAME, STACKZONE_BG_DEFAULT); brushes[Role::Stack] = loadBrush(STACKZONE_BG_NAME, STACKZONE_BG_DEFAULT);
}
for (auto &brushCache : brushesCache) { for (auto &brushCache : brushesCache) {
brushCache.clear(); brushCache.clear();
} }

View file

@ -1,14 +1,12 @@
/** /**
* @file theme_manager.h * @file theme_manager.h
* @ingroup CoreSettings * @ingroup CoreSettings
* @brief TODO: Document this.
*/ */
//! \todo Document this file.
#ifndef THEMEMANAGER_H #ifndef THEMEMANAGER_H
#define THEMEMANAGER_H #define THEMEMANAGER_H
#include "theme_config.h"
#include <QBrush> #include <QBrush>
#include <QDir> #include <QDir>
#include <QLoggingCategory> #include <QLoggingCategory>
@ -43,7 +41,6 @@ public:
private: private:
QString defaultStyleName; QString defaultStyleName;
QString currentThemePath;
std::array<QBrush, Role::MaxRole + 1> brushes; std::array<QBrush, Role::MaxRole + 1> brushes;
QStringMap availableThemes; QStringMap availableThemes;
/* /*
@ -55,37 +52,17 @@ protected:
void ensureThemeDirectoryExists(); void ensureThemeDirectoryExists();
QBrush loadBrush(QString fileName, QColor fallbackColor); QBrush loadBrush(QString fileName, QColor fallbackColor);
QBrush loadExtraBrush(QString fileName, QBrush &fallbackBrush); QBrush loadExtraBrush(QString fileName, QBrush &fallbackBrush);
void applyStyleAndPalette(const QString &themeName,
const ThemeConfig &themeCfg,
const PaletteConfig &palCfg,
const QString &activeScheme);
public: public:
bool isBuiltInTheme(); bool isBuiltInTheme();
bool isDarkMode(const QString &themeDirPath); bool isDarkMode();
QStringMap &getAvailableThemes(); QStringMap &getAvailableThemes();
// Returns the path to the currently active theme directory (empty = default)
QString getCurrentThemePath() const
{
return currentThemePath;
}
// Load the global theme settings (style + color scheme preference)
static ThemeConfig loadGlobalConfig(const QString &themeDirPath);
static bool saveGlobalConfig(const QString &themeDirPath, const ThemeConfig &cfg);
// Load/save per-scheme palette colors
static PaletteConfig loadPaletteConfig(const QString &themeDirPath, const QString &colorScheme);
static bool savePaletteConfig(const QString &themeDirPath, const QString &colorScheme, const PaletteConfig &cfg);
void setColorScheme(const QString &scheme);
void reloadCurrentTheme();
void previewPalette(const PaletteConfig &cfg, const QString &scheme);
QBrush &getBgBrush(Role zone); QBrush &getBgBrush(Role zone);
QBrush getExtraBgBrush(Role zone, int zoneId = 0); QBrush getExtraBgBrush(Role zone, int zoneId = 0);
protected slots: protected slots:
void themeChangedSlot(); void themeChangedSlot();
signals: signals:
void themeChanged(); void themeChanged();
}; };

View file

@ -31,7 +31,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
connect(&themeBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppearanceSettingsPage::themeBoxChanged); connect(&themeBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppearanceSettingsPage::themeBoxChanged);
connect(&openThemeButton, &QPushButton::clicked, this, &AppearanceSettingsPage::openThemeLocation); connect(&openThemeButton, &QPushButton::clicked, this, &AppearanceSettingsPage::openThemeLocation);
schemeCombo.addItem(tr("Light"), QStringLiteral("Light")); /*schemeCombo.addItem(tr("Light"), QStringLiteral("Light"));
schemeCombo.addItem(tr("Dark"), QStringLiteral("Dark")); schemeCombo.addItem(tr("Dark"), QStringLiteral("Dark"));
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
schemeCombo.addItem(tr("System"), QStringLiteral("System")); schemeCombo.addItem(tr("System"), QStringLiteral("System"));
@ -58,15 +58,18 @@ AppearanceSettingsPage::AppearanceSettingsPage()
schemeCombo.blockSignals(false); schemeCombo.blockSignals(false);
}); });
connect(&editPaletteButton, &QPushButton::clicked, this, &AppearanceSettingsPage::editPalette); connect(&editPaletteButton, &QPushButton::clicked, this, &AppearanceSettingsPage::editPalette);*/
schemeComboLabel.setHidden(true);
schemeCombo.setHidden(true);
editPaletteButton.setHidden(true);
auto *themeGrid = new QGridLayout; auto *themeGrid = new QGridLayout;
themeGrid->addWidget(&themeLabel, 0, 0); themeGrid->addWidget(&themeLabel, 0, 0);
themeGrid->addWidget(&themeBox, 0, 1); themeGrid->addWidget(&themeBox, 0, 1);
themeGrid->addWidget(&openThemeButton, 1, 1); themeGrid->addWidget(&openThemeButton, 1, 1);
themeGrid->addWidget(&schemeComboLabel, 2, 0); //themeGrid->addWidget(&schemeComboLabel, 2, 0);
themeGrid->addWidget(&schemeCombo, 2, 1); //themeGrid->addWidget(&schemeCombo, 2, 1);
themeGrid->addWidget(&editPaletteButton, 3, 1); //themeGrid->addWidget(&editPaletteButton, 3, 1);
themeGroupBox = new QGroupBox; themeGroupBox = new QGroupBox;
themeGroupBox->setLayout(themeGrid); themeGroupBox->setLayout(themeGrid);
@ -322,8 +325,8 @@ void AppearanceSettingsPage::openThemeLocation()
void AppearanceSettingsPage::editPalette() void AppearanceSettingsPage::editPalette()
{ {
PaletteEditorDialog dlg(themeManager->getCurrentThemePath(), SettingsCache::instance().getThemeName(), this); //PaletteEditorDialog dlg(themeManager->getCurrentThemePath(), SettingsCache::instance().getThemeName(), this);
dlg.exec(); //dlg.exec();
} }
void AppearanceSettingsPage::updateHomeTabSettingsVisibility() void AppearanceSettingsPage::updateHomeTabSettingsVisibility()

View file

@ -1,63 +0,0 @@
[Palette]
WindowText = #ffffffff
Button = #ff383838
Light = #ff737373
Midlight = #ff525252
Dark = #ff161616
Mid = #ff252525
Text = #ffffffff
BrightText = #ffb4dd8b
ButtonText = #ffffffff
Base = #ff2b2b2b
Window = #ff1c1c1c
Shadow = #ff000000
HighlightedText = #ff000000
Link = #ffcde4b6
LinkVisited = #ff99d999
AlternateBase = #ff242424
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #6effffff
[Palette.Disabled]
WindowText = #ff9d9d9d
Button = #ff1c1c1c
Light = #ff737373
Midlight = #ff525252
Dark = #ff161616
Mid = #ff252525
Text = #ff9d9d9d
BrightText = #ffb4dd8b
ButtonText = #ff787878
Base = #ff1c1c1c
Window = #ff1c1c1c
Shadow = #ff000000
HighlightedText = #ff9d9d9d
Link = #ff308cc6
LinkVisited = #ffb450ff
AlternateBase = #ff242424
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #46ffffff
[Palette.Inactive]
WindowText = #ffffffff
Button = #ff383838
Light = #ff737373
Midlight = #ff525252
Dark = #ff161616
Mid = #ff252525
Text = #ffffffff
BrightText = #ffb4dd8b
ButtonText = #ffffffff
Base = #ff2b2b2b
Window = #ff1c1c1c
Shadow = #ff000000
HighlightedText = #ffffffff
Link = #ffcde4b6
LinkVisited = #ff99d999
AlternateBase = #ff242424
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #6effffff

View file

@ -1,5 +0,0 @@
[Appearance]
ColorScheme = Light
[Style]
Name = Default

View file

@ -1,69 +0,0 @@
[Palette]
WindowText = #ffffffff
Button = #ff3c3c3c
Light = #ff787878
Midlight = #ff5a5a5a
Dark = #ff1e1e1e
Mid = #ff282828
Text = #ffffffff
BrightText = #ff00f652
ButtonText = #ffffffff
Base = #ff2d2d2d
Window = #ff1e1e1e
Shadow = #ff000000
Highlight = #ff148c3c
HighlightedText = #ffffffff
Link = #ff00f652
LinkVisited = #ff00d346
AlternateBase = #ff353535
ToolTipBase = #ff3c3c3c
ToolTipText = #ffd4d4d4
PlaceholderText = #80ffffff
Accent = #ff00d346
[Palette.Disabled]
WindowText = #ff9d9d9d
Button = #ff3c3c3c
Light = #ff787878
Midlight = #ff5a5a5a
Dark = #ff1e1e1e
Mid = #ff282828
Text = #ff9d9d9d
BrightText = #ff00f652
ButtonText = #ff9d9d9d
Base = #ff1e1e1e
Window = #ff1e1e1e
Shadow = #ff000000
Highlight = #ff148c3c
HighlightedText = #ffffffff
Link = #ff308cc6
LinkVisited = #ffff00ff
AlternateBase = #ff353535
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #80ffffff
Accent = #ff9d9d9d
[Palette.Inactive]
WindowText = #ffffffff
Button = #ff3c3c3c
Light = #ff787878
Midlight = #ff5a5a5a
Dark = #ff1e1e1e
Mid = #ff282828
Text = #ffffffff
BrightText = #ff00f652
ButtonText = #ffffffff
Base = #ff2d2d2d
Window = #ff1e1e1e
Shadow = #ff000000
Highlight = #ff1e1e1e
HighlightedText = #ffffffff
Link = #ff00f652
LinkVisited = #ff00d346
AlternateBase = #ff353535
ToolTipBase = #ff3c3c3c
ToolTipText = #ffd4d4d4
PlaceholderText = #80ffffff
Accent = #ff1e1e1e

View file

@ -1,69 +0,0 @@
[Palette]
WindowText = #ff000000
Button = #fff0f0f0
Light = #ffffffff
Midlight = #ffe3e3e3
Dark = #ffa0a0a0
Mid = #ffa0a0a0
Text = #ff000000
BrightText = #ffffffff
ButtonText = #ff000000
Base = #ffffffff
Window = #fff0f0f0
Shadow = #ff696969
Highlight = #ff148c3c
HighlightedText = #ffffffff
Link = #ff0d5f28
LinkVisited = #ff08401b
AlternateBase = #ffe9e7e3
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #80000000
Accent = #ff107532
[Palette.Disabled]
WindowText = #ff787878
Button = #fff0f0f0
Light = #ffffffff
Midlight = #fff7f7f7
Dark = #ffa0a0a0
Mid = #ffa0a0a0
Text = #ff787878
BrightText = #ffffffff
ButtonText = #ff787878
Base = #fff0f0f0
Window = #fff0f0f0
Shadow = #ff000000
Highlight = #ff148c3c
HighlightedText = #ffffffff
Link = #ff0000ff
LinkVisited = #ffff00ff
AlternateBase = #fff7f7f7
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #80000000
Accent = #ff787878
[Palette.Inactive]
WindowText = #ff000000
Button = #fff0f0f0
Light = #ffffffff
Midlight = #ffe3e3e3
Dark = #ffa0a0a0
Mid = #ffa0a0a0
Text = #ff000000
BrightText = #ffffffff
ButtonText = #ff000000
Base = #ffffffff
Window = #fff0f0f0
Shadow = #ff696969
Highlight = #fff0f0f0
HighlightedText = #ff000000
Link = #ff0d5f28
LinkVisited = #ff08401b
AlternateBase = #ffe9e7e3
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #80000000
Accent = #fff0f0f0

View file

@ -1,5 +0,0 @@
[Appearance]
ColorScheme = Dark
[Style]
Name = Fusion