diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt
index 63ccc4e9c..4263fc6e2 100644
--- a/cockatrice/CMakeLists.txt
+++ b/cockatrice/CMakeLists.txt
@@ -403,6 +403,7 @@ set(cockatrice_SOURCES
src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp
src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.cpp
src/interface/widgets/onboarding/banner_shader_config.h
+ src/interface/widgets/onboarding/brand_colors.h
src/interface/widgets/onboarding/first_run_wizard.cpp
src/interface/widgets/onboarding/first_run_wizard.h
src/interface/widgets/onboarding/first_run_wizard_page.cpp
@@ -530,6 +531,7 @@ qt6_add_shaders(
"src/interface/widgets/onboarding/shaders"
FILES
src/interface/widgets/onboarding/shaders/brand_banner.frag
+ src/interface/widgets/onboarding/shaders/brand_plate.frag
)
qt6_add_resources(
diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index e21bdb0be..49c3f27b5 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -63,6 +63,8 @@
resources/icons/mana/W.svg
resources/backgrounds/home.png
+ resources/backgrounds/home-dark.png
+ resources/backgrounds/home-light.png
resources/backgrounds/card_triplet.svg
resources/backgrounds/placeholder_printing_selector.svg
diff --git a/cockatrice/resources/backgrounds/home-dark.png b/cockatrice/resources/backgrounds/home-dark.png
new file mode 100644
index 000000000..68f48e2c2
Binary files /dev/null and b/cockatrice/resources/backgrounds/home-dark.png differ
diff --git a/cockatrice/resources/backgrounds/home-light.png b/cockatrice/resources/backgrounds/home-light.png
new file mode 100644
index 000000000..eaaaba932
Binary files /dev/null and b/cockatrice/resources/backgrounds/home-light.png differ
diff --git a/cockatrice/resources/backgrounds/home.png b/cockatrice/resources/backgrounds/home.png
index 68f48e2c2..eaaaba932 100644
Binary files a/cockatrice/resources/backgrounds/home.png and b/cockatrice/resources/backgrounds/home.png differ
diff --git a/cockatrice/src/interface/theme_config.cpp b/cockatrice/src/interface/theme_config.cpp
index 4420eefe1..8293a82cf 100644
--- a/cockatrice/src/interface/theme_config.cpp
+++ b/cockatrice/src/interface/theme_config.cpp
@@ -16,7 +16,7 @@ QString ThemeConfig::toIni() const
out += "[Appearance]\n";
out += QString("ColorScheme = %1\n").arg(colorScheme.isEmpty() ? "System" : colorScheme);
out += "\n[Style]\n";
- out += QString("Name = %1\n").arg(styleName.isEmpty() ? "Default" : styleName);
+ out += QString("Name = %1\n").arg(styleName.isEmpty() ? "System" : styleName);
return out;
}
diff --git a/cockatrice/src/interface/theme_manager.cpp b/cockatrice/src/interface/theme_manager.cpp
index da9f14408..d86ed77f9 100644
--- a/cockatrice/src/interface/theme_manager.cpp
+++ b/cockatrice/src/interface/theme_manager.cpp
@@ -22,7 +22,7 @@
#include
#include
-#define NONE_THEME_NAME "Default"
+#define SYSTEM_THEME_NAME "System"
#define FUSION_THEME_NAME "Fusion"
#define STYLE_CSS_NAME "style.css"
#define HANDZONE_BG_NAME "handzone"
@@ -96,7 +96,7 @@ struct PaletteColorInfo
static QString usableDefaultStyle(const QString &style)
{
// The Windows 11 native style is broken: when the OS default
- // ("Default" theme selection) would use it, fall back to the Vista style.
+ // ("System" theme selection) would use it, fall back to the Vista style.
// Explicitly choosing "windows11" in a theme is still honored.
return style.compare("windows11", Qt::CaseInsensitive) == 0 ? QStringLiteral("windowsvista") : style;
}
@@ -119,10 +119,16 @@ ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
void ThemeManager::ensureThemeDirectoryExists()
{
- if (SettingsCache::instance().getThemeName().isEmpty() ||
- !getAvailableThemes().contains(SettingsCache::instance().getThemeName())) {
+ auto &settings = SettingsCache::instance();
+
+ // Migrate the old "Default" theme name to "System"
+ if (settings.getThemeName() == "Default") {
+ settings.setThemeName(SYSTEM_THEME_NAME);
+ }
+
+ if (settings.getThemeName().isEmpty() || !getAvailableThemes().contains(settings.getThemeName())) {
qCInfo(ThemeManagerLog) << "Theme name not set, setting default value";
- SettingsCache::instance().setThemeName(NONE_THEME_NAME);
+ settings.setThemeName(FUSION_THEME_NAME);
}
}
@@ -235,9 +241,7 @@ QStringMap &ThemeManager::getAvailableThemes()
// load themes from user profile dir
dir.setPath(SettingsCache::instance().paths().getThemesPath());
- // add default value
- availableThemes.insert(NONE_THEME_NAME, dir.absoluteFilePath("Default"));
-
+ availableThemes.insert(SYSTEM_THEME_NAME, dir.absoluteFilePath("System"));
availableThemes.insert(FUSION_THEME_NAME, dir.absoluteFilePath("Fusion"));
for (QString themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
@@ -395,7 +399,7 @@ void ThemeManager::applyStyleAndPalette(const QString &themeName,
Q_UNUSED(activeScheme)
#endif
QString styleName = themeCfg.styleName;
- if (styleName.isEmpty() || styleName.compare("Default", Qt::CaseInsensitive) == 0) {
+ if (styleName.isEmpty() || styleName.compare("System", Qt::CaseInsensitive) == 0) {
if (themeName == FUSION_THEME_NAME) {
styleName = "Fusion";
} else {
diff --git a/cockatrice/src/interface/widgets/general/home_widget.cpp b/cockatrice/src/interface/widgets/general/home_widget.cpp
index 27fd065a5..648d315f9 100644
--- a/cockatrice/src/interface/widgets/general/home_widget.cpp
+++ b/cockatrice/src/interface/widgets/general/home_widget.cpp
@@ -11,6 +11,8 @@
#include "home_tab_button_color.h"
#include
+#include
+#include
#include
#include
#include
@@ -21,8 +23,7 @@
#include
HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
- : QWidget(parent), tabSupervisor(_tabSupervisor), background(themePixmap(QStringLiteral("backgrounds/home"))),
- overlay(themePixmap(QStringLiteral("cockatrice")))
+ : QWidget(parent), tabSupervisor(_tabSupervisor), background(themePixmap(QStringLiteral("backgrounds/home")))
{
layout = new QGridLayout(this);
@@ -54,6 +55,8 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
// Lambda is cleaner to read than overloading this
connect(&SettingsCache::instance().appearance(), &AppearanceSettings::homeTabDisplayCardNameChanged, this,
[this] { repaint(); });
+ connect(&SettingsCache::instance().appearance(), &AppearanceSettings::homeTabBackgroundDimChanged, this,
+ [this] { repaint(); });
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this,
&HomeWidget::initializeBackgroundFromSource);
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this,
@@ -62,12 +65,17 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
// not on SettingsCache::themeChanged, so re-resolve the variant background.
connect(themeManager, &ThemeManager::themeChanged, this, &HomeWidget::initializeBackgroundFromSource);
connect(themeManager, &ThemeManager::paletteChanged, this, &HomeWidget::updateButtonsToBackgroundColor);
+ connect(themeManager, &ThemeManager::paletteChanged, this, &HomeWidget::updateLogoOverlay);
connect(&SettingsCache::instance().appearance(), &AppearanceSettings::homeTabButtonColorChanged, this,
&HomeWidget::updateButtonsToBackgroundColor);
}
void HomeWidget::initializeBackgroundFromSource()
{
+ // The featured logo is theme/scheme-derived too; reload it alongside the
+ // background so a theme or appearance switch doesn't leave it stale.
+ updateLogoOverlay();
+
if (CardDatabaseManager::getInstance()->getLoadStatus() != LoadStatus::Ok) {
connect(CardDatabaseManager::getInstance(), &CardDatabase::cardDatabaseLoadingFinished, this,
&HomeWidget::initializeBackgroundFromSource);
@@ -227,10 +235,10 @@ QGroupBox *HomeWidget::createButtons()
QVBoxLayout *boxLayout = new QVBoxLayout;
boxLayout->setAlignment(Qt::AlignHCenter);
- QLabel *logoLabel = new QLabel;
- logoLabel->setPixmap(overlay.scaledToWidth(200, Qt::SmoothTransformation));
+ logoLabel = new QLabel;
logoLabel->setAlignment(Qt::AlignCenter);
boxLayout->addWidget(logoLabel);
+ updateLogoOverlay();
boxLayout->addSpacing(25);
connectButton = new HomeStyledButton("Connect/Play", gradientColors);
@@ -358,13 +366,15 @@ void HomeWidget::paintEvent(QPaintEvent *event)
painter.drawPixmap(topLeft, toDraw);
}
- // Draw translucent black overlay with rounded corners
- QRectF overlayRect(5, 5, width() - 10, height() - 10);
- QPainterPath roundedRectPath;
- roundedRectPath.addRoundedRect(overlayRect, 20, 20);
+ if (SettingsCache::instance().appearance().getHomeTabBackgroundDim()) {
+ // Draw translucent black overlay with rounded corners
+ QRectF overlayRect(5, 5, width() - 10, height() - 10);
+ QPainterPath roundedRectPath;
+ roundedRectPath.addRoundedRect(overlayRect, 20, 20);
- QColor semiTransparentBlack(0, 0, 0, static_cast(255 * 0.33));
- painter.fillPath(roundedRectPath, semiTransparentBlack);
+ QColor semiTransparentBlack(0, 0, 0, static_cast(255 * 0.33));
+ painter.fillPath(roundedRectPath, semiTransparentBlack);
+ }
// Card name overlay (above the attribution, bottom-right)
QString cardName;
@@ -429,3 +439,56 @@ void HomeWidget::paintEvent(QPaintEvent *event)
QWidget::paintEvent(event);
}
+
+void HomeWidget::updateLogoOverlay()
+{
+ // Emulate cockatrice.svg in Qt rather than rendering the baked-in SVG.
+ // The SVG has no separate plate: the gradient fills the bird's silhouette
+ // paths (light #c9fd62/AccentSoft at the top-left, dark #139740/AccentStrong
+ // toward the bottom-right — the SVG's linearGradient4265-7-8 stops along
+ // its userSpaceOnUse axis), and the white highlight path
+ // (cockatrice-logo-white) sits on top. So we paint that gradient clipped to
+ // the full logo silhouette (the full-color logo's alpha), then overlay the
+ // white mark. Colours stay fully theme-driven and independent of the static
+ // greens baked into the SVG.
+ const QColor strong = themeManager->appColor(AppColor::AccentStrong);
+ const QColor soft = themeManager->appColor(AppColor::AccentSoft);
+
+ const QPixmap silhouette = themePixmap(QStringLiteral("cockatrice")).scaledToWidth(200, Qt::SmoothTransformation);
+ const QPixmap whiteMark =
+ themePixmap(QStringLiteral("cockatrice-logo-white")).scaledToWidth(200, Qt::SmoothTransformation);
+ if (silhouette.isNull() || whiteMark.isNull()) {
+ return;
+ }
+
+ QPixmap composite(silhouette.size());
+ composite.fill(Qt::transparent);
+
+ {
+ QPainter painter(&composite);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+
+ // Recreate cockatrice.svg's own gradient geometry (linearGradient
+ // 4265-7-8, userSpaceOnUse): light AccentSoft at S=(-8.097,-97.746),
+ // dark AccentStrong at E=(162.455,295.208), on the SVG's 300x300
+ // canvas. Scale those coordinates to this composite's size.
+ const qreal scale = composite.width() / 300.0;
+ QLinearGradient gradient(QPointF(-8.097, -97.746) * scale, QPointF(162.455, 295.208) * scale);
+ gradient.setColorAt(0.0, soft);
+ gradient.setColorAt(1.0, strong);
+ painter.fillRect(composite.rect(), gradient);
+
+ // Clip the gradient to the full logo silhouette exactly as the SVG's
+ // gradient paths are confined to the bird.
+ painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ painter.drawPixmap(0, 0, silhouette);
+
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ painter.drawPixmap(0, 0, whiteMark);
+ }
+
+ if (logoLabel) {
+ logoLabel->setPixmap(composite);
+ }
+}
diff --git a/cockatrice/src/interface/widgets/general/home_widget.h b/cockatrice/src/interface/widgets/general/home_widget.h
index 9df0d7b6a..1cadc4a67 100644
--- a/cockatrice/src/interface/widgets/general/home_widget.h
+++ b/cockatrice/src/interface/widgets/general/home_widget.h
@@ -15,6 +15,9 @@
#include
#include
+class QGridLayout;
+class QLabel;
+
class HomeWidget : public QWidget
{
@@ -41,13 +44,14 @@ private:
QPixmap background;
CardInfoPictureArtCropWidget *backgroundSourceCard = nullptr;
DeckList backgroundSourceDeck;
- QPixmap overlay;
+ QLabel *logoLabel = nullptr;
QPair gradientColors;
HomeStyledButton *connectButton;
void setRandomCard(ExactCard &newCard);
void loadBackgroundSourceDeck();
QPair determineButtonColor() const;
+ void updateLogoOverlay();
};
#endif // HOME_WIDGET_H
diff --git a/cockatrice/src/interface/widgets/onboarding/banner_shader_config.h b/cockatrice/src/interface/widgets/onboarding/banner_shader_config.h
index 32f3e89c0..6008044ff 100644
--- a/cockatrice/src/interface/widgets/onboarding/banner_shader_config.h
+++ b/cockatrice/src/interface/widgets/onboarding/banner_shader_config.h
@@ -38,6 +38,10 @@ class BannerShaderConfig : public QObject
Q_PROPERTY(QColor colorA READ colorA WRITE setColorA NOTIFY colorAChanged)
Q_PROPERTY(QColor colorB READ colorB WRITE setColorB NOTIFY colorBChanged)
Q_PROPERTY(QColor accent READ accent WRITE setAccent NOTIFY accentChanged)
+ Q_PROPERTY(QColor glowColor READ glowColor WRITE setGlowColor NOTIFY glowColorChanged)
+ Q_PROPERTY(QColor brandStrong READ brandStrong WRITE setBrandStrong NOTIFY brandStrongChanged)
+ Q_PROPERTY(QColor brandSoft READ brandSoft WRITE setBrandSoft NOTIFY brandSoftChanged)
+ Q_PROPERTY(qreal vignetteMin READ vignetteMin WRITE setVignetteMin NOTIFY vignetteMinChanged)
Q_PROPERTY(bool logoVisible READ logoVisible WRITE setLogoVisible NOTIFY logoVisibleChanged)
Q_PROPERTY(qreal logoGlow READ logoGlow WRITE setLogoGlow NOTIFY logoGlowChanged)
@@ -185,6 +189,54 @@ public:
}
}
+ QColor glowColor() const
+ {
+ return m_glowColor;
+ }
+ void setGlowColor(const QColor &c)
+ {
+ if (c != m_glowColor) {
+ m_glowColor = c;
+ emit glowColorChanged();
+ }
+ }
+
+ QColor brandStrong() const
+ {
+ return m_brandStrong;
+ }
+ void setBrandStrong(const QColor &c)
+ {
+ if (c != m_brandStrong) {
+ m_brandStrong = c;
+ emit brandStrongChanged();
+ }
+ }
+
+ QColor brandSoft() const
+ {
+ return m_brandSoft;
+ }
+ void setBrandSoft(const QColor &c)
+ {
+ if (c != m_brandSoft) {
+ m_brandSoft = c;
+ emit brandSoftChanged();
+ }
+ }
+
+ qreal vignetteMin() const
+ {
+ return m_vignetteMin;
+ }
+ void setVignetteMin(qreal v)
+ {
+ if (v != m_vignetteMin) {
+ m_vignetteMin = v;
+ emit vignetteMinChanged();
+ }
+ }
+
bool logoVisible() const
{
return m_logoVisible;
@@ -222,6 +274,10 @@ signals:
void colorAChanged();
void colorBChanged();
void accentChanged();
+ void glowColorChanged();
+ void brandStrongChanged();
+ void brandSoftChanged();
+ void vignetteMinChanged();
void logoVisibleChanged();
void logoGlowChanged();
@@ -239,9 +295,16 @@ private:
bool m_frontIsA = true;
+ // Curated fallback seed values -- BannerHost overwrites these with
+ // palette-derived colours (see shader_banner_widget.cpp) before the first
+ // paint, so they only matter as a safe pre-first-apply default.
QColor m_colorA{0x1A, 0x1A, 0x20};
QColor m_colorB{0x0E, 0x0E, 0x12};
QColor m_accent{0x8B, 0xDD, 0x6B};
+ QColor m_glowColor{Qt::white};
+ QColor m_brandStrong{0x13, 0x97, 0x40};
+ QColor m_brandSoft{0xC9, 0xFD, 0x62};
+ qreal m_vignetteMin = 0.62;
bool m_logoVisible = false;
qreal m_logoGlow = 1.0;
diff --git a/cockatrice/src/interface/widgets/onboarding/brand_colors.h b/cockatrice/src/interface/widgets/onboarding/brand_colors.h
new file mode 100644
index 000000000..bf173270b
--- /dev/null
+++ b/cockatrice/src/interface/widgets/onboarding/brand_colors.h
@@ -0,0 +1,15 @@
+#ifndef BRAND_COLORS_H
+#define BRAND_COLORS_H
+
+#include
+
+/** @brief Cockatrice brand green.
+ *
+ * Single source of truth for the onboarding brand accent: it backs the
+ * banner's shader-accent uniform as the curated fallback when the active
+ * palette resolves no usable Highlight, and it preseads the wizard's
+ * QuickSetupPanel so a freshly generated palette keeps the brand identity
+ * until the user picks their own look. */
+inline const QColor kCockatriceBrandGreen(0x8B, 0xDD, 0x6B);
+
+#endif // BRAND_COLORS_H
\ No newline at end of file
diff --git a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp
index 3293b19ac..797fe4425 100644
--- a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp
+++ b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp
@@ -14,10 +14,31 @@
#include
#include
#include
+#include
#include
#include
#include
+namespace
+{
+/** @brief A theme's shipped identity accent, immune to any user- or auto-
+ * generated palette that may currently be masking appColor(). */
+QColor themeIdentityAccent(const QString &themeDirPath, const QString &themeName)
+{
+ for (const QString &scheme : {QStringLiteral("Light"), QStringLiteral("Dark")}) {
+ const PaletteConfig cfg = ThemeManager::loadDefaultPaletteConfig(themeDirPath, themeName, scheme);
+ if (cfg.appColors.contains(AppColor::AccentStrong)) {
+ return cfg.appColors.value(AppColor::AccentStrong);
+ }
+ const QColor highlight = cfg.colors.value(QPalette::Active).value(QPalette::Highlight);
+ if (highlight.isValid()) {
+ return highlight;
+ }
+ }
+ return {};
+}
+} // namespace
+
ThemeSetupPage::ThemeSetupPage(QWidget *parent) : FirstRunWizardPage(parent)
{
themeCombo = new QComboBox(this);
@@ -30,6 +51,15 @@ ThemeSetupPage::ThemeSetupPage(QWidget *parent) : FirstRunWizardPage(parent)
quickSetupPanel = new QuickSetupPanel(this);
+ // Seed the picker from the current theme's own identity accent rather than
+ // a hardcoded brand green: Plasma seeds violet, Fusion green, etc., and it
+ // is immune to stale generated palettes that may mask appColor(). This was
+ // initially a brand-green workaround from before Fusion became the default.
+ // setAccentColor blocks signals, so this never triggers a generation.
+ lastSeededTheme = SettingsCache::instance().getThemeName();
+ quickSetupPanel->setAccentColor(
+ themeIdentityAccent(themeManager->getAvailableThemes().value(lastSeededTheme), lastSeededTheme));
+
connect(themeCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeSetupPage::onThemeChanged);
connect(schemeCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeSetupPage::onSchemeChanged);
connect(quickSetupPanel, &QuickSetupPanel::valueChanged, this, &ThemeSetupPage::onGenerateFromAccent);
@@ -47,7 +77,8 @@ ThemeSetupPage::ThemeSetupPage(QWidget *parent) : FirstRunWizardPage(parent)
// Mirrors AppearanceSettingsPage's identical listener for the combo-sync
// half of this.
connect(themeManager, &ThemeManager::themeChanged, this, [this] {
- const QString newDir = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName());
+ const QString newTheme = SettingsCache::instance().getThemeName();
+ const QString newDir = themeManager->getAvailableThemes().value(newTheme);
const ThemeConfig cfg = ThemeConfig::fromThemeDir(newDir);
const QString current = cfg.colorScheme;
@@ -56,6 +87,14 @@ ThemeSetupPage::ThemeSetupPage(QWidget *parent) : FirstRunWizardPage(parent)
schemeCombo->setCurrentIndex(idx >= 0 ? idx : 0);
schemeCombo->blockSignals(false);
+ // Keep the picker's accent in step with the theme's own identity; the
+ // swatch seeded at construction would otherwise stay stale (e.g. green
+ // from a previous theme) when the user toggles themes.
+ if (newTheme != lastSeededTheme) {
+ lastSeededTheme = newTheme;
+ quickSetupPanel->setAccentColor(themeIdentityAccent(newDir, newTheme));
+ }
+
maybeAutoGeneratePalette();
});
@@ -158,8 +197,14 @@ void ThemeSetupPage::maybeAutoGeneratePalette()
const QString dirPath = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName());
const QString scheme = resolvedScheme();
+ // The theme dir may resolve to the user profile even for built-in themes
+ // (getAvailableThemes gives the user copy precedence), so consult the
+ // shipped palette too -- both via loadDefaultPaletteConfig's system fallback.
+ // Without it, scheme flips regenerate a fresh palette from the picker accent
+ // and clobber the curated colours the theme explicitly ships.
if (PaletteConfig::fromScheme(dirPath, scheme).hasPalette() ||
- PaletteConfig::fromDefault(dirPath, scheme).hasPalette()) {
+ ThemeManager::loadDefaultPaletteConfig(dirPath, SettingsCache::instance().getThemeName(), scheme)
+ .hasPalette()) {
return; // theme already has something real to show -- leave it alone
}
diff --git a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h
index d1f84c1b9..16a3c9a5d 100644
--- a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h
+++ b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h
@@ -53,6 +53,9 @@ private:
QComboBox *homeTabBackgroundCombo;
bool paletteDirty = false;
+
+ /// Theme whose identity accent currently seeds the picker.
+ QString lastSeededTheme;
};
#endif // THEME_SETUP_PAGE_H
diff --git a/cockatrice/src/interface/widgets/onboarding/qml/BrandBanner.qml b/cockatrice/src/interface/widgets/onboarding/qml/BrandBanner.qml
index f1a385cad..d94e15280 100644
--- a/cockatrice/src/interface/widgets/onboarding/qml/BrandBanner.qml
+++ b/cockatrice/src/interface/widgets/onboarding/qml/BrandBanner.qml
@@ -16,6 +16,8 @@ Item {
property vector4d uColorA: Qt.vector4d(bannerConfig.colorA.r, bannerConfig.colorA.g, bannerConfig.colorA.b, 1.0)
property vector4d uColorB: Qt.vector4d(bannerConfig.colorB.r, bannerConfig.colorB.g, bannerConfig.colorB.b, 1.0)
property vector4d uAccent: Qt.vector4d(bannerConfig.accent.r, bannerConfig.accent.g, bannerConfig.accent.b, 1.0)
+ property vector4d uGlowColor: Qt.vector4d(bannerConfig.glowColor.r, bannerConfig.glowColor.g, bannerConfig.glowColor.b, 1.0)
+ property real uVignetteMin: bannerConfig.vignetteMin
property real uLogoGlow: bannerConfig.logoGlow
fragmentShader: "qrc:/onboarding/shaders/brand_banner.frag.qsb"
}
@@ -33,30 +35,62 @@ Item {
property vector4d uColorA: Qt.vector4d(bannerConfig.colorA.r, bannerConfig.colorA.g, bannerConfig.colorA.b, 1.0)
property vector4d uColorB: Qt.vector4d(bannerConfig.colorB.r, bannerConfig.colorB.g, bannerConfig.colorB.b, 1.0)
property vector4d uAccent: Qt.vector4d(bannerConfig.accent.r, bannerConfig.accent.g, bannerConfig.accent.b, 1.0)
+ property vector4d uGlowColor: Qt.vector4d(bannerConfig.glowColor.r, bannerConfig.glowColor.g, bannerConfig.glowColor.b, 1.0)
+ property real uVignetteMin: bannerConfig.vignetteMin
property real uLogoGlow: bannerConfig.logoGlow
fragmentShader: "qrc:/onboarding/shaders/brand_banner.frag.qsb"
}
- // The hero logo itself — breathes cleanly over a 0.5–1.0 opacity range
- Image {
- id: logo
- anchors.centerIn: parent
+ // The white logo sits at full opacity on top of the static gradient plate —
+ // no glow, no breathing. The plate matches home_widget's QPainter composite.
+ Item {
+ id: logoHost
visible: bannerConfig.logoVisible
- source: "qrc:/resources/cockatrice-logo-white.svg"
+ anchors.centerIn: parent
width: root.height * 0.6
- height: width * (sourceSize.height > 0 ? sourceSize.height / Math.max(sourceSize.width, 1) : 1)
- fillMode: Image.PreserveAspectFit
- smooth: true
- opacity: 0.5 + 0.5 * bannerConfig.logoGlow
- sourceSize: Qt.size(256, 256)
+ height: width
- Behavior on opacity { NumberAnimation { duration: 300; easing.type: Easing.InOutSine } }
+ // The full-color logo renders beneath the white mark and is consumed as
+ // a texture (layer.enabled) by the plate shader's silhouette mask, so
+ // the gradient is clipped to the bird exactly as the SVG's gradient
+ // paths are. It is never drawn to the screen itself.
+ Image {
+ id: silhouetteMask
+ anchors.fill: parent
+ source: "qrc:/resources/cockatrice.svg"
+ sourceSize: Qt.size(256, 256)
+ fillMode: Image.PreserveAspectFit
+ smooth: true
+ visible: false
+ layer.enabled: true
+ layer.smooth: true
+ }
- transform: Scale {
- origin.x: logo.width / 2
- origin.y: logo.height / 2
- xScale: 0.94 + 0.06 * bannerConfig.logoGlow
- yScale: 0.94 + 0.06 * bannerConfig.logoGlow
+ // The logo's gradient plate, drawn behind the mark: a linear
+ // AccentSoft (light) -> AccentStrong (dark) sheet along the same
+ // top-left -> bottom-right userSpaceOnUse axis the baked-in SVG used,
+ // clipped to the bird silhouette via uSilhouette. The white highlight
+ // path above is theme independent. Sized to the logo itself — no
+ // rounded badge, matching home_widget's QPainter composite. Static.
+ // Small ShaderEffect, Qt 6.4-safe.
+ ShaderEffect {
+ id: brandPlate
+ anchors.fill: parent
+ property vector4d uStrong: Qt.vector4d(bannerConfig.brandStrong.r, bannerConfig.brandStrong.g,
+ bannerConfig.brandStrong.b, 1.0)
+ property vector4d uSoft: Qt.vector4d(bannerConfig.brandSoft.r, bannerConfig.brandSoft.g,
+ bannerConfig.brandSoft.b, 1.0)
+ property var uSilhouette: silhouetteMask
+ fragmentShader: "qrc:/onboarding/shaders/brand_plate.frag.qsb"
+ }
+
+ Image {
+ id: logoImage
+ anchors.fill: parent
+ source: "qrc:/resources/cockatrice-logo-white.svg"
+ sourceSize: Qt.size(256, 256)
+ fillMode: Image.PreserveAspectFit
+ smooth: true
}
}
-}
+}
\ No newline at end of file
diff --git a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp
index fd1fb2a98..0b9f65783 100644
--- a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp
+++ b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp
@@ -1,7 +1,10 @@
#include "shader_banner_widget.h"
+#include "../../theme_manager.h"
#include "banner_shader_config.h"
+#include "brand_colors.h"
+#include
#include
#include
#include
@@ -11,11 +14,98 @@
namespace
{
-// Near-black base palette -- the background is dark and quiet so the green
-// accent stands out.
-constexpr QRgb kColorA = 0x1A1A20;
-constexpr QRgb kColorB = 0x0E0E12;
-constexpr QRgb kAccent = 0x8BDD6B;
+// Curated near-black stage -- used only when the active palette resolves no
+// usable window colour. Matches the banner's original design (dark and quiet
+// so the accent stands out) and satisfies design-plans §2.1's "identity
+// survives a bare palette".
+constexpr QRgb kFallbackColorA = 0x1A1A20;
+constexpr QRgb kFallbackColorB = 0x0E0E12;
+
+struct SuggestedColors
+{
+ QColor colorA;
+ QColor colorB;
+ QColor accent;
+ QColor glowColor;
+ QColor brandStrong;
+ QColor brandSoft;
+ qreal vignetteMin = 0.62;
+};
+
+SuggestedColors suggestedBannerColors()
+{
+ const QPalette &pal = qApp->palette();
+ const QColor window = pal.color(QPalette::Active, QPalette::Window);
+ // Identity accent: the theme's [AppColors] AccentStrong, which appColor()
+ // resolves to QPalette::Highlight when a theme doesn't pin AccentStrong.
+ // Reading bare Highlight ignored curated accent tokens (Plasma's violet
+ // vs Default's green) whenever a palette didn't set the role itself.
+ const QColor accentStrong = themeManager->appColor(AppColor::AccentStrong);
+ if (!window.isValid() || !accentStrong.isValid()) {
+ return {QColor(kFallbackColorA),
+ QColor(kFallbackColorB),
+ kCockatriceBrandGreen,
+ QColor(Qt::white),
+ kCockatriceBrandGreen,
+ QColor(0xC9, 0xFD, 0x62),
+ 0.62};
+ }
+
+ // The theme's brand pair: AccentStrong is the deep green, AccentSoft the
+ // lime. These two appColors form the logo's "surrounding gradient" (deep
+ // core grading out to the soft, brand-toned glow) on both the banner and
+ // the home screen.
+ const QColor brandStrong = accentStrong;
+ const QColor brandSoft = themeManager->appColor(AppColor::AccentSoft);
+
+ // Dress the stage for the scheme so the banner never fights the
+ // surrounding window in either mode. Dark palettes keep the original
+ // quiet near-black stage (lightness 29 → 16) with the theme's window
+ // hue; light palettes get a pastel "frosted accent" treatment built from
+ // the accent hue instead of a plain near-white copy: a coloured wash that
+ // clearly belongs to the theme.
+ const qreal luma = 0.299 * window.red() + 0.587 * window.green() + 0.114 * window.blue();
+ const bool lightStage = luma > 115.0;
+ if (lightStage) {
+ const int hue = accentStrong.hslHue();
+ // Achromatic accents (grey) get a neutral near-white stage instead.
+ const int stageSat = hue < 0 ? 0 : 64;
+ const int hueSafe = hue < 0 ? 0 : hue;
+ // Depth is what stops a light stage reading as a washed-out near-white
+ // copy of the page behind the banner: deepen the lower pastel band and
+ // raise saturation so the hue is clearly present while staying frosted.
+ auto pastel = [hueSafe, stageSat](int lightness) { return QColor::fromHsl(hueSafe, stageSat, lightness); };
+ auto pastelLower = [hueSafe](int lightness) { return QColor::fromHsl(hueSafe, 76, lightness); };
+ // Brightness-lifted accent for additive glows: the raw accent on a
+ // light stage must be mid-bright to read instead of washing out, so
+ // lift lightness and saturation together.
+ const int accentLightness = qBound(158, accentStrong.lightness() + 82, 198);
+ const int accentSaturation = hue < 0 ? 0 : qMax(accentStrong.hslSaturation(), 180);
+ const QColor liftedAccent =
+ hue < 0 ? accentStrong : QColor::fromHsl(hueSafe, accentSaturation, accentLightness);
+ // The centre glow (and logo tint in QML) uses the deep accent itself:
+ // a coloured halo/fill behind the logo instead of a white or black one.
+ return {pastel(214), pastelLower(186), liftedAccent, accentStrong, brandStrong, brandSoft, 0.80};
+ }
+
+ // Dark stage: force the window hue down to the banner's curated darkness,
+ // scaling saturation away so chromatic palettes tint it without going
+ // muddy. The accent is the bright, brand-driven tone (hue from the accent
+ // itself, never the -- often grey -- window), and it drives both the
+ // embers/fog and the logo glow so the mark tints like the light stage.
+ auto stage = [&window](int lightness) {
+ const int hue = window.hslHue();
+ const int saturation = hue < 0 ? 0 : qBound(0, qRound(window.hslSaturation() * (lightness / 40.0)), 255);
+ return QColor::fromHsl(hue, saturation, lightness);
+ };
+ const int accentHue = accentStrong.hslHue();
+ const int accentHueSafe = accentHue < 0 ? 0 : accentHue;
+ const int accentLightness = qBound(150, accentStrong.lightness() + 70, 185);
+ const int accentSaturation = accentHue < 0 ? 0 : qMax(accentStrong.hslSaturation(), 160);
+ const QColor accent =
+ accentHue < 0 ? accentStrong : QColor::fromHsl(accentHueSafe, accentSaturation, accentLightness);
+ return {stage(29), stage(16), accent, accent, brandStrong, brandSoft, 0.62};
+}
} // namespace
class GradientFallbackWidget : public QWidget
@@ -23,15 +113,27 @@ class GradientFallbackWidget : public QWidget
public:
using QWidget::QWidget;
+ void setColors(const QColor &a, const QColor &b)
+ {
+ if (a != colorA || b != colorB) {
+ colorA = a;
+ colorB = b;
+ }
+ }
+
protected:
void paintEvent(QPaintEvent *) override
{
QPainter painter(this);
QLinearGradient gradient(0, 0, width(), height());
- gradient.setColorAt(0.0, QColor(kColorA));
- gradient.setColorAt(1.0, QColor(kColorB));
+ gradient.setColorAt(0.0, colorA);
+ gradient.setColorAt(1.0, colorB);
painter.fillRect(rect(), gradient);
}
+
+private:
+ QColor colorA{QColor(kFallbackColorA)};
+ QColor colorB{QColor(kFallbackColorB)};
};
BannerHost::BannerHost(QWidget *parent) : QWidget(parent)
@@ -62,6 +164,9 @@ BannerHost::BannerHost(QWidget *parent) : QWidget(parent)
connect(&clock, &QTimer::timeout, this, &BannerHost::tick);
clock.setInterval(16); // ~60fps; the shader itself is cheap, this is just a wall clock
+ connect(themeManager, &ThemeManager::themeChanged, this, &BannerHost::applyThemeColors);
+ applyThemeColors();
+
applyMotifPreset(currentMotif);
updateAspect();
}
@@ -123,9 +228,9 @@ void BannerHost::applyMotifPreset(Motif motif)
const Preset p = presetFor(motif);
- config->setColorA(QColor(kColorA));
- config->setColorB(QColor(kColorB));
- config->setAccent(QColor(kAccent));
+ config->setColorA(bannerColorA);
+ config->setColorB(bannerColorB);
+ config->setAccent(bannerAccent);
config->setLogoVisible(motif == Motif::Welcome);
if (isFirstApply) {
@@ -183,8 +288,34 @@ void BannerHost::hideEvent(QHideEvent *event)
clock.stop();
}
+void BannerHost::applyThemeColors()
+{
+ const SuggestedColors colors = suggestedBannerColors();
+ bannerColorA = colors.colorA;
+ bannerColorB = colors.colorB;
+ bannerAccent = colors.accent;
+
+ if (usingFallback) {
+ fallback->setColors(bannerColorA, bannerColorB);
+ fallback->update();
+ } else if (config) {
+ config->setColorA(bannerColorA);
+ config->setColorB(bannerColorB);
+ config->setAccent(bannerAccent);
+ config->setGlowColor(colors.glowColor);
+ config->setBrandStrong(colors.brandStrong);
+ config->setBrandSoft(colors.brandSoft);
+ config->setVignetteMin(colors.vignetteMin);
+ }
+}
+
void BannerHost::tick()
{
+ // Palette previews (e.g. accent drags in the wizard's QuickSetupPanel)
+ // apply qApp->palette() without firing themeChanged, so re-derive here;
+ // BannerShaderConfig's setters are equality-guarded, so this is a no-op
+ // unless the colours actually changed.
+ applyThemeColors();
if (config) {
qreal t = elapsed.elapsed() / 1000.0;
config->setTime(t);
diff --git a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h
index 2e230ad7f..ac47b1141 100644
--- a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h
+++ b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h
@@ -1,6 +1,7 @@
#ifndef SHADER_BANNER_WIDGET_H
#define SHADER_BANNER_WIDGET_H
+#include
#include
#include
#include
@@ -53,6 +54,7 @@ protected:
private slots:
void tick();
void onSceneGraphFailed();
+ void applyThemeColors();
private:
struct Preset
@@ -73,6 +75,12 @@ private:
BannerShaderConfig *config = nullptr;
GradientFallbackWidget *fallback = nullptr;
+ // Palette-derived banner colours -- the theme's window hue forced down to
+ // the banner's curated darkness, plus the theme's Highlight as accent.
+ QColor bannerColorA;
+ QColor bannerColorB;
+ QColor bannerAccent;
+
QTimer clock;
QElapsedTimer elapsed;
Motif currentMotif = Motif::Welcome;
diff --git a/cockatrice/src/interface/widgets/onboarding/shaders/brand_banner.frag b/cockatrice/src/interface/widgets/onboarding/shaders/brand_banner.frag
index 508bd4bc4..2bf6d0abf 100644
--- a/cockatrice/src/interface/widgets/onboarding/shaders/brand_banner.frag
+++ b/cockatrice/src/interface/widgets/onboarding/shaders/brand_banner.frag
@@ -28,6 +28,8 @@ layout(std140, binding = 0) uniform buf
vec4 uColorA;
vec4 uColorB;
vec4 uAccent;
+ vec4 uGlowColor;
+ float uVignetteMin;
float uLogoGlow;
};
@@ -119,7 +121,7 @@ vec3 backgroundField(vec2 uv, float time)
// Accent-coloured fog layer: flowNoise peaks above 0.6 contribute accent
float fog = flowNoise(uv * 0.8 + vec2(100.0, 50.0), time * 0.02);
- col += uAccent.rgb * max(fog - 0.6, 0.0) * 0.10;
+ col += uAccent.rgb * max(fog - 0.6, 0.0) * 0.14;
return col;
}
@@ -136,14 +138,17 @@ vec3 motifWelcome(vec2 uv, vec3 bg, float t)
vec2 center = vec2(asp * 0.5, 0.5);
float cDist = length(ac - center);
- // Centre bloom at logo position; intensity scales with uLogoGlow
+ // Centre bloom at logo position; intensity scales with uLogoGlow. The
+ // QML brandGlow halo now supplies the primary logo surround (the two
+ // brand appColors), so this shader bloom is deliberately kept as a subtle
+ // ambience rather than a competing glow.
float centreLight = bloom(cDist, 0.08 * asp, 0.40 * asp);
- col += centreLight * 0.20 * uLogoGlow;
+ col += uGlowColor.rgb * centreLight * 0.20 * uLogoGlow;
// Flow-noise shimmer gated by Gaussian mask at centre
float shimmer = flowNoise(ac * 0.8 + vec2(55.0, 33.0), t * 0.05) * 0.5 + 0.5;
float shimmerMask = exp(-(cDist * cDist) / (0.18 * asp * 0.18 * asp));
- col += shimmer * shimmerMask * 0.04 * uLogoGlow;
+ col += uGlowColor.rgb * shimmer * shimmerMask * 0.04 * uLogoGlow;
// 48 ember particles: hash-seeded position, speed, size, brightness.
// Embers within a distance threshold of centre are deflected into an
@@ -162,8 +167,8 @@ vec3 motifWelcome(vec2 uv, vec3 bg, float t)
float pX = baseX * asp + sin(t * driftFreq + fi * 1.7) * driftAmp * asp;
float pY = fract(baseY + t * riseSpeed);
- float size = 0.006 + hash21(vec2(fi * 2.9, uSeed * 4.7)) * 0.012;
- float bright = 0.15 + hash21(vec2(fi * 6.1, uSeed * 0.9)) * 0.30;
+ float size = 0.010 + hash21(vec2(fi * 2.9, uSeed * 4.7)) * 0.014;
+ float bright = 0.18 + hash21(vec2(fi * 6.1, uSeed * 0.9)) * 0.32;
// Fade out near top/bottom edges
float edgeFade = smoothstep(0.0, 0.12, pY) * smoothstep(1.0, 0.88, pY);
@@ -232,7 +237,7 @@ vec3 motifCardDatabase(vec2 uv, vec3 bg, float t)
// Semi-transparent dark fill
float fill = smoothstep(0.015, -0.005, d);
- col = mix(col, uColorB.rgb * 0.55, fill * 0.50);
+ col = mix(col, uColorB.rgb * 0.60, fill * 0.62);
// Accent outline
float edge = smoothstep(0.035, 0.0, abs(d));
@@ -309,7 +314,7 @@ vec3 motifAccount(vec2 uv, vec3 bg, float t)
// Node glow via bloom; intensity modulated by pulse
float dist = length(ac - pos);
- col += uAccent.rgb * bloom(dist, 0.018, 0.08) * mix(0.20, 0.45, pulse);
+ col += uAccent.rgb * bloom(dist, 0.018, 0.08) * mix(0.30, 0.55, pulse);
}
// Edges: connect nodes within a radius threshold
@@ -323,19 +328,19 @@ vec3 motifAccount(vec2 uv, vec3 bg, float t)
vec2 ba = nodePos[j] - nodePos[i];
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
float lineDist = length(pa - ba * h);
- col += uAccent.rgb * smoothstep(0.010, 0.0, lineDist) * strength * 0.10;
+ col += uAccent.rgb * smoothstep(0.010, 0.0, lineDist) * strength * 0.14;
}
}
}
// Central bloom at banner centre
float cDist = length(ac - center);
- col += uAccent.rgb * bloom(cDist, 0.04, 0.25) * 0.12;
+ col += uAccent.rgb * bloom(cDist, 0.04, 0.25) * 0.20;
// Periodic expanding ring from centre
float ripplePhase = t * 0.4;
float rippleDist = abs(cDist - fract(ripplePhase) * asp * 0.7);
- col += uAccent.rgb * smoothstep(0.02, 0.0, rippleDist) * 0.10;
+ col += uAccent.rgb * smoothstep(0.02, 0.0, rippleDist) * 0.14;
return col;
}
@@ -456,6 +461,8 @@ void main()
else if (uMode < 4.5) col = motifPreferences(uv, bg, t);
else col = motifFinish(uv, bg, t);
- col *= mix(0.62, 1.0, vignette(uv));
+ // Corner vignette; uVignetteMin is scheme-driven (0.62 on dark stages,
+ // gentler on light ones so near-white corners don't go muddy grey).
+ col *= mix(uVignetteMin, 1.0, vignette(uv));
fragColor = vec4(col, 1.0) * qt_Opacity;
}
diff --git a/cockatrice/src/interface/widgets/onboarding/shaders/brand_plate.frag b/cockatrice/src/interface/widgets/onboarding/shaders/brand_plate.frag
new file mode 100644
index 000000000..43b798c9f
--- /dev/null
+++ b/cockatrice/src/interface/widgets/onboarding/shaders/brand_plate.frag
@@ -0,0 +1,42 @@
+#version 440
+
+// The logo's gradient plate, drawn by us rather than the baked-in SVG: a
+// linear blend between the two brand appColors (light AccentSoft at the
+// top-left grading to dark AccentStrong at the bottom-right, mirroring
+// cockatrice.svg's linearGradient4265-7-8 userSpaceOnUse axis), clipped to
+// the bird's full silhouette via the full-color logo's alpha (uSilhouette).
+// The white highlight path (cockatrice-logo-white) is overlaid in QML on top,
+// exactly as the SVG stacks its white path over the gradient paths. Fully
+// static: no glow, no breathing — the plate just sits there like the home
+// widget's QPainter composite.
+
+layout(location = 0) in vec2 qt_TexCoord0;
+layout(location = 0) out vec4 fragColor;
+
+layout(std140, binding = 0) uniform buf
+{
+ mat4 qt_Matrix;
+ float qt_Opacity;
+ vec4 uStrong;
+ vec4 uSoft;
+};
+
+// The full-color logo's alpha channel acts as the silhouette mask: the
+// gradient only appears inside the bird, exactly like the SVG's gradient paths.
+layout(binding = 1) uniform sampler2D uSilhouette;
+
+void main()
+{
+ // Recreate cockatrice.svg's own gradient geometry (linearGradient4265-7-8,
+ // userSpaceOnUse): light AccentSoft at the start point S=(-8.097,-97.746),
+ // dark AccentStrong at the end E=(162.455,295.208), on the SVG's 300x300
+ // canvas. Normalized to UV space, V=E-S=(0.5685,1.3098), so
+ // t = dot(uv - S_norm, V)/|V|^2 with S_norm=(-0.0270,-0.3258).
+ float t = clamp(dot(qt_TexCoord0 - vec2(-0.02699, -0.32582), vec2(0.56851, 1.30985)) / 2.03891, 0.0, 1.0);
+ vec3 color = mix(uSoft.rgb, uStrong.rgb, t);
+
+ // Anti-aliased silhouette clip from the full-color logo's alpha.
+ float alpha = texture(uSilhouette, qt_TexCoord0).a;
+
+ fragColor = vec4(color * alpha, alpha) * qt_Opacity;
+}
\ No newline at end of file
diff --git a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp
index c45373757..f161f0f19 100644
--- a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp
+++ b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp
@@ -59,8 +59,8 @@ AppearanceSettingsPage::AppearanceSettingsPage()
connect(&schemeCombo, &QComboBox::currentIndexChanged, this,
[this] { themeManager->setColorScheme(schemeCombo.currentData().toString()); });
- // Qt widget style; "Default" lets the application decide
- styleCombo.addItem(tr("Default"), QStringLiteral("Default"));
+ // Qt widget style; "System" lets the application decide
+ styleCombo.addItem(tr("System"), QStringLiteral("System"));
for (const QString &key : QStyleFactory::keys()) {
styleCombo.addItem(key, key);
}
@@ -132,6 +132,10 @@ AppearanceSettingsPage::AppearanceSettingsPage()
connect(&homeTabDisplayCardNameCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.appearance(),
&AppearanceSettings::setHomeTabDisplayCardName);
+ homeTabBackgroundDimCheckBox.setChecked(settings.appearance().getHomeTabBackgroundDim());
+ connect(&homeTabBackgroundDimCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.appearance(),
+ &AppearanceSettings::setHomeTabBackgroundDim);
+
for (const auto &entry : HomeTabButtonColor::all()) {
homeTabButtonColorSourceBox.addItem(QObject::tr(entry.trKey));
}
@@ -150,6 +154,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
homeTabGrid->addWidget(&homeTabDisplayCardNameCheckBox, 2, 0, 1, 2);
homeTabGrid->addWidget(&homeTabButtonColorSourceLabel, 3, 0);
homeTabGrid->addWidget(&homeTabButtonColorSourceBox, 3, 1);
+ homeTabGrid->addWidget(&homeTabBackgroundDimCheckBox, 4, 0, 1, 2);
homeTabGroupBox = new QGroupBox;
homeTabGroupBox->setLayout(homeTabGrid);
@@ -508,6 +513,9 @@ void AppearanceSettingsPage::retranslateUi()
homeTabBackgroundShuffleFrequencyLabel.setText(tr("Home tab background shuffle frequency:"));
homeTabBackgroundShuffleFrequencySpinBox.setSpecialValueText(tr("Disabled"));
homeTabDisplayCardNameCheckBox.setText(tr("Display card name of background in bottom right"));
+ homeTabBackgroundDimCheckBox.setText(tr("Dim the home tab background"));
+ homeTabBackgroundDimCheckBox.setToolTip(
+ tr("Draw a translucent overlay over the home tab background so buttons and text stand out"));
homeTabButtonColorSourceLabel.setText(tr("Home tab button color:"));
homeTabButtonColorSourceBox.setToolTip(
tr("Use the theme's identity accent colors, or extract colors from the background image"));
diff --git a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h
index 8db71ff8f..bec4cd72f 100644
--- a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h
+++ b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h
@@ -41,6 +41,7 @@ private:
QLabel homeTabBackgroundShuffleFrequencyLabel;
QSpinBox homeTabBackgroundShuffleFrequencySpinBox;
QCheckBox homeTabDisplayCardNameCheckBox;
+ QCheckBox homeTabBackgroundDimCheckBox;
QLabel homeTabButtonColorSourceLabel;
QComboBox homeTabButtonColorSourceBox;
diff --git a/cockatrice/themes/CMakeLists.txt b/cockatrice/themes/CMakeLists.txt
index 577977551..70344d95a 100644
--- a/cockatrice/themes/CMakeLists.txt
+++ b/cockatrice/themes/CMakeLists.txt
@@ -2,7 +2,7 @@
#
# add themes subfolders
-set(defthemes Default Fabric Fusion Leather Plasma VelvetMarble)
+set(defthemes Fabric Fusion Leather Plasma VelvetMarble System)
if(UNIX)
if(APPLE)
diff --git a/cockatrice/themes/Fabric/backgrounds/home-dark.png b/cockatrice/themes/Fabric/backgrounds/home-dark.png
new file mode 100644
index 000000000..8d9514626
Binary files /dev/null and b/cockatrice/themes/Fabric/backgrounds/home-dark.png differ
diff --git a/cockatrice/themes/Fabric/backgrounds/home-light.png b/cockatrice/themes/Fabric/backgrounds/home-light.png
new file mode 100644
index 000000000..78f51a686
Binary files /dev/null and b/cockatrice/themes/Fabric/backgrounds/home-light.png differ
diff --git a/cockatrice/themes/Fabric/palette-default-dark.toml b/cockatrice/themes/Fabric/palette-default-dark.toml
new file mode 100644
index 000000000..cad18921a
--- /dev/null
+++ b/cockatrice/themes/Fabric/palette-default-dark.toml
@@ -0,0 +1,74 @@
+# Fabric — dark identity palette (navy-cloth chrome)
+[Palette]
+WindowText = #e8ecf2
+Button = #2b374a
+Light = #3a4759
+Midlight = #333f50
+Dark = #141a23
+Mid = #252c38
+Text = #e8ecf2
+BrightText = #8ec2ff
+ButtonText = #f2f4f8
+Base = #222c3d
+Window = #18202e
+Shadow = #0b0f15
+Highlight = #4a82e6
+HighlightedText = #ffffff
+Link = #7fb0f2
+LinkVisited = #a98ad9
+AlternateBase = #1d2636
+ToolTipBase = #2b3546
+ToolTipText = #f2f4f8
+PlaceholderText = #6ee8ecf2
+Accent = #4a82e6
+
+[Palette.Disabled]
+WindowText = #9d9d9d
+Button = #18202e
+Light = #3a4759
+Midlight = #333f50
+Dark = #141a23
+Mid = #252c38
+Text = #9d9d9d
+BrightText = #8ec2ff
+ButtonText = #787878
+Base = #18202e
+Window = #18202e
+Shadow = #0b0f15
+Highlight = #222d40
+HighlightedText = #9d9d9d
+Link = #308cc6
+LinkVisited = #b450ff
+AlternateBase = #1d2636
+ToolTipBase = #2b3546
+ToolTipText = #f2f4f8
+PlaceholderText = #6ee8ecf2
+Accent = #9d9d9d
+
+[Palette.Inactive]
+WindowText = #e8ecf2
+Button = #2b374a
+Light = #3a4759
+Midlight = #333f50
+Dark = #141a23
+Mid = #252c38
+Text = #e8ecf2
+BrightText = #8ec2ff
+ButtonText = #f2f4f8
+Base = #222c3d
+Window = #18202e
+Shadow = #0b0f15
+Highlight = #222d40
+HighlightedText = #ffffff
+Link = #7fb0f2
+LinkVisited = #a98ad9
+AlternateBase = #1d2636
+ToolTipBase = #2b3546
+ToolTipText = #f2f4f8
+PlaceholderText = #6ee8ecf2
+Accent = #4a82e6
+
+[AppColors]
+AccentStrong = #3a6fd6
+AccentSoft = #8fb8f2
+
diff --git a/cockatrice/themes/Fabric/palette-default-light.toml b/cockatrice/themes/Fabric/palette-default-light.toml
new file mode 100644
index 000000000..f5151af3e
--- /dev/null
+++ b/cockatrice/themes/Fabric/palette-default-light.toml
@@ -0,0 +1,74 @@
+# Fabric — light identity palette (navy-cloth chrome)
+[Palette]
+WindowText = #1c2330
+Button = #c8d6ea
+Light = #ffffff
+Midlight = #b9c6dc
+Dark = #8fa0bd
+Mid = #a3b3cd
+Text = #1c2330
+BrightText = #1d4fa0
+ButtonText = #141c29
+Base = #f6f8fc
+Window = #dbe3ef
+Shadow = #5a6a85
+Highlight = #2f6fd6
+HighlightedText = #ffffff
+Link = #2555b0
+LinkVisited = #6a4bb8
+AlternateBase = #e9eef7
+ToolTipBase = #e9eff8
+ToolTipText = #141c29
+PlaceholderText = #7a1c2330
+Accent = #2f6fd6
+
+[Palette.Disabled]
+WindowText = #787878
+Button = #dbe3ef
+Light = #ffffff
+Midlight = #b9c6dc
+Dark = #8fa0bd
+Mid = #a3b3cd
+Text = #787878
+BrightText = #1d4fa0
+ButtonText = #969696
+Base = #dbe3ef
+Window = #dbe3ef
+Shadow = #5a6a85
+Highlight = #cdd8e9
+HighlightedText = #787878
+Link = #0000ff
+LinkVisited = #ff00ff
+AlternateBase = #e9eef7
+ToolTipBase = #e9eff8
+ToolTipText = #141c29
+PlaceholderText = #7a1c2330
+Accent = #787878
+
+[Palette.Inactive]
+WindowText = #1c2330
+Button = #c8d6ea
+Light = #ffffff
+Midlight = #b9c6dc
+Dark = #8fa0bd
+Mid = #a3b3cd
+Text = #1c2330
+BrightText = #1d4fa0
+ButtonText = #141c29
+Base = #f6f8fc
+Window = #dbe3ef
+Shadow = #5a6a85
+Highlight = #cdd8e9
+HighlightedText = #000000
+Link = #2555b0
+LinkVisited = #6a4bb8
+AlternateBase = #e9eef7
+ToolTipBase = #e9eff8
+ToolTipText = #141c29
+PlaceholderText = #7a1c2330
+Accent = #2f6fd6
+
+[AppColors]
+AccentStrong = #3a6fd6
+AccentSoft = #8fb8f2
+
diff --git a/cockatrice/themes/Fabric/theme.cfg b/cockatrice/themes/Fabric/theme.cfg
new file mode 100644
index 000000000..55b916e71
--- /dev/null
+++ b/cockatrice/themes/Fabric/theme.cfg
@@ -0,0 +1,5 @@
+[Appearance]
+ColorScheme = System
+
+[Style]
+Name = Fusion
\ No newline at end of file
diff --git a/cockatrice/themes/Fabric/zones/handzone-light.png b/cockatrice/themes/Fabric/zones/handzone-light.png
new file mode 100644
index 000000000..a87f9e292
Binary files /dev/null and b/cockatrice/themes/Fabric/zones/handzone-light.png differ
diff --git a/cockatrice/themes/Fabric/zones/handzone.png b/cockatrice/themes/Fabric/zones/handzone.png
index 25d22b070..a5b72286c 100644
Binary files a/cockatrice/themes/Fabric/zones/handzone.png and b/cockatrice/themes/Fabric/zones/handzone.png differ
diff --git a/cockatrice/themes/Fabric/zones/playerzone-light.png b/cockatrice/themes/Fabric/zones/playerzone-light.png
new file mode 100644
index 000000000..05da3ea9b
Binary files /dev/null and b/cockatrice/themes/Fabric/zones/playerzone-light.png differ
diff --git a/cockatrice/themes/Fabric/zones/playerzone.png b/cockatrice/themes/Fabric/zones/playerzone.png
index 728fccdfa..7fa977249 100644
Binary files a/cockatrice/themes/Fabric/zones/playerzone.png and b/cockatrice/themes/Fabric/zones/playerzone.png differ
diff --git a/cockatrice/themes/Fabric/zones/stackzone-light.png b/cockatrice/themes/Fabric/zones/stackzone-light.png
new file mode 100644
index 000000000..dcd6dc045
Binary files /dev/null and b/cockatrice/themes/Fabric/zones/stackzone-light.png differ
diff --git a/cockatrice/themes/Fabric/zones/stackzone.png b/cockatrice/themes/Fabric/zones/stackzone.png
index 89e2080f8..9046aa049 100644
Binary files a/cockatrice/themes/Fabric/zones/stackzone.png and b/cockatrice/themes/Fabric/zones/stackzone.png differ
diff --git a/cockatrice/themes/Fabric/zones/tablezone-light.png b/cockatrice/themes/Fabric/zones/tablezone-light.png
new file mode 100644
index 000000000..cb297e7e1
Binary files /dev/null and b/cockatrice/themes/Fabric/zones/tablezone-light.png differ
diff --git a/cockatrice/themes/Fabric/zones/tablezone.png b/cockatrice/themes/Fabric/zones/tablezone.png
index 6a2ce68e1..8048a4cc1 100644
Binary files a/cockatrice/themes/Fabric/zones/tablezone.png and b/cockatrice/themes/Fabric/zones/tablezone.png differ
diff --git a/cockatrice/themes/Fusion/palette-default-dark.toml b/cockatrice/themes/Fusion/palette-default-dark.toml
index a988c2f14..b180e9b63 100644
--- a/cockatrice/themes/Fusion/palette-default-dark.toml
+++ b/cockatrice/themes/Fusion/palette-default-dark.toml
@@ -11,15 +11,15 @@ ButtonText = #ffffffff
Base = #ff2d2d2d
Window = #ff1e1e1e
Shadow = #ff000000
-Highlight = #ff148c3c
+Highlight = #ff139740
HighlightedText = #ffffffff
-Link = #ff00f652
-LinkVisited = #ff00d346
+Link = #ffc9fd62
+LinkVisited = #ff9ad43e
AlternateBase = #ff353535
ToolTipBase = #ff3c3c3c
ToolTipText = #ffd4d4d4
PlaceholderText = #80ffffff
-Accent = #ff00d346
+Accent = #ffc9fd62
[Palette.Disabled]
WindowText = #ff9d9d9d
@@ -34,7 +34,7 @@ ButtonText = #ff9d9d9d
Base = #ff1e1e1e
Window = #ff1e1e1e
Shadow = #ff000000
-Highlight = #ff148c3c
+Highlight = #ff139740
HighlightedText = #ffffffff
Link = #ff308cc6
LinkVisited = #ffff00ff
@@ -59,8 +59,8 @@ Window = #ff1e1e1e
Shadow = #ff000000
Highlight = #ff1e1e1e
HighlightedText = #ffffffff
-Link = #ff00f652
-LinkVisited = #ff00d346
+Link = #ffc9fd62
+LinkVisited = #ff9ad43e
AlternateBase = #ff353535
ToolTipBase = #ff3c3c3c
ToolTipText = #ffd4d4d4
@@ -69,5 +69,5 @@ Accent = #ff1e1e1e
[AppColors]
-AccentStrong = #ff148c3c
-AccentSoft = #ff78c850
+AccentStrong = #ff139740
+AccentSoft = #ffc9fd62
diff --git a/cockatrice/themes/Fusion/palette-default-light.toml b/cockatrice/themes/Fusion/palette-default-light.toml
index b72b79b11..5a1163a2b 100644
--- a/cockatrice/themes/Fusion/palette-default-light.toml
+++ b/cockatrice/themes/Fusion/palette-default-light.toml
@@ -11,15 +11,15 @@ ButtonText = #ff000000
Base = #ffffffff
Window = #fff0f0f0
Shadow = #ff696969
-Highlight = #ff148c3c
+Highlight = #ff139740
HighlightedText = #ffffffff
-Link = #ff0d5f28
-LinkVisited = #ff08401b
+Link = #ff0e6b31
+LinkVisited = #ff0a521f
AlternateBase = #ffe9e7e3
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
PlaceholderText = #80000000
-Accent = #ff107532
+Accent = #ff139740
[Palette.Disabled]
WindowText = #ff787878
@@ -34,7 +34,7 @@ ButtonText = #ff787878
Base = #fff0f0f0
Window = #fff0f0f0
Shadow = #ff000000
-Highlight = #ff148c3c
+Highlight = #ff139740
HighlightedText = #ffffffff
Link = #ff0000ff
LinkVisited = #ffff00ff
@@ -59,8 +59,8 @@ Window = #fff0f0f0
Shadow = #ff696969
Highlight = #fff0f0f0
HighlightedText = #ff000000
-Link = #ff0d5f28
-LinkVisited = #ff08401b
+Link = #ff0e6b31
+LinkVisited = #ff0a521f
AlternateBase = #ffe9e7e3
ToolTipBase = #ffffffdc
ToolTipText = #ff000000
@@ -69,5 +69,5 @@ Accent = #fff0f0f0
[AppColors]
-AccentStrong = #ff148c3c
-AccentSoft = #ff78c850
+AccentStrong = #ff139740
+AccentSoft = #ffc9fd62
diff --git a/cockatrice/themes/Leather/backgrounds/home-dark.png b/cockatrice/themes/Leather/backgrounds/home-dark.png
new file mode 100644
index 000000000..20d16a27f
Binary files /dev/null and b/cockatrice/themes/Leather/backgrounds/home-dark.png differ
diff --git a/cockatrice/themes/Leather/backgrounds/home-light.png b/cockatrice/themes/Leather/backgrounds/home-light.png
new file mode 100644
index 000000000..ee1da361d
Binary files /dev/null and b/cockatrice/themes/Leather/backgrounds/home-light.png differ
diff --git a/cockatrice/themes/Leather/palette-default-dark.toml b/cockatrice/themes/Leather/palette-default-dark.toml
new file mode 100644
index 000000000..b0db0e90a
--- /dev/null
+++ b/cockatrice/themes/Leather/palette-default-dark.toml
@@ -0,0 +1,74 @@
+# Leather — dark identity palette (black-brown chrome with brass accents)
+[Palette]
+WindowText = #eee9e2
+Button = #332d26
+Light = #4a4239
+Midlight = #3d3730
+Dark = #131009
+Mid = #26221c
+Text = #eee9e2
+BrightText = #e3c27e
+ButtonText = #f5f1ea
+Base = #26221d
+Window = #1d1a16
+Shadow = #0d0b07
+Highlight = #4a5f8f
+HighlightedText = #ffffff
+Link = #cfa263
+LinkVisited = #9a7db8
+AlternateBase = #211d19
+ToolTipBase = #37302a
+ToolTipText = #f5f1ea
+PlaceholderText = #6eeee9e2
+Accent = #c9995a
+
+[Palette.Disabled]
+WindowText = #9d9d9d
+Button = #1d1a16
+Light = #4a4239
+Midlight = #3d3730
+Dark = #131009
+Mid = #26221c
+Text = #9d9d9d
+BrightText = #e3c27e
+ButtonText = #787878
+Base = #1d1a16
+Window = #1d1a16
+Shadow = #0d0b07
+Highlight = #2d2822
+HighlightedText = #9d9d9d
+Link = #308cc6
+LinkVisited = #b450ff
+AlternateBase = #211d19
+ToolTipBase = #37302a
+ToolTipText = #f5f1ea
+PlaceholderText = #6eeee9e2
+Accent = #9d9d9d
+
+[Palette.Inactive]
+WindowText = #eee9e2
+Button = #332d26
+Light = #4a4239
+Midlight = #3d3730
+Dark = #131009
+Mid = #26221c
+Text = #eee9e2
+BrightText = #e3c27e
+ButtonText = #f5f1ea
+Base = #26221d
+Window = #1d1a16
+Shadow = #0d0b07
+Highlight = #2d2822
+HighlightedText = #ffffff
+Link = #cfa263
+LinkVisited = #9a7db8
+AlternateBase = #211d19
+ToolTipBase = #37302a
+ToolTipText = #f5f1ea
+PlaceholderText = #6eeee9e2
+Accent = #c9995a
+
+[AppColors]
+AccentStrong = #b7823b
+AccentSoft = #e4c58f
+
diff --git a/cockatrice/themes/Leather/palette-default-light.toml b/cockatrice/themes/Leather/palette-default-light.toml
new file mode 100644
index 000000000..ff122db76
--- /dev/null
+++ b/cockatrice/themes/Leather/palette-default-light.toml
@@ -0,0 +1,74 @@
+# Leather — light identity palette (black-brown chrome with brass accents)
+[Palette]
+WindowText = #2a2114
+Button = #dfcbb0
+Light = #ffffff
+Midlight = #c6b08c
+Dark = #a18a64
+Mid = #b29a74
+Text = #2a2114
+BrightText = #7a531c
+ButtonText = #1f1710
+Base = #fdf8ee
+Window = #f0e2cb
+Shadow = #5d4d33
+Highlight = #34508c
+HighlightedText = #ffffff
+Link = #8a5e1e
+LinkVisited = #6b5190
+AlternateBase = #f5ebd7
+ToolTipBase = #fff7e8
+ToolTipText = #1f1710
+PlaceholderText = #7a2a2114
+Accent = #a5712f
+
+[Palette.Disabled]
+WindowText = #787878
+Button = #f0e2cb
+Light = #ffffff
+Midlight = #c6b08c
+Dark = #a18a64
+Mid = #b29a74
+Text = #787878
+BrightText = #7a531c
+ButtonText = #969696
+Base = #f0e2cb
+Window = #f0e2cb
+Shadow = #5d4d33
+Highlight = #ecd9bb
+HighlightedText = #787878
+Link = #0000ff
+LinkVisited = #ff00ff
+AlternateBase = #f5ebd7
+ToolTipBase = #fff7e8
+ToolTipText = #1f1710
+PlaceholderText = #7a2a2114
+Accent = #787878
+
+[Palette.Inactive]
+WindowText = #2a2114
+Button = #dfcbb0
+Light = #ffffff
+Midlight = #c6b08c
+Dark = #a18a64
+Mid = #b29a74
+Text = #2a2114
+BrightText = #7a531c
+ButtonText = #1f1710
+Base = #fdf8ee
+Window = #f0e2cb
+Shadow = #5d4d33
+Highlight = #ecd9bb
+HighlightedText = #000000
+Link = #8a5e1e
+LinkVisited = #6b5190
+AlternateBase = #f5ebd7
+ToolTipBase = #fff7e8
+ToolTipText = #1f1710
+PlaceholderText = #7a2a2114
+Accent = #a5712f
+
+[AppColors]
+AccentStrong = #b7823b
+AccentSoft = #e4c58f
+
diff --git a/cockatrice/themes/Leather/theme.cfg b/cockatrice/themes/Leather/theme.cfg
new file mode 100644
index 000000000..55b916e71
--- /dev/null
+++ b/cockatrice/themes/Leather/theme.cfg
@@ -0,0 +1,5 @@
+[Appearance]
+ColorScheme = System
+
+[Style]
+Name = Fusion
\ No newline at end of file
diff --git a/cockatrice/themes/Leather/zones/handzone-light.png b/cockatrice/themes/Leather/zones/handzone-light.png
new file mode 100644
index 000000000..b2c9bba34
Binary files /dev/null and b/cockatrice/themes/Leather/zones/handzone-light.png differ
diff --git a/cockatrice/themes/Leather/zones/handzone.png b/cockatrice/themes/Leather/zones/handzone.png
index aba879683..5f803df74 100644
Binary files a/cockatrice/themes/Leather/zones/handzone.png and b/cockatrice/themes/Leather/zones/handzone.png differ
diff --git a/cockatrice/themes/Leather/zones/playerzone-light.png b/cockatrice/themes/Leather/zones/playerzone-light.png
new file mode 100644
index 000000000..a26f96a5e
Binary files /dev/null and b/cockatrice/themes/Leather/zones/playerzone-light.png differ
diff --git a/cockatrice/themes/Leather/zones/playerzone.png b/cockatrice/themes/Leather/zones/playerzone.png
index 4f42ee41d..cccbb3fd3 100644
Binary files a/cockatrice/themes/Leather/zones/playerzone.png and b/cockatrice/themes/Leather/zones/playerzone.png differ
diff --git a/cockatrice/themes/Leather/zones/stackzone-light.png b/cockatrice/themes/Leather/zones/stackzone-light.png
new file mode 100644
index 000000000..117c738f7
Binary files /dev/null and b/cockatrice/themes/Leather/zones/stackzone-light.png differ
diff --git a/cockatrice/themes/Leather/zones/stackzone.png b/cockatrice/themes/Leather/zones/stackzone.png
index c02e2284a..d9cff892b 100644
Binary files a/cockatrice/themes/Leather/zones/stackzone.png and b/cockatrice/themes/Leather/zones/stackzone.png differ
diff --git a/cockatrice/themes/Leather/zones/tablezone-light.png b/cockatrice/themes/Leather/zones/tablezone-light.png
new file mode 100644
index 000000000..912cbfb94
Binary files /dev/null and b/cockatrice/themes/Leather/zones/tablezone-light.png differ
diff --git a/cockatrice/themes/Leather/zones/tablezone.png b/cockatrice/themes/Leather/zones/tablezone.png
index 152f4f7e9..8af4c853d 100644
Binary files a/cockatrice/themes/Leather/zones/tablezone.png and b/cockatrice/themes/Leather/zones/tablezone.png differ
diff --git a/cockatrice/themes/Plasma/backgrounds/home-dark.png b/cockatrice/themes/Plasma/backgrounds/home-dark.png
new file mode 100644
index 000000000..ce1469e2b
Binary files /dev/null and b/cockatrice/themes/Plasma/backgrounds/home-dark.png differ
diff --git a/cockatrice/themes/Plasma/backgrounds/home-light.png b/cockatrice/themes/Plasma/backgrounds/home-light.png
new file mode 100644
index 000000000..2e9000bd6
Binary files /dev/null and b/cockatrice/themes/Plasma/backgrounds/home-light.png differ
diff --git a/cockatrice/themes/Plasma/palette-default-dark.toml b/cockatrice/themes/Plasma/palette-default-dark.toml
new file mode 100644
index 000000000..222456f4f
--- /dev/null
+++ b/cockatrice/themes/Plasma/palette-default-dark.toml
@@ -0,0 +1,74 @@
+# Plasma — dark identity palette (electric violet chrome with cyan sparks)
+[Palette]
+WindowText = #eeebff
+Button = #2a2440
+Light = #453d63
+Midlight = #383252
+Dark = #0e0c16
+Mid = #211e31
+Text = #eeebff
+BrightText = #7fd7ff
+ButtonText = #f6f4ff
+Base = #1e1a2e
+Window = #151220
+Shadow = #08070e
+Highlight = #6a4df0
+HighlightedText = #ffffff
+Link = #37c7e8
+LinkVisited = #9b7aff
+AlternateBase = #1a1726
+ToolTipBase = #2c2745
+ToolTipText = #f6f4ff
+PlaceholderText = #6eeeebff
+Accent = #6a4df0
+
+[Palette.Disabled]
+WindowText = #9d9d9d
+Button = #151220
+Light = #453d63
+Midlight = #383252
+Dark = #0e0c16
+Mid = #211e31
+Text = #9d9d9d
+BrightText = #7fd7ff
+ButtonText = #787878
+Base = #151220
+Window = #151220
+Shadow = #08070e
+Highlight = #211c32
+HighlightedText = #9d9d9d
+Link = #308cc6
+LinkVisited = #b450ff
+AlternateBase = #1a1726
+ToolTipBase = #2c2745
+ToolTipText = #f6f4ff
+PlaceholderText = #6eeeebff
+Accent = #9d9d9d
+
+[Palette.Inactive]
+WindowText = #eeebff
+Button = #2a2440
+Light = #453d63
+Midlight = #383252
+Dark = #0e0c16
+Mid = #211e31
+Text = #eeebff
+BrightText = #7fd7ff
+ButtonText = #f6f4ff
+Base = #1e1a2e
+Window = #151220
+Shadow = #08070e
+Highlight = #211c32
+HighlightedText = #ffffff
+Link = #37c7e8
+LinkVisited = #9b7aff
+AlternateBase = #1a1726
+ToolTipBase = #2c2745
+ToolTipText = #f6f4ff
+PlaceholderText = #6eeeebff
+Accent = #6a4df0
+
+[AppColors]
+AccentStrong = #5b3ee0
+AccentSoft = #a28bf7
+
diff --git a/cockatrice/themes/Plasma/palette-default-light.toml b/cockatrice/themes/Plasma/palette-default-light.toml
new file mode 100644
index 000000000..d54db31d2
--- /dev/null
+++ b/cockatrice/themes/Plasma/palette-default-light.toml
@@ -0,0 +1,74 @@
+# Plasma — light identity palette (electric violet chrome with cyan sparks)
+[Palette]
+WindowText = #1d1830
+Button = #cfc6f0
+Light = #ffffff
+Midlight = #b7adde
+Dark = #9589c8
+Mid = #a49ad2
+Text = #1d1830
+BrightText = #10406e
+ButtonText = #120d26
+Base = #f9f7ff
+Window = #e3dcf7
+Shadow = #554c85
+Highlight = #5a3ee2
+HighlightedText = #ffffff
+Link = #0f8fb5
+LinkVisited = #6a45d6
+AlternateBase = #ece8fa
+ToolTipBase = #f5f3ff
+ToolTipText = #120d26
+PlaceholderText = #7a1d1830
+Accent = #5a3ee2
+
+[Palette.Disabled]
+WindowText = #787878
+Button = #e3dcf7
+Light = #ffffff
+Midlight = #b7adde
+Dark = #9589c8
+Mid = #a49ad2
+Text = #787878
+BrightText = #10406e
+ButtonText = #969696
+Base = #e3dcf7
+Window = #e3dcf7
+Shadow = #554c85
+Highlight = #d6ccf3
+HighlightedText = #787878
+Link = #0000ff
+LinkVisited = #ff00ff
+AlternateBase = #ece8fa
+ToolTipBase = #f5f3ff
+ToolTipText = #120d26
+PlaceholderText = #7a1d1830
+Accent = #787878
+
+[Palette.Inactive]
+WindowText = #1d1830
+Button = #cfc6f0
+Light = #ffffff
+Midlight = #b7adde
+Dark = #9589c8
+Mid = #a49ad2
+Text = #1d1830
+BrightText = #10406e
+ButtonText = #120d26
+Base = #f9f7ff
+Window = #e3dcf7
+Shadow = #554c85
+Highlight = #d6ccf3
+HighlightedText = #000000
+Link = #0f8fb5
+LinkVisited = #6a45d6
+AlternateBase = #ece8fa
+ToolTipBase = #f5f3ff
+ToolTipText = #120d26
+PlaceholderText = #7a1d1830
+Accent = #5a3ee2
+
+[AppColors]
+AccentStrong = #5b3ee0
+AccentSoft = #a28bf7
+
diff --git a/cockatrice/themes/Plasma/theme.cfg b/cockatrice/themes/Plasma/theme.cfg
new file mode 100644
index 000000000..55b916e71
--- /dev/null
+++ b/cockatrice/themes/Plasma/theme.cfg
@@ -0,0 +1,5 @@
+[Appearance]
+ColorScheme = System
+
+[Style]
+Name = Fusion
\ No newline at end of file
diff --git a/cockatrice/themes/Plasma/zones/handzone-light.png b/cockatrice/themes/Plasma/zones/handzone-light.png
new file mode 100644
index 000000000..89fa7e6d4
Binary files /dev/null and b/cockatrice/themes/Plasma/zones/handzone-light.png differ
diff --git a/cockatrice/themes/Plasma/zones/handzone.png b/cockatrice/themes/Plasma/zones/handzone.png
index 543571d8a..82debb405 100644
Binary files a/cockatrice/themes/Plasma/zones/handzone.png and b/cockatrice/themes/Plasma/zones/handzone.png differ
diff --git a/cockatrice/themes/Plasma/zones/playerzone-light.png b/cockatrice/themes/Plasma/zones/playerzone-light.png
new file mode 100644
index 000000000..9034818f2
Binary files /dev/null and b/cockatrice/themes/Plasma/zones/playerzone-light.png differ
diff --git a/cockatrice/themes/Plasma/zones/playerzone.png b/cockatrice/themes/Plasma/zones/playerzone.png
index eebcd1f84..4623524f6 100644
Binary files a/cockatrice/themes/Plasma/zones/playerzone.png and b/cockatrice/themes/Plasma/zones/playerzone.png differ
diff --git a/cockatrice/themes/Plasma/zones/stackzone-light.png b/cockatrice/themes/Plasma/zones/stackzone-light.png
new file mode 100644
index 000000000..2607b3389
Binary files /dev/null and b/cockatrice/themes/Plasma/zones/stackzone-light.png differ
diff --git a/cockatrice/themes/Plasma/zones/stackzone.png b/cockatrice/themes/Plasma/zones/stackzone.png
index 1845c7091..144d991f3 100644
Binary files a/cockatrice/themes/Plasma/zones/stackzone.png and b/cockatrice/themes/Plasma/zones/stackzone.png differ
diff --git a/cockatrice/themes/Plasma/zones/tablezone-light.png b/cockatrice/themes/Plasma/zones/tablezone-light.png
new file mode 100644
index 000000000..dcf2ef95e
Binary files /dev/null and b/cockatrice/themes/Plasma/zones/tablezone-light.png differ
diff --git a/cockatrice/themes/Plasma/zones/tablezone.png b/cockatrice/themes/Plasma/zones/tablezone.png
index 8f998d4bb..4dc36ec2d 100644
Binary files a/cockatrice/themes/Plasma/zones/tablezone.png and b/cockatrice/themes/Plasma/zones/tablezone.png differ
diff --git a/cockatrice/themes/Default/palette-default-dark.toml b/cockatrice/themes/System/palette-default-dark.toml
similarity index 100%
rename from cockatrice/themes/Default/palette-default-dark.toml
rename to cockatrice/themes/System/palette-default-dark.toml
diff --git a/cockatrice/themes/Default/palette-default-light.toml b/cockatrice/themes/System/palette-default-light.toml
similarity index 100%
rename from cockatrice/themes/Default/palette-default-light.toml
rename to cockatrice/themes/System/palette-default-light.toml
diff --git a/cockatrice/themes/Default/theme.cfg b/cockatrice/themes/System/theme.cfg
similarity index 73%
rename from cockatrice/themes/Default/theme.cfg
rename to cockatrice/themes/System/theme.cfg
index d2016a238..4b756a5e8 100644
--- a/cockatrice/themes/Default/theme.cfg
+++ b/cockatrice/themes/System/theme.cfg
@@ -2,4 +2,4 @@
ColorScheme = Light
[Style]
-Name = Default
+Name = System
diff --git a/cockatrice/themes/VelvetMarble/backgrounds/home-dark.png b/cockatrice/themes/VelvetMarble/backgrounds/home-dark.png
new file mode 100644
index 000000000..34738090f
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/backgrounds/home-dark.png differ
diff --git a/cockatrice/themes/VelvetMarble/backgrounds/home-light.png b/cockatrice/themes/VelvetMarble/backgrounds/home-light.png
new file mode 100644
index 000000000..de783e086
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/backgrounds/home-light.png differ
diff --git a/cockatrice/themes/VelvetMarble/palette-default-dark.toml b/cockatrice/themes/VelvetMarble/palette-default-dark.toml
new file mode 100644
index 000000000..496943931
--- /dev/null
+++ b/cockatrice/themes/VelvetMarble/palette-default-dark.toml
@@ -0,0 +1,74 @@
+# VelvetMarble — dark identity palette (charcoal-velvet chrome with slate marble)
+[Palette]
+WindowText = #e8eaee
+Button = #262a31
+Light = #3a3f47
+Midlight = #31363d
+Dark = #0e1013
+Mid = #1f2329
+Text = #e8eaee
+BrightText = #c3d8f2
+ButtonText = #f2f3f6
+Base = #1b1e23
+Window = #131519
+Shadow = #08090b
+Highlight = #8fa6c0
+HighlightedText = #101318
+Link = #a9c6e8
+LinkVisited = #b9a8d9
+AlternateBase = #171a1f
+ToolTipBase = #2d323a
+ToolTipText = #f2f3f6
+PlaceholderText = #6ee8eaee
+Accent = #8fa6c0
+
+[Palette.Disabled]
+WindowText = #9d9d9d
+Button = #131519
+Light = #3a3f47
+Midlight = #31363d
+Dark = #0e1013
+Mid = #1f2329
+Text = #9d9d9d
+BrightText = #c3d8f2
+ButtonText = #787878
+Base = #131519
+Window = #131519
+Shadow = #08090b
+Highlight = #1f2229
+HighlightedText = #9d9d9d
+Link = #308cc6
+LinkVisited = #b450ff
+AlternateBase = #171a1f
+ToolTipBase = #2d323a
+ToolTipText = #f2f3f6
+PlaceholderText = #6ee8eaee
+Accent = #9d9d9d
+
+[Palette.Inactive]
+WindowText = #e8eaee
+Button = #262a31
+Light = #3a3f47
+Midlight = #31363d
+Dark = #0e1013
+Mid = #1f2329
+Text = #e8eaee
+BrightText = #c3d8f2
+ButtonText = #f2f3f6
+Base = #1b1e23
+Window = #131519
+Shadow = #08090b
+Highlight = #1f2229
+HighlightedText = #ffffff
+Link = #a9c6e8
+LinkVisited = #b9a8d9
+AlternateBase = #171a1f
+ToolTipBase = #2d323a
+ToolTipText = #f2f3f6
+PlaceholderText = #6ee8eaee
+Accent = #8fa6c0
+
+[AppColors]
+AccentStrong = #54687e
+AccentSoft = #9db0c4
+
diff --git a/cockatrice/themes/VelvetMarble/palette-default-light.toml b/cockatrice/themes/VelvetMarble/palette-default-light.toml
new file mode 100644
index 000000000..5323fd320
--- /dev/null
+++ b/cockatrice/themes/VelvetMarble/palette-default-light.toml
@@ -0,0 +1,74 @@
+# VelvetMarble — light identity palette (charcoal-velvet chrome with slate marble)
+[Palette]
+WindowText = #1b1d21
+Button = #c7d1dd
+Light = #ffffff
+Midlight = #b3becb
+Dark = #93a0b1
+Mid = #a1adbc
+Text = #1b1d21
+BrightText = #26465f
+ButtonText = #121418
+Base = #f7f9fb
+Window = #d9e0ea
+Shadow = #57626f
+Highlight = #54687e
+HighlightedText = #ffffff
+Link = #2e4d6b
+LinkVisited = #5d4a78
+AlternateBase = #e6ebf2
+ToolTipBase = #f2f4f6
+ToolTipText = #121418
+PlaceholderText = #7a1b1d21
+Accent = #54687e
+
+[Palette.Disabled]
+WindowText = #787878
+Button = #d9e0ea
+Light = #ffffff
+Midlight = #b3becb
+Dark = #93a0b1
+Mid = #a1adbc
+Text = #787878
+BrightText = #26465f
+ButtonText = #969696
+Base = #d9e0ea
+Window = #d9e0ea
+Shadow = #57626f
+Highlight = #ccd5e3
+HighlightedText = #787878
+Link = #0000ff
+LinkVisited = #ff00ff
+AlternateBase = #e6ebf2
+ToolTipBase = #f2f4f6
+ToolTipText = #121418
+PlaceholderText = #7a1b1d21
+Accent = #787878
+
+[Palette.Inactive]
+WindowText = #1b1d21
+Button = #c7d1dd
+Light = #ffffff
+Midlight = #b3becb
+Dark = #93a0b1
+Mid = #a1adbc
+Text = #1b1d21
+BrightText = #26465f
+ButtonText = #121418
+Base = #f7f9fb
+Window = #d9e0ea
+Shadow = #57626f
+Highlight = #ccd5e3
+HighlightedText = #000000
+Link = #2e4d6b
+LinkVisited = #5d4a78
+AlternateBase = #e6ebf2
+ToolTipBase = #f2f4f6
+ToolTipText = #121418
+PlaceholderText = #7a1b1d21
+Accent = #54687e
+
+[AppColors]
+AccentStrong = #54687e
+AccentSoft = #9db0c4
+
diff --git a/cockatrice/themes/VelvetMarble/theme.cfg b/cockatrice/themes/VelvetMarble/theme.cfg
new file mode 100644
index 000000000..55b916e71
--- /dev/null
+++ b/cockatrice/themes/VelvetMarble/theme.cfg
@@ -0,0 +1,5 @@
+[Appearance]
+ColorScheme = System
+
+[Style]
+Name = Fusion
\ No newline at end of file
diff --git a/cockatrice/themes/VelvetMarble/zones/handzone-light.png b/cockatrice/themes/VelvetMarble/zones/handzone-light.png
new file mode 100644
index 000000000..b21e78e61
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/handzone-light.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/handzone.jpg b/cockatrice/themes/VelvetMarble/zones/handzone.jpg
deleted file mode 100644
index 2ec9b37fe..000000000
Binary files a/cockatrice/themes/VelvetMarble/zones/handzone.jpg and /dev/null differ
diff --git a/cockatrice/themes/VelvetMarble/zones/handzone.png b/cockatrice/themes/VelvetMarble/zones/handzone.png
new file mode 100644
index 000000000..3e2b7ebea
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/handzone.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/playerzone-light.png b/cockatrice/themes/VelvetMarble/zones/playerzone-light.png
new file mode 100644
index 000000000..630aac6eb
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/playerzone-light.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/playerzone.jpg b/cockatrice/themes/VelvetMarble/zones/playerzone.jpg
deleted file mode 100644
index dd13cab78..000000000
Binary files a/cockatrice/themes/VelvetMarble/zones/playerzone.jpg and /dev/null differ
diff --git a/cockatrice/themes/VelvetMarble/zones/playerzone.png b/cockatrice/themes/VelvetMarble/zones/playerzone.png
new file mode 100644
index 000000000..dcf21ba38
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/playerzone.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/stackzone-light.png b/cockatrice/themes/VelvetMarble/zones/stackzone-light.png
new file mode 100644
index 000000000..62027827c
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/stackzone-light.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/stackzone.jpg b/cockatrice/themes/VelvetMarble/zones/stackzone.jpg
deleted file mode 100644
index b63aa0902..000000000
Binary files a/cockatrice/themes/VelvetMarble/zones/stackzone.jpg and /dev/null differ
diff --git a/cockatrice/themes/VelvetMarble/zones/stackzone.png b/cockatrice/themes/VelvetMarble/zones/stackzone.png
new file mode 100644
index 000000000..a47f7bf9d
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/stackzone.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/tablezone-light.png b/cockatrice/themes/VelvetMarble/zones/tablezone-light.png
new file mode 100644
index 000000000..5a9014f9d
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/tablezone-light.png differ
diff --git a/cockatrice/themes/VelvetMarble/zones/tablezone.jpg b/cockatrice/themes/VelvetMarble/zones/tablezone.jpg
deleted file mode 100644
index 9f511491a..000000000
Binary files a/cockatrice/themes/VelvetMarble/zones/tablezone.jpg and /dev/null differ
diff --git a/cockatrice/themes/VelvetMarble/zones/tablezone.png b/cockatrice/themes/VelvetMarble/zones/tablezone.png
new file mode 100644
index 000000000..1523d0821
Binary files /dev/null and b/cockatrice/themes/VelvetMarble/zones/tablezone.png differ
diff --git a/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp b/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp
index 2f19d6224..839e33be4 100644
--- a/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp
@@ -70,6 +70,17 @@ void AppearanceSettings::setHomeTabDisplayCardName(bool _displayCardName)
emit homeTabDisplayCardNameChanged();
}
+bool AppearanceSettings::getHomeTabBackgroundDim() const
+{
+ return getValue("homeTabBackgroundDim", QString(), QString(), true).toBool();
+}
+
+void AppearanceSettings::setHomeTabBackgroundDim(bool _dimBackground)
+{
+ setValue(_dimBackground, "homeTabBackgroundDim");
+ emit homeTabBackgroundDimChanged();
+}
+
int AppearanceSettings::getHomeTabButtonColorSourceIndex() const
{
return getValue("homeTabButtonColorSource", "", "", 0).toInt();
diff --git a/libcockatrice_settings/libcockatrice/settings/appearance_settings.h b/libcockatrice_settings/libcockatrice/settings/appearance_settings.h
index 3a63f0df0..a4504798e 100644
--- a/libcockatrice_settings/libcockatrice/settings/appearance_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/appearance_settings.h
@@ -27,6 +27,8 @@ public:
void setHomeTabBackgroundShuffleFrequency(int _frequency);
[[nodiscard]] bool getHomeTabDisplayCardName() const;
void setHomeTabDisplayCardName(bool _displayCardName);
+ [[nodiscard]] bool getHomeTabBackgroundDim() const;
+ void setHomeTabBackgroundDim(bool _dimBackground);
[[nodiscard]] int getHomeTabButtonColorSourceIndex() const;
void setHomeTabButtonColorSourceIndex(int index);
@@ -36,6 +38,7 @@ signals:
void homeTabBackgroundSourceChanged();
void homeTabBackgroundShuffleFrequencyChanged();
void homeTabDisplayCardNameChanged();
+ void homeTabBackgroundDimChanged();
void homeTabButtonColorChanged();
public:
diff --git a/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp b/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp
index 37dc9a0a0..f6e107dad 100644
--- a/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp
@@ -374,7 +374,11 @@ static void migrateAppearanceSettings(const QString &settingsPath, QSettings &gl
QSettings appearanceIni(settingsPath + "appearance.ini", QSettings::IniFormat);
for (auto it = appearanceKeyMap.constBegin(); it != appearanceKeyMap.constEnd(); ++it) {
if (globalIni.contains(it.key())) {
- appearanceIni.setValue(it.value(), globalIni.value(it.key()));
+ QVariant value = globalIni.value(it.key());
+ if (it.key() == "theme/name" && value.toString() == "Default") {
+ value = "System";
+ }
+ appearanceIni.setValue(it.value(), value);
}
}
}
diff --git a/tests/settings/settings_defaults_test.cpp b/tests/settings/settings_defaults_test.cpp
index 340859323..c8c5ad4c8 100644
--- a/tests/settings/settings_defaults_test.cpp
+++ b/tests/settings/settings_defaults_test.cpp
@@ -386,6 +386,19 @@ TEST_F(SettingsDefaultsTest, Appearance_HomeTabDisplayCardName_Default)
ASSERT_EQ(s.getHomeTabDisplayCardName(), true);
}
+TEST_F(SettingsDefaultsTest, Appearance_HomeTabBackgroundDim_Default)
+{
+ AppearanceSettings s(settingsPath, nullptr);
+ ASSERT_EQ(s.getHomeTabBackgroundDim(), true);
+}
+
+TEST_F(SettingsDefaultsTest, Appearance_HomeTabBackgroundDim_SetAndGet)
+{
+ AppearanceSettings s(settingsPath, nullptr);
+ s.setHomeTabBackgroundDim(false);
+ ASSERT_EQ(s.getHomeTabBackgroundDim(), false);
+}
+
// --- InterfaceSettings ---
TEST_F(SettingsDefaultsTest, Interface_ShowStatusBar_Default)