UI: highlight pinned printings in Printing Selector (#6252)

* UI: highlight pinned printings in Printing Selector

Fixes #5930.

Signed-off-by: Gauwal <gauwain2611@hotmail.com>

* Fix: adjust pin highlighting behavior + making it sharp/not blurry

* Using qceil

* Isolating pin badge init to it's own method + adding comments

* Cleaning up unnecessary #includes

---------

Signed-off-by: Gauwal <gauwain2611@hotmail.com>
This commit is contained in:
Gauwal
2025-11-09 09:53:27 +01:00
committed by GitHub
parent 0ad31fea46
commit e5d5dfa8d8
4 changed files with 130 additions and 0 deletions

View File

@@ -25,6 +25,7 @@
<file>resources/icons/lock.svg</file>
<file>resources/icons/not_ready_start.svg</file>
<file>resources/icons/pencil.svg</file>
<file>resources/icons/pin.svg</file>
<file>resources/icons/player.svg</file>
<file>resources/icons/ready_start.svg</file>
<file>resources/icons/reload.svg</file>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="64" height="64">
<g transform="matrix(0 1 -1 0 99.465813 0)" opacity="0.7">
<path fill="#000000" fill-rule="evenodd" clip-rule="evenodd"
stroke="#ffffff"
stroke-width="4"
stroke-linejoin="round"
stroke-linecap="round"
d="M65.5 62
L78 49
C73.5 44.5 69.5 42 63 44
L45 31 C47 25 46 22 41.5 18
L19 41.5
C23 45.5 25 46.5 31 45
L44 62.5
C42.3 69 45 73.5 49 78
L61.5 65.5
L84 87
L87 87
L87.5 86.5
L87.5 83.5 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 736 B

View File

@@ -3,9 +3,12 @@
#include "../../../client/settings/cache_settings.h"
#include "printing_selector_card_display_widget.h"
#include <QImageReader>
#include <QLabel>
#include <QMenu>
#include <QMouseEvent>
#include <QVBoxLayout>
#include <QtMath>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/relation/card_relation.h>
#include <utility>
@@ -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();
}

View File

@@ -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;