diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index 88d1e62dc..469cf3d77 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -25,6 +25,7 @@
resources/icons/lock.svgresources/icons/not_ready_start.svgresources/icons/pencil.svg
+ resources/icons/pin.svgresources/icons/player.svgresources/icons/ready_start.svgresources/icons/reload.svg
diff --git a/cockatrice/resources/icons/pin.svg b/cockatrice/resources/icons/pin.svg
new file mode 100644
index 000000000..71d4c9c9c
--- /dev/null
+++ b/cockatrice/resources/icons/pin.svg
@@ -0,0 +1,24 @@
+
+
+
diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp
index 40f38ac43..5f3a44b30 100644
--- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp
+++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp
@@ -3,9 +3,12 @@
#include "../../../client/settings/cache_settings.h"
#include "printing_selector_card_display_widget.h"
+#include
+#include
#include
#include
#include
+#include
#include
#include
#include
@@ -46,6 +49,15 @@ PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *pa
cardInfoPicture->setCard(_rootCard);
mainLayout->addWidget(cardInfoPicture);
+ initializePinBadge();
+
+ // Update when this overlay emits cardPreferenceChanged or when size/scale changes
+ connect(this, &PrintingSelectorCardOverlayWidget::cardPreferenceChanged, this,
+ &PrintingSelectorCardOverlayWidget::updatePinBadgeVisibility);
+ connect(cardSizeSlider, &QSlider::valueChanged, this, &PrintingSelectorCardOverlayWidget::updatePinBadgeVisibility);
+ // initial state
+ updatePinBadgeVisibility();
+
// Add AllZonesCardAmountWidget
allZonesCardAmountWidget =
new AllZonesCardAmountWidget(this, deckEditor, deckModel, deckView, cardSizeSlider, _rootCard);
@@ -128,6 +140,40 @@ void PrintingSelectorCardOverlayWidget::enterEvent(QEvent *event)
// Show the widget if amounts are 0
allZonesCardAmountWidget->setVisible(true);
}
+/**
+ * @brief Updates the pin badge visibility and position based on the card's pinned state.
+ *
+ * This method checks whether the current card printing is pinned and updates the
+ * pin badge accordingly. If the card is pinned, the badge is made visible and positioned in the
+ * top-right corner of the card image with appropriate margins. If the card is not pinned, the
+ * badge is hidden.
+ *
+ * The method is called whenever the card preference changes or the card size is adjusted via
+ * the slider to ensure the badge remains properly positioned.
+ */
+void PrintingSelectorCardOverlayWidget::updatePinBadgeVisibility()
+{
+ if (!pinBadge || !cardInfoPicture)
+ return;
+
+ // Query the persisted preference override to decide whether this printing is pinned.
+ const auto &preferredProviderId =
+ SettingsCache::instance().cardOverrides().getCardPreferenceOverride(rootCard.getName());
+ const auto &cardProviderId = rootCard.getPrinting().getUuid();
+ const bool isPinned = (!preferredProviderId.isEmpty() && preferredProviderId == cardProviderId);
+
+ // Toggle the badge once; the pixmap was already rasterized in initializePinBadge().
+ pinBadge->setVisible(isPinned);
+
+ if (isPinned) {
+ // Keep a small margin that scales with the card size to avoid obscuring stuff.
+ const int margin = qMax(3, int(cardInfoPicture->width() * 0.03));
+ int x = qMax(0, cardInfoPicture->width() - pinBadge->width() - margin);
+ int y = margin * 3;
+ pinBadge->move(x, y);
+ pinBadge->raise();
+ }
+}
/**
* @brief Handles the mouse leave event when the cursor leaves the overlay widget area.
@@ -204,3 +250,57 @@ void PrintingSelectorCardOverlayWidget::customMenu(QPoint point)
}
menu.exec(this->mapToGlobal(point));
}
+
+/**
+ * @brief Initializes the pin badge overlay and loads its icon with DPI-aware rasterization.
+ *
+ * The icon is rasterized once using 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.
+ * If the SVG cannot be read, a textual fallback badge is created instead.
+ */
+void PrintingSelectorCardOverlayWidget::initializePinBadge()
+{
+ if (!pinBadge) {
+ // construct the overlay label once
+ pinBadge = new QLabel(this);
+ pinBadge->setObjectName(QStringLiteral("printingSelectorPinBadge"));
+ } else {
+ // Clear any previous pixmap / style in case we reinitialize for a DPR change.
+ pinBadge->clear();
+ pinBadge->setStyleSheet(QString());
+ }
+
+ bool pinLoaded = false;
+ QImageReader pinReader(QStringLiteral("theme:icons/pin"));
+
+ 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 qreal dpr = pinBadge->devicePixelRatioF();
+ const QSize rasterSize(qMax(1, qCeil(targetSize.width() * dpr)), qMax(1, qCeil(targetSize.height() * dpr)));
+ pinReader.setScaledSize(rasterSize);
+ 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->setFixedSize(targetSize);
+ pinBadge->setStyleSheet(QStringLiteral("background: transparent;"));
+ pinLoaded = true;
+ }
+ }
+
+ if (!pinLoaded) {
+ // Fall back to a text badge when the SVG cannot be decoded (e.g., missing theme resource).
+ pinBadge->setText(QStringLiteral("PIN"));
+ pinBadge->setAlignment(Qt::AlignCenter);
+ pinBadge->setFixedSize(24, 12);
+ pinBadge->setStyleSheet(QStringLiteral("background: yellow; color: black; border: 1px solid red;"));
+ }
+
+ // The overlay is mouse-transparent and hidden until we know the card is pinned.
+ pinBadge->setAttribute(Qt::WA_TransparentForMouseEvents);
+ pinBadge->setVisible(false);
+ pinBadge->raise();
+}
diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h
index 1bafda4fe..f2351f509 100644
--- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h
+++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h
@@ -42,9 +42,14 @@ protected:
signals:
void cardPreferenceChanged();
+private slots:
+ void updatePinBadgeVisibility();
+
private:
+ void initializePinBadge();
CardInfoPictureWidget *cardInfoPicture;
AllZonesCardAmountWidget *allZonesCardAmountWidget;
+ QLabel *pinBadge = nullptr;
AbstractTabDeckEditor *deckEditor;
DeckListModel *deckModel;
QTreeView *deckView;