diff --git a/cockatrice/src/game/selection_subtype_tally.cpp b/cockatrice/src/game/selection_subtype_tally.cpp index 0d83a1670..c033d42c9 100644 --- a/cockatrice/src/game/selection_subtype_tally.cpp +++ b/cockatrice/src/game/selection_subtype_tally.cpp @@ -5,7 +5,7 @@ #include #include -namespace SelectionSubtypeTally +namespace { QStringList extractSubtypesFromFace(const QString &faceType) @@ -17,6 +17,11 @@ QStringList extractSubtypesFromFace(const QString &faceType) return {}; } +} // anonymous namespace + +namespace SelectionSubtypeTally +{ + QList countSubtypes(const QList &cards) { QMap> subtypesByMainType; @@ -81,49 +86,4 @@ QList countSubtypes(const QList &cards) return groups; } -QString formatAsHtml(const QList &groups) -{ - // Flatten to final ordered list - QList sortedEntries; - for (const MainTypeGroup &group : groups) { - for (const auto &entry : group.subtypes) { - sortedEntries.append(entry); - } - } - - // Calculate padding widths - int maxNameLen = 0; - int maxCountLen = 0; - for (const auto &entry : sortedEntries) { - maxNameLen = qMax(maxNameLen, entry.name.length()); - maxCountLen = qMax(maxCountLen, QString::number(entry.count).length()); - } - - // Format output - QStringList lines; - for (const auto &entry : sortedEntries) { - QString name = entry.name.toHtmlEscaped(); - QString count = QString::number(entry.count); - - QString namePadding = QString(QStringLiteral(" ")).repeated(maxNameLen - entry.name.length()); - QString countPadding = QString(QStringLiteral(" ")).repeated(maxCountLen - count.length()); - - lines << QStringLiteral( - "%1%2 %3%4") - .arg(namePadding, name, countPadding, count); - } - - return QStringLiteral("") + lines.join(QStringLiteral("
")) + - QStringLiteral("
"); -} - -QString buildSubtypeTallyText(const QList &cards) -{ - QList groups = countSubtypes(cards); - if (groups.isEmpty()) { - return QString(); - } - return formatAsHtml(groups); -} - } // namespace SelectionSubtypeTally diff --git a/cockatrice/src/game/selection_subtype_tally.h b/cockatrice/src/game/selection_subtype_tally.h index 3c2f2092b..a5014fafe 100644 --- a/cockatrice/src/game/selection_subtype_tally.h +++ b/cockatrice/src/game/selection_subtype_tally.h @@ -22,10 +22,7 @@ struct MainTypeGroup namespace SelectionSubtypeTally { -QStringList extractSubtypesFromFace(const QString &faceType); QList countSubtypes(const QList &cards); -QString formatAsHtml(const QList &groups); -QString buildSubtypeTallyText(const QList &cards); } // namespace SelectionSubtypeTally #endif diff --git a/cockatrice/src/game_graphics/game_view.cpp b/cockatrice/src/game_graphics/game_view.cpp index 3c268db37..3822bb4a5 100644 --- a/cockatrice/src/game_graphics/game_view.cpp +++ b/cockatrice/src/game_graphics/game_view.cpp @@ -2,10 +2,13 @@ #include "../client/settings/cache_settings.h" #include "game_scene.h" +#include "libcockatrice/utility/qt_utils.h" #include "selection_subtype_tally.h" #include +#include #include +#include #include #include @@ -74,10 +77,12 @@ GameView::GameView(GameScene *scene, QWidget *parent) : QGraphicsView(scene, par totalCountLabel->setStyleSheet(totalCountLabelStyle); totalCountLabel->hide(); - subtypeCountLabel = new QLabel(this); - subtypeCountLabel->setStyleSheet(subtypeCountLabelStyle); - subtypeCountLabel->setTextFormat(Qt::RichText); - subtypeCountLabel->hide(); + subtypeCountContainer = new QWidget(this); + subtypeCountContainer->setStyleSheet(subtypeCountLabelStyle); + subtypeCountLayout = new QGridLayout(subtypeCountContainer); + subtypeCountLayout->setContentsMargins(2, 2, 2, 2); + subtypeCountLayout->setSpacing(2); + subtypeCountContainer->hide(); } void GameView::resizeEvent(QResizeEvent *event) @@ -172,13 +177,33 @@ void GameView::refreshShortcuts() SettingsCache::instance().shortcuts().getShortcut("Player/aCloseMostRecentZoneView")); } -QString GameView::buildSubtypeTallyText() const +void GameView::clearSubtypeLabels() { - GameScene *gameScene = dynamic_cast(scene()); - if (!gameScene) { - return QString(); + QtUtils::clearLayoutRec(subtypeCountLayout); +} + +void GameView::rebuildSubtypeLabels(const QList &entries) +{ + clearSubtypeLabels(); + + const QString nameStyle = QStringLiteral("color: white; font-size: 12px; background: transparent;"); + const QString countStyle = + QStringLiteral("color: white; font-size: 14px; font-weight: bold; background: transparent;"); + + int row = 0; + for (const SubtypeEntry &entry : entries) { + auto *nameLabel = new QLabel(entry.name, subtypeCountContainer); + nameLabel->setStyleSheet(nameStyle); + nameLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + subtypeCountLayout->addWidget(nameLabel, row, 0); + + auto *countLabel = new QLabel(QString::number(entry.count), subtypeCountContainer); + countLabel->setStyleSheet(countStyle); + countLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + subtypeCountLayout->addWidget(countLabel, row, 1); + + ++row; } - return SelectionSubtypeTally::buildSubtypeTallyText(gameScene->selectedCards()); } void GameView::updateSelectionCount(const QSize &viewSize) @@ -204,31 +229,46 @@ void GameView::updateSelectionCount(const QSize &viewSize) } if (!SettingsCache::instance().getShowSubtypeSelectionCount() || count <= 1) { - subtypeCountLabel->hide(); + subtypeCountContainer->hide(); return; } - QString subtypeText = buildSubtypeTallyText(); - - if (subtypeText.isEmpty()) { - subtypeCountLabel->hide(); + GameScene *gameScene = dynamic_cast(scene()); + if (!gameScene) { + subtypeCountContainer->hide(); return; } - subtypeCountLabel->setText(subtypeText); - subtypeCountLabel->adjustSize(); + QList groups = SelectionSubtypeTally::countSubtypes(gameScene->selectedCards()); + if (groups.isEmpty()) { + subtypeCountContainer->hide(); + return; + } - int x = availableWidth - subtypeCountLabel->width() - kMarginInPixels; + QList entries; + for (const MainTypeGroup &group : groups) { + entries.append(group.subtypes); + } + + if (entries.isEmpty()) { + subtypeCountContainer->hide(); + return; + } + + rebuildSubtypeLabels(entries); + subtypeCountContainer->adjustSize(); + + int x = availableWidth - subtypeCountContainer->width() - kMarginInPixels; int y; if (totalCountLabel->isVisible()) { - y = totalCountLabel->y() - subtypeCountLabel->height() - kSpacingBetweenLabels; + y = totalCountLabel->y() - subtypeCountContainer->height() - kSpacingBetweenLabels; } else { - y = availableHeight - subtypeCountLabel->height() - kMarginInPixels; + y = availableHeight - subtypeCountContainer->height() - kMarginInPixels; } y = qMax(kMarginInPixels, y); - subtypeCountLabel->move(x, y); - subtypeCountLabel->show(); + subtypeCountContainer->move(x, y); + subtypeCountContainer->show(); } diff --git a/cockatrice/src/game_graphics/game_view.h b/cockatrice/src/game_graphics/game_view.h index 1d8e586b9..7e9e31e2f 100644 --- a/cockatrice/src/game_graphics/game_view.h +++ b/cockatrice/src/game_graphics/game_view.h @@ -10,8 +10,10 @@ #include class GameScene; +class QGridLayout; class QLabel; class QRubberBand; +struct SubtypeEntry; class GameView : public QGraphicsView { @@ -21,11 +23,12 @@ private: QRubberBand *rubberBand; QLabel *dragCountLabel; QLabel *totalCountLabel; - QLabel *subtypeCountLabel; ///< Label displaying subtype breakdown for selected cards + QWidget *subtypeCountContainer; ///< Container widget for subtype tally display + QGridLayout *subtypeCountLayout; ///< Grid layout for subtype name/count pairs QPointF selectionOrigin; - /** @brief Builds formatted text showing subtype tally for all selected cards */ - QString buildSubtypeTallyText() const; + void rebuildSubtypeLabels(const QList &entries); + void clearSubtypeLabels(); protected: void resizeEvent(QResizeEvent *event) override; diff --git a/libcockatrice_utility/libcockatrice/utility/qt_utils.h b/libcockatrice_utility/libcockatrice/utility/qt_utils.h index 334e56027..8e5212031 100644 --- a/libcockatrice_utility/libcockatrice/utility/qt_utils.h +++ b/libcockatrice_utility/libcockatrice/utility/qt_utils.h @@ -1,5 +1,6 @@ #ifndef COCKATRICE_QT_UTILS_H #define COCKATRICE_QT_UTILS_H +#include #include namespace QtUtils