[Client] Show custom zones in the card display widgets (#7206)

* [Client] Show custom zones in the card display widgets

Card group displays and deck zone displays learn to render custom
zones alongside the standard boards.

- Group display widgets treat custom-zone nodes like other group
  headers, keeping counts and layout consistent.
- Zone display widgets resolve their title through visibleNameFromName
  so custom zones show their user-chosen names localized like the
  standard zones.

* [DeckEditor] Apply sort criteria inside custom zones and align display order with the model

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-09-05 22:00:21 +02:00 committed by GitHub
parent 0d09e633e3
commit b0e566ed54
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 36 deletions

View file

@ -174,18 +174,20 @@ void CardGroupDisplayWidget::updateCardDisplays()
QModelIndex sourceIndex = proxy.mapToSource(proxyIndex);
// 4. persist the source index
QPersistentModelIndex persistent(sourceIndex);
addCardWidgets(QPersistentModelIndex(sourceIndex));
}
}
void CardGroupDisplayWidget::addCardWidgets(const QPersistentModelIndex &persistent)
{
// Get the card amount
int cardAmount =
sourceIndex.sibling(sourceIndex.row(), DeckListModelColumns::CARD_AMOUNT).data(Qt::EditRole).toInt();
int cardAmount = persistent.sibling(persistent.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()
{

View file

@ -35,6 +35,7 @@ public:
void onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void refreshSelectionForIndex(const QPersistentModelIndex &persistent);
void clearAllDisplayWidgets();
void addCardWidgets(const QPersistentModelIndex &persistent);
DeckListModel *deckListModel;
QItemSelectionModel *selectionModel;

View file

@ -5,6 +5,7 @@
#include "libcockatrice/card/database/card_database_manager.h"
#include <QResizeEvent>
#include <algorithm>
#include <libcockatrice/models/deck_list/deck_list_model.h>
DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
@ -51,11 +52,6 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
// User Interaction
// =====================================================================================================================
void DeckCardZoneDisplayWidget::onClick(QMouseEvent *event, const ExactCard &card)
{
emit cardClicked(event, card, zoneName);
}
void DeckCardZoneDisplayWidget::onHover(const ExactCard &card)
{
emit cardHovered(card);
@ -95,12 +91,18 @@ void DeckCardZoneDisplayWidget::constructAppropriateWidget(QPersistentModelIndex
}
auto categoryName = index.sibling(index.row(), DeckListModelColumns::CARD_NAME).data(Qt::EditRole).toString();
// Cards in a custom zone belong to that zone, not the board zone, so that
// increment/decrement/swap actions target the custom zone.
const bool isCustomZone = index.data(DeckRoles::IsCustomZoneRole).toBool();
const QString effectiveZoneName = isCustomZone ? categoryName : zoneName;
const auto routeCardClick = [this, effectiveZoneName](QMouseEvent *event, const ExactCard &card) {
emit cardClicked(event, card, effectiveZoneName);
};
if (displayType == DisplayType::Overlap) {
auto *displayWidget = new OverlappedCardGroupDisplayWidget(
cardGroupContainer, deckListModel, selectionModel, index, zoneName, categoryName, activeGroupCriteria,
activeSortCriteria, subBannerOpacity, cardSizeWidget);
connect(displayWidget, &OverlappedCardGroupDisplayWidget::cardClicked, this,
&DeckCardZoneDisplayWidget::onClick);
cardGroupContainer, deckListModel, selectionModel, index, effectiveZoneName, categoryName,
activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget);
connect(displayWidget, &OverlappedCardGroupDisplayWidget::cardClicked, this, routeCardClick);
connect(displayWidget, &OverlappedCardGroupDisplayWidget::cardHovered, this,
&DeckCardZoneDisplayWidget::onHover);
connect(displayWidget, &CardGroupDisplayWidget::cleanupRequested, this,
@ -111,9 +113,9 @@ void DeckCardZoneDisplayWidget::constructAppropriateWidget(QPersistentModelIndex
indexToWidgetMap.insert(index, displayWidget);
} else if (displayType == DisplayType::Flat) {
auto *displayWidget = new FlatCardGroupDisplayWidget(cardGroupContainer, deckListModel, selectionModel, index,
zoneName, categoryName, activeGroupCriteria,
effectiveZoneName, categoryName, activeGroupCriteria,
activeSortCriteria, subBannerOpacity, cardSizeWidget);
connect(displayWidget, &FlatCardGroupDisplayWidget::cardClicked, this, &DeckCardZoneDisplayWidget::onClick);
connect(displayWidget, &FlatCardGroupDisplayWidget::cardClicked, this, routeCardClick);
connect(displayWidget, &FlatCardGroupDisplayWidget::cardHovered, this, &DeckCardZoneDisplayWidget::onHover);
connect(displayWidget, &CardGroupDisplayWidget::cleanupRequested, this,
&DeckCardZoneDisplayWidget::cleanupInvalidCardGroup);
@ -126,24 +128,18 @@ void DeckCardZoneDisplayWidget::constructAppropriateWidget(QPersistentModelIndex
void DeckCardZoneDisplayWidget::displayCards()
{
QSortFilterProxyModel proxy;
proxy.setSourceModel(deckListModel);
proxy.setSortRole(Qt::EditRole);
proxy.sort(DeckListModelColumns::CARD_NAME, Qt::AscendingOrder);
if (!trackedIndex.isValid()) {
return;
}
// 1. trackedIndex is a source index → map it to proxy space
QModelIndex proxyParent = proxy.mapFromSource(trackedIndex);
// 2. iterate children under the proxy parent
for (int i = 0; i < proxy.rowCount(proxyParent); ++i) {
QModelIndex proxyIndex = proxy.index(i, 0, proxyParent);
// 3. map back to source
QModelIndex sourceIndex = proxy.mapToSource(proxyIndex);
// 4. persist the source index
QPersistentModelIndex persistent(sourceIndex);
// Iterate the direct children of the tracked zone, keeping the tree view's row
// order (criteria groups first, then custom zones, both in the model's sort order).
QList<QPersistentModelIndex> rows;
for (int i = 0; i < deckListModel->rowCount(trackedIndex); ++i) {
rows.append(QPersistentModelIndex(deckListModel->index(i, 0, trackedIndex)));
}
for (const QPersistentModelIndex &persistent : rows) {
constructAppropriateWidget(persistent);
}
}

View file

@ -42,7 +42,6 @@ public:
void addCardsToOverlapWidget();
public slots:
void onClick(QMouseEvent *event, const ExactCard &card);
void onHover(const ExactCard &card);
void cleanupInvalidCardGroup(CardGroupDisplayWidget *displayWidget);
void constructAppropriateWidget(QPersistentModelIndex index);