From 4fbb9d968267e9545a5e5dc9cf3194897b8600cc Mon Sep 17 00:00:00 2001
From: RickyRister <42636155+RickyRister@users.noreply.github.com>
Date: Sat, 3 Jan 2026 01:04:56 -0800
Subject: [PATCH] [PrintingSelector] optimize amount calculation (#6478)
---
.../all_zones_card_amount_widget.cpp | 18 ++++++-
.../all_zones_card_amount_widget.h | 3 ++
.../printing_selector/card_amount_widget.cpp | 42 ++++++----------
.../printing_selector/card_amount_widget.h | 4 +-
.../printing_selector/printing_selector.cpp | 36 ++++++++++++++
.../printing_selector/printing_selector.h | 7 +++
.../printing_selector_card_display_widget.cpp | 8 +++-
.../printing_selector_card_display_widget.h | 2 +
.../printing_selector_card_overlay_widget.cpp | 48 +++++++++----------
.../printing_selector_card_overlay_widget.h | 4 ++
10 files changed, 115 insertions(+), 57 deletions(-)
diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp
index b1346e4fd..36bccbcc3 100644
--- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp
+++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp
@@ -72,6 +72,12 @@ void AllZonesCardAmountWidget::adjustFontSize(int scalePercentage)
repaint();
}
+void AllZonesCardAmountWidget::setAmounts(int mainboardAmount, int sideboardAmount)
+{
+ buttonBoxMainboard->setAmount(mainboardAmount);
+ buttonBoxSideboard->setAmount(sideboardAmount);
+}
+
/**
* @brief Gets the card count in the mainboard zone.
*
@@ -79,7 +85,7 @@ void AllZonesCardAmountWidget::adjustFontSize(int scalePercentage)
*/
int AllZonesCardAmountWidget::getMainboardAmount()
{
- return buttonBoxMainboard->countCardsInZone(DECK_ZONE_MAIN);
+ return buttonBoxMainboard->getAmount();
}
/**
@@ -89,7 +95,15 @@ int AllZonesCardAmountWidget::getMainboardAmount()
*/
int AllZonesCardAmountWidget::getSideboardAmount()
{
- return buttonBoxSideboard->countCardsInZone(DECK_ZONE_SIDE);
+ return buttonBoxSideboard->getAmount();
+}
+
+/**
+ * @brief Checks if the amount is at least one in either the mainboard or sideboard.
+ */
+bool AllZonesCardAmountWidget::isNonZero()
+{
+ return getMainboardAmount() > 0 || getSideboardAmount() > 0;
}
/**
diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h
index 5a03c5f4a..d158d257e 100644
--- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h
+++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h
@@ -23,6 +23,8 @@ public:
const ExactCard &rootCard);
int getMainboardAmount();
int getSideboardAmount();
+ bool isNonZero();
+
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent *event) override;
#else
@@ -31,6 +33,7 @@ public:
public slots:
void adjustFontSize(int scalePercentage);
+ void setAmounts(int mainboardAmount, int sideboardAmount);
private:
QVBoxLayout *layout;
diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp
index 62c8e2d60..f8002eb89 100644
--- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp
+++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp
@@ -45,20 +45,28 @@ CardAmountWidget::CardAmountWidget(QWidget *parent,
connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingSideboard);
}
- cardCountInZone = new QLabel(QString::number(countCardsInZone(zoneName)), this);
+ cardCountInZone = new QLabel(QString::number(amount), this);
cardCountInZone->setAlignment(Qt::AlignCenter);
layout->addWidget(decrementButton);
layout->addWidget(cardCountInZone);
layout->addWidget(incrementButton);
- // React to model changes
- connect(deckStateManager, &DeckStateManager::cardModified, this, &CardAmountWidget::updateCardCount);
-
// Connect slider for dynamic font size adjustment
connect(cardSizeSlider, &QSlider::valueChanged, this, &CardAmountWidget::adjustFontSize);
}
+int CardAmountWidget::getAmount()
+{
+ return amount;
+}
+
+void CardAmountWidget::setAmount(int _amount)
+{
+ amount = _amount;
+ updateCardCount();
+}
+
/**
* @brief Handles the painting of the widget, drawing a semi-transparent background.
*
@@ -124,7 +132,7 @@ void CardAmountWidget::adjustFontSize(int scalePercentage)
*/
void CardAmountWidget::updateCardCount()
{
- cardCountInZone->setText("" + QString::number(countCardsInZone(zoneName)) + "");
+ cardCountInZone->setText("" + QString::number(amount) + "");
layout->invalidate();
layout->activate();
}
@@ -169,8 +177,8 @@ void CardAmountWidget::addPrinting(const QString &zone)
QString foundProviderId =
existing.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data(Qt::DisplayRole).toString();
if (foundProviderId.isEmpty()) {
- int amount = existing.data(Qt::DisplayRole).toInt();
- extraCopies = amount - 1; // One less because we *always* add one
+ int existingAmount = existing.data(Qt::DisplayRole).toInt();
+ extraCopies = existingAmount - 1; // One less because we *always* add one
replacingProviderless = true;
}
}
@@ -246,23 +254,3 @@ void CardAmountWidget::decrementCardHelper(const QString &zone)
return model->offsetCountAtIndex(idx, -1);
});
}
-
-/**
- * @brief Counts the number of cards in a specific zone (mainboard or sideboard).
- *
- * @param deckZone The name of the zone (e.g., DECK_ZONE_MAIN or DECK_ZONE_SIDE).
- * @return The number of cards in the zone.
- */
-int CardAmountWidget::countCardsInZone(const QString &deckZone)
-{
- QString uuid = rootCard.getPrinting().getUuid();
-
- if (uuid.isEmpty()) {
- return 0; // Cards without uuids/providerIds CANNOT match another card, they are undefined for us.
- }
-
- QList cards = deckStateManager->getModel()->getCardsForZone(deckZone);
-
- return std::count_if(cards.cbegin(), cards.cend(),
- [&uuid](const ExactCard &card) { return card.getPrinting().getUuid() == uuid; });
-}
\ No newline at end of file
diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h
index 983416782..3051b1691 100644
--- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h
+++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h
@@ -31,9 +31,10 @@ public:
QSlider *cardSizeSlider,
const ExactCard &rootCard,
const QString &zoneName);
- int countCardsInZone(const QString &deckZone);
+ int getAmount();
public slots:
+ void setAmount(int _amount);
void updateCardCount();
void addPrinting(const QString &zone);
@@ -52,6 +53,7 @@ private:
QLabel *cardCountInZone;
bool hovered;
+ int amount = 0;
void decrementCardHelper(const QString &zoneName);
diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp
index 95d6b2cdf..becfa16a3 100644
--- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp
+++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp
@@ -78,6 +78,7 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck
// Connect deck model data change signal to update display
connect(deckStateManager, &DeckStateManager::uniqueCardsChanged, this, &PrintingSelector::printingsInDeckChanged);
+ connect(deckStateManager, &DeckStateManager::cardModified, this, &PrintingSelector::updateCardAmounts);
retranslateUi();
}
@@ -93,6 +94,36 @@ void PrintingSelector::printingsInDeckChanged()
QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
}
+/**
+ * @return A map of uuid to amounts (main, side).
+ */
+static QMap> tallyUuidCounts(const DeckListModel *model, const QString &cardName)
+{
+ QMap> map;
+
+ auto mainNodes = model->getCardNodesForZone(DECK_ZONE_MAIN);
+ for (auto &node : mainNodes) {
+ if (node->getName() == cardName) {
+ map[node->getCardProviderId()].first += node->getNumber();
+ }
+ }
+
+ auto sideNodes = model->getCardNodesForZone(DECK_ZONE_SIDE);
+ for (auto &node : sideNodes) {
+ if (node->getName() == cardName) {
+ map[node->getCardProviderId()].second += node->getNumber();
+ }
+ }
+
+ return map;
+}
+
+void PrintingSelector::updateCardAmounts()
+{
+ auto map = tallyUuidCounts(deckStateManager->getModel(), selectedCard->getName());
+ emit cardAmountsChanged(map);
+}
+
/**
* @brief Updates the display by clearing the layout and loading new sets for the current card.
*/
@@ -156,6 +187,8 @@ void PrintingSelector::getAllSetsForCurrentCard()
}
printingsToUse = sortToolBar->prependPinnedPrintings(printingsToUse, selectedCard->getName());
+ auto uuidToAmounts = tallyUuidCounts(deckStateManager->getModel(), selectedCard->getName());
+
// Defer widget creation
currentIndex = 0;
@@ -166,8 +199,11 @@ void PrintingSelector::getAllSetsForCurrentCard()
cardSizeWidget->getSlider(), card);
flowWidget->addWidget(cardDisplayWidget);
cardDisplayWidget->clampSetNameToPicture();
+ cardDisplayWidget->updateCardAmounts(uuidToAmounts);
connect(cardDisplayWidget, &PrintingSelectorCardDisplayWidget::cardPreferenceChanged, this,
&PrintingSelector::updateDisplay);
+ connect(this, &PrintingSelector::cardAmountsChanged, cardDisplayWidget,
+ &PrintingSelectorCardDisplayWidget::updateCardAmounts);
}
// Stop timer when done
diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h
index e1c07addf..e48eb2f2c 100644
--- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h
+++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h
@@ -44,6 +44,7 @@ public slots:
private slots:
void printingsInDeckChanged();
+ void updateCardAmounts();
signals:
/**
@@ -55,6 +56,12 @@ signals:
*/
void nextCardRequested();
+ /**
+ * The amounts of the printings in the deck has changed
+ * @param uuidToAmounts Map of uuids to the amounts (maindeck, sideboard) in the deck
+ */
+ void cardAmountsChanged(const QMap> &uuidToAmounts);
+
private:
QVBoxLayout *layout;
SettingsButtonWidget *displayOptionsWidget;
diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp
index 92cf2437c..b95c25cbd 100644
--- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp
+++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp
@@ -27,7 +27,7 @@ PrintingSelectorCardDisplayWidget::PrintingSelectorCardDisplayWidget(QWidget *pa
DeckStateManager *deckStateManager,
QSlider *cardSizeSlider,
const ExactCard &rootCard)
- : QWidget(parent)
+ : QWidget(parent), rootCard(rootCard)
{
layout = new QVBoxLayout(this);
setLayout(layout);
@@ -64,3 +64,9 @@ void PrintingSelectorCardDisplayWidget::clampSetNameToPicture()
}
update();
}
+
+void PrintingSelectorCardDisplayWidget::updateCardAmounts(const QMap> &uuidToAmounts)
+{
+ auto [main, side] = uuidToAmounts.value(rootCard.getPrinting().getUuid());
+ overlayWidget->updateCardAmounts(main, side);
+}
diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h
index 2637b0e57..64bb72e22 100644
--- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h
+++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h
@@ -27,11 +27,13 @@ public:
public slots:
void clampSetNameToPicture();
+ void updateCardAmounts(const QMap> &uuidToAmounts);
signals:
void cardPreferenceChanged();
private:
+ ExactCard rootCard;
QVBoxLayout *layout;
SetNameAndCollectorsNumberDisplayWidget *setNameAndCollectorsNumberDisplayWidget;
PrintingSelectorCardOverlayWidget *overlayWidget;
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 ac36f2cf4..4298b6dc3 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
@@ -59,12 +59,6 @@ PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *pa
allZonesCardAmountWidget = new AllZonesCardAmountWidget(this, deckStateManager, cardSizeSlider, _rootCard);
allZonesCardAmountWidget->raise(); // Ensure it's on top of the picture
- // Set initial visibility based on amounts
- if (allZonesCardAmountWidget->getMainboardAmount() > 0 || allZonesCardAmountWidget->getSideboardAmount() > 0) {
- allZonesCardAmountWidget->setVisible(true);
- } else {
- allZonesCardAmountWidget->setVisible(false);
- }
// Attempt to cast the parent to PrintingSelectorCardDisplayWidget
if (const auto *parentWidget = qobject_cast(parent)) {
@@ -113,8 +107,7 @@ void PrintingSelectorCardOverlayWidget::resizeEvent(QResizeEvent *event)
/**
* @brief Handles the mouse enter event when the cursor enters the overlay widget area.
*
- * When the cursor enters the widget, the card information is updated, and the card amount widget
- * is displayed if the amounts are zero for both the mainboard and sideboard.
+ * When the cursor enters the widget, the card amount widget becomes visible regardless of whether the amounts are zero.
*
* @param event The event triggered when the mouse enters the widget.
*/
@@ -126,16 +119,27 @@ void PrintingSelectorCardOverlayWidget::enterEvent(QEvent *event)
{
QWidget::enterEvent(event);
deckEditor->updateCard(rootCard);
-
- // Check if either mainboard or sideboard amount is greater than 0
- if (allZonesCardAmountWidget->getMainboardAmount() > 0 || allZonesCardAmountWidget->getSideboardAmount() > 0) {
- // Don't change visibility if amounts are greater than 0
- return;
- }
-
- // Show the widget if amounts are 0
- allZonesCardAmountWidget->setVisible(true);
+ updateVisibility();
}
+
+void PrintingSelectorCardOverlayWidget::updateCardAmounts(int mainboardAmount, int sideboardAmount)
+{
+ allZonesCardAmountWidget->setAmounts(mainboardAmount, sideboardAmount);
+ updateVisibility();
+}
+
+/**
+ * @brief Sets the visibility of the widgets depending on the amounts and whether the mouse is hovering over.
+ */
+void PrintingSelectorCardOverlayWidget::updateVisibility()
+{
+ if (allZonesCardAmountWidget->isNonZero() || underMouse()) {
+ allZonesCardAmountWidget->setVisible(true);
+ } else {
+ allZonesCardAmountWidget->setVisible(false);
+ }
+}
+
/**
* @brief Updates the pin badge visibility and position based on the card's pinned state.
*
@@ -182,15 +186,7 @@ void PrintingSelectorCardOverlayWidget::updatePinBadgeVisibility()
void PrintingSelectorCardOverlayWidget::leaveEvent(QEvent *event)
{
QWidget::leaveEvent(event);
-
- // Check if either mainboard or sideboard amount is greater than 0
- if (allZonesCardAmountWidget->getMainboardAmount() > 0 || allZonesCardAmountWidget->getSideboardAmount() > 0) {
- // Don't hide the widget if amounts are greater than 0
- return;
- }
-
- // Hide the widget if amounts are 0
- allZonesCardAmountWidget->setVisible(false);
+ updateVisibility();
}
/**
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 8550612bd..ae2307c45 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
@@ -38,7 +38,11 @@ protected:
signals:
void cardPreferenceChanged();
+public slots:
+ void updateCardAmounts(int mainboardAmount, int sideboardAmount);
+
private slots:
+ void updateVisibility();
void updatePinBadgeVisibility();
private: