[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
10 changed files with 115 additions and 57 deletions

View File

@@ -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;
}
/**

View File

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

View File

@@ -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("<font color='white'>" + QString::number(countCardsInZone(zoneName)) + "</font>");
cardCountInZone->setText("<font color='white'>" + QString::number(amount) + "</font>");
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<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,
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);

View File

@@ -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<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.
*/
@@ -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

View File

@@ -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<QString, QPair<int, int>> &uuidToAmounts);
private:
QVBoxLayout *layout;
SettingsButtonWidget *displayOptionsWidget;

View File

@@ -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<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:
void clampSetNameToPicture();
void updateCardAmounts(const QMap<QString, QPair<int, int>> &uuidToAmounts);
signals:
void cardPreferenceChanged();
private:
ExactCard rootCard;
QVBoxLayout *layout;
SetNameAndCollectorsNumberDisplayWidget *setNameAndCollectorsNumberDisplayWidget;
PrintingSelectorCardOverlayWidget *overlayWidget;

View File

@@ -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<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.
*
* 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();
}
/**

View File

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