From ed5dbb77b53f3462f01a4894ae582a65010eb6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Thu, 22 Jan 2026 20:36:53 +0100 Subject: [PATCH] [VDE] Accurately represent card amounts. Took 40 minutes Took 3 seconds Took 3 minutes Took 2 minutes --- .../card_group_display_widget.cpp | 78 +++++++++++++++---- .../card_group_display_widget.h | 3 +- .../flat_card_group_display_widget.cpp | 8 +- .../overlapped_card_group_display_widget.cpp | 7 +- 4 files changed, 75 insertions(+), 21 deletions(-) diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp index 8e6ebed63..a8ce6a671 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp @@ -37,6 +37,7 @@ CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent, &CardGroupDisplayWidget::onSelectionChanged); } connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); + connect(deckListModel, &QAbstractItemModel::dataChanged, this, &CardGroupDisplayWidget::onDataChanged); } // Just here so it can get overwritten in subclasses. @@ -81,8 +82,11 @@ void CardGroupDisplayWidget::onSelectionChanged(const QItemSelection &selected, auto it = indexToWidgetMap.find(QPersistentModelIndex(idx)); if (it != indexToWidgetMap.end()) { - if (auto displayWidget = qobject_cast(it.value())) { - displayWidget->setHighlighted(true); + // Highlight all copies of this card + for (auto widget : it.value()) { + if (auto displayWidget = qobject_cast(widget)) { + displayWidget->setHighlighted(true); + } } } } @@ -96,8 +100,11 @@ void CardGroupDisplayWidget::onSelectionChanged(const QItemSelection &selected, auto it = indexToWidgetMap.find(QPersistentModelIndex(idx)); if (it != indexToWidgetMap.end()) { - if (auto displayWidget = qobject_cast(it.value())) { - displayWidget->setHighlighted(false); + // Un-highlight all copies of this card + for (auto widget : it.value()) { + if (auto displayWidget = qobject_cast(widget)) { + displayWidget->setHighlighted(false); + } } } } @@ -110,9 +117,6 @@ void CardGroupDisplayWidget::onSelectionChanged(const QItemSelection &selected, QWidget *CardGroupDisplayWidget::constructWidgetForIndex(QPersistentModelIndex index) { - if (indexToWidgetMap.contains(index)) { - return indexToWidgetMap[index]; - } auto cardName = index.sibling(index.row(), DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString(); auto cardProviderId = index.sibling(index.row(), DeckListModelColumns::CARD_PROVIDER_ID).data(Qt::EditRole).toString(); @@ -125,7 +129,12 @@ QWidget *CardGroupDisplayWidget::constructWidgetForIndex(QPersistentModelIndex i connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, &CardGroupDisplayWidget::onHover); connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget, &CardInfoPictureWidget::setScaleFactor); - indexToWidgetMap.insert(index, widget); + // Add to the list of widgets for this index + if (!indexToWidgetMap.contains(index)) { + indexToWidgetMap.insert(index, QList()); + } + indexToWidgetMap[index].append(widget); + return widget; } @@ -152,17 +161,25 @@ void CardGroupDisplayWidget::updateCardDisplays() // 4. persist the source index QPersistentModelIndex persistent(sourceIndex); - addToLayout(constructWidgetForIndex(persistent)); + // Get the card amount + int cardAmount = + sourceIndex.sibling(sourceIndex.row(), DeckListModelColumns::CARD_AMOUNT).data(Qt::EditRole).toInt(); + + // Create multiple widgets for the card count + for (int copy = 0; copy < cardAmount; ++copy) { + addToLayout(constructWidgetForIndex(persistent)); + } } } void CardGroupDisplayWidget::clearAllDisplayWidgets() { for (auto idx : indexToWidgetMap.keys()) { - auto displayWidget = indexToWidgetMap.value(idx); - removeFromLayout(displayWidget); + for (auto displayWidget : indexToWidgetMap.value(idx)) { + removeFromLayout(displayWidget); + delete displayWidget; + } indexToWidgetMap.remove(idx); - delete displayWidget; } } @@ -184,7 +201,13 @@ void CardGroupDisplayWidget::onCardAddition(const QModelIndex &parent, int first // Persist the index QPersistentModelIndex persistent(child); - insertIntoLayout(constructWidgetForIndex(persistent), row); + // Get the card amount for the newly added card + int cardAmount = child.sibling(child.row(), DeckListModelColumns::CARD_AMOUNT).data(Qt::EditRole).toInt(); + + // Insert multiple copies + for (int copy = 0; copy < cardAmount; ++copy) { + insertIntoLayout(constructWidgetForIndex(persistent), row); + } } } } @@ -193,21 +216,44 @@ void CardGroupDisplayWidget::onCardRemoval(const QModelIndex &parent, int first, { Q_UNUSED(first); Q_UNUSED(last); + if (parent == trackedIndex) { + QList keysToRemove; + for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) { if (!idx.isValid()) { - removeFromLayout(indexToWidgetMap.value(idx)); - indexToWidgetMap.value(idx)->deleteLater(); - indexToWidgetMap.remove(idx); + keysToRemove.append(idx); } } + for (const QPersistentModelIndex &idx : keysToRemove) { + for (auto widget : indexToWidgetMap.value(idx)) { + removeFromLayout(widget); + widget->deleteLater(); + } + indexToWidgetMap.remove(idx); + } + if (!trackedIndex.isValid()) { emit cleanupRequested(this); } } } +void CardGroupDisplayWidget::onDataChanged(const QModelIndex &topLeft, + const QModelIndex &bottomRight, + const QVector &roles) +{ + Q_UNUSED(roles); + if (topLeft.parent() != trackedIndex && bottomRight.parent() != trackedIndex) { + return; + } + + // When card amounts change, rebuild the display + clearAllDisplayWidgets(); + updateCardDisplays(); +} + void CardGroupDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria) { activeSortCriteria = std::move(_activeSortCriteria); diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h index 73c43abbc..e3a47dfd0 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h @@ -38,7 +38,7 @@ public: DeckListModel *deckListModel; QItemSelectionModel *selectionModel; QPersistentModelIndex trackedIndex; - QHash indexToWidgetMap; + QMap> indexToWidgetMap; QString zoneName; QString cardGroupCategory; QString activeGroupCriteria; @@ -53,6 +53,7 @@ public slots: virtual void updateCardDisplays(); virtual void onCardAddition(const QModelIndex &parent, int first, int last); virtual void onCardRemoval(const QModelIndex &parent, int first, int last); + void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); void onActiveSortCriteriaChanged(QStringList activeSortCriteria); void resizeEvent(QResizeEvent *event) override; diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp index e52242c7b..a192d13d8 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp @@ -31,13 +31,17 @@ FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent, layout->addWidget(flowWidget); + // Clear all existing widgets for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) { - FlatCardGroupDisplayWidget::removeFromLayout(indexToWidgetMap.value(idx)); - indexToWidgetMap.value(idx)->deleteLater(); + for (auto widget : indexToWidgetMap.value(idx)) { + FlatCardGroupDisplayWidget::removeFromLayout(widget); + widget->deleteLater(); + } indexToWidgetMap.remove(idx); } FlatCardGroupDisplayWidget::updateCardDisplays(); + disconnect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition); disconnect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp index 27741a79c..dca8ee2a5 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp @@ -30,9 +30,12 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare layout->addWidget(overlapWidget); + // Clear all existing widgets for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) { - OverlappedCardGroupDisplayWidget::removeFromLayout(indexToWidgetMap.value(idx)); - indexToWidgetMap.value(idx)->deleteLater(); + for (auto widget : indexToWidgetMap.value(idx)) { + OverlappedCardGroupDisplayWidget::removeFromLayout(widget); + widget->deleteLater(); + } indexToWidgetMap.remove(idx); }