[PrintingSelector] Load the pin badge through the themed icon engine

The badge rasterized `theme:icons/pin` with QImageReader, which cannot resolve
the palette token and left the glyph at its first-render colors. Ask QIcon for a
64x64 logical pixmap instead, and re-render the badge when the palette or theme
changes so it stays legible against both card art and the surrounding UI.
This commit is contained in:
Lukas Brübach 2026-10-20 12:59:54 +02:00
parent 1a3142aa0c
commit 459c7ca4df

View file

@ -2,6 +2,8 @@
#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/cache_settings.h"
#include "../../card_picture_loader/card_picture_loader.h" #include "../../card_picture_loader/card_picture_loader.h"
#include "../../theme_icon.h"
#include "../../theme_manager.h"
#include "../cards/card_info_picture_widget.h" #include "../cards/card_info_picture_widget.h"
#include "../tabs/abstract_tab_deck_editor.h" #include "../tabs/abstract_tab_deck_editor.h"
#include "all_zones_card_amount_widget.h" #include "all_zones_card_amount_widget.h"
@ -16,7 +18,6 @@
#include <QFileDialog> #include <QFileDialog>
#include <QGuiApplication> #include <QGuiApplication>
#include <QImage> #include <QImage>
#include <QImageReader>
#include <QLabel> #include <QLabel>
#include <QList> #include <QList>
#include <QMenu> #include <QMenu>
@ -36,7 +37,6 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QVariant> #include <QVariant>
#include <QtGlobal> #include <QtGlobal>
#include <QtMath>
#include <libcockatrice/card/database/card_database_manager.h> #include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/relation/card_relation.h> #include <libcockatrice/card/relation/card_relation.h>
#include <libcockatrice/settings/card_override_settings.h> #include <libcockatrice/settings/card_override_settings.h>
@ -121,6 +121,12 @@ PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *pa
mainLayout->addWidget(cardInfoPicture); mainLayout->addWidget(cardInfoPicture);
initializePinBadge(); initializePinBadge();
auto refreshPinBadge = [this] {
initializePinBadge();
updatePinBadgeVisibility();
};
connect(themeManager, &ThemeManager::paletteChanged, this, refreshPinBadge);
connect(themeManager, &ThemeManager::themeChanged, this, refreshPinBadge);
// Parent the preview to this overlay so it is destroyed with it (Qt::ToolTip keeps // Parent the preview to this overlay so it is destroyed with it (Qt::ToolTip keeps
// it a frameless, non-activating top-level window despite the parent). // it a frameless, non-activating top-level window despite the parent).
@ -402,10 +408,11 @@ void PrintingSelectorCardOverlayWidget::customMenu(QPoint point)
} }
/** /**
* @brief Initializes the pin badge overlay and loads its icon with DPI-aware rasterization. * @brief Initializes the pin badge overlay and loads a DPI-aware icon pixmap.
* *
* The icon is rasterized once using the label's device pixel ratio so it stays crisp on HiDPI * The icon is asked for at the label's device pixel ratio so it stays crisp on HiDPI
* displays. The resulting pixmap is cached on the QLabel and simply shown/hidden when needed. * displays, and re-rendered when the palette or theme changes so the badge follows the
* surrounding UI instead of freezing at its first colors.
* If the SVG cannot be read, a textual fallback badge is created instead. * If the SVG cannot be read, a textual fallback badge is created instead.
*/ */
void PrintingSelectorCardOverlayWidget::initializePinBadge() void PrintingSelectorCardOverlayWidget::initializePinBadge()
@ -421,25 +428,16 @@ void PrintingSelectorCardOverlayWidget::initializePinBadge()
} }
bool pinLoaded = false; bool pinLoaded = false;
QImageReader pinReader(QStringLiteral("theme:icons/pin")); // Ask QIcon for a 64×64 logical pixmap; QIcon applies the target DPR itself.
if (pinReader.canRead()) {
// Rasterize a 64×64 logical icon so it has a consistent size regardless of card scaling.
const QSize targetSize(64, 64); const QSize targetSize(64, 64);
const qreal dpr = pinBadge->devicePixelRatioF(); const QPixmap pinPix =
const QSize rasterSize(qMax(1, qCeil(targetSize.width() * dpr)), qMax(1, qCeil(targetSize.height() * dpr))); loadThemedIcon(QStringLiteral("icons/pin")).pixmap(targetSize, pinBadge->devicePixelRatioF());
pinReader.setScaledSize(rasterSize); if (!pinPix.isNull()) {
const QImage pinImage = pinReader.read();
if (!pinImage.isNull()) {
// Tag the pixmap with the same DPR so Qt renders it at the correct physical size.
QPixmap pinPix = QPixmap::fromImage(pinImage);
pinPix.setDevicePixelRatio(dpr);
pinBadge->setPixmap(pinPix); pinBadge->setPixmap(pinPix);
pinBadge->setFixedSize(targetSize); pinBadge->setFixedSize(targetSize);
pinBadge->setStyleSheet(QStringLiteral("background: transparent;")); pinBadge->setStyleSheet(QStringLiteral("background: transparent;"));
pinLoaded = true; pinLoaded = true;
} }
}
if (!pinLoaded) { if (!pinLoaded) {
// Fall back to a text badge when the SVG cannot be decoded (e.g., missing theme resource). // Fall back to a text badge when the SVG cannot be decoded (e.g., missing theme resource).