From 8382bd4160079342c3a63966fe5ace01f90fbd22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Sun, 9 Nov 2025 04:46:31 +0100 Subject: [PATCH] Style proxy. Took 14 minutes Took 6 minutes Took 1 minute --- cockatrice/CMakeLists.txt | 1 + .../deck_editor_deck_dock_widget.cpp | 7 +- .../deck_editor/deck_list_style_proxy.cpp | 36 +++++ .../deck_editor/deck_list_style_proxy.h | 15 ++ .../models/deck_list/deck_list_model.cpp | 138 +++++++++--------- .../models/deck_list/deck_list_model.h | 9 ++ 6 files changed, 133 insertions(+), 73 deletions(-) create mode 100644 cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp create mode 100644 cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 279de0533..995b55258 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -150,6 +150,7 @@ set(cockatrice_SOURCES src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp + src/interface/widgets/deck_editor/deck_list_style_proxy.cpp src/interface/widgets/general/background_sources.cpp src/interface/widgets/general/display/banner_widget.cpp src/interface/widgets/general/display/bar_widget.cpp diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp index 444855bff..8f5f875b1 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp @@ -2,6 +2,7 @@ #include "../../../client/settings/cache_settings.h" #include "../../deck_loader/deck_loader.h" +#include "deck_list_style_proxy.h" #include #include @@ -30,9 +31,13 @@ void DeckEditorDeckDockWidget::createDeckDock() deckModel = new DeckListModel(this); deckModel->setObjectName("deckModel"); connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash); + + DeckListStyleProxy *proxy = new DeckListStyleProxy(this); + proxy->setSourceModel(deckModel); + deckView = new QTreeView(); deckView->setObjectName("deckView"); - deckView->setModel(deckModel); + deckView->setModel(proxy); deckView->setUniformRowHeights(true); deckView->setSortingEnabled(true); deckView->sortByColumn(1, Qt::AscendingOrder); diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp new file mode 100644 index 000000000..a4233e3b4 --- /dev/null +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp @@ -0,0 +1,36 @@ +#include "deck_list_style_proxy.h" + +#include +#include +#include +#include + +QVariant DeckListStyleProxy::data(const QModelIndex &index, int role) const +{ + QVariant value = QIdentityProxyModel::data(index, role); + + const bool isCard = QIdentityProxyModel::data(index, DeckRoles::IsCardRole).toBool(); + + if (role == Qt::FontRole && !isCard) { + QFont f; + f.setBold(true); + return f; + } + + if (role == Qt::BackgroundRole) { + if (isCard) { + const bool legal = QIdentityProxyModel::data(index, DeckRoles::IsLegalRole).toBool(); + int base = 255 - (index.row() % 2) * 30; + return legal ? QBrush(QColor(base, base, base)) : QBrush(QColor(255, base / 3, base / 3)); + } else { + int depth = QIdentityProxyModel::data(index, DeckRoles::DepthRole).toInt(); + int color = 90 + 60 * depth; + return QBrush(QColor(color, 255, color)); + } + } + + if (role == Qt::ForegroundRole) + return QBrush(QColor(0, 0, 0)); + + return value; +} diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h new file mode 100644 index 000000000..a7e58eb02 --- /dev/null +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h @@ -0,0 +1,15 @@ +#ifndef COCKATRICE_DECK_LIST_STYLE_PROXY_H +#define COCKATRICE_DECK_LIST_STYLE_PROXY_H + +#include + +class DeckListStyleProxy : public QIdentityProxyModel +{ + Q_OBJECT +public: + using QIdentityProxyModel::QIdentityProxyModel; + + QVariant data(const QModelIndex &index, int role) const override; +}; + +#endif // COCKATRICE_DECK_LIST_STYLE_PROXY_H diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp index 42219e759..45343672c 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp @@ -88,92 +88,86 @@ int DeckListModel::columnCount(const QModelIndex & /*parent*/) const QVariant DeckListModel::data(const QModelIndex &index, int role) const { - // debugIndexInfo("data", index); - if (!index.isValid()) { + if (!index.isValid()) return {}; - } - if (index.column() >= columnCount()) { + if (index.column() >= columnCount()) return {}; - } - auto *temp = static_cast(index.internalPointer()); - auto *card = dynamic_cast(temp); - if (card == nullptr) { - const auto *node = dynamic_cast(temp); + auto *node = static_cast(index.internalPointer()); + auto *card = dynamic_cast(node); + + // Group node + if (!card) { + auto *group = static_cast(node); + switch (role) { - case Qt::FontRole: { - QFont f; - f.setBold(true); - return f; - } case Qt::DisplayRole: - case Qt::EditRole: { + case Qt::EditRole: switch (index.column()) { - case 0: - return node->recursiveCount(true); - case 1: { - if (role == Qt::DisplayRole) - return node->getVisibleName(); - return node->getName(); - } - case 2: { - return node->getCardSetShortName(); - } - case 3: { - return node->getCardCollectorNumber(); - } - case 4: { - return node->getCardProviderId(); - } - default: - return {}; + case 0: return group->recursiveCount(true); + case 1: return (role == Qt::DisplayRole + ? group->getVisibleName() + : group->getName()); + case 2: return group->getCardSetShortName(); + case 3: return group->getCardCollectorNumber(); + case 4: return group->getCardProviderId(); + default: return {}; } - } - case Qt::UserRole + 1: + + case DeckRoles::IsCardRole: return false; - case Qt::BackgroundRole: { - int color = 90 + 60 * node->depth(); - return QBrush(QColor(color, 255, color)); - } - case Qt::ForegroundRole: { - return QBrush(QColor(0, 0, 0)); - } - default: - return {}; - } - } else { - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - switch (index.column()) { - case 0: - return card->getNumber(); - case 1: - return card->getName(); - case 2: - return card->getCardSetShortName(); - case 3: - return card->getCardCollectorNumber(); - case 4: - return card->getCardProviderId(); - default: - return {}; - } - } - case Qt::UserRole + 1: + + case DeckRoles::DepthRole: + return group->depth(); + + // legality does not apply to group nodes + case DeckRoles::IsLegalRole: return true; - case Qt::BackgroundRole: { - int color = 255 - (index.row() % 2) * 30; - return QBrush(QColor(color, color, color)); - } - case Qt::ForegroundRole: { - return QBrush(QColor(0, 0, 0)); - } + default: return {}; } } + + // Card node + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + switch (index.column()) { + case 0: return card->getNumber(); + case 1: return card->getName(); + case 2: return card->getCardSetShortName(); + case 3: return card->getCardCollectorNumber(); + case 4: return card->getCardProviderId(); + default: return {}; + } + + case DeckRoles::IsCardRole: + return true; + + case DeckRoles::DepthRole: + return card->depth(); + + default: + return {}; + } +} + +void DeckListModel::emitBackgroundUpdates(const QModelIndex &parent) +{ + int rows = rowCount(parent); + if (rows == 0) + return; + + QModelIndex topLeft = index(0, 0, parent); + QModelIndex bottomRight = index(rows - 1, columnCount() - 1, parent); + emit dataChanged(topLeft, bottomRight, {Qt::BackgroundRole}); + + for (int r = 0; r < rows; ++r) { + QModelIndex child = index(r, 0, parent); + emitBackgroundUpdates(child); + } } QVariant DeckListModel::headerData(const int section, const Qt::Orientation orientation, const int role) const diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h index d4c15d5b8..0d8ce628c 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h @@ -12,6 +12,14 @@ class CardDatabase; class QPrinter; class QTextCursor; +namespace DeckRoles { +enum { + IsCardRole = Qt::UserRole + 1, + DepthRole, + IsLegalRole +}; +} + /** * @brief Specifies the criteria used to group cards in the DeckListModel. */ @@ -163,6 +171,7 @@ public: int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; + void emitBackgroundUpdates(const QModelIndex &parent); QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QModelIndex index(int row, int column, const QModelIndex &parent) const override; QModelIndex parent(const QModelIndex &index) const override;