Fix and improve sorting, properly layout grouping and sorting.

This commit is contained in:
Lukas Brübach 2025-03-08 10:24:09 +01:00
parent c9f95e1df1
commit edd0199efb
6 changed files with 102 additions and 76 deletions

View file

@ -10,7 +10,7 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
DeckListModel *_deckListModel, DeckListModel *_deckListModel,
QString _zoneName, QString _zoneName,
QString _activeGroupCriteria, QString _activeGroupCriteria,
QString _activeSortCriteria, QStringList _activeSortCriteria,
int bannerOpacity, int bannerOpacity,
int subBannerOpacity) int subBannerOpacity)
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), activeGroupCriteria(_activeGroupCriteria), : QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), activeGroupCriteria(_activeGroupCriteria),
@ -108,7 +108,7 @@ void DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged(QString _activeGrou
displayCards(); displayCards();
} }
void DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged(QString _activeSortCriteria) void DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria)
{ {
activeSortCriteria = _activeSortCriteria; activeSortCriteria = _activeSortCriteria;
emit activeSortCriteriaChanged(activeSortCriteria); emit activeSortCriteriaChanged(activeSortCriteria);

View file

@ -19,7 +19,7 @@ public:
DeckListModel *deckListModel, DeckListModel *deckListModel,
QString zoneName, QString zoneName,
QString activeGroupCriteria, QString activeGroupCriteria,
QString activeSortCriteria, QStringList activeSortCriteria,
int bannerOpacity, int bannerOpacity,
int subBannerOpacity); int subBannerOpacity);
DeckListModel *deckListModel; DeckListModel *deckListModel;
@ -34,17 +34,17 @@ public slots:
void addCardGroupIfItDoesNotExist(); void addCardGroupIfItDoesNotExist();
void deleteCardGroupIfItDoesNotExist(); void deleteCardGroupIfItDoesNotExist();
void onActiveGroupCriteriaChanged(QString activeGroupCriteria); void onActiveGroupCriteriaChanged(QString activeGroupCriteria);
void onActiveSortCriteriaChanged(QString activeSortCriteria); void onActiveSortCriteriaChanged(QStringList activeSortCriteria);
QList<QString> getGroupCriteriaValueList(); QList<QString> getGroupCriteriaValueList();
signals: signals:
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName); void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName);
void cardHovered(CardInfoPtr card); void cardHovered(CardInfoPtr card);
void activeSortCriteriaChanged(QString activeSortCriteria); void activeSortCriteriaChanged(QStringList activeSortCriteria);
private: private:
QString activeGroupCriteria; QString activeGroupCriteria;
QString activeSortCriteria; QStringList activeSortCriteria;
QVBoxLayout *layout; QVBoxLayout *layout;
BannerWidget *banner; BannerWidget *banner;
QWidget *cardGroupContainer; QWidget *cardGroupContainer;

View file

@ -12,7 +12,7 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare
QString _zoneName, QString _zoneName,
QString _cardGroupCategory, QString _cardGroupCategory,
QString _activeGroupCriteria, QString _activeGroupCriteria,
QString _activeSortCriteria, QStringList _activeSortCriteria,
int bannerOpacity) int bannerOpacity)
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory), : QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory),
activeGroupCriteria(_activeGroupCriteria), activeSortCriteria(_activeSortCriteria) activeGroupCriteria(_activeGroupCriteria), activeSortCriteria(_activeSortCriteria)
@ -33,69 +33,70 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare
void OverlappedCardGroupDisplayWidget::updateCardDisplays() void OverlappedCardGroupDisplayWidget::updateCardDisplays()
{ {
// Retrieve and sort cards
QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName)); QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName));
// Show or hide widget
bool shouldBeVisible = !cardsInZone.isEmpty(); bool shouldBeVisible = !cardsInZone.isEmpty();
if (shouldBeVisible != isVisible()) { if (shouldBeVisible != isVisible()) {
setVisible(shouldBeVisible); setVisible(shouldBeVisible);
} }
// Retrieve existing widgets
QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets = QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets =
overlapWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>(); overlapWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>();
QHash<QString, int> requiredCounts;
for (const CardInfoPtr &card : cardsInZone) {
requiredCounts[card->getName()]++;
}
QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap; QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap;
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) { for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
widgetMap[widget->getInfo()->getName()].append(widget); widgetMap[widget->getInfo()->getName()].append(widget);
} }
// Remove excess widgets
for (auto it = widgetMap.begin(); it != widgetMap.end(); ++it) {
QString name = it.key();
QList<CardInfoPictureWithTextOverlayWidget *> &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<CardInfoPictureWithTextOverlayWidget *> sortedWidgets; QList<CardInfoPictureWithTextOverlayWidget *> sortedWidgets;
QSet<CardInfoPictureWithTextOverlayWidget *> usedWidgets;
// Ensure widgets are ordered to match the sorted cards
for (const CardInfoPtr &card : cardsInZone) { for (const CardInfoPtr &card : cardsInZone) {
QString name = card->getName(); QString name = card->getName();
CardInfoPictureWithTextOverlayWidget *widget = nullptr;
if (!widgetMap[name].isEmpty()) { if (!widgetMap[name].isEmpty()) {
// Use existing widget // Reuse an existing widget
CardInfoPictureWithTextOverlayWidget *widget = widgetMap[name].takeFirst(); widget = widgetMap[name].takeFirst();
sortedWidgets.append(widget);
} else { } else {
// Create new widget if needed // Create a new widget if needed
auto *display = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true); widget = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true);
display->setCard(card); widget->setCard(card);
connect(display, &CardInfoPictureWithTextOverlayWidget::imageClicked, this, connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this,
&OverlappedCardGroupDisplayWidget::onClick); &OverlappedCardGroupDisplayWidget::onClick);
connect(display, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this, connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this,
&OverlappedCardGroupDisplayWidget::onHover); &OverlappedCardGroupDisplayWidget::onHover);
sortedWidgets.append(display); overlapWidget->addWidget(widget);
overlapWidget->addWidget(display); }
// 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** // **Reorder widgets in place**
for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) { for (int i = 0; i < sortedWidgets.size(); ++i) {
overlapWidget->removeWidget(widget); sortedWidgets[i]->setParent(nullptr); // Temporarily detach
overlapWidget->addWidget(widget); }
for (int i = 0; i < sortedWidgets.size(); ++i) {
overlapWidget->addWidget(sortedWidgets[i]); // Reattach in correct order
} }
// Ensure proper layering
for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) { for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) {
widget->raise(); widget->raise();
} }
@ -105,35 +106,29 @@ void OverlappedCardGroupDisplayWidget::updateCardDisplays()
QList<CardInfoPtr> OverlappedCardGroupDisplayWidget::getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort) QList<CardInfoPtr> OverlappedCardGroupDisplayWidget::getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort)
{ {
cardsToSort = sortCardList(cardsToSort, activeSortCriteria, Qt::SortOrder::AscendingOrder);
QList<CardInfoPtr> activeList; QList<CardInfoPtr> activeList;
for (const CardInfoPtr &info : cardsToSort) {
QStringList sortCriteria; if (info && info->getProperty(activeGroupCriteria) == cardGroupCategory) {
sortCriteria.append(activeSortCriteria); activeList.append(info);
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!";
} }
} }
return activeList; return activeList;
} }
void OverlappedCardGroupDisplayWidget::sortCardList(QList<CardInfoPtr> cardsToSort, QList<CardInfoPtr> OverlappedCardGroupDisplayWidget::sortCardList(QList<CardInfoPtr> cardsToSort,
const QStringList properties, const QStringList properties,
Qt::SortOrder order = Qt::AscendingOrder) Qt::SortOrder order = Qt::AscendingOrder)
{ {
CardInfoComparator comparator(properties, order); CardInfoComparator comparator(properties, order);
std::sort(cardsToSort.begin(), cardsToSort.end(), comparator); std::sort(cardsToSort.begin(), cardsToSort.end(), comparator);
return cardsToSort;
} }
void OverlappedCardGroupDisplayWidget::onActiveSortCriteriaChanged(QString _activeSortCriteria) void OverlappedCardGroupDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria)
{ {
if (activeSortCriteria != _activeSortCriteria) { if (activeSortCriteria != _activeSortCriteria) {
activeSortCriteria = _activeSortCriteria; activeSortCriteria = _activeSortCriteria;

View file

@ -21,7 +21,7 @@ public:
QString zoneName, QString zoneName,
QString cardGroupCategory, QString cardGroupCategory,
QString activeGroupCriteria, QString activeGroupCriteria,
QString activeSortCriteria, QStringList activeSortCriteria,
int bannerOpacity); int bannerOpacity);
QList<CardInfoPtr> getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort); QList<CardInfoPtr> getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort);
@ -31,14 +31,14 @@ public:
QString zoneName; QString zoneName;
QString cardGroupCategory; QString cardGroupCategory;
QString activeGroupCriteria; QString activeGroupCriteria;
QString activeSortCriteria; QStringList activeSortCriteria;
public slots: public slots:
void sortCardList(QList<CardInfoPtr> cardsToSort, QStringList properties, Qt::SortOrder order); QList<CardInfoPtr> sortCardList(QList<CardInfoPtr> cardsToSort, QStringList properties, Qt::SortOrder order);
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
void onHover(CardInfoPtr card); void onHover(CardInfoPtr card);
void updateCardDisplays(); void updateCardDisplays();
void onActiveSortCriteriaChanged(QString activeSortCriteria); void onActiveSortCriteriaChanged(QStringList activeSortCriteria);
signals: signals:
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);

View file

@ -27,6 +27,11 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_
mainLayout = new QVBoxLayout(); mainLayout = new QVBoxLayout();
this->setLayout(mainLayout); this->setLayout(mainLayout);
groupAndSortContainer = new QWidget(this);
groupAndSortLayout = new QHBoxLayout(groupAndSortContainer);
groupAndSortLayout->setAlignment(Qt::AlignLeft);
groupAndSortContainer->setLayout(groupAndSortLayout);
groupByComboBox = new QComboBox(); groupByComboBox = new QComboBox();
QStringList groupProperties; QStringList groupProperties;
groupProperties << "maintype" groupProperties << "maintype"
@ -34,21 +39,35 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_
<< "cmc" << "cmc"
<< "name"; << "name";
groupByComboBox->addItems(groupProperties); groupByComboBox->addItems(groupProperties);
groupByComboBox->setMinimumWidth(300);
connect(groupByComboBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged), this, connect(groupByComboBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged), this,
&VisualDeckEditorWidget::actChangeActiveGroupCriteria); &VisualDeckEditorWidget::actChangeActiveGroupCriteria);
actChangeActiveGroupCriteria(); actChangeActiveGroupCriteria();
sortByComboBox = new QComboBox(); sortCriteriaButton = new SettingsButtonWidget(this);
QStringList sortProperties;
sortProperties << "name" QStringList sortProperties = {"colors", "cmc", "name", "maintype"};
<< "cmc" sortByListWidget = new QListWidget();
<< "colors" sortByListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
<< "maintype"; sortByListWidget->setDragDropMode(QAbstractItemView::InternalMove);
sortByComboBox->addItems(sortProperties); sortByListWidget->setDefaultDropAction(Qt::MoveAction);
connect(sortByComboBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged), this,
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); &VisualDeckEditorWidget::actChangeActiveSortCriteria);
// connect(sortByListWidget, &QListWidget::itemChanged, this, &VisualDeckEditorWidget::actChangeActiveSortCriteria);
actChangeActiveSortCriteria(); actChangeActiveSortCriteria();
sortByListWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
sortCriteriaButton->addSettingsWidget(sortByListWidget);
groupAndSortLayout->addWidget(groupByComboBox);
groupAndSortLayout->addWidget(sortCriteriaButton);
scrollArea = new QScrollArea(); scrollArea = new QScrollArea();
scrollArea->setWidgetResizable(true); scrollArea->setWidgetResizable(true);
scrollArea->setMinimumSize(0, 0); scrollArea->setMinimumSize(0, 0);
@ -67,8 +86,7 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_
overlapControlWidget = new OverlapControlWidget(80, 1, 1, Qt::Vertical, this); overlapControlWidget = new OverlapControlWidget(80, 1, 1, Qt::Vertical, this);
mainLayout->addWidget(groupByComboBox); mainLayout->addWidget(groupAndSortContainer);
mainLayout->addWidget(sortByComboBox);
mainLayout->addWidget(scrollArea); mainLayout->addWidget(scrollArea);
mainLayout->addWidget(overlapControlWidget); mainLayout->addWidget(overlapControlWidget);
} }
@ -139,8 +157,16 @@ void VisualDeckEditorWidget::actChangeActiveGroupCriteria()
void VisualDeckEditorWidget::actChangeActiveSortCriteria() void VisualDeckEditorWidget::actChangeActiveSortCriteria()
{ {
activeSortCriteria = sortByComboBox->currentText(); qDebug() << "lol lmao, triggered";
emit activeSortCriteriaChanged(activeSortCriteria); 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) void VisualDeckEditorWidget::decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight)

View file

@ -6,7 +6,9 @@
#include "../cards/card_info_picture_with_text_overlay_widget.h" #include "../cards/card_info_picture_with_text_overlay_widget.h"
#include "../general/layout_containers/flow_widget.h" #include "../general/layout_containers/flow_widget.h"
#include "../general/layout_containers/overlap_control_widget.h" #include "../general/layout_containers/overlap_control_widget.h"
#include "../quick_settings/settings_button_widget.h"
#include <QListWidget>
#include <QWidget> #include <QWidget>
#include <qscrollarea.h> #include <qscrollarea.h>
@ -29,7 +31,7 @@ public slots:
signals: signals:
void activeCardChanged(CardInfoPtr activeCard); void activeCardChanged(CardInfoPtr activeCard);
void activeGroupCriteriaChanged(QString activeGroupCriteria); void activeGroupCriteriaChanged(QString activeGroupCriteria);
void activeSortCriteriaChanged(QString activeSortCriteria); void activeSortCriteriaChanged(QStringList activeSortCriteria);
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName); void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
protected slots: protected slots:
@ -41,10 +43,13 @@ protected slots:
private: private:
DeckListModel *deckListModel; DeckListModel *deckListModel;
QVBoxLayout *mainLayout; QVBoxLayout *mainLayout;
QWidget *groupAndSortContainer;
QHBoxLayout *groupAndSortLayout;
QComboBox *groupByComboBox; QComboBox *groupByComboBox;
QString activeGroupCriteria = "maintype"; QString activeGroupCriteria = "maintype";
QComboBox *sortByComboBox; SettingsButtonWidget *sortCriteriaButton;
QString activeSortCriteria = "name"; QListWidget *sortByListWidget;
QStringList activeSortCriteria = {"name", "cmc", "colors", "maintype"};
QScrollArea *scrollArea; QScrollArea *scrollArea;
QWidget *zoneContainer; QWidget *zoneContainer;
QVBoxLayout *zoneContainerLayout; QVBoxLayout *zoneContainerLayout;