mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-23 10:05:10 -07:00
[Theme] Add scheme-variant asset resolution (#7275)
* Add scheme-variant theme asset resolution (#7209-1) ThemeManager::assetPath() and schemeVariantPath() resolve a theme asset to its scheme-variant file (prefix-light/dark.png) with fallback to the plain asset, and themePixmap()/loadBrush()/loadExtraBrush() use them. CSS files load style-dark.css or style-light.css when present. Home widget re-resolves its background on theme change. Link pixel_map_generator.cpp into the oracle target, which needs Qt6::Xml for QDomDocument. * Fix clang-format wrap of theme format probe lists --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
202a5ac958
commit
e9bf1e6e46
7 changed files with 147 additions and 12 deletions
|
|
@ -1,5 +1,7 @@
|
|||
#include "pixel_map_generator.h"
|
||||
|
||||
#include "theme_manager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
|
|
@ -83,7 +85,13 @@ static QPixmap loadSvg(const QString &svgPath, const QSize &size, bool expandOnl
|
|||
/**
|
||||
* Try to load path image from non-SVG formats, otherwise fall back to SVG.
|
||||
* This is to allow custom themes to support non-SVG format type overrides, since SVG requires custom loading.
|
||||
* @param path The path to the file, with no file extension. File formats will be automatically detected.
|
||||
*
|
||||
* The path may already carry the resolved file extension (e.g. via
|
||||
* ThemeManager::assetPath); such paths are loaded directly. Otherwise a
|
||||
* format-agnostic lookup probes png, jpg and finally svg.
|
||||
*
|
||||
* @param path The path to the file, with no file extension unless the caller
|
||||
* already resolved it. File formats will be automatically detected.
|
||||
* @param size The desired size of the pixmap.
|
||||
* @param expandOnly If true, then keep the size of the initial pixmap to at least the size (Only relevant if SVG).
|
||||
*
|
||||
|
|
@ -91,6 +99,19 @@ static QPixmap loadSvg(const QString &svgPath, const QSize &size, bool expandOnl
|
|||
*/
|
||||
static QPixmap tryLoadImage(const QString &path, const QSize &size, bool expandOnly = false)
|
||||
{
|
||||
if (path.endsWith(QLatin1String(".svg"), Qt::CaseInsensitive)) {
|
||||
return loadSvg(path, size, expandOnly);
|
||||
}
|
||||
if (path.endsWith(QLatin1String(".png"), Qt::CaseInsensitive) ||
|
||||
path.endsWith(QLatin1String(".jpg"), Qt::CaseInsensitive) ||
|
||||
path.endsWith(QLatin1String(".jpeg"), Qt::CaseInsensitive)) {
|
||||
QPixmap pix(path);
|
||||
if (!pix.isNull()) {
|
||||
return pix.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto formats = {"png", "jpg"};
|
||||
|
||||
QPixmap returnPixmap;
|
||||
|
|
@ -112,7 +133,8 @@ QPixmap PhasePixmapGenerator::generatePixmap(int height, QString name)
|
|||
return pmCache.value(key);
|
||||
}
|
||||
|
||||
QPixmap pixmap = tryLoadImage("theme:phases/" + name, QSize(height, height));
|
||||
QPixmap pixmap = tryLoadImage(QStringLiteral("theme:") + themeManager->assetPath(QStringLiteral("phases/") + name),
|
||||
QSize(height, height));
|
||||
|
||||
pmCache.insert(key, pixmap);
|
||||
return pixmap;
|
||||
|
|
@ -399,7 +421,8 @@ QPixmap LockPixmapGenerator::generatePixmap(int height)
|
|||
return pmCache.value(key);
|
||||
}
|
||||
|
||||
QPixmap pixmap = tryLoadImage("theme:icons/lock", QSize(height, height), true);
|
||||
QPixmap pixmap = tryLoadImage(QStringLiteral("theme:") + themeManager->assetPath(QStringLiteral("icons/lock")),
|
||||
QSize(height, height), true);
|
||||
pmCache.insert(key, pixmap);
|
||||
return pixmap;
|
||||
}
|
||||
|
|
@ -414,7 +437,8 @@ QPixmap DropdownIconPixmapGenerator::generatePixmap(int height, bool expanded)
|
|||
}
|
||||
|
||||
QString name = expanded ? "dropdown_expanded" : "dropdown_collapsed";
|
||||
QPixmap pixmap = tryLoadImage("theme:icons/" + name, QSize(height, height), true);
|
||||
QPixmap pixmap = tryLoadImage(QStringLiteral("theme:") + themeManager->assetPath(QStringLiteral("icons/") + name),
|
||||
QSize(height, height), true);
|
||||
|
||||
pmCache.insert(key, pixmap);
|
||||
return pixmap;
|
||||
|
|
@ -475,6 +499,13 @@ QHash<QString, QPixmap> ManaSymbolPixmapGenerator::scaledCache;
|
|||
|
||||
QPixmap loadColorAdjustedPixmap(const QString &name)
|
||||
{
|
||||
// Prefer an authored scheme-qualified variant when one exists for this asset.
|
||||
const QString variant = themeManager->schemeVariantPath(QStringView(name).mid(QStringLiteral("theme:").size()));
|
||||
if (!variant.isEmpty()) {
|
||||
return QPixmap(QStringLiteral("theme:") + variant);
|
||||
}
|
||||
|
||||
// Legacy fallback: runtime-invert for dark mode when no authored variant.
|
||||
if (qApp->palette().windowText().color().lightness() > 200) {
|
||||
QImage img(name);
|
||||
img.invertPixels();
|
||||
|
|
@ -485,3 +516,21 @@ QPixmap loadColorAdjustedPixmap(const QString &name)
|
|||
return QPixmap(name);
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap themePixmap(QStringView prefix)
|
||||
{
|
||||
const QString resolved = themeManager->assetPath(prefix);
|
||||
return QPixmap(QStringLiteral("theme:") + resolved);
|
||||
}
|
||||
|
||||
void clearPixmapGeneratorCaches()
|
||||
{
|
||||
PhasePixmapGenerator::clear();
|
||||
CounterPixmapGenerator::clear();
|
||||
PingPixmapGenerator::clear();
|
||||
CountryPixmapGenerator::clear();
|
||||
UserLevelPixmapGenerator::clear();
|
||||
LockPixmapGenerator::clear();
|
||||
DropdownIconPixmapGenerator::clear();
|
||||
ManaSymbolPixmapGenerator::clear();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue