mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-26 08:33:54 -07:00
[App/Theme] Palette Editor (#6877)
* [App/Theme] Palette Editor Took 1 minute Took 1 hour 47 minutes Took 6 seconds Took 3 minutes Took 5 minutes Took 3 minutes * Add oracle, add palette files and configs. Took 10 minutes * Fix a stupid include mistake, thanks IDE Took 3 minutes Took 20 seconds * Includes. Took 4 minutes * Fix ampersand not displaying correctly. Took 14 minutes * Longer variable names. Took 10 minutes Took 5 seconds * Change ampersand everywhere Took 23 seconds * Doxygen properly. Took 1 minute * Remove namespace, fold I/O into structs. Took 12 minutes * Remove namespace, fold I/O into structs. Took 33 seconds * Alphabetize. Took 35 seconds * Lint. Took 49 seconds * Add a combo box to quick switch settings. Took 19 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
989a5be23b
commit
117ea543c5
23 changed files with 1874 additions and 232 deletions
|
|
@ -19,9 +19,7 @@
|
|||
#include <Qt>
|
||||
|
||||
#define NONE_THEME_NAME "Default"
|
||||
#define FUSION_THEME_NAME "Fusion (System Default)"
|
||||
#define FUSION_THEME_NAME_LIGHT "Fusion (Light)"
|
||||
#define FUSION_THEME_NAME_DARK "Fusion (Dark)"
|
||||
#define FUSION_THEME_NAME "Fusion"
|
||||
#define STYLE_CSS_NAME "style.css"
|
||||
#define HANDZONE_BG_NAME "handzone"
|
||||
#define PLAYERZONE_BG_NAME "playerzone"
|
||||
|
|
@ -115,37 +113,28 @@ void ThemeManager::ensureThemeDirectoryExists()
|
|||
}
|
||||
}
|
||||
|
||||
bool ThemeManager::isDarkMode()
|
||||
bool ThemeManager::isDarkMode(const QString &themeDirPath)
|
||||
{
|
||||
auto themeName = SettingsCache::instance().getThemeName();
|
||||
// Explicit Dark Mode
|
||||
if (themeName == FUSION_THEME_NAME_LIGHT || themeName.endsWith("(Light)")) {
|
||||
ThemeConfig themeConfig = ThemeConfig::fromThemeDir(themeDirPath);
|
||||
if (themeConfig.colorScheme.compare("Dark", Qt::CaseInsensitive) == 0) {
|
||||
return true;
|
||||
} else if (themeConfig.colorScheme.compare("Light", Qt::CaseInsensitive) == 0) {
|
||||
return false;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||
bool osDark = (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark);
|
||||
#else
|
||||
bool osDark = false;
|
||||
#endif
|
||||
// Default to light mode
|
||||
return false;
|
||||
return osDark;
|
||||
}
|
||||
}
|
||||
|
||||
bool ThemeManager::isBuiltInTheme()
|
||||
{
|
||||
const auto themeName = SettingsCache::instance().getThemeName();
|
||||
|
||||
return themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME || themeName == FUSION_THEME_NAME_LIGHT ||
|
||||
themeName == FUSION_THEME_NAME_DARK;
|
||||
return themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME;
|
||||
}
|
||||
|
||||
QStringMap &ThemeManager::getAvailableThemes()
|
||||
|
|
@ -153,15 +142,13 @@ QStringMap &ThemeManager::getAvailableThemes()
|
|||
QDir dir;
|
||||
availableThemes.clear();
|
||||
|
||||
// add default value
|
||||
availableThemes.insert(NONE_THEME_NAME, QString());
|
||||
|
||||
// load themes from user profile dir
|
||||
dir.setPath(SettingsCache::instance().getThemesPath());
|
||||
|
||||
availableThemes.insert(FUSION_THEME_NAME, dir.filePath("Fusion (System Default)"));
|
||||
availableThemes.insert(FUSION_THEME_NAME_LIGHT, dir.filePath("Fusion (Light)"));
|
||||
availableThemes.insert(FUSION_THEME_NAME_DARK, dir.filePath("Fusion (Dark)"));
|
||||
// add default value
|
||||
availableThemes.insert(NONE_THEME_NAME, dir.absoluteFilePath("Default"));
|
||||
|
||||
availableThemes.insert(FUSION_THEME_NAME, dir.absoluteFilePath("Fusion"));
|
||||
|
||||
for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
|
||||
if (!availableThemes.contains(themeName)) {
|
||||
|
|
@ -217,192 +204,112 @@ QBrush ThemeManager::loadExtraBrush(QString fileName, QBrush &fallbackBrush)
|
|||
return brush;
|
||||
}
|
||||
|
||||
static inline QPalette createDarkGreenFusionPalette()
|
||||
ThemeConfig ThemeManager::loadGlobalConfig(const QString &themeDirPath)
|
||||
{
|
||||
QPalette p = QStyleFactory::create("Fusion")->standardPalette();
|
||||
|
||||
// ---------- Core backgrounds ----------
|
||||
p.setColor(QPalette::Window, QColor(30, 30, 30)); // #ff1e1e1e
|
||||
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
|
||||
|
||||
// ---------- Core text ----------
|
||||
p.setColor(QPalette::WindowText, Qt::white); // #ffffffff
|
||||
p.setColor(QPalette::Text, Qt::white); // #ffffffff
|
||||
p.setColor(QPalette::ButtonText, Qt::white); // #ffffffff
|
||||
p.setColor(QPalette::ToolTipText, QColor(212, 212, 212)); // #ffd4d4d4
|
||||
p.setColor(QPalette::PlaceholderText, QColor(255, 255, 255, 128)); // #80ffffff
|
||||
|
||||
// ---------- 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(0, 246, 82)); // #ff00f652
|
||||
p.setColor(QPalette::LinkVisited, QColor(0, 211, 70)); // #ff00d346
|
||||
|
||||
// ---------- Accent (Qt 6) ----------
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
|
||||
p.setColor(QPalette::Accent, QColor(0, 211, 70)); // #ff00d346
|
||||
#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;
|
||||
return ThemeConfig::fromThemeDir(themeDirPath);
|
||||
}
|
||||
|
||||
static inline QPalette createLightGreenFusionPalette()
|
||||
bool ThemeManager::saveGlobalConfig(const QString &themeDirPath, const ThemeConfig &cfg)
|
||||
{
|
||||
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;
|
||||
return cfg.save(themeDirPath);
|
||||
}
|
||||
|
||||
void ThemeManager::themeChangedSlot()
|
||||
PaletteConfig ThemeManager::loadPaletteConfig(const QString &themeDirPath, const QString &colorScheme)
|
||||
{
|
||||
QString themeName = SettingsCache::instance().getThemeName();
|
||||
qCInfo(ThemeManagerLog) << "Theme changed:" << themeName;
|
||||
if (themeDirPath.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
return PaletteConfig::fromScheme(themeDirPath, colorScheme);
|
||||
}
|
||||
|
||||
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 {
|
||||
qApp->setStyleSheet("");
|
||||
bool ThemeManager::savePaletteConfig(const QString &themeDirPath, const QString &colorScheme, const PaletteConfig &cfg)
|
||||
{
|
||||
if (themeDirPath.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QStyle *newStyle = nullptr;
|
||||
QPalette newPalette;
|
||||
QDir dir(themeDirPath);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(".");
|
||||
}
|
||||
|
||||
if (themeName == FUSION_THEME_NAME) {
|
||||
newStyle = QStyleFactory::create("Fusion");
|
||||
QFile f(dir.absoluteFilePath(PaletteConfig::fileName(colorScheme)));
|
||||
if (!f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#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));
|
||||
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;
|
||||
}
|
||||
#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();
|
||||
}
|
||||
|
||||
// Apply palette FIRST.
|
||||
qApp->setPalette(newPalette);
|
||||
// Then apply style.
|
||||
qApp->setStyle(newStyle);
|
||||
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
|
||||
} else {
|
||||
base = qApp->palette();
|
||||
}
|
||||
|
||||
// Overlay custom palette colours
|
||||
if (palCfg.hasPalette()) {
|
||||
base = palCfg.apply(base);
|
||||
}
|
||||
|
||||
// Palette BEFORE style — setStyle() triggers a synchronous repolish of all
|
||||
// widgets immediately. If the palette isn't set yet at that point, every
|
||||
// widget gets polished against the stale colours, requiring a second apply
|
||||
// to fully resolve. Setting palette first means setStyle's repolish cascade
|
||||
// already sees the correct colours.
|
||||
qApp->setPalette(base);
|
||||
qApp->setStyle(style);
|
||||
|
||||
// Force every widget to re-polish and repaint immediately rather than
|
||||
// waiting for natural expose events, which produces a patchwork of old
|
||||
|
|
@ -412,34 +319,57 @@ void ThemeManager::themeChangedSlot()
|
|||
// palette (WA_SetPalette not set). Calling it unconditionally would clobber
|
||||
// intentional per-widget palette customisations across the whole app.
|
||||
for (QWidget *widget : qApp->allWidgets()) {
|
||||
if (widget->isVisible()) {
|
||||
newStyle->unpolish(widget);
|
||||
newStyle->polish(widget);
|
||||
|
||||
widget->update();
|
||||
}
|
||||
style->unpolish(widget);
|
||||
style->polish(widget);
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
if (dirPath.isEmpty()) {
|
||||
// set default values
|
||||
QDir::setSearchPaths("theme", DEFAULT_RESOURCE_PATHS);
|
||||
brushes[Role::Hand] = HANDZONE_BG_DEFAULT;
|
||||
brushes[Role::Table] = TABLEZONE_BG_DEFAULT;
|
||||
brushes[Role::Player] = PLAYERZONE_BG_DEFAULT;
|
||||
brushes[Role::Stack] = STACKZONE_BG_DEFAULT;
|
||||
void ThemeManager::themeChangedSlot()
|
||||
{
|
||||
QString themeName = SettingsCache::instance().getThemeName();
|
||||
QString dirPath = getAvailableThemes().value(themeName);
|
||||
currentThemePath = dirPath;
|
||||
QDir dir(dirPath);
|
||||
|
||||
// CSS
|
||||
if (!dirPath.isEmpty() && dir.exists(STYLE_CSS_NAME)) {
|
||||
qApp->setStyleSheet("file:///" + dir.absoluteFilePath(STYLE_CSS_NAME));
|
||||
} else {
|
||||
// resources
|
||||
QStringList resources;
|
||||
resources << dir.absolutePath() << DEFAULT_RESOURCE_PATHS;
|
||||
QDir::setSearchPaths("theme", resources);
|
||||
|
||||
// zones bg
|
||||
dir.cd("zones");
|
||||
brushes[Role::Hand] = loadBrush(HANDZONE_BG_NAME, HANDZONE_BG_DEFAULT);
|
||||
brushes[Role::Table] = loadBrush(TABLEZONE_BG_NAME, TABLEZONE_BG_DEFAULT);
|
||||
brushes[Role::Player] = loadBrush(PLAYERZONE_BG_NAME, PLAYERZONE_BG_DEFAULT);
|
||||
brushes[Role::Stack] = loadBrush(STACKZONE_BG_NAME, STACKZONE_BG_DEFAULT);
|
||||
qApp->setStyleSheet("");
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (!dirPath.isEmpty()) {
|
||||
resources << dir.absolutePath();
|
||||
}
|
||||
resources << DEFAULT_RESOURCE_PATHS;
|
||||
|
||||
QDir::setSearchPaths("theme", resources);
|
||||
|
||||
brushes[Role::Hand] = loadBrush(HANDZONE_BG_NAME, HANDZONE_BG_DEFAULT);
|
||||
|
||||
brushes[Role::Table] = loadBrush(TABLEZONE_BG_NAME, TABLEZONE_BG_DEFAULT);
|
||||
|
||||
brushes[Role::Player] = loadBrush(PLAYERZONE_BG_NAME, PLAYERZONE_BG_DEFAULT);
|
||||
|
||||
brushes[Role::Stack] = loadBrush(STACKZONE_BG_NAME, STACKZONE_BG_DEFAULT);
|
||||
for (auto &brushCache : brushesCache) {
|
||||
brushCache.clear();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue