From f72c82d0f9a33828ad9bbaeeb0a91ed8ebe14ffc Mon Sep 17 00:00:00 2001 From: kongwu <167565490+kongwu666@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:46:43 +0800 Subject: [PATCH] [DeckEditor] Replace mainboard/sideboard with tokensboard for tokens (#6971) * [DeckEditor] Replace mainboard/sideboard with tokensboard for token cards (#6546) * [PrintingSelector] Replace std::tuple with ZoneCounts struct for readability (#6546) --- .../deck_editor/deck_state_manager.cpp | 4 ++ .../all_zones_card_amount_widget.cpp | 37 ++++++++++++-- .../all_zones_card_amount_widget.h | 5 +- .../printing_selector/card_amount_widget.cpp | 48 ++++++++++++++++--- .../printing_selector/card_amount_widget.h | 2 + .../printing_selector/printing_selector.cpp | 17 +++++-- .../printing_selector/printing_selector.h | 11 ++++- .../printing_selector_card_display_widget.cpp | 6 +-- .../printing_selector_card_display_widget.h | 2 +- .../printing_selector_card_overlay_widget.cpp | 10 ++-- .../printing_selector_card_overlay_widget.h | 2 +- 11 files changed, 115 insertions(+), 29 deletions(-) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp index 6db8e5623..f8fb450ce 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp @@ -255,6 +255,10 @@ bool DeckStateManager::swapCardAtIndex(const QModelIndex &idx) } QString zoneName = gparent.siblingAtColumn(DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString(); + // tokens have no swap target + if (zoneName == DECK_ZONE_TOKENS) { + return false; + } QString otherZoneName = zoneName == DECK_ZONE_MAIN ? DECK_ZONE_SIDE : DECK_ZONE_MAIN; QString reason = tr("Moved to %1 1 × \"%2\" (%3)") // 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 36bccbcc3..05e269174 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 @@ -8,7 +8,7 @@ * @brief Constructor for the AllZonesCardAmountWidget class. * * Initializes the widget with its layout and sets up the connections and necessary - * UI elements for managing card counts in both the mainboard and sideboard zones. + * UI elements for managing card counts in all the mainboard, tokensboard and sideboard zones. * * @param parent The parent widget. * @param deckStateManager Pointer to the DeckStateManager @@ -31,13 +31,28 @@ AllZonesCardAmountWidget::AllZonesCardAmountWidget(QWidget *parent, buttonBoxMainboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_MAIN); zoneLabelSideboard = new ShadowBackgroundLabel(this, tr("Sideboard")); buttonBoxSideboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_SIDE); + zoneLabelTokensboard = new ShadowBackgroundLabel(this, tr("Tokens")); + buttonBoxTokensboard = new CardAmountWidget(this, deckStateManager, cardSizeSlider, rootCard, DECK_ZONE_TOKENS); layout->addWidget(zoneLabelMainboard, 0, Qt::AlignHCenter | Qt::AlignBottom); layout->addWidget(buttonBoxMainboard, 0, Qt::AlignHCenter | Qt::AlignTop); - layout->addSpacing(25); + layout->addSpacing(12); + layout->addWidget(zoneLabelTokensboard, 0, Qt::AlignHCenter | Qt::AlignBottom); + layout->addWidget(buttonBoxTokensboard, 0, Qt::AlignHCenter | Qt::AlignTop); + layout->addSpacing(13); layout->addWidget(zoneLabelSideboard, 0, Qt::AlignHCenter | Qt::AlignBottom); layout->addWidget(buttonBoxSideboard, 0, Qt::AlignHCenter | Qt::AlignTop); + // Show Tokens buttons for token cards, Mainboard/Sideboard for non-token cards + bool isToken = rootCard.getInfo().getIsToken(); + + zoneLabelMainboard->setVisible(!isToken); + buttonBoxMainboard->setVisible(!isToken); + zoneLabelTokensboard->setVisible(isToken); + buttonBoxTokensboard->setVisible(isToken); + zoneLabelSideboard->setVisible(!isToken); + buttonBoxSideboard->setVisible(!isToken); + connect(cardSizeSlider, &QSlider::valueChanged, this, &AllZonesCardAmountWidget::adjustFontSize); QTimer::singleShot(10, this, [this]() { adjustFontSize(this->cardSizeSlider->value()); }); @@ -67,15 +82,17 @@ void AllZonesCardAmountWidget::adjustFontSize(int scalePercentage) zoneLabelFont.setPointSize(newFontSize); zoneLabelMainboard->setFont(zoneLabelFont); zoneLabelSideboard->setFont(zoneLabelFont); + zoneLabelTokensboard->setFont(zoneLabelFont); // Repaint the widget (if necessary) repaint(); } -void AllZonesCardAmountWidget::setAmounts(int mainboardAmount, int sideboardAmount) +void AllZonesCardAmountWidget::setAmounts(int mainboardAmount, int sideboardAmount, int tokensboardAmount) { buttonBoxMainboard->setAmount(mainboardAmount); buttonBoxSideboard->setAmount(sideboardAmount); + buttonBoxTokensboard->setAmount(tokensboardAmount); } /** @@ -99,11 +116,21 @@ int AllZonesCardAmountWidget::getSideboardAmount() } /** - * @brief Checks if the amount is at least one in either the mainboard or sideboard. + * @brief Gets the card count in the tokensboard zone. + * + * @return The number of cards in the tokensboard. + */ +int AllZonesCardAmountWidget::getTokensboardAmount() +{ + return buttonBoxTokensboard->getAmount(); +} + +/** + * @brief Checks if the amount is at least one in either the mainboard or sideboard or tokensboard. */ bool AllZonesCardAmountWidget::isNonZero() { - return getMainboardAmount() > 0 || getSideboardAmount() > 0; + return getMainboardAmount() > 0 || getSideboardAmount() > 0 || getTokensboardAmount() > 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 05047d94f..de4a984be 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,7 @@ public: const ExactCard &rootCard); int getMainboardAmount(); int getSideboardAmount(); + int getTokensboardAmount(); bool isNonZero(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) @@ -33,7 +34,7 @@ public: public slots: void adjustFontSize(int scalePercentage); - void setAmounts(int mainboardAmount, int sideboardAmount); + void setAmounts(int mainboardAmount, int sideboardAmount, int tokensboardAmount); private: QVBoxLayout *layout; @@ -42,6 +43,8 @@ private: CardAmountWidget *buttonBoxMainboard; QLabel *zoneLabelSideboard; CardAmountWidget *buttonBoxSideboard; + QLabel *zoneLabelTokensboard; + CardAmountWidget *buttonBoxTokensboard; }; #endif // ALL_ZONES_CARD_AMOUNT_WIDGET_H 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 25222f437..ff47e7b9c 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp @@ -11,7 +11,7 @@ * @param parent The parent widget. * @param cardSizeSlider Pointer to the QSlider for adjusting font size. * @param rootCard The root card to manage within the widget. - * @param zoneName The zone name (e.g., DECK_ZONE_MAIN or DECK_ZONE_SIDE). + * @param zoneName The zone name (e.g., DECK_ZONE_MAIN , DECK_ZONE_SIDE, or DECK_ZONE_TOKENS). */ CardAmountWidget::CardAmountWidget(QWidget *parent, DeckStateManager *deckStateManager, @@ -36,13 +36,16 @@ CardAmountWidget::CardAmountWidget(QWidget *parent, incrementButton->setFixedSize(parentWidget()->size().width() / 3, parentWidget()->size().height() / 9); decrementButton->setFixedSize(parentWidget()->size().width() / 3, parentWidget()->size().height() / 9); - // Set up connections based on the zone (Mainboard or Sideboard) + // Set up connections based on the zone (Mainboard, Sideboard, or Tokensboard) if (zoneName == DECK_ZONE_MAIN) { connect(incrementButton, &QPushButton::clicked, this, &CardAmountWidget::addPrintingMainboard); connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingMainboard); } else if (zoneName == DECK_ZONE_SIDE) { connect(incrementButton, &QPushButton::clicked, this, &CardAmountWidget::addPrintingSideboard); connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingSideboard); + } else if (zoneName == DECK_ZONE_TOKENS) { + connect(incrementButton, &QPushButton::clicked, this, &CardAmountWidget::addPrintingTokensboard); + connect(decrementButton, &QPushButton::clicked, this, &CardAmountWidget::removePrintingTokensboard); } cardCountInZone = new QLabel(QString::number(amount), this); @@ -137,6 +140,19 @@ void CardAmountWidget::updateCardCount() layout->activate(); } +static QString zoneLogName(const QString &zone) +{ + if (zone == DECK_ZONE_MAIN) { + return "mainboard"; + } else if (zone == DECK_ZONE_SIDE) { + return "sideboard"; + } else if (zone == DECK_ZONE_TOKENS) { + return "tokens"; + } else { + return "unknown"; + } +} + static QModelIndex addAndReplacePrintings(DeckListModel *model, const QModelIndex &existing, const ExactCard &rootCard, @@ -161,9 +177,9 @@ static QModelIndex addAndReplacePrintings(DeckListModel *model, } /** - * @brief Adds a printing of the card to the specified zone (Mainboard or Sideboard). + * @brief Adds a printing of the card to the specified zone (Mainboard, Sideboard, or Tokensboard). * - * @param zone The zone to add the card to (DECK_ZONE_MAIN or DECK_ZONE_SIDE). + * @param zone The zone to add the card to (DECK_ZONE_MAIN, DECK_ZONE_SIDE, or DECK_ZONE_TOKENS). */ void CardAmountWidget::addPrinting(const QString &zone) { @@ -183,12 +199,13 @@ void CardAmountWidget::addPrinting(const QString &zone) } } + QString zoneName = zoneLogName(zone); QString reason = QString("Added %1 copies of '%2 (%3) %4' to %5 [ProviderID: %6]%7") .arg(1 + extraCopies) .arg(rootCard.getName()) .arg(rootCard.getPrinting().getSet()->getShortName()) .arg(rootCard.getPrinting().getProperty("num")) - .arg(zone == DECK_ZONE_MAIN ? "mainboard" : "sideboard") + .arg(zoneName) .arg(rootCard.getPrinting().getUuid()) .arg(replacingProviderless ? " (replaced providerless printings)" : ""); @@ -218,6 +235,14 @@ void CardAmountWidget::addPrintingSideboard() addPrinting(DECK_ZONE_SIDE); } +/** + * @brief Adds a printing to the tokens zone. + */ +void CardAmountWidget::addPrintingTokensboard() +{ + addPrinting(DECK_ZONE_TOKENS); +} + /** * @brief Removes a printing from the mainboard zone. */ @@ -234,18 +259,27 @@ void CardAmountWidget::removePrintingSideboard() decrementCardHelper(DECK_ZONE_SIDE); } +/** + * @brief Removes a printing from the tokens zone. + */ +void CardAmountWidget::removePrintingTokensboard() +{ + decrementCardHelper(DECK_ZONE_TOKENS); +} + /** * @brief Helper function to decrement the card count for a given zone. * - * @param zone The zone from which to remove the card (DECK_ZONE_MAIN or DECK_ZONE_SIDE). + * @param zone The zone from which to remove the card (DECK_ZONE_MAIN, DECK_ZONE_SIDE, or DECK_ZONE_TOKENS). */ void CardAmountWidget::decrementCardHelper(const QString &zone) { + QString zoneName = zoneLogName(zone); QString reason = QString("Removed 1 copy of '%1 (%2) %3' from %4 [ProviderID: %5]") .arg(rootCard.getName()) .arg(rootCard.getPrinting().getSet()->getShortName()) .arg(rootCard.getPrinting().getProperty("num")) - .arg(zone == DECK_ZONE_MAIN ? "mainboard" : "sideboard") + .arg(zoneName) .arg(rootCard.getPrinting().getUuid()); deckStateManager->modifyDeck(reason, [this, &zone](auto model) { 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 f0f2128f0..2780e3ad2 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h @@ -60,8 +60,10 @@ private: private slots: void addPrintingMainboard(); void addPrintingSideboard(); + void addPrintingTokensboard(); void removePrintingMainboard(); void removePrintingSideboard(); + void removePrintingTokensboard(); void adjustFontSize(int scalePercentage); }; diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp index 71b93b297..76a416587 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp @@ -105,23 +105,30 @@ void PrintingSelector::printingsInDeckChanged() } /** - * @return A map of uuid to amounts (main, side). + * @return A map of uuid to amounts (main, side, tokens). */ -static QMap> tallyUuidCounts(const DeckListModel *model, const QString &cardName) +static QMap tallyUuidCounts(const DeckListModel *model, const QString &cardName) { - QMap> map; + QMap map; auto mainNodes = model->getCardNodesForZone(DECK_ZONE_MAIN); for (auto &node : mainNodes) { if (node->getName() == cardName) { - map[node->getCardProviderId()].first += node->getNumber(); + map[node->getCardProviderId()].mainboard += node->getNumber(); } } auto sideNodes = model->getCardNodesForZone(DECK_ZONE_SIDE); for (auto &node : sideNodes) { if (node->getName() == cardName) { - map[node->getCardProviderId()].second += node->getNumber(); + map[node->getCardProviderId()].sideboard += node->getNumber(); + } + } + + auto tokensNodes = model->getCardNodesForZone(DECK_ZONE_TOKENS); + for (auto &node : tokensNodes) { + if (node->getName() == cardName) { + map[node->getCardProviderId()].tokensboard += node->getNumber(); } } diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h index b9e6723f2..14d73f836 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h @@ -22,6 +22,13 @@ #define BATCH_SIZE 10 +struct ZoneCounts +{ + int mainboard = 0; + int sideboard = 0; + int tokensboard = 0; +}; + class DeckStateManager; class PrintingSelectorCardSearchWidget; class PrintingSelectorCardSelectionWidget; @@ -59,9 +66,9 @@ signals: /** * The amounts of the printings in the deck has changed - * @param uuidToAmounts Map of uuids to the amounts (maindeck, sideboard) in the deck + * @param uuidToAmounts Map of uuids to the amounts (maindeck, sideboard, tokensboard) in the deck */ - void cardAmountsChanged(const QMap> &uuidToAmounts); + void cardAmountsChanged(const QMap &uuidToAmounts); private: QVBoxLayout *layout; 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 7d0b4882f..edeba86d1 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 @@ -67,10 +67,10 @@ void PrintingSelectorCardDisplayWidget::clampSetNameToPicture() update(); } -void PrintingSelectorCardDisplayWidget::updateCardAmounts(const QMap> &uuidToAmounts) +void PrintingSelectorCardDisplayWidget::updateCardAmounts(const QMap &uuidToAmounts) { - auto [main, side] = uuidToAmounts.value(rootCard.getPrinting().getUuid()); - overlayWidget->updateCardAmounts(main, side); + auto counts = uuidToAmounts.value(rootCard.getPrinting().getUuid()); + overlayWidget->updateCardAmounts(counts.mainboard, counts.sideboard, counts.tokensboard); } void PrintingSelectorCardDisplayWidget::resizeEvent(QResizeEvent *event) 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 b708bd973..4de561f4f 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,7 +27,7 @@ public: public slots: void clampSetNameToPicture(); - void updateCardAmounts(const QMap> &uuidToAmounts); + void updateCardAmounts(const QMap &uuidToAmounts); void resizeEvent(QResizeEvent *event) override; 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 69334d6f3..dd5f6dd7f 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 @@ -116,9 +116,11 @@ void PrintingSelectorCardOverlayWidget::enterEvent(QEvent *event) updateVisibility(); } -void PrintingSelectorCardOverlayWidget::updateCardAmounts(int mainboardAmount, int sideboardAmount) +void PrintingSelectorCardOverlayWidget::updateCardAmounts(int mainboardAmount, + int sideboardAmount, + int tokensboardAmount) { - allZonesCardAmountWidget->setAmounts(mainboardAmount, sideboardAmount); + allZonesCardAmountWidget->setAmounts(mainboardAmount, sideboardAmount, tokensboardAmount); updateVisibility(); } @@ -173,8 +175,8 @@ void PrintingSelectorCardOverlayWidget::updatePinBadgeVisibility() /** * @brief Handles the mouse leave event when the cursor leaves the overlay widget area. * - * When the cursor leaves the widget, the card amount widget is hidden if both the mainboard and sideboard - * amounts are zero. + * When the cursor leaves the widget, the card amount widget is hidden if all of the mainboard, sideboard, and + * tokensboard amounts are zero. * * @param event The event triggered when the mouse leaves the widget. */ 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 2fdf5ab74..52a43d220 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 @@ -39,7 +39,7 @@ signals: void cardPreferenceChanged(); public slots: - void updateCardAmounts(int mainboardAmount, int sideboardAmount); + void updateCardAmounts(int mainboardAmount, int sideboardAmount, int tokensboardAmount); private slots: void updateVisibility();