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 ce920c33c..81f9f7c7e 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 @@ -10,7 +10,7 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, QString _zoneName, QString _activeGroupCriteria, - QString _activeSortCriteria, + QStringList _activeSortCriteria, int bannerOpacity, int subBannerOpacity) : QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), activeGroupCriteria(_activeGroupCriteria), @@ -108,7 +108,7 @@ void DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged(QString _activeGrou displayCards(); } -void DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged(QString _activeSortCriteria) +void DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria) { activeSortCriteria = _activeSortCriteria; emit activeSortCriteriaChanged(activeSortCriteria); 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 7810a21a8..1f0d28c96 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 @@ -19,7 +19,7 @@ public: DeckListModel *deckListModel, QString zoneName, QString activeGroupCriteria, - QString activeSortCriteria, + QStringList activeSortCriteria, int bannerOpacity, int subBannerOpacity); DeckListModel *deckListModel; @@ -34,17 +34,17 @@ public slots: void addCardGroupIfItDoesNotExist(); void deleteCardGroupIfItDoesNotExist(); void onActiveGroupCriteriaChanged(QString activeGroupCriteria); - void onActiveSortCriteriaChanged(QString activeSortCriteria); + void onActiveSortCriteriaChanged(QStringList activeSortCriteria); QList getGroupCriteriaValueList(); signals: void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName); void cardHovered(CardInfoPtr card); - void activeSortCriteriaChanged(QString activeSortCriteria); + void activeSortCriteriaChanged(QStringList activeSortCriteria); private: QString activeGroupCriteria; - QString activeSortCriteria; + QStringList activeSortCriteria; QVBoxLayout *layout; BannerWidget *banner; QWidget *cardGroupContainer; diff --git a/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.cpp index 1da5775f1..75d12bee9 100644 --- a/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.cpp @@ -12,7 +12,7 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare QString _zoneName, QString _cardGroupCategory, QString _activeGroupCriteria, - QString _activeSortCriteria, + QStringList _activeSortCriteria, int bannerOpacity) : QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory), activeGroupCriteria(_activeGroupCriteria), activeSortCriteria(_activeSortCriteria) @@ -33,69 +33,70 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare void OverlappedCardGroupDisplayWidget::updateCardDisplays() { + // 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 requiredCounts; - for (const CardInfoPtr &card : cardsInZone) { - requiredCounts[card->getName()]++; - } - QHash> widgetMap; for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) { widgetMap[widget->getInfo()->getName()].append(widget); } - // Remove excess widgets - for (auto it = widgetMap.begin(); it != widgetMap.end(); ++it) { - QString name = it.key(); - QList &widgets = it.value(); - - int neededCount = requiredCounts.value(name, 0); - while (widgets.size() > neededCount) { - CardInfoPictureWithTextOverlayWidget *widgetToRemove = widgets.takeLast(); - overlapWidget->layout()->removeWidget(widgetToRemove); // Remove from layout - delete widgetToRemove; - } - } - - // Add missing widgets and reorder existing ones 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()) { - // Use existing widget - CardInfoPictureWithTextOverlayWidget *widget = widgetMap[name].takeFirst(); - sortedWidgets.append(widget); + // Reuse an existing widget + widget = widgetMap[name].takeFirst(); } else { - // Create new widget if needed - auto *display = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true); - display->setCard(card); + // Create a new widget if needed + widget = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true); + widget->setCard(card); - connect(display, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, + connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, &OverlappedCardGroupDisplayWidget::onClick); - connect(display, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, + connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, &OverlappedCardGroupDisplayWidget::onHover); - sortedWidgets.append(display); - overlapWidget->addWidget(display); + 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); + delete widget; } } - // **Reorder Widgets in Layout** - for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) { - overlapWidget->removeWidget(widget); - overlapWidget->addWidget(widget); + // **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(); } @@ -105,35 +106,29 @@ void OverlappedCardGroupDisplayWidget::updateCardDisplays() QList OverlappedCardGroupDisplayWidget::getCardsMatchingGroup(QList cardsToSort) { + cardsToSort = sortCardList(cardsToSort, activeSortCriteria, Qt::SortOrder::AscendingOrder); + QList activeList; - - QStringList sortCriteria; - sortCriteria.append(activeSortCriteria); - sortCardList(cardsToSort, sortCriteria, Qt::SortOrder::AscendingOrder); - - for (int i = 0; i < cardsToSort.size(); ++i) { - CardInfoPtr info = cardsToSort.at(i); - if (info) { - if (info->getProperty(activeGroupCriteria) == cardGroupCategory) { - activeList.append(info); - } - } else { - qDebug() << "Card not found in database!"; + for (const CardInfoPtr &info : cardsToSort) { + if (info && info->getProperty(activeGroupCriteria) == cardGroupCategory) { + activeList.append(info); } } return activeList; } -void OverlappedCardGroupDisplayWidget::sortCardList(QList cardsToSort, - const QStringList properties, - Qt::SortOrder order = Qt::AscendingOrder) +QList OverlappedCardGroupDisplayWidget::sortCardList(QList cardsToSort, + const QStringList properties, + Qt::SortOrder order = Qt::AscendingOrder) { CardInfoComparator comparator(properties, order); std::sort(cardsToSort.begin(), cardsToSort.end(), comparator); + + return cardsToSort; } -void OverlappedCardGroupDisplayWidget::onActiveSortCriteriaChanged(QString _activeSortCriteria) +void OverlappedCardGroupDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria) { if (activeSortCriteria != _activeSortCriteria) { activeSortCriteria = _activeSortCriteria; diff --git a/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.h b/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.h index 00ce7c138..cbc3e5428 100644 --- a/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/overlapped_card_group_display_widget.h @@ -21,7 +21,7 @@ public: QString zoneName, QString cardGroupCategory, QString activeGroupCriteria, - QString activeSortCriteria, + QStringList activeSortCriteria, int bannerOpacity); QList getCardsMatchingGroup(QList cardsToSort); @@ -31,14 +31,14 @@ public: QString zoneName; QString cardGroupCategory; QString activeGroupCriteria; - QString activeSortCriteria; + QStringList activeSortCriteria; public slots: - void sortCardList(QList cardsToSort, QStringList properties, Qt::SortOrder order); + QList sortCardList(QList cardsToSort, QStringList properties, Qt::SortOrder order); void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); void onHover(CardInfoPtr card); void updateCardDisplays(); - void onActiveSortCriteriaChanged(QString activeSortCriteria); + void onActiveSortCriteriaChanged(QStringList activeSortCriteria); signals: void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); 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 382e6c0a4..332330cb9 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 @@ -27,6 +27,11 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_ mainLayout = new QVBoxLayout(); this->setLayout(mainLayout); + groupAndSortContainer = new QWidget(this); + groupAndSortLayout = new QHBoxLayout(groupAndSortContainer); + groupAndSortLayout->setAlignment(Qt::AlignLeft); + groupAndSortContainer->setLayout(groupAndSortLayout); + groupByComboBox = new QComboBox(); QStringList groupProperties; groupProperties << "maintype" @@ -34,21 +39,35 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_ << "cmc" << "name"; groupByComboBox->addItems(groupProperties); + groupByComboBox->setMinimumWidth(300); connect(groupByComboBox, QOverload::of(&QComboBox::currentTextChanged), this, &VisualDeckEditorWidget::actChangeActiveGroupCriteria); actChangeActiveGroupCriteria(); - sortByComboBox = new QComboBox(); - QStringList sortProperties; - sortProperties << "name" - << "cmc" - << "colors" - << "maintype"; - sortByComboBox->addItems(sortProperties); - connect(sortByComboBox, QOverload::of(&QComboBox::currentTextChanged), this, + sortCriteriaButton = new SettingsButtonWidget(this); + + QStringList sortProperties = {"colors", "cmc", "name", "maintype"}; + sortByListWidget = new QListWidget(); + sortByListWidget->setSelectionMode(QAbstractItemView::SingleSelection); + sortByListWidget->setDragDropMode(QAbstractItemView::InternalMove); + sortByListWidget->setDefaultDropAction(Qt::MoveAction); + + for (const QString &property : sortProperties) { + QListWidgetItem *item = new QListWidgetItem(property, sortByListWidget); + item->setFlags(item->flags() | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + } + + connect(sortByListWidget->model(), &QAbstractItemModel::rowsMoved, this, &VisualDeckEditorWidget::actChangeActiveSortCriteria); + // connect(sortByListWidget, &QListWidget::itemChanged, this, &VisualDeckEditorWidget::actChangeActiveSortCriteria); actChangeActiveSortCriteria(); + sortByListWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + sortCriteriaButton->addSettingsWidget(sortByListWidget); + + groupAndSortLayout->addWidget(groupByComboBox); + groupAndSortLayout->addWidget(sortCriteriaButton); + scrollArea = new QScrollArea(); scrollArea->setWidgetResizable(true); scrollArea->setMinimumSize(0, 0); @@ -67,8 +86,7 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_ overlapControlWidget = new OverlapControlWidget(80, 1, 1, Qt::Vertical, this); - mainLayout->addWidget(groupByComboBox); - mainLayout->addWidget(sortByComboBox); + mainLayout->addWidget(groupAndSortContainer); mainLayout->addWidget(scrollArea); mainLayout->addWidget(overlapControlWidget); } @@ -139,8 +157,16 @@ void VisualDeckEditorWidget::actChangeActiveGroupCriteria() void VisualDeckEditorWidget::actChangeActiveSortCriteria() { - activeSortCriteria = sortByComboBox->currentText(); - emit activeSortCriteriaChanged(activeSortCriteria); + qDebug() << "lol lmao, triggered"; + QStringList selectedCriteria; + for (int i = 0; i < sortByListWidget->count(); ++i) { + QListWidgetItem *item = sortByListWidget->item(i); + selectedCriteria.append(item->text()); // Collect user-defined sort order + } + + activeSortCriteria = selectedCriteria; + + emit activeSortCriteriaChanged(selectedCriteria); } void VisualDeckEditorWidget::decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight) diff --git a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h index 0a57b28b2..3d69352c6 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h +++ b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h @@ -6,7 +6,9 @@ #include "../cards/card_info_picture_with_text_overlay_widget.h" #include "../general/layout_containers/flow_widget.h" #include "../general/layout_containers/overlap_control_widget.h" +#include "../quick_settings/settings_button_widget.h" +#include #include #include @@ -29,7 +31,7 @@ public slots: signals: void activeCardChanged(CardInfoPtr activeCard); void activeGroupCriteriaChanged(QString activeGroupCriteria); - void activeSortCriteriaChanged(QString activeSortCriteria); + void activeSortCriteriaChanged(QStringList activeSortCriteria); void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName); protected slots: @@ -41,10 +43,13 @@ protected slots: private: DeckListModel *deckListModel; QVBoxLayout *mainLayout; + QWidget *groupAndSortContainer; + QHBoxLayout *groupAndSortLayout; QComboBox *groupByComboBox; QString activeGroupCriteria = "maintype"; - QComboBox *sortByComboBox; - QString activeSortCriteria = "name"; + SettingsButtonWidget *sortCriteriaButton; + QListWidget *sortByListWidget; + QStringList activeSortCriteria = {"name", "cmc", "colors", "maintype"}; QScrollArea *scrollArea; QWidget *zoneContainer; QVBoxLayout *zoneContainerLayout;