From 6c60fc482b815e29a7c88e0e46f4a6e42599933d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Sun, 18 May 2025 16:06:57 +0200 Subject: [PATCH] Actually make widgets track their indices. --- .../src/client/ui/layouts/flow_layout.cpp | 8 ++ .../src/client/ui/layouts/flow_layout.h | 1 + .../card_group_display_widget.cpp | 74 ++++++++---- .../card_group_display_widget.h | 33 +++++- .../flat_card_group_display_widget.cpp | 83 ++++--------- .../flat_card_group_display_widget.h | 27 ++++- .../overlapped_card_group_display_widget.cpp | 83 +------------ .../overlapped_card_group_display_widget.h | 19 ++- .../cards/deck_card_zone_display_widget.cpp | 110 ++++++++---------- .../cards/deck_card_zone_display_widget.h | 1 - .../general/layout_containers/flow_widget.cpp | 6 + .../general/layout_containers/flow_widget.h | 1 + .../visual_deck_editor_widget.cpp | 13 ++- 13 files changed, 213 insertions(+), 246 deletions(-) diff --git a/cockatrice/src/client/ui/layouts/flow_layout.cpp b/cockatrice/src/client/ui/layouts/flow_layout.cpp index 6e00fdb68..3a91e39c3 100644 --- a/cockatrice/src/client/ui/layouts/flow_layout.cpp +++ b/cockatrice/src/client/ui/layouts/flow_layout.cpp @@ -548,6 +548,14 @@ void FlowLayout::addItem(QLayoutItem *item) } } +void FlowLayout::insertWidgetAtIndex(QWidget *toInsert, int index) +{ + addChildWidget(toInsert); + items.insert(qBound(0, index, std::max(0, static_cast(items.size()))), new QWidgetItem(toInsert)); + + invalidate(); +} + /** * @brief Retrieves the count of items in the layout. * @return The number of layout items. diff --git a/cockatrice/src/client/ui/layouts/flow_layout.h b/cockatrice/src/client/ui/layouts/flow_layout.h index d8c6d15c8..19f696d1c 100644 --- a/cockatrice/src/client/ui/layouts/flow_layout.h +++ b/cockatrice/src/client/ui/layouts/flow_layout.h @@ -15,6 +15,7 @@ public: explicit FlowLayout(QWidget *parent = nullptr); FlowLayout(QWidget *parent, Qt::Orientation _flowDirection, int margin = 0, int hSpacing = 0, int vSpacing = 0); ~FlowLayout() override; + void insertWidgetAtIndex(QWidget *toInsert, int index); QSize calculateMinimumSizeHorizontal() const; QSize calculateSizeHintVertical() const; diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp index 7e2caaccc..7af47f79f 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp @@ -9,13 +9,14 @@ CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, + QPersistentModelIndex _trackedIndex, QString _zoneName, QString _cardGroupCategory, QString _activeGroupCriteria, QStringList _activeSortCriteria, int bannerOpacity, CardSizeWidget *_cardSizeWidget) - : QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory), + : QWidget(parent), deckListModel(_deckListModel), trackedIndex(_trackedIndex), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory), activeGroupCriteria(_activeGroupCriteria), activeSortCriteria(_activeSortCriteria), cardSizeWidget(_cardSizeWidget) { @@ -27,41 +28,66 @@ CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent, layout->addWidget(banner); CardGroupDisplayWidget::updateCardDisplays(); + + connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition); + connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); +} + +QWidget* CardGroupDisplayWidget::constructWidgetForIndex(int rowIndex) +{ + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(rowIndex, 0, trackedIndex)); + + if (indexToWidgetMap.contains(index)) { + return indexToWidgetMap[index]; + } + auto cardName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); + auto cardProviderId = deckListModel->data(index.sibling(index.row(), 4), Qt::EditRole).toString(); + qInfo() << cardName; + + auto widget = new CardInfoPictureWithTextOverlayWidget(getLayoutParent(), true); + widget->setScaleFactor(cardSizeWidget->getSlider()->value()); + widget->setCard(CardDatabaseManager::getInstance()->getCardByNameAndProviderId(cardName, cardProviderId)); + + connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, &CardGroupDisplayWidget::onClick); + connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, &CardGroupDisplayWidget::onHover); + connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget, &CardInfoPictureWidget::setScaleFactor); + + indexToWidgetMap.insert(index, widget); + return widget; } void CardGroupDisplayWidget::updateCardDisplays() { + qInfo() << "Constructing Card Display Widgets for Card Group Display widget"; + qInfo() << deckListModel->data(trackedIndex.sibling(trackedIndex.row(), 1), Qt::EditRole).toString() << " has " + << deckListModel->rowCount(trackedIndex.sibling(trackedIndex.row(), 0)) << " entries."; + for (int i = 0; i < deckListModel->rowCount(trackedIndex); ++i) { + addToLayout(constructWidgetForIndex(i)); + } } -QList CardGroupDisplayWidget::getCardsMatchingGroup(QList cardsToSort) +void CardGroupDisplayWidget::onCardAddition(const QModelIndex &parent, int first, int last) { - cardsToSort = sortCardList(cardsToSort, activeSortCriteria, Qt::SortOrder::AscendingOrder); - - QList activeList; - for (const CardInfoPtr &info : cardsToSort) { - if (info && info->getProperty(activeGroupCriteria) == cardGroupCategory) { - activeList.append(info); + if (parent == trackedIndex) { + for (int i = first; i <= last; i++) { + insertIntoLayout(constructWidgetForIndex(i), i); } } - - return activeList; } -QList CardGroupDisplayWidget::sortCardList(QList cardsToSort, - const QStringList properties, - Qt::SortOrder order = Qt::AscendingOrder) +void CardGroupDisplayWidget::onCardRemoval(const QModelIndex &parent, int first, int last) { - CardInfoComparator comparator(properties, order); - std::sort(cardsToSort.begin(), cardsToSort.end(), comparator); - - return cardsToSort; -} - -void CardGroupDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria) -{ - if (activeSortCriteria != _activeSortCriteria) { - activeSortCriteria = _activeSortCriteria; - updateCardDisplays(); // Refresh display with new sorting + Q_UNUSED(parent); + Q_UNUSED(first); + Q_UNUSED(last); + if (parent == trackedIndex) { + for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) { + if (!idx.isValid()) { + removeFromLayout(indexToWidgetMap.value(idx)); + indexToWidgetMap.value(idx)->deleteLater(); + indexToWidgetMap.remove(idx); + } + } } } diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h index 079c5e3ea..244d4f5c9 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h @@ -18,6 +18,7 @@ class CardGroupDisplayWidget : public QWidget public: CardGroupDisplayWidget(QWidget *parent, DeckListModel *deckListModel, + QPersistentModelIndex trackedIndex, QString zoneName, QString cardGroupCategory, QString activeGroupCriteria, @@ -25,10 +26,9 @@ public: int bannerOpacity, CardSizeWidget *cardSizeWidget); - QList getCardsMatchingGroup(QList cardsToSort); - void resizeEvent(QResizeEvent *event) override; - DeckListModel *deckListModel; + QPersistentModelIndex trackedIndex; + QHash indexToWidgetMap; QString zoneName; QString cardGroupCategory; QString activeGroupCriteria; @@ -36,11 +36,13 @@ public: CardSizeWidget *cardSizeWidget; public slots: - QList sortCardList(QList cardsToSort, QStringList properties, Qt::SortOrder order); void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); void onHover(CardInfoPtr card); + virtual QWidget* constructWidgetForIndex(int rowIndex); virtual void updateCardDisplays(); - void onActiveSortCriteriaChanged(QStringList activeSortCriteria); + void onCardAddition(const QModelIndex &parent, int first, int last); + void onCardRemoval(const QModelIndex &parent, int first, int last); + void resizeEvent(QResizeEvent *event) override; signals: void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); @@ -49,5 +51,26 @@ signals: protected: QVBoxLayout *layout; BannerWidget *banner; + + virtual QWidget* getLayoutParent() + { + return this; + } + + virtual void addToLayout(QWidget* toAdd) + { + layout->addWidget(toAdd); + } + + virtual void insertIntoLayout(QWidget *toInsert, int insertAt) + { + qInfo() << "Default card group insert"; + layout->insertWidget(insertAt, toInsert); + } + + virtual void removeFromLayout(QWidget* toRemove) + { + layout->removeWidget(toRemove); + } }; #endif // CARD_GROUP_DISPLAY_WIDGET_H diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp index 62eeb0134..ee8c9d2e5 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp @@ -6,9 +6,11 @@ #include "../card_info_picture_with_text_overlay_widget.h" #include +#include FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, + QPersistentModelIndex _trackedIndex, QString _zoneName, QString _cardGroupCategory, QString _activeGroupCriteria, @@ -17,6 +19,7 @@ FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent, CardSizeWidget *_cardSizeWidget) : CardGroupDisplayWidget(parent, _deckListModel, + std::move(_trackedIndex), _zoneName, _cardGroupCategory, _activeGroupCriteria, @@ -29,78 +32,34 @@ FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent, layout->addWidget(flowWidget); FlatCardGroupDisplayWidget::updateCardDisplays(); - connect(deckListModel, &DeckListModel::dataChanged, this, &FlatCardGroupDisplayWidget::updateCardDisplays); + // connect(deckListModel, &DeckListModel::dataChanged, this, &FlatCardGroupDisplayWidget::updateCardDisplays); } -void FlatCardGroupDisplayWidget::updateCardDisplays() +QWidget* FlatCardGroupDisplayWidget::constructWidgetForIndex(int row) { - // Retrieve and sort cards - QList cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName)); + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(row, 0, trackedIndex)); - // Show or hide widget - bool shouldBeVisible = !cardsInZone.isEmpty(); - if (shouldBeVisible != isVisible()) { - setVisible(shouldBeVisible); + if (indexToWidgetMap.contains(index)) { + return indexToWidgetMap[index]; } + auto cardName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); + auto cardProviderId = deckListModel->data(index.sibling(index.row(), 4), Qt::EditRole).toString(); + qInfo() << cardName; - // Retrieve existing widgets - QList existingWidgets = - flowWidget->findChildren(); + auto widget = new CardInfoPictureWithTextOverlayWidget(flowWidget, true); + widget->setScaleFactor(cardSizeWidget->getSlider()->value()); + widget->setCard(CardDatabaseManager::getInstance()->getCardByNameAndProviderId(cardName, cardProviderId)); - QHash> widgetMap; - for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) { - widgetMap[widget->getInfo()->getName()].append(widget); - } + connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, &FlatCardGroupDisplayWidget::onClick); + connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, &FlatCardGroupDisplayWidget::onHover); + connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget, &CardInfoPictureWidget::setScaleFactor); - QList sortedWidgets; - QSet usedWidgets; - - // Ensure widgets are ordered to match the sorted cards - for (const CardInfoPtr &card : cardsInZone) { - QString name = card->getName(); - CardInfoPictureWithTextOverlayWidget *widget = nullptr; - - if (!widgetMap[name].isEmpty()) { - // Reuse an existing widget - widget = widgetMap[name].takeFirst(); - } else { - // Create a new widget if needed - widget = new CardInfoPictureWithTextOverlayWidget(flowWidget, true); - widget->setScaleFactor(cardSizeWidget->getSlider()->value()); - widget->setCard(card); - - connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, - &FlatCardGroupDisplayWidget::onClick); - connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, - &FlatCardGroupDisplayWidget::onHover); - connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget, - &CardInfoPictureWidget::setScaleFactor); - - flowWidget->addWidget(widget); - } - - // Store in sorted order - sortedWidgets.append(widget); - usedWidgets.insert(widget); - } - - // Remove extra widgets - for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) { - if (!usedWidgets.contains(widget)) { - flowWidget->layout()->removeWidget(widget); - widget->deleteLater(); - } - } - - // **Reorder widgets in place** - for (int i = 0; i < sortedWidgets.size(); ++i) { - sortedWidgets[i]->setParent(nullptr); // Temporarily detach - } - for (int i = 0; i < sortedWidgets.size(); ++i) { - flowWidget->addWidget(sortedWidgets[i]); // Reattach in correct order - } + indexToWidgetMap.insert(index, widget); + return widget; } + + void FlatCardGroupDisplayWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h index 45a75907e..12008e174 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h @@ -11,6 +11,7 @@ class FlatCardGroupDisplayWidget : public CardGroupDisplayWidget public: FlatCardGroupDisplayWidget(QWidget *parent, DeckListModel *deckListModel, + QPersistentModelIndex trackedIndex, QString zoneName, QString cardGroupCategory, QString activeGroupCriteria, @@ -18,13 +19,33 @@ public: int bannerOpacity, CardSizeWidget *cardSizeWidget); - void resizeEvent(QResizeEvent *event) override; - public slots: - void updateCardDisplays() override; + QWidget* constructWidgetForIndex(int row) override; + void resizeEvent(QResizeEvent *event) override; private: FlowWidget *flowWidget; + + QWidget* getLayoutParent() override + { + return flowWidget; + } + + void addToLayout(QWidget* toAdd) override + { + flowWidget->addWidget(toAdd); + } + + void insertIntoLayout(QWidget *toInsert, int insertAt) override + { + qInfo() << "Flat card group insertion at " << insertAt; + flowWidget->insertWidgetAtIndex(toInsert, insertAt); + } + + void removeFromLayout(QWidget* toRemove) override + { + flowWidget->removeWidget(toRemove); + } }; #endif // FLAT_CARD_GROUP_DISPLAY_WIDGET_H diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp index 0e4a88cf3..fbae212d1 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp @@ -9,6 +9,7 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, + QPersistentModelIndex _trackedIndex, QString _zoneName, QString _cardGroupCategory, QString _activeGroupCriteria, @@ -17,6 +18,7 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare CardSizeWidget *_cardSizeWidget) : CardGroupDisplayWidget(parent, _deckListModel, + _trackedIndex, _zoneName, _cardGroupCategory, _activeGroupCriteria, @@ -29,90 +31,11 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare layout->addWidget(overlapWidget); OverlappedCardGroupDisplayWidget::updateCardDisplays(); - connect(deckListModel, &DeckListModel::dataChanged, this, &OverlappedCardGroupDisplayWidget::updateCardDisplays); + connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, this, [this]() { overlapWidget->adjustMaxColumnsAndRows(); }); } -void OverlappedCardGroupDisplayWidget::updateCardDisplays() -{ - overlapWidget->setUpdatesEnabled(false); - // Retrieve and sort cards - QList cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName)); - - // Show or hide widget - bool shouldBeVisible = !cardsInZone.isEmpty(); - if (shouldBeVisible != isVisible()) { - setVisible(shouldBeVisible); - } - - // Retrieve existing widgets - QList existingWidgets = - overlapWidget->findChildren(); - - QHash> widgetMap; - for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) { - widgetMap[widget->getInfo()->getName()].append(widget); - } - - QList sortedWidgets; - QSet usedWidgets; - - // Ensure widgets are ordered to match the sorted cards - for (const CardInfoPtr &card : cardsInZone) { - QString name = card->getName(); - CardInfoPictureWithTextOverlayWidget *widget = nullptr; - - if (!widgetMap[name].isEmpty()) { - // Reuse an existing widget - widget = widgetMap[name].takeFirst(); - } else { - // Create a new widget if needed - widget = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true); - widget->setScaleFactor(cardSizeWidget->getSlider()->value()); - widget->setCard(card); - - connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, - &OverlappedCardGroupDisplayWidget::onClick); - connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, - &OverlappedCardGroupDisplayWidget::onHover); - connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget, - &CardInfoPictureWidget::setScaleFactor); - - overlapWidget->addWidget(widget); - } - - // Store in sorted order - sortedWidgets.append(widget); - usedWidgets.insert(widget); - } - - // Remove extra widgets - for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) { - if (!usedWidgets.contains(widget)) { - overlapWidget->layout()->removeWidget(widget); - widget->deleteLater(); - } - } - - // **Reorder widgets in place** - for (int i = 0; i < sortedWidgets.size(); ++i) { - sortedWidgets[i]->setParent(nullptr); // Temporarily detach - } - for (int i = 0; i < sortedWidgets.size(); ++i) { - overlapWidget->addWidget(sortedWidgets[i]); // Reattach in correct order - } - - // Ensure proper layering - for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) { - widget->raise(); - } - - overlapWidget->adjustMaxColumnsAndRows(); - overlapWidget->setUpdatesEnabled(true); - overlapWidget->update(); -} - void OverlappedCardGroupDisplayWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h index e492316cd..70189fc87 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h @@ -11,6 +11,7 @@ class OverlappedCardGroupDisplayWidget : public CardGroupDisplayWidget public: OverlappedCardGroupDisplayWidget(QWidget *parent, DeckListModel *deckListModel, + QPersistentModelIndex trackedIndex, QString zoneName, QString cardGroupCategory, QString activeGroupCriteria, @@ -20,11 +21,23 @@ public: void resizeEvent(QResizeEvent *event) override; -public slots: - void updateCardDisplays() override; - private: OverlapWidget *overlapWidget; + + QWidget* getLayoutParent() override + { + return overlapWidget; + } + + void addToLayout(QWidget* toAdd) override + { + overlapWidget->addWidget(toAdd); + } + + void removeFromLayout(QWidget* toRemove) override + { + overlapWidget->removeWidget(toRemove); + } }; #endif // OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H diff --git a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp index c92b521c9..70c8cd304 100644 --- a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp @@ -35,8 +35,8 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent, banner->setBuddy(cardGroupContainer); displayCards(); - //connect(deckListModel, &DeckListModel::dataChanged, this, &DeckCardZoneDisplayWidget::displayCards); - //connect(deckListModel, &DeckListModel::dataChanged, this, &DeckCardZoneDisplayWidget::decklistDataChanged); + // connect(deckListModel, &DeckListModel::dataChanged, this, &DeckCardZoneDisplayWidget::displayCards); + // connect(deckListModel, &DeckListModel::dataChanged, this, &DeckCardZoneDisplayWidget::decklistDataChanged); connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &DeckCardZoneDisplayWidget::onCategoryAddition); connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &DeckCardZoneDisplayWidget::onCategoryRemoval); } @@ -44,35 +44,33 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent, void DeckCardZoneDisplayWidget::onCategoryAddition(const QModelIndex &parent, int first, int last) { if (parent == trackedIndex) { + qInfo() << deckListModel->data(trackedIndex.sibling(trackedIndex.row(), 1), Qt::EditRole).toString() << " zone thinks it has a new category"; for (int i = first; i <= last; i++) { - QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 1, trackedIndex)); + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, trackedIndex)); if (indexToWidgetMap.contains(index)) { continue; } - qInfo() << deckListModel->data(index, Qt::EditRole).toString(); + auto categoryName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); + qInfo() << categoryName; if (displayType == "overlap") { auto *display_widget = new OverlappedCardGroupDisplayWidget( - cardGroupContainer, deckListModel, zoneName, deckListModel->data(index, Qt::EditRole).toString(), activeGroupCriteria, activeSortCriteria, - subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, - SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); + cardGroupContainer, deckListModel, index, zoneName, categoryName, + activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); + connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), + this, SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - connect(this, &DeckCardZoneDisplayWidget::activeSortCriteriaChanged, display_widget, - &CardGroupDisplayWidget::onActiveSortCriteriaChanged); cardGroupLayout->addWidget(display_widget); indexToWidgetMap.insert(index, display_widget); } else if (displayType == "flat") { - auto *display_widget = new FlatCardGroupDisplayWidget(cardGroupContainer, deckListModel, zoneName, - deckListModel->data(index, Qt::EditRole).toString(), activeGroupCriteria, activeSortCriteria, - subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, - SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); + auto *display_widget = new FlatCardGroupDisplayWidget( + cardGroupContainer, deckListModel, index, zoneName, categoryName, + activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); + connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), + this, SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - connect(this, &DeckCardZoneDisplayWidget::activeSortCriteriaChanged, display_widget, - &CardGroupDisplayWidget::onActiveSortCriteriaChanged); cardGroupLayout->addWidget(display_widget); indexToWidgetMap.insert(index, display_widget); } @@ -115,6 +113,37 @@ void DeckCardZoneDisplayWidget::onHover(CardInfoPtr card) void DeckCardZoneDisplayWidget::displayCards() { + qInfo() << "Constructing Group Display Widgets for Zone Display widget"; + qInfo() << deckListModel->data(trackedIndex.sibling(trackedIndex.row(), 1), Qt::EditRole).toString() << " has " << deckListModel->rowCount(trackedIndex.sibling(trackedIndex.row(), 0)) << " entries."; + for (int i = 0; i < deckListModel->rowCount(trackedIndex); ++i) { + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, trackedIndex)); + + if (indexToWidgetMap.contains(index)) { + continue; + } + auto categoryName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); + qInfo() << categoryName; + + if (displayType == "overlap") { + auto *display_widget = new OverlappedCardGroupDisplayWidget( + cardGroupContainer, deckListModel, index, zoneName, categoryName, + activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); + connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, + SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); + connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); + cardGroupLayout->addWidget(display_widget); + indexToWidgetMap.insert(index, display_widget); + } else if (displayType == "flat") { + auto *display_widget = new FlatCardGroupDisplayWidget( + cardGroupContainer, deckListModel, index, zoneName, categoryName, + activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); + connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, + SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); + connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); + cardGroupLayout->addWidget(display_widget); + indexToWidgetMap.insert(index, display_widget); + } + } } void DeckCardZoneDisplayWidget::refreshDisplayType(const DisplayType &_displayType) @@ -130,6 +159,8 @@ void DeckCardZoneDisplayWidget::refreshDisplayType(const DisplayType &_displayTy delete item; } + indexToWidgetMap.clear(); + // We gotta wait for all the deleteLater's to finish so we fire after the next event cycle auto timer = new QTimer(this); @@ -138,51 +169,6 @@ void DeckCardZoneDisplayWidget::refreshDisplayType(const DisplayType &_displayTy timer->start(); } -void DeckCardZoneDisplayWidget::addCardGroupIfItDoesNotExist() -{ - QList cardGroupsDisplayWidgets = - cardGroupContainer->findChildren(); - - QList cardGroups = getGroupCriteriaValueList(); - - for (QString cardGroup : cardGroups) { - bool found = false; - for (CardGroupDisplayWidget *cardGroupDisplayWidget : cardGroupsDisplayWidgets) { - if (cardGroupDisplayWidget->cardGroupCategory == cardGroup) { - found = true; - cardGroupDisplayWidget->updateCardDisplays(); - break; - } - } - - if (found) { - continue; - } - - if (displayType == DisplayType::Overlap) { - auto *display_widget = new OverlappedCardGroupDisplayWidget( - cardGroupContainer, deckListModel, zoneName, cardGroup, activeGroupCriteria, activeSortCriteria, - subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, - SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); - connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - connect(this, &DeckCardZoneDisplayWidget::activeSortCriteriaChanged, display_widget, - &CardGroupDisplayWidget::onActiveSortCriteriaChanged); - cardGroupLayout->addWidget(display_widget); - } else if (displayType == DisplayType::Flat) { - auto *display_widget = new FlatCardGroupDisplayWidget(cardGroupContainer, deckListModel, zoneName, - cardGroup, activeGroupCriteria, activeSortCriteria, - subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, - SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); - connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - connect(this, &DeckCardZoneDisplayWidget::activeSortCriteriaChanged, display_widget, - &CardGroupDisplayWidget::onActiveSortCriteriaChanged); - cardGroupLayout->addWidget(display_widget); - } - } -} - void DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged(QString _activeGroupCriteria) { activeGroupCriteria = _activeGroupCriteria; diff --git a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h index e1abd4931..2c0f9c929 100644 --- a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h @@ -38,7 +38,6 @@ public slots: void onHover(CardInfoPtr card); void displayCards(); void refreshDisplayType(const DisplayType &displayType); - void addCardGroupIfItDoesNotExist(); void onActiveGroupCriteriaChanged(QString activeGroupCriteria); void onActiveSortCriteriaChanged(QStringList activeSortCriteria); QList getGroupCriteriaValueList(); diff --git a/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.cpp b/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.cpp index 73b86a573..75ab56b34 100644 --- a/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.cpp +++ b/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.cpp @@ -88,6 +88,12 @@ void FlowWidget::addWidget(QWidget *widget_to_add) const flowLayout->addWidget(widget_to_add); } +void FlowWidget::insertWidgetAtIndex(QWidget *toInsert, int index) +{ + flowLayout->insertWidgetAtIndex(toInsert, index); + update(); +} + void FlowWidget::removeWidget(QWidget *widgetToRemove) const { flowLayout->removeWidget(widgetToRemove); diff --git a/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.h b/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.h index 75ccbf345..246b5a274 100644 --- a/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.h +++ b/cockatrice/src/client/ui/widgets/general/layout_containers/flow_widget.h @@ -20,6 +20,7 @@ public: Qt::ScrollBarPolicy horizontalPolicy, Qt::ScrollBarPolicy verticalPolicy); void addWidget(QWidget *widget_to_add) const; + void insertWidgetAtIndex(QWidget *toInsert, int index); void removeWidget(QWidget *widgetToRemove) const; void clearLayout(); [[nodiscard]] int count() const; diff --git a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp index cf1c49b70..333055c8d 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp @@ -203,16 +203,16 @@ void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first { if (parent == deckListModel->getRoot()) { for (int i = first; i <= last; i++) { - QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 1, deckListModel->getRoot())); + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, deckListModel->getRoot())); if (indexToWidgetMap.contains(index)) { continue; } - qInfo() << deckListModel->data(index, Qt::EditRole).toString(); + qInfo() << "Created zone for " << deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); DeckCardZoneDisplayWidget *zoneDisplayWidget = new DeckCardZoneDisplayWidget( - zoneContainer, deckListModel, index, deckListModel->data(index, Qt::EditRole).toString(), activeGroupCriteria, + zoneContainer, deckListModel, index, deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(), activeGroupCriteria, activeSortCriteria, 20, 10, cardSizeWidget); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick); @@ -222,6 +222,7 @@ void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first &DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged); connect(this, &VisualDeckEditorWidget::displayTypeChanged, zoneDisplayWidget, &DeckCardZoneDisplayWidget::refreshDisplayType); + zoneDisplayWidget->refreshDisplayType(currentDisplayType == DisplayType::Flat ? "flat" : "overlap"); zoneContainerLayout->addWidget(zoneDisplayWidget); indexToWidgetMap.insert(index, zoneDisplayWidget); @@ -247,16 +248,16 @@ void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel() { qInfo() << "Constructing zone widgets"; for (int i = 0; i < deckListModel->rowCount(deckListModel->parent(QModelIndex())); ++i) { - QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 1, deckListModel->getRoot())); + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, deckListModel->getRoot())); if (indexToWidgetMap.contains(index)) { continue; } - qInfo() << deckListModel->data(index, Qt::EditRole).toString(); + qInfo() << deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); DeckCardZoneDisplayWidget *zoneDisplayWidget = new DeckCardZoneDisplayWidget( - zoneContainer, deckListModel, index, deckListModel->data(index, Qt::EditRole).toString(), activeGroupCriteria, + zoneContainer, deckListModel, index, deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(), activeGroupCriteria, activeSortCriteria, 20, 10, cardSizeWidget); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick);