feat: Configurable colors for card counter

This patch adds support for:

 - User-defined colors for card counters;
 - 3 additional types of card counters.

The colors used for counters is stored locally and not shared with other
users. This is intentional as the feature is likely to be used for
improved accessibility.

In order to preserve backwards-compatibility, and because I don't have a
better idea, counters keep their existing color-based names (Red, Green,
Yellow) in menus and in the message log. For consistency, the new
counters also get assigned color-based names (Cyan, Purple, Magenta).

This choice is a compromise, as allowing user-defined names for counters
raises many additional (UI/UX) questions that I don't know how to
answer. A good long-term solution would be to include counter names as
part of a game definition system and hence would be in scope for #1740.

The choice of adding 3 additional types of counters and the Cyan, Purple
and Magenta names are not random. The existing code for determining
counter colors goes: Red, Green, Yellow, Cyan, Purple, Magenta, Black
(unreadable) and thus 6 is the maximum number of counters that existing
versions of Cockatrice are able to support. This way, released clients
get a degraded experience (cannot interact with the new counters,
messages in the server log say "Player X places 1 on Card (now 1)"
without specifying 1 of what), but do see the counters properly.

Fixes #2020
This commit is contained in:
Basile Clément 2025-04-24 23:31:15 +02:00
parent 77d13090b5
commit cb423dbfbc
No known key found for this signature in database
12 changed files with 241 additions and 36 deletions

View file

@ -11,13 +11,17 @@
#include "../game/cards/card_database_manager.h"
#include "../main.h"
#include "../settings/cache_settings.h"
#include "../settings/card_counter_settings.h"
#include "../settings/shortcut_treeview.h"
#include "../utility/sequence_edit.h"
#include <QAbstractButton>
#include <QAbstractListModel>
#include <QAction>
#include <QApplication>
#include <QCheckBox>
#include <QCloseEvent>
#include <QColorDialog>
#include <QComboBox>
#include <QDebug>
#include <QDesktopServices>
@ -41,7 +45,7 @@
#include <QStackedWidget>
#include <QToolBar>
#include <QTranslator>
#include <qabstractbutton.h>
#include <QVariant>
#define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs"
#define WIKI_CUSTOM_SHORTCUTS "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts"
@ -441,6 +445,55 @@ AppearanceSettingsPage::AppearanceSettingsPage()
cardsGroupBox = new QGroupBox;
cardsGroupBox->setLayout(cardsGrid);
// Card counter colors
auto *cardCounterColorsLayout = new QGridLayout;
cardCounterColorsLayout->setColumnStretch(1, 1);
cardCounterColorsLayout->setColumnStretch(3, 1);
cardCounterColorsLayout->setColumnStretch(5, 1);
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
for (int index = 0; index < 6; ++index) {
auto *pushButton = new QPushButton;
pushButton->setStyleSheet(QString("background-color: %1").arg(cardCounterSettings.color(index).name()));
connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, pushButton,
[index, pushButton](int changedIndex, const QColor &color) {
if (index == changedIndex) {
pushButton->setStyleSheet(QString("background-color: %1").arg(color.name()));
}
});
connect(pushButton, &QPushButton::clicked, this, [index, pushButton]() {
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
auto newColor = QColorDialog::getColor(cardCounterSettings.color(index), pushButton);
if (!newColor.isValid())
return;
cardCounterSettings.setColor(index, newColor);
});
auto *colorName = new QLabel;
cardCounterNames.append(colorName);
int row = index / 3;
int column = 2 * (index % 3);
cardCounterColorsLayout->addWidget(pushButton, row, column);
cardCounterColorsLayout->addWidget(colorName, row, column + 1);
}
auto *cardCountersLayout = new QVBoxLayout;
cardCountersLayout->addLayout(cardCounterColorsLayout, 1);
cardCountersNameWarning = new QLabel;
cardCountersNameWarning->setWordWrap(true);
cardCountersLayout->addWidget(cardCountersNameWarning);
cardCountersGroupBox = new QGroupBox;
cardCountersGroupBox->setLayout(cardCountersLayout);
// Hand layout
horizontalHandCheckBox.setChecked(settings.getHorizontalHand());
connect(&horizontalHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings, &SettingsCache::setHorizontalHand);
@ -488,6 +541,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
mainLayout->addWidget(themeGroupBox);
mainLayout->addWidget(menuGroupBox);
mainLayout->addWidget(cardsGroupBox);
mainLayout->addWidget(cardCountersGroupBox);
mainLayout->addWidget(handGroupBox);
mainLayout->addWidget(tableGroupBox);
mainLayout->addStretch();
@ -576,6 +630,15 @@ void AppearanceSettingsPage::retranslateUi()
cardViewExpandedRowsMaxLabel.setText(tr("Maximum expanded height for card view window:"));
cardViewExpandedRowsMaxBox.setSuffix(tr(" rows"));
cardCountersGroupBox->setTitle(tr("Card counters"));
cardCountersNameWarning->setText(
tr("<b>Note:</b> The names can't be changed and might not match the actual colors."));
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
for (int index = 0; index < cardCounterNames.size(); ++index) {
cardCounterNames[index]->setText(cardCounterSettings.displayName(index));
}
handGroupBox->setTitle(tr("Hand layout"));
horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)"));
leftJustifiedHandCheckBox.setText(tr("Enable left justification"));