[PrintingSelector] optimize amount calculation (#6478)

This commit is contained in:
RickyRister 2026-01-03 01:04:56 -08:00 committed by GitHub
parent 84aefda486
commit 4fbb9d9682
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 115 additions and 57 deletions

View file

@ -72,6 +72,12 @@ void AllZonesCardAmountWidget::adjustFontSize(int scalePercentage)
repaint(); repaint();
} }
void AllZonesCardAmountWidget::setAmounts(int mainboardAmount, int sideboardAmount)
{
buttonBoxMainboard->setAmount(mainboardAmount);
buttonBoxSideboard->setAmount(sideboardAmount);
}
/** /**
* @brief Gets the card count in the mainboard zone. * @brief Gets the card count in the mainboard zone.
* *
@ -79,7 +85,7 @@ void AllZonesCardAmountWidget::adjustFontSize(int scalePercentage)
*/ */
int AllZonesCardAmountWidget::getMainboardAmount() int AllZonesCardAmountWidget::getMainboardAmount()
{ {
return buttonBoxMainboard->countCardsInZone(DECK_ZONE_MAIN); return buttonBoxMainboard->getAmount();
} }
/** /**
@ -89,7 +95,15 @@ int AllZonesCardAmountWidget::getMainboardAmount()
*/ */
int AllZonesCardAmountWidget::getSideboardAmount() 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;
} }
/** /**

View file

@ -23,6 +23,8 @@ public:
const ExactCard &rootCard); const ExactCard &rootCard);
int getMainboardAmount(); int getMainboardAmount();
int getSideboardAmount(); int getSideboardAmount();
bool isNonZero();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent *event) override; void enterEvent(QEnterEvent *event) override;
#else #else
@ -31,6 +33,7 @@ public:
public slots: public slots:
void adjustFontSize(int scalePercentage); void adjustFontSize(int scalePercentage);
void setAmounts(int mainboardAmount, int sideboardAmount);
private: private:
QVBoxLayout *layout; QVBoxLayout *layout;

View file

@ -45,20 +45,28 @@ CardAmountWidget::CardAmountWidget(QWidget *parent,
connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingSideboard); 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); cardCountInZone->setAlignment(Qt::AlignCenter);
layout->addWidget(decrementButton); layout->addWidget(decrementButton);
layout->addWidget(cardCountInZone); layout->addWidget(cardCountInZone);
layout->addWidget(incrementButton); layout->addWidget(incrementButton);
// React to model changes
connect(deckStateManager, &DeckStateManager::cardModified, this, &CardAmountWidget::updateCardCount);
// Connect slider for dynamic font size adjustment // Connect slider for dynamic font size adjustment
connect(cardSizeSlider, &QSlider::valueChanged, this, &CardAmountWidget::adjustFontSize); 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. * @brief Handles the painting of the widget, drawing a semi-transparent background.
* *
@ -124,7 +132,7 @@ void CardAmountWidget::adjustFontSize(int scalePercentage)
*/ */
void CardAmountWidget::updateCardCount() void CardAmountWidget::updateCardCount()
{ {
cardCountInZone->setText("<font color='white'>" + QString::number(countCardsInZone(zoneName)) + "</font>"); cardCountInZone->setText("<font color='white'>" + QString::number(amount) + "</font>");
layout->invalidate(); layout->invalidate();
layout->activate(); layout->activate();
} }
@ -169,8 +177,8 @@ void CardAmountWidget::addPrinting(const QString &zone)
QString foundProviderId = QString foundProviderId =
existing.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data(Qt::DisplayRole).toString(); existing.siblingAtColumn(DeckListModelColumns::CARD_PROVIDER_ID).data(Qt::DisplayRole).toString();
if (foundProviderId.isEmpty()) { if (foundProviderId.isEmpty()) {
int amount = existing.data(Qt::DisplayRole).toInt(); int existingAmount = existing.data(Qt::DisplayRole).toInt();
extraCopies = amount - 1; // One less because we *always* add one extraCopies = existingAmount - 1; // One less because we *always* add one
replacingProviderless = true; replacingProviderless = true;
} }
} }
@ -246,23 +254,3 @@ void CardAmountWidget::decrementCardHelper(const QString &zone)
return model->offsetCountAtIndex(idx, -1); 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<ExactCard> cards = deckStateManager->getModel()->getCardsForZone(deckZone);
return std::count_if(cards.cbegin(), cards.cend(),
[&uuid](const ExactCard &card) { return card.getPrinting().getUuid() == uuid; });
}

View file

@ -31,9 +31,10 @@ public:
QSlider *cardSizeSlider, QSlider *cardSizeSlider,
const ExactCard &rootCard, const ExactCard &rootCard,
const QString &zoneName); const QString &zoneName);
int countCardsInZone(const QString &deckZone); int getAmount();
public slots: public slots:
void setAmount(int _amount);
void updateCardCount(); void updateCardCount();
void addPrinting(const QString &zone); void addPrinting(const QString &zone);
@ -52,6 +53,7 @@ private:
QLabel *cardCountInZone; QLabel *cardCountInZone;
bool hovered; bool hovered;
int amount = 0;
void decrementCardHelper(const QString &zoneName); void decrementCardHelper(const QString &zoneName);

View file

@ -78,6 +78,7 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck
// Connect deck model data change signal to update display // Connect deck model data change signal to update display
connect(deckStateManager, &DeckStateManager::uniqueCardsChanged, this, &PrintingSelector::printingsInDeckChanged); connect(deckStateManager, &DeckStateManager::uniqueCardsChanged, this, &PrintingSelector::printingsInDeckChanged);
connect(deckStateManager, &DeckStateManager::cardModified, this, &PrintingSelector::updateCardAmounts);
retranslateUi(); retranslateUi();
} }
@ -93,6 +94,36 @@ void PrintingSelector::printingsInDeckChanged()
QTimer::singleShot(100, this, &PrintingSelector::updateDisplay); QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
} }
/**
* @return A map of uuid to amounts (main, side).
*/
static QMap<QString, QPair<int, int>> tallyUuidCounts(const DeckListModel *model, const QString &cardName)
{
QMap<QString, QPair<int, int>> 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. * @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()); printingsToUse = sortToolBar->prependPinnedPrintings(printingsToUse, selectedCard->getName());
auto uuidToAmounts = tallyUuidCounts(deckStateManager->getModel(), selectedCard->getName());
// Defer widget creation // Defer widget creation
currentIndex = 0; currentIndex = 0;
@ -166,8 +199,11 @@ void PrintingSelector::getAllSetsForCurrentCard()
cardSizeWidget->getSlider(), card); cardSizeWidget->getSlider(), card);
flowWidget->addWidget(cardDisplayWidget); flowWidget->addWidget(cardDisplayWidget);
cardDisplayWidget->clampSetNameToPicture(); cardDisplayWidget->clampSetNameToPicture();
cardDisplayWidget->updateCardAmounts(uuidToAmounts);
connect(cardDisplayWidget, &PrintingSelectorCardDisplayWidget::cardPreferenceChanged, this, connect(cardDisplayWidget, &PrintingSelectorCardDisplayWidget::cardPreferenceChanged, this,
&PrintingSelector::updateDisplay); &PrintingSelector::updateDisplay);
connect(this, &PrintingSelector::cardAmountsChanged, cardDisplayWidget,
&PrintingSelectorCardDisplayWidget::updateCardAmounts);
} }
// Stop timer when done // Stop timer when done

View file

@ -44,6 +44,7 @@ public slots:
private slots: private slots:
void printingsInDeckChanged(); void printingsInDeckChanged();
void updateCardAmounts();
signals: signals:
/** /**
@ -55,6 +56,12 @@ signals:
*/ */
void nextCardRequested(); 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<QString, QPair<int, int>> &uuidToAmounts);
private: private:
QVBoxLayout *layout; QVBoxLayout *layout;
SettingsButtonWidget *displayOptionsWidget; SettingsButtonWidget *displayOptionsWidget;

View file

@ -27,7 +27,7 @@ PrintingSelectorCardDisplayWidget::PrintingSelectorCardDisplayWidget(QWidget *pa
DeckStateManager *deckStateManager, DeckStateManager *deckStateManager,
QSlider *cardSizeSlider, QSlider *cardSizeSlider,
const ExactCard &rootCard) const ExactCard &rootCard)
: QWidget(parent) : QWidget(parent), rootCard(rootCard)
{ {
layout = new QVBoxLayout(this); layout = new QVBoxLayout(this);
setLayout(layout); setLayout(layout);
@ -64,3 +64,9 @@ void PrintingSelectorCardDisplayWidget::clampSetNameToPicture()
} }
update(); update();
} }
void PrintingSelectorCardDisplayWidget::updateCardAmounts(const QMap<QString, QPair<int, int>> &uuidToAmounts)
{
auto [main, side] = uuidToAmounts.value(rootCard.getPrinting().getUuid());
overlayWidget->updateCardAmounts(main, side);
}

View file

@ -27,11 +27,13 @@ public:
public slots: public slots:
void clampSetNameToPicture(); void clampSetNameToPicture();
void updateCardAmounts(const QMap<QString, QPair<int, int>> &uuidToAmounts);
signals: signals:
void cardPreferenceChanged(); void cardPreferenceChanged();
private: private:
ExactCard rootCard;
QVBoxLayout *layout; QVBoxLayout *layout;
SetNameAndCollectorsNumberDisplayWidget *setNameAndCollectorsNumberDisplayWidget; SetNameAndCollectorsNumberDisplayWidget *setNameAndCollectorsNumberDisplayWidget;
PrintingSelectorCardOverlayWidget *overlayWidget; PrintingSelectorCardOverlayWidget *overlayWidget;

View file

@ -59,12 +59,6 @@ PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *pa
allZonesCardAmountWidget = new AllZonesCardAmountWidget(this, deckStateManager, cardSizeSlider, _rootCard); allZonesCardAmountWidget = new AllZonesCardAmountWidget(this, deckStateManager, cardSizeSlider, _rootCard);
allZonesCardAmountWidget->raise(); // Ensure it's on top of the picture 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 // Attempt to cast the parent to PrintingSelectorCardDisplayWidget
if (const auto *parentWidget = qobject_cast<PrintingSelectorCardDisplayWidget *>(parent)) { if (const auto *parentWidget = qobject_cast<PrintingSelectorCardDisplayWidget *>(parent)) {
@ -113,8 +107,7 @@ void PrintingSelectorCardOverlayWidget::resizeEvent(QResizeEvent *event)
/** /**
* @brief Handles the mouse enter event when the cursor enters the overlay widget area. * @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 * When the cursor enters the widget, the card amount widget becomes visible regardless of whether the amounts are zero.
* is displayed if the amounts are zero for both the mainboard and sideboard.
* *
* @param event The event triggered when the mouse enters the widget. * @param event The event triggered when the mouse enters the widget.
*/ */
@ -126,16 +119,27 @@ void PrintingSelectorCardOverlayWidget::enterEvent(QEvent *event)
{ {
QWidget::enterEvent(event); QWidget::enterEvent(event);
deckEditor->updateCard(rootCard); deckEditor->updateCard(rootCard);
updateVisibility();
// 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);
} }
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. * @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) void PrintingSelectorCardOverlayWidget::leaveEvent(QEvent *event)
{ {
QWidget::leaveEvent(event); QWidget::leaveEvent(event);
updateVisibility();
// 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);
} }
/** /**

View file

@ -38,7 +38,11 @@ protected:
signals: signals:
void cardPreferenceChanged(); void cardPreferenceChanged();
public slots:
void updateCardAmounts(int mainboardAmount, int sideboardAmount);
private slots: private slots:
void updateVisibility();
void updatePinBadgeVisibility(); void updatePinBadgeVisibility();
private: private: