Functional stuff.

This commit is contained in:
Lukas Brübach 2025-06-13 01:58:21 +02:00
parent d6f3f876c3
commit b0b244a342
10 changed files with 167 additions and 82 deletions

View file

@ -28,17 +28,17 @@ CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent,
layout->addWidget(banner);
qInfo() << "Tracked index (default CardGroupDisplayWidget): " << cardGroupCategory << " (" << zoneName << ")"
<< "_trackedIndex.isValid()=" << _trackedIndex.isValid()
<< "row=" << _trackedIndex.row()
<< "column=" << _trackedIndex.column()
<< "parent(row)=" << _trackedIndex.parent().row()
<< "_trackedIndex.isValid()=" << _trackedIndex.isValid() << "row=" << _trackedIndex.row()
<< "column=" << _trackedIndex.column() << "parent(row)=" << _trackedIndex.parent().row()
<< "parent(column)=" << _trackedIndex.parent().column();
connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition);
connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval);
// CardGroupDisplayWidget::updateCardDisplays();
// connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition);
// connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval);
}
QWidget* CardGroupDisplayWidget::constructWidgetForIndex(int rowIndex)
QWidget *CardGroupDisplayWidget::constructWidgetForIndex(int rowIndex)
{
QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(rowIndex, 0, trackedIndex));
@ -73,12 +73,14 @@ void CardGroupDisplayWidget::updateCardDisplays()
void CardGroupDisplayWidget::onCardAddition(const QModelIndex &parent, int first, int last)
{
if (!trackedIndex.isValid()) {
emit cleanupRequested(this);
return;
}
if (parent == trackedIndex) {
qInfo() << "Tracked index (default CardGroupDisplayWidget): " << cardGroupCategory << " (" << zoneName << ")"
<< "_trackedIndex.isValid()=" << trackedIndex.isValid()
<< "row=" << trackedIndex.row()
<< "column=" << trackedIndex.column()
<< "parent(row)=" << trackedIndex.parent().row()
<< "_trackedIndex.isValid()=" << trackedIndex.isValid() << "row=" << trackedIndex.row()
<< "column=" << trackedIndex.column() << "parent(row)=" << trackedIndex.parent().row()
<< "parent(column)=" << trackedIndex.parent().column();
qInfo() << "Card addition to " << cardGroupCategory;
for (int i = first; i <= last; i++) {
@ -101,6 +103,9 @@ void CardGroupDisplayWidget::onCardRemoval(const QModelIndex &parent, int first,
indexToWidgetMap.remove(idx);
}
}
if (!trackedIndex.isValid()) {
emit cleanupRequested(this);
}
}
}

View file

@ -47,6 +47,7 @@ public slots:
signals:
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
void cardHovered(CardInfoPtr card);
void cleanupRequested(CardGroupDisplayWidget *cardGroupDisplayWidget);
protected:
QVBoxLayout *layout;

View file

@ -31,12 +31,24 @@ FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent,
banner->setBuddy(flowWidget);
layout->addWidget(flowWidget);
for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) {
FlatCardGroupDisplayWidget::removeFromLayout(indexToWidgetMap.value(idx));
indexToWidgetMap.value(idx)->deleteLater();
indexToWidgetMap.remove(idx);
}
qInfo() << "Initialized a flat CardGroupDisplayWidget";
FlatCardGroupDisplayWidget::updateCardDisplays();
// connect(deckListModel, &DeckListModel::dataChanged, this, &FlatCardGroupDisplayWidget::updateCardDisplays);
disconnect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition);
disconnect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval);
connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &FlatCardGroupDisplayWidget::onCardAddition);
connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &FlatCardGroupDisplayWidget::onCardRemoval);
}
QWidget* FlatCardGroupDisplayWidget::constructWidgetForIndex(int row)
QWidget *FlatCardGroupDisplayWidget::constructWidgetForIndex(int row)
{
QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(row, 0, trackedIndex));
@ -59,8 +71,6 @@ QWidget* FlatCardGroupDisplayWidget::constructWidgetForIndex(int row)
return widget;
}
void FlatCardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);

View file

@ -30,11 +30,24 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare
banner->setBuddy(overlapWidget);
layout->addWidget(overlapWidget);
for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) {
OverlappedCardGroupDisplayWidget::removeFromLayout(indexToWidgetMap.value(idx));
indexToWidgetMap.value(idx)->deleteLater();
indexToWidgetMap.remove(idx);
}
qInfo() << "Initialized an overlap CardGroupDisplayWidget";
OverlappedCardGroupDisplayWidget::updateCardDisplays();
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, this,
[this]() { overlapWidget->adjustMaxColumnsAndRows(); });
disconnect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition);
disconnect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval);
connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &OverlappedCardGroupDisplayWidget::onCardAddition);
connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &OverlappedCardGroupDisplayWidget::onCardRemoval);
}
void OverlappedCardGroupDisplayWidget::resizeEvent(QResizeEvent *event)

View file

@ -45,50 +45,80 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
<< "parent(row)=" << _trackedIndex.parent().row() << "parent(column)=" << _trackedIndex.parent().column()
<< "parent(valid)=" << _trackedIndex.parent().isValid();
}
qInfo() << "Cleaning up invalid card group " << displayWidget->cardGroupCategory << " from " << displayWidget->zoneName;
void DeckCardZoneDisplayWidget::cleanupInvalidCardGroup(CardGroupDisplayWidget *displayWidget)
{
qInfo() << "Cleaning up invalid card group " << displayWidget->cardGroupCategory << " from "
<< displayWidget->zoneName;
cardGroupLayout->removeWidget(displayWidget);
for (auto idx : indexToWidgetMap.keys()) {
if (!idx.isValid()) {
indexToWidgetMap.remove(idx);
}
}
displayWidget->deleteLater();
qInfo() << "Cleaned.";
}
void DeckCardZoneDisplayWidget::constructAppropriateWidget(QPersistentModelIndex index)
{
auto categoryName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString();
if (indexToWidgetMap.contains(index)) {
qInfo() << categoryName << " is already contained in the index to widget map";
return;
} else {
qInfo() << categoryName << " needs a widget";
}
if (displayType == "overlap") {
qInfo() << "It's getting an overlap widget.";
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)));
connect(display_widget, &CardGroupDisplayWidget::cleanupRequested, this,
&DeckCardZoneDisplayWidget::cleanupInvalidCardGroup);
cardGroupLayout->addWidget(display_widget);
indexToWidgetMap.insert(index, display_widget);
} else if (displayType == "flat") {
qInfo() << "Getting a flat widget for christmas";
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(display_widget, &CardGroupDisplayWidget::cleanupRequested, this,
&DeckCardZoneDisplayWidget::cleanupInvalidCardGroup);
cardGroupLayout->addWidget(display_widget);
indexToWidgetMap.insert(index, display_widget);
}
}
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));
constructAppropriateWidget(index);
}
}
void DeckCardZoneDisplayWidget::onCategoryAddition(const QModelIndex &parent, int first, int last)
{
if (!trackedIndex.isValid()) {
emit requestCleanup(this);
}
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, 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);
}
constructAppropriateWidget(index);
}
}
}
@ -105,6 +135,9 @@ void DeckCardZoneDisplayWidget::onCategoryRemoval(const QModelIndex &parent, int
indexToWidgetMap.remove(idx);
}
}
if (!trackedIndex.isValid()) {
emit requestCleanup(this);
}
}
void DeckCardZoneDisplayWidget::resizeEvent(QResizeEvent *event)
@ -126,42 +159,7 @@ void DeckCardZoneDisplayWidget::onHover(CardInfoPtr card)
emit cardHovered(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)
void DeckCardZoneDisplayWidget::refreshDisplayType(const QString &_displayType)
{
displayType = _displayType;
QLayoutItem *item;

View file

@ -6,6 +6,7 @@
#include "../general/display/banner_widget.h"
#include "../general/layout_containers/overlap_widget.h"
#include "../visual_deck_editor/visual_deck_editor_widget.h"
#include "card_group_display_widgets/card_group_display_widget.h"
#include "card_info_picture_with_text_overlay_widget.h"
#include "card_size_widget.h"
@ -36,6 +37,8 @@ public:
public slots:
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
void onHover(CardInfoPtr card);
void cleanupInvalidCardGroup(CardGroupDisplayWidget *displayWidget);
void constructAppropriateWidget(QPersistentModelIndex index);
void displayCards();
void refreshDisplayType(const DisplayType &displayType);
void onActiveGroupCriteriaChanged(QString activeGroupCriteria);
@ -48,6 +51,7 @@ signals:
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName);
void cardHovered(CardInfoPtr card);
void activeSortCriteriaChanged(QStringList activeSortCriteria);
void requestCleanup(DeckCardZoneDisplayWidget *displayWidget);
private:
QString activeGroupCriteria;

View file

@ -198,8 +198,19 @@ void VisualDeckEditorWidget::retranslateUi()
displayTypeButton->setToolTip(
tr("Change how cards are displayed within zones (i.e. overlapped or fully visible.)"));
}
void VisualDeckEditorWidget::cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget)
{
qInfo() << "Cleaning up invalid card zone " << displayWidget->zoneName;
zoneContainerLayout->removeWidget(displayWidget);
for (auto idx : indexToWidgetMap.keys()) {
if (!idx.isValid()) {
indexToWidgetMap.remove(idx);
}
}
displayWidget->deleteLater();
qInfo() << "Cleaned.";
}
void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first, int last)
{
@ -218,6 +229,8 @@ void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first
activeSortCriteria, 20, 10, cardSizeWidget);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::requestCleanup, this,
&VisualDeckEditorWidget::cleanupInvalidZones);
connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged);
connect(this, &VisualDeckEditorWidget::activeGroupCriteriaChanged, zoneDisplayWidget,
@ -249,7 +262,7 @@ void VisualDeckEditorWidget::onCardRemoval(const QModelIndex &parent, int first,
void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel()
{
qInfo() << "Constructing zone widgets";
for (int i = 0; i < deckListModel->rowCount(deckListModel->parent(QModelIndex())); ++i) {
for (int i = 0; i < deckListModel->rowCount(deckListModel->parent(QModelIndex())); i++) {
QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, deckListModel->getRoot()));
if (indexToWidgetMap.contains(index)) {
@ -263,6 +276,8 @@ void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel()
activeSortCriteria, 20, 10, cardSizeWidget);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::requestCleanup, this,
&VisualDeckEditorWidget::cleanupInvalidZones);
connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged);
connect(this, &VisualDeckEditorWidget::activeGroupCriteriaChanged, zoneDisplayWidget,

View file

@ -17,6 +17,7 @@
#include <QWidget>
#include <qscrollarea.h>
class DeckCardZoneDisplayWidget;
enum class DisplayType
{
Flat,
@ -41,6 +42,7 @@ public slots:
void decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight);
void updateZoneWidgets();
void updateDisplayType();
void cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget);
void onCardAddition(const QModelIndex &parent, int first, int last);
void onCardRemoval(const QModelIndex &parent, int first, int last);
void constructZoneWidgetsFromDeckListModel();

View file

@ -410,7 +410,10 @@ QModelIndex DeckListModel::addCard(const QString &cardName,
if (!cardNode) {
auto *decklistCard = deckList->addCard(cardInfo->getName(), zoneName, cardSetName,
cardInfoSet.getProperty("num"), cardInfoSet.getProperty("uuid"));
beginInsertRows(parentIndex, static_cast<int>(cardTypeNode->size()), static_cast<int>(cardTypeNode->size()));
// Determine the correct index
int insertRow = findSortedInsertRow(cardTypeNode, cardNode);
beginInsertRows(parentIndex, insertRow, insertRow);
cardNode = new DecklistModelCardNode(decklistCard, cardTypeNode);
endInsertRows();
} else {
@ -420,11 +423,44 @@ QModelIndex DeckListModel::addCard(const QString &cardName,
cardNode->setCardProviderId(cardInfoSet.getProperty("uuid"));
deckList->refreshDeckHash();
}
sort(lastKnownColumn, lastKnownOrder);
// sort(lastKnownColumn, lastKnownOrder);
emitRecursiveUpdates(parentIndex);
return nodeToIndex(cardNode);
}
int DeckListModel::findSortedInsertRow(InnerDecklistNode *parent, AbstractDecklistNode *newNode) const
{
auto *newCard = dynamic_cast<const DecklistModelCardNode *>(newNode);
if (!newCard)
return parent->size(); // fallback: append at end
for (int i = 0; i < parent->size(); ++i) {
auto *existingCard = dynamic_cast<const DecklistModelCardNode *>(parent->at(i));
if (!existingCard)
continue;
bool lessThan = false;
switch (lastKnownColumn) {
case 0: // ByNumber
lessThan = lastKnownOrder == Qt::AscendingOrder
? newCard->getCardCollectorNumber() < existingCard->getCardCollectorNumber()
: newCard->getCardCollectorNumber() > existingCard->getCardCollectorNumber();
break;
case 1: // ByName
default:
lessThan = lastKnownOrder == Qt::AscendingOrder
? newCard->getName().localeAwareCompare(existingCard->getName()) < 0
: newCard->getName().localeAwareCompare(existingCard->getName()) > 0;
break;
}
if (lessThan)
return i;
}
return parent->size(); // insert at end if no earlier match
}
QModelIndex DeckListModel::nodeToIndex(AbstractDecklistNode *node) const
{
if (node == nullptr || node == root) {

View file

@ -115,6 +115,7 @@ public:
const CardInfoPerSet &cardInfoSet,
const QString &zoneName,
bool abAddAnyway = false);
int findSortedInsertRow(InnerDecklistNode *parent, AbstractDecklistNode *newNode) const;
void sort(int column, Qt::SortOrder order) override;
void cleanList();
DeckLoader *getDeckList() const