Fix subtype tally alignment by using grid layout instead of character padding

This commit is contained in:
DawnFire42 2026-06-04 20:29:28 -04:00
parent 3c2a59ce6e
commit 74381b5c06
No known key found for this signature in database
GPG key ID: 24BB855EE2911B33
5 changed files with 74 additions and 73 deletions

View file

@ -5,7 +5,7 @@
#include <QMap> #include <QMap>
#include <algorithm> #include <algorithm>
namespace SelectionSubtypeTally namespace
{ {
QStringList extractSubtypesFromFace(const QString &faceType) QStringList extractSubtypesFromFace(const QString &faceType)
@ -17,6 +17,11 @@ QStringList extractSubtypesFromFace(const QString &faceType)
return {}; return {};
} }
} // anonymous namespace
namespace SelectionSubtypeTally
{
QList<MainTypeGroup> countSubtypes(const QList<CardItem *> &cards) QList<MainTypeGroup> countSubtypes(const QList<CardItem *> &cards)
{ {
QMap<QString, QMap<QString, int>> subtypesByMainType; QMap<QString, QMap<QString, int>> subtypesByMainType;
@ -81,49 +86,4 @@ QList<MainTypeGroup> countSubtypes(const QList<CardItem *> &cards)
return groups; return groups;
} }
QString formatAsHtml(const QList<MainTypeGroup> &groups)
{
// Flatten to final ordered list
QList<SubtypeEntry> 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("&nbsp;")).repeated(maxNameLen - entry.name.length());
QString countPadding = QString(QStringLiteral("&nbsp;")).repeated(maxCountLen - count.length());
lines << QStringLiteral(
"%1%2 <span style='font-size:14px;font-weight:bold;vertical-align:middle;'>%3%4</span>")
.arg(namePadding, name, countPadding, count);
}
return QStringLiteral("<span style='font-family: monospace;'>") + lines.join(QStringLiteral("<br>")) +
QStringLiteral("</span>");
}
QString buildSubtypeTallyText(const QList<CardItem *> &cards)
{
QList<MainTypeGroup> groups = countSubtypes(cards);
if (groups.isEmpty()) {
return QString();
}
return formatAsHtml(groups);
}
} // namespace SelectionSubtypeTally } // namespace SelectionSubtypeTally

View file

@ -22,10 +22,7 @@ struct MainTypeGroup
namespace SelectionSubtypeTally namespace SelectionSubtypeTally
{ {
QStringList extractSubtypesFromFace(const QString &faceType);
QList<MainTypeGroup> countSubtypes(const QList<CardItem *> &cards); QList<MainTypeGroup> countSubtypes(const QList<CardItem *> &cards);
QString formatAsHtml(const QList<MainTypeGroup> &groups);
QString buildSubtypeTallyText(const QList<CardItem *> &cards);
} // namespace SelectionSubtypeTally } // namespace SelectionSubtypeTally
#endif #endif

View file

@ -2,10 +2,13 @@
#include "../client/settings/cache_settings.h" #include "../client/settings/cache_settings.h"
#include "game_scene.h" #include "game_scene.h"
#include "libcockatrice/utility/qt_utils.h"
#include "selection_subtype_tally.h" #include "selection_subtype_tally.h"
#include <QAction> #include <QAction>
#include <QGridLayout>
#include <QLabel> #include <QLabel>
#include <QLayout>
#include <QResizeEvent> #include <QResizeEvent>
#include <QRubberBand> #include <QRubberBand>
@ -76,10 +79,12 @@ GameView::GameView(GameScene *scene, QWidget *parent) : QGraphicsView(scene, par
totalCountLabel->setStyleSheet(totalCountLabelStyle); totalCountLabel->setStyleSheet(totalCountLabelStyle);
totalCountLabel->hide(); totalCountLabel->hide();
subtypeCountLabel = new QLabel(this); subtypeCountContainer = new QWidget(this);
subtypeCountLabel->setStyleSheet(subtypeCountLabelStyle); subtypeCountContainer->setStyleSheet(subtypeCountLabelStyle);
subtypeCountLabel->setTextFormat(Qt::RichText); subtypeCountLayout = new QGridLayout(subtypeCountContainer);
subtypeCountLabel->hide(); subtypeCountLayout->setContentsMargins(2, 2, 2, 2);
subtypeCountLayout->setSpacing(2);
subtypeCountContainer->hide();
} }
void GameView::resizeEvent(QResizeEvent *event) void GameView::resizeEvent(QResizeEvent *event)
@ -174,13 +179,33 @@ void GameView::refreshShortcuts()
SettingsCache::instance().shortcuts().getShortcut("Player/aCloseMostRecentZoneView")); SettingsCache::instance().shortcuts().getShortcut("Player/aCloseMostRecentZoneView"));
} }
QString GameView::buildSubtypeTallyText() const void GameView::clearSubtypeLabels()
{ {
GameScene *gameScene = dynamic_cast<GameScene *>(scene()); QtUtils::clearLayoutRec(subtypeCountLayout);
if (!gameScene) { }
return QString();
void GameView::rebuildSubtypeLabels(const QList<SubtypeEntry> &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::updateTotalSelectionCount(const QSize &viewSize) void GameView::updateTotalSelectionCount(const QSize &viewSize)
@ -206,33 +231,48 @@ void GameView::updateTotalSelectionCount(const QSize &viewSize)
} }
if (!SettingsCache::instance().getShowSubtypeSelectionCount() || count <= 1) { if (!SettingsCache::instance().getShowSubtypeSelectionCount() || count <= 1) {
subtypeCountLabel->hide(); subtypeCountContainer->hide();
return; return;
} }
QString subtypeText = buildSubtypeTallyText(); GameScene *gameScene = dynamic_cast<GameScene *>(scene());
if (!gameScene) {
if (subtypeText.isEmpty()) { subtypeCountContainer->hide();
subtypeCountLabel->hide();
return; return;
} }
subtypeCountLabel->setText(subtypeText); QList<MainTypeGroup> groups = SelectionSubtypeTally::countSubtypes(gameScene->selectedCards());
subtypeCountLabel->adjustSize(); if (groups.isEmpty()) {
subtypeCountContainer->hide();
return;
}
int x = availableWidth - subtypeCountLabel->width() - kMarginInPixels; QList<SubtypeEntry> 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; int y;
if (totalCountLabel->isVisible()) { if (totalCountLabel->isVisible()) {
y = totalCountLabel->y() - subtypeCountLabel->height() - kSpacingBetweenLabels; y = totalCountLabel->y() - subtypeCountContainer->height() - kSpacingBetweenLabels;
} else { } else {
y = availableHeight - subtypeCountLabel->height() - kMarginInPixels; y = availableHeight - subtypeCountContainer->height() - kMarginInPixels;
} }
y = qMax(kMarginInPixels, y); y = qMax(kMarginInPixels, y);
subtypeCountLabel->move(x, y); subtypeCountContainer->move(x, y);
subtypeCountLabel->show(); subtypeCountContainer->show();
} }
/** /**

View file

@ -10,8 +10,10 @@
#include <QGraphicsView> #include <QGraphicsView>
class GameScene; class GameScene;
class QGridLayout;
class QLabel; class QLabel;
class QRubberBand; class QRubberBand;
struct SubtypeEntry;
class GameView : public QGraphicsView class GameView : public QGraphicsView
{ {
@ -21,11 +23,12 @@ private:
QRubberBand *rubberBand; QRubberBand *rubberBand;
QLabel *dragCountLabel; QLabel *dragCountLabel;
QLabel *totalCountLabel; 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; QPointF selectionOrigin;
/** @brief Builds formatted text showing subtype tally for all selected cards */ void rebuildSubtypeLabels(const QList<SubtypeEntry> &entries);
QString buildSubtypeTallyText() const; void clearSubtypeLabels();
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;

View file

@ -1,5 +1,6 @@
#ifndef COCKATRICE_QT_UTILS_H #ifndef COCKATRICE_QT_UTILS_H
#define COCKATRICE_QT_UTILS_H #define COCKATRICE_QT_UTILS_H
#include <QLayout>
#include <QObject> #include <QObject>
namespace QtUtils namespace QtUtils