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: