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.svg resources/icons/not_ready_start.svg resources/icons/pencil.svg + resources/icons/pin.svg resources/icons/player.svg resources/icons/ready_start.svg resources/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;