mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-14 14:32:15 -07:00
Merge branch 'master' into edit-default-tags
This commit is contained in:
commit
297654b053
22 changed files with 294 additions and 83 deletions
|
|
@ -235,6 +235,7 @@ set(cockatrice_SOURCES
|
|||
src/server/user/user_list_manager.cpp
|
||||
src/server/user/user_list_widget.cpp
|
||||
src/settings/cache_settings.cpp
|
||||
src/settings/card_counter_settings.cpp
|
||||
src/settings/card_database_settings.cpp
|
||||
src/settings/card_override_settings.cpp
|
||||
src/settings/debug_settings.cpp
|
||||
|
|
|
|||
|
|
@ -8,6 +8,20 @@ searches are case insensitive.
|
|||
<dd>[red deck wins](#red deck wins) <small>(Any deck with a display name containing the words red, deck, and wins)</small></dd>
|
||||
<dd>["red deck wins"](#%22red deck wins%22) <small>(Any deck with a display name containing the exact phrase "red deck wins")</small></dd>
|
||||
|
||||
<dt>Deck <u>N</u>ame:</dt>
|
||||
<dd>[n:aggro](#n:aggro) <small>(Any deck with a name containing the word aggro)</small></dd>
|
||||
<dd>[n:red n:deck n:wins](#n:red n:deck n:wins) <small>(Any deck with a name containing the words red, deck, and wins)</small></dd>
|
||||
<dd>[n:"red deck wins"](#n:%22red deck wins%22) <small>(Any deck with a name containing the exact phrase "red deck wins")</small></dd>
|
||||
|
||||
<dt><u>F</u>ile Name:</dt>
|
||||
<dd>[f:aggro](#f:aggro) <small>(Any deck with a filename containing the word aggro)</small></dd>
|
||||
<dd>[f:red f:deck f:wins](#f:red f:deck f:wins) <small>(Any deck with a filename containing the words red, deck, and wins)</small></dd>
|
||||
<dd>[f:"red deck wins"](#f:%22red deck wins%22) <small>(Any deck with a filename containing the exact phrase "red deck wins")</small></dd>
|
||||
|
||||
<dt>Relative <u>P</u>ath (starting from the deck folder):</dt>
|
||||
<dd>[p:aggro](#p:aggro) <small>(Any deck that has "aggro" somewhere in its relative path)</small></dd>
|
||||
<dd>[p:edh/](#p:edh/) <small>(Any deck with "edh/" in its relative path, A.K.A. decks in the "edh" folder)</small></dd>
|
||||
|
||||
<dt>Deck Contents (Uses [card search expressions](#cardSearchSyntaxHelp)):</dt>
|
||||
<dd><a href="#[[plains]]">[[plains]]</a> <small>(Any deck that contains at least one card with "plains" in its name)</small></dd>
|
||||
<dd><a href="#[[t:legendary]]">[[t:legendary]]</a> <small>(Any deck that contains at least one legendary)</small></dd>
|
||||
|
|
|
|||
|
|
@ -42,14 +42,6 @@ VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidg
|
|||
connect(showBannerCardComboBoxCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setVisualDeckStorageShowBannerCardComboBox);
|
||||
|
||||
// search folder names checkbox
|
||||
searchFolderNamesCheckBox = new QCheckBox(this);
|
||||
searchFolderNamesCheckBox->setChecked(SettingsCache::instance().getVisualDeckStorageSearchFolderNames());
|
||||
connect(searchFolderNamesCheckBox, &QCheckBox::QT_STATE_CHANGED, this,
|
||||
&VisualDeckStorageQuickSettingsWidget::searchFolderNamesChanged);
|
||||
connect(searchFolderNamesCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setVisualDeckStorageSearchFolderNames);
|
||||
|
||||
// draw unused color identities checkbox
|
||||
drawUnusedColorIdentitiesCheckBox = new QCheckBox(this);
|
||||
drawUnusedColorIdentitiesCheckBox->setChecked(
|
||||
|
|
@ -113,7 +105,6 @@ VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidg
|
|||
this->addSettingsWidget(showTagFilterCheckBox);
|
||||
this->addSettingsWidget(showTagsOnDeckPreviewsCheckBox);
|
||||
this->addSettingsWidget(showBannerCardComboBoxCheckBox);
|
||||
this->addSettingsWidget(searchFolderNamesCheckBox);
|
||||
this->addSettingsWidget(drawUnusedColorIdentitiesCheckBox);
|
||||
this->addSettingsWidget(unusedColorIdentityOpacityWidget);
|
||||
this->addSettingsWidget(deckPreviewTooltipWidget);
|
||||
|
|
@ -130,7 +121,6 @@ void VisualDeckStorageQuickSettingsWidget::retranslateUi()
|
|||
showTagFilterCheckBox->setText(tr("Show Tag Filter"));
|
||||
showTagsOnDeckPreviewsCheckBox->setText(tr("Show Tags On Deck Previews"));
|
||||
showBannerCardComboBoxCheckBox->setText(tr("Show Banner Card Selection Option"));
|
||||
searchFolderNamesCheckBox->setText(tr("Include Folder Names in Search"));
|
||||
drawUnusedColorIdentitiesCheckBox->setText(tr("Draw unused Color Identities"));
|
||||
unusedColorIdentitiesOpacityLabel->setText(tr("Unused Color Identities Opacity"));
|
||||
unusedColorIdentitiesOpacitySpinBox->setSuffix("%");
|
||||
|
|
@ -165,11 +155,6 @@ bool VisualDeckStorageQuickSettingsWidget::getShowTagsOnDeckPreviews() const
|
|||
return showTagsOnDeckPreviewsCheckBox->isChecked();
|
||||
}
|
||||
|
||||
bool VisualDeckStorageQuickSettingsWidget::getSearchFolderNames() const
|
||||
{
|
||||
return searchFolderNamesCheckBox->isChecked();
|
||||
}
|
||||
|
||||
int VisualDeckStorageQuickSettingsWidget::getUnusedColorIdentitiesOpacity() const
|
||||
{
|
||||
return unusedColorIdentitiesOpacitySpinBox->value();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ class VisualDeckStorageQuickSettingsWidget : public SettingsButtonWidget
|
|||
QCheckBox *showBannerCardComboBoxCheckBox;
|
||||
QCheckBox *showTagFilterCheckBox;
|
||||
QCheckBox *showTagsOnDeckPreviewsCheckBox;
|
||||
QCheckBox *searchFolderNamesCheckBox;
|
||||
QLabel *unusedColorIdentitiesOpacityLabel;
|
||||
QSpinBox *unusedColorIdentitiesOpacitySpinBox;
|
||||
QLabel *deckPreviewTooltipLabel;
|
||||
|
|
@ -50,7 +49,6 @@ public:
|
|||
bool getShowBannerCardComboBox() const;
|
||||
bool getShowTagFilter() const;
|
||||
bool getShowTagsOnDeckPreviews() const;
|
||||
bool getSearchFolderNames() const;
|
||||
int getUnusedColorIdentitiesOpacity() const;
|
||||
TooltipType getDeckPreviewTooltip() const;
|
||||
int getCardSize() const;
|
||||
|
|
@ -61,7 +59,6 @@ signals:
|
|||
void showBannerCardComboBoxChanged(bool enabled);
|
||||
void showTagFilterChanged(bool enabled);
|
||||
void showTagsOnDeckPreviewsChanged(bool enabled);
|
||||
void searchFolderNamesChanged(bool enabled);
|
||||
void unusedColorIdentitiesOpacityChanged(int opacity);
|
||||
void deckPreviewTooltipChanged(TooltipType tooltip);
|
||||
void cardSizeChanged(int scale);
|
||||
|
|
|
|||
|
|
@ -52,17 +52,15 @@ QString VisualDeckStorageSearchWidget::getSearchText()
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the filename used for the search.
|
||||
* Converts the filepath into a relative filepath starting from the deck folder.
|
||||
* If the file isn't in the deck folder, then this will just return the filename.
|
||||
*
|
||||
* if includeFolderName is true, then this returns the relative filepath starting from the deck folder.
|
||||
* If the file isn't in the deck folder, or includeFolderName is false, then this will just return the filename.
|
||||
*
|
||||
* @param filePath The filePath to convert into a search name
|
||||
* @param filePath The filepath to convert into a relative filepath
|
||||
*/
|
||||
static QString getFileSearchName(const QString &filePath, bool includeFolderName)
|
||||
static QString toRelativeFilepath(const QString &filePath)
|
||||
{
|
||||
QString deckPath = SettingsCache::instance().getDeckPath();
|
||||
if (includeFolderName && filePath.startsWith(deckPath)) {
|
||||
if (filePath.startsWith(deckPath)) {
|
||||
return filePath.mid(deckPath.length());
|
||||
}
|
||||
|
||||
|
|
@ -71,14 +69,12 @@ static QString getFileSearchName(const QString &filePath, bool includeFolderName
|
|||
return fileName;
|
||||
}
|
||||
|
||||
void VisualDeckStorageSearchWidget::filterWidgets(QList<DeckPreviewWidget *> widgets,
|
||||
const QString &searchText,
|
||||
bool includeFolderName)
|
||||
void VisualDeckStorageSearchWidget::filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText)
|
||||
{
|
||||
auto filterString = DeckFilterString(searchText);
|
||||
|
||||
for (auto widget : widgets) {
|
||||
QString fileSearchName = getFileSearchName(widget->filePath, includeFolderName);
|
||||
widget->filteredBySearch = !filterString.check(widget, {fileSearchName});
|
||||
QString relativeFilePath = toRelativeFilepath(widget->filePath);
|
||||
widget->filteredBySearch = !filterString.check(widget, {relativeFilePath});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class VisualDeckStorageSearchWidget : public QWidget
|
|||
public:
|
||||
explicit VisualDeckStorageSearchWidget(VisualDeckStorageWidget *parent);
|
||||
QString getSearchText();
|
||||
void filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText, bool includeFolderName);
|
||||
void filterWidgets(QList<DeckPreviewWidget *> widgets, const QString &searchText);
|
||||
|
||||
private:
|
||||
QHBoxLayout *layout;
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
|
|||
&VisualDeckStorageWidget::updateShowFolders);
|
||||
connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::showTagFilterChanged, this,
|
||||
&VisualDeckStorageWidget::updateTagsVisibility);
|
||||
connect(quickSettingsWidget, &VisualDeckStorageQuickSettingsWidget::searchFolderNamesChanged, this,
|
||||
&VisualDeckStorageWidget::updateSearchFilter);
|
||||
|
||||
searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget);
|
||||
searchAndSortLayout->addWidget(sortWidget);
|
||||
|
|
@ -196,8 +194,7 @@ void VisualDeckStorageWidget::updateColorFilter()
|
|||
void VisualDeckStorageWidget::updateSearchFilter()
|
||||
{
|
||||
if (folderWidget) {
|
||||
searchWidget->filterWidgets(folderWidget->findChildren<DeckPreviewWidget *>(), searchWidget->getSearchText(),
|
||||
quickSettingsWidget->getSearchFolderNames());
|
||||
searchWidget->filterWidgets(folderWidget->findChildren<DeckPreviewWidget *>(), searchWidget->getSearchText());
|
||||
folderWidget->updateVisibility();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,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>
|
||||
|
|
@ -42,7 +46,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"
|
||||
|
|
@ -442,6 +446,51 @@ 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, this]() {
|
||||
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
|
||||
|
||||
auto newColor = QColorDialog::getColor(cardCounterSettings.color(index), this);
|
||||
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);
|
||||
|
||||
cardCountersGroupBox = new QGroupBox;
|
||||
cardCountersGroupBox->setLayout(cardCountersLayout);
|
||||
|
||||
// Hand layout
|
||||
horizontalHandCheckBox.setChecked(settings.getHorizontalHand());
|
||||
connect(&horizontalHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings, &SettingsCache::setHorizontalHand);
|
||||
|
|
@ -489,6 +538,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
|||
mainLayout->addWidget(themeGroupBox);
|
||||
mainLayout->addWidget(menuGroupBox);
|
||||
mainLayout->addWidget(cardsGroupBox);
|
||||
mainLayout->addWidget(cardCountersGroupBox);
|
||||
mainLayout->addWidget(handGroupBox);
|
||||
mainLayout->addWidget(tableGroupBox);
|
||||
mainLayout->addStretch();
|
||||
|
|
@ -577,6 +627,13 @@ void AppearanceSettingsPage::retranslateUi()
|
|||
cardViewExpandedRowsMaxLabel.setText(tr("Maximum expanded height for card view window:"));
|
||||
cardViewExpandedRowsMaxBox.setSuffix(tr(" rows"));
|
||||
|
||||
cardCountersGroupBox->setTitle(tr("Card counters"));
|
||||
|
||||
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
|
||||
for (int index = 0; index < cardCounterNames.size(); ++index) {
|
||||
cardCounterNames[index]->setText(tr("Counter %1").arg(cardCounterSettings.displayName(index)));
|
||||
}
|
||||
|
||||
handGroupBox->setTitle(tr("Hand layout"));
|
||||
horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)"));
|
||||
leftJustifiedHandCheckBox.setText(tr("Enable left justification"));
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ private:
|
|||
QGroupBox *cardsGroupBox;
|
||||
QGroupBox *handGroupBox;
|
||||
QGroupBox *tableGroupBox;
|
||||
QGroupBox *cardCountersGroupBox;
|
||||
QList<QLabel *> cardCounterNames;
|
||||
QSpinBox minPlayersForMultiColumnLayoutEdit;
|
||||
QSpinBox maxFontSizeForCardsEdit;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../../client/tabs/tab_game.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../../settings/card_counter_settings.h"
|
||||
#include "../cards/card_info.h"
|
||||
#include "../game_scene.h"
|
||||
#include "../player/player.h"
|
||||
|
|
@ -32,6 +33,11 @@ CardItem::CardItem(Player *_owner,
|
|||
ptMenu = new QMenu;
|
||||
moveMenu = new QMenu;
|
||||
|
||||
connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) {
|
||||
if (counters.contains(counterId))
|
||||
update();
|
||||
});
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
|
|
@ -84,6 +90,8 @@ void CardItem::retranslateUi()
|
|||
|
||||
void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
|
||||
|
||||
painter->save();
|
||||
AbstractCardItem::paint(painter, option, widget);
|
||||
|
||||
|
|
@ -91,8 +99,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|||
QMapIterator<int, int> counterIterator(counters);
|
||||
while (counterIterator.hasNext()) {
|
||||
counterIterator.next();
|
||||
QColor _color;
|
||||
_color.setHsv(counterIterator.key() * 60, 150, 255);
|
||||
QColor _color = cardCounterSettings.color(counterIterator.key());
|
||||
|
||||
paintNumberEllipse(counterIterator.value(), 14, _color, i, counters.size(), painter);
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ QueryPartList <- ComplexQueryPart ( ws ("AND" ws)? ComplexQueryPart)* ws*
|
|||
ComplexQueryPart <- SomewhatComplexQueryPart ws "OR" ws ComplexQueryPart / SomewhatComplexQueryPart
|
||||
SomewhatComplexQueryPart <- [(] QueryPartList [)] / QueryPart
|
||||
|
||||
QueryPart <- NotQuery / DeckContentQuery / GenericQuery
|
||||
QueryPart <- NotQuery / DeckContentQuery / DeckNameQuery / FileNameQuery / PathQuery / GenericQuery
|
||||
|
||||
NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart
|
||||
|
||||
|
|
@ -20,6 +20,10 @@ DeckContentQuery <- CardSearch NumericExpression?
|
|||
CardSearch <- '[[' CardFilterString ']]'
|
||||
CardFilterString <- (!']]'.)*
|
||||
|
||||
DeckNameQuery <- ([Dd] 'eck')? [Nn] 'ame'? [:] String
|
||||
FileNameQuery <- [Ff] ('ile' 'name'?)? [:] String
|
||||
PathQuery <- [Pp] 'ath'? [:] String
|
||||
|
||||
GenericQuery <- String
|
||||
|
||||
NonDoubleQuoteUnlessEscaped <- '\\\"'. / !["].
|
||||
|
|
@ -129,6 +133,28 @@ static void setupParserRules()
|
|||
return QString::fromStdString(std::string(sv.sv()));
|
||||
};
|
||||
|
||||
search["DeckNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
return deck->deckLoader->getName().contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["FileNameQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
auto filename = QFileInfo(deck->filePath).fileName();
|
||||
return filename.contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["PathQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *, const ExtraDeckSearchInfo &info) {
|
||||
return info.relativeFilePath.contains(name, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ inline Q_LOGGING_CATEGORY(DeckFilterStringLog, "deck_filter_string");
|
|||
struct ExtraDeckSearchInfo
|
||||
{
|
||||
/**
|
||||
* The filename used for filtering. Varies based on settings.
|
||||
* The relative filepath starting from the deck folder
|
||||
*/
|
||||
QString fileSearchName;
|
||||
QString relativeFilePath;
|
||||
};
|
||||
|
||||
typedef std::function<bool(const DeckPreviewWidget *, const ExtraDeckSearchInfo &)> DeckFilter;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "../../dialogs/dlg_roll_dice.h"
|
||||
#include "../../main.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../../settings/card_counter_settings.h"
|
||||
#include "../board/arrow_item.h"
|
||||
#include "../board/card_item.h"
|
||||
#include "../board/card_list.h"
|
||||
|
|
@ -419,6 +420,8 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
|
|||
createPredefinedTokenMenu = new QMenu(QString());
|
||||
createPredefinedTokenMenu->setEnabled(false);
|
||||
|
||||
mCardCounters = new QMenu;
|
||||
|
||||
playerMenu->addSeparator();
|
||||
countersMenu = playerMenu->addMenu(QString());
|
||||
playerMenu->addSeparator();
|
||||
|
|
@ -461,6 +464,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
|
|||
mCustomZones = nullptr;
|
||||
aCreateAnotherToken = nullptr;
|
||||
createPredefinedTokenMenu = nullptr;
|
||||
mCardCounters = nullptr;
|
||||
}
|
||||
|
||||
aTap = new QAction(this);
|
||||
|
|
@ -538,7 +542,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T
|
|||
aPlayFacedown = new QAction(this);
|
||||
connect(aPlayFacedown, &QAction::triggered, this, &Player::actPlayFacedown);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
auto *tempAddCounter = new QAction(this);
|
||||
tempAddCounter->setData(9 + i * 1000);
|
||||
auto *tempRemoveCounter = new QAction(this);
|
||||
|
|
@ -892,19 +896,17 @@ void Player::retranslateUi()
|
|||
aResetPT->setText(tr("Reset p&ower and toughness"));
|
||||
aSetAnnotation->setText(tr("&Set annotation..."));
|
||||
|
||||
QStringList counterColors;
|
||||
counterColors.append(tr("Red"));
|
||||
counterColors.append(tr("Yellow"));
|
||||
counterColors.append(tr("Green"));
|
||||
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
|
||||
|
||||
mCardCounters->setTitle(tr("Ca&rd counters"));
|
||||
for (int i = 0; i < aAddCounter.size(); ++i) {
|
||||
aAddCounter[i]->setText(tr("&Add counter (%1)").arg(counterColors[i]));
|
||||
aAddCounter[i]->setText(tr("&Add counter (%1)").arg(cardCounterSettings.displayName(i)));
|
||||
}
|
||||
for (int i = 0; i < aRemoveCounter.size(); ++i) {
|
||||
aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(counterColors[i]));
|
||||
aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(cardCounterSettings.displayName(i)));
|
||||
}
|
||||
for (int i = 0; i < aSetCounter.size(); ++i) {
|
||||
aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(counterColors[i]));
|
||||
aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(cardCounterSettings.displayName(i)));
|
||||
}
|
||||
|
||||
aMoveToTopLibrary->setText(tr("&Top of library in random order"));
|
||||
|
|
@ -960,24 +962,33 @@ void Player::setShortcutsActive()
|
|||
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCRed"));
|
||||
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCYellow"));
|
||||
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCGreen"));
|
||||
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCCyan"));
|
||||
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCPurple"));
|
||||
addCCShortCuts.append(shortcuts.getSingleShortcut("Player/aCCMagenta"));
|
||||
|
||||
QList<QKeySequence> removeCCShortCuts;
|
||||
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCRed"));
|
||||
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCYellow"));
|
||||
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCGreen"));
|
||||
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCCyan"));
|
||||
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCPurple"));
|
||||
removeCCShortCuts.append(shortcuts.getSingleShortcut("Player/aRCMagenta"));
|
||||
|
||||
QList<QKeySequence> setCCShortCuts;
|
||||
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCRed"));
|
||||
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCYellow"));
|
||||
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCGreen"));
|
||||
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCCyan"));
|
||||
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCPurple"));
|
||||
setCCShortCuts.append(shortcuts.getSingleShortcut("Player/aSCMagenta"));
|
||||
|
||||
for (int i = 0; i < aAddCounter.size(); ++i) {
|
||||
for (int i = 0; i < addCCShortCuts.size(); ++i) {
|
||||
aAddCounter[i]->setShortcut(addCCShortCuts.at(i));
|
||||
}
|
||||
for (int i = 0; i < aRemoveCounter.size(); ++i) {
|
||||
for (int i = 0; i < removeCCShortCuts.size(); ++i) {
|
||||
aRemoveCounter[i]->setShortcut(removeCCShortCuts.at(i));
|
||||
}
|
||||
for (int i = 0; i < aSetCounter.size(); ++i) {
|
||||
for (int i = 0; i < setCCShortCuts.size(); ++i) {
|
||||
aSetCounter[i]->setShortcut(setCCShortCuts.at(i));
|
||||
}
|
||||
|
||||
|
|
@ -3944,15 +3955,18 @@ void Player::updateCardMenu(const CardItem *card)
|
|||
cardMenu->addAction(aSelectAll);
|
||||
cardMenu->addAction(aSelectRow);
|
||||
|
||||
cardMenu->addSeparator();
|
||||
mCardCounters->clear();
|
||||
for (int i = 0; i < aAddCounter.size(); ++i) {
|
||||
cardMenu->addSeparator();
|
||||
cardMenu->addAction(aAddCounter[i]);
|
||||
mCardCounters->addSeparator();
|
||||
mCardCounters->addAction(aAddCounter[i]);
|
||||
if (card->getCounters().contains(i)) {
|
||||
cardMenu->addAction(aRemoveCounter[i]);
|
||||
mCardCounters->addAction(aRemoveCounter[i]);
|
||||
}
|
||||
cardMenu->addAction(aSetCounter[i]);
|
||||
mCardCounters->addAction(aSetCounter[i]);
|
||||
}
|
||||
cardMenu->addSeparator();
|
||||
cardMenu->addMenu(mCardCounters);
|
||||
} else if (card->getZone()->getName() == "stack") {
|
||||
// Card is on the stack
|
||||
if (canModifyCard) {
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ public:
|
|||
private:
|
||||
TabGame *game;
|
||||
QMenu *sbMenu, *countersMenu, *sayMenu, *createPredefinedTokenMenu, *mRevealLibrary, *mLendLibrary, *mRevealTopCard,
|
||||
*mRevealHand, *mRevealRandomHandCard, *mRevealRandomGraveyardCard, *mCustomZones;
|
||||
*mRevealHand, *mRevealRandomHandCard, *mRevealRandomGraveyardCard, *mCustomZones, *mCardCounters;
|
||||
TearOffMenu *moveGraveMenu, *moveRfgMenu, *graveMenu, *moveHandMenu, *handMenu, *libraryMenu, *topLibraryMenu,
|
||||
*bottomLibraryMenu, *rfgMenu, *playerMenu;
|
||||
QList<QMenu *> playerLists;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../game/phase.h"
|
||||
#include "../game/player/player.h"
|
||||
#include "../game/zones/card_zone.h"
|
||||
#include "../settings/card_counter_settings.h"
|
||||
#include "pb/context_move_card.pb.h"
|
||||
#include "pb/context_mulligan.pb.h"
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
|
|
@ -613,28 +614,15 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c
|
|||
QString finalStr;
|
||||
int delta = abs(oldValue - value);
|
||||
if (value > oldValue) {
|
||||
finalStr = tr("%1 places %2 %3 on %4 (now %5).");
|
||||
finalStr = tr("%1 places %2 \"%3\" counter(s) on %4 (now %5).", "", delta);
|
||||
} else {
|
||||
finalStr = tr("%1 removes %2 %3 from %4 (now %5).");
|
||||
}
|
||||
|
||||
QString colorStr;
|
||||
switch (counterId) {
|
||||
case 0:
|
||||
colorStr = tr("red counter(s)", "", delta);
|
||||
break;
|
||||
case 1:
|
||||
colorStr = tr("yellow counter(s)", "", delta);
|
||||
break;
|
||||
case 2:
|
||||
colorStr = tr("green counter(s)", "", delta);
|
||||
break;
|
||||
default:;
|
||||
finalStr = tr("%1 removes %2 \"%3\" counter(s) from %4 (now %5).", "", delta);
|
||||
}
|
||||
|
||||
auto &cardCounterSettings = SettingsCache::instance().cardCounters();
|
||||
appendHtmlServerMessage(finalStr.arg(sanitizeHtml(player->getName()))
|
||||
.arg("<font class=\"blue\">" + QString::number(delta) + "</font>")
|
||||
.arg(colorStr)
|
||||
.arg(cardCounterSettings.displayName(counterId))
|
||||
.arg(cardLink(std::move(cardName)))
|
||||
.arg(value));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#include "cache_settings.h"
|
||||
|
||||
#include "../client/network/release_channel.h"
|
||||
#include "card_counter_settings.h"
|
||||
#include "card_override_settings.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
|
@ -179,6 +181,8 @@ SettingsCache::SettingsCache()
|
|||
cardOverrideSettings = new CardOverrideSettings(settingsPath, this);
|
||||
debugSettings = new DebugSettings(settingsPath, this);
|
||||
|
||||
cardCounterSettings = new CardCounterSettings(settingsPath, this);
|
||||
|
||||
if (!QFile(settingsPath + "global.ini").exists())
|
||||
translateLegacySettings();
|
||||
|
||||
|
|
@ -1439,3 +1443,8 @@ SettingsCache &SettingsCache::instance()
|
|||
{
|
||||
return *settingsCache;
|
||||
}
|
||||
|
||||
CardCounterSettings &SettingsCache::cardCounters() const
|
||||
{
|
||||
return *cardCounterSettings;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ inline QStringList defaultTags = {
|
|||
};
|
||||
|
||||
class QSettings;
|
||||
class CardCounterSettings;
|
||||
|
||||
class SettingsCache : public QObject
|
||||
{
|
||||
|
|
@ -185,6 +186,7 @@ private:
|
|||
RecentsSettings *recentsSettings;
|
||||
CardOverrideSettings *cardOverrideSettings;
|
||||
DebugSettings *debugSettings;
|
||||
CardCounterSettings *cardCounterSettings;
|
||||
|
||||
QByteArray mainWindowGeometry;
|
||||
QByteArray tokenDialogGeometry;
|
||||
|
|
@ -870,6 +872,8 @@ public:
|
|||
{
|
||||
return *debugSettings;
|
||||
}
|
||||
CardCounterSettings &cardCounters() const;
|
||||
|
||||
bool getIsPortableBuild() const
|
||||
{
|
||||
return isPortableBuild;
|
||||
|
|
|
|||
56
cockatrice/src/settings/card_counter_settings.cpp
Normal file
56
cockatrice/src/settings/card_counter_settings.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "card_counter_settings.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QSettings>
|
||||
#include <QtMath>
|
||||
|
||||
CardCounterSettings::CardCounterSettings(const QString &settingsPath, QObject *parent)
|
||||
: SettingsManager(settingsPath + "global.ini", parent)
|
||||
{
|
||||
}
|
||||
|
||||
void CardCounterSettings::setColor(int counterId, const QColor &color)
|
||||
{
|
||||
QString key = QString("cards/counters/%1/color").arg(counterId);
|
||||
|
||||
if (settings.value(key).value<QColor>() == color)
|
||||
return;
|
||||
|
||||
settings.setValue(key, color);
|
||||
emit colorChanged(counterId, color);
|
||||
}
|
||||
|
||||
QColor CardCounterSettings::color(int counterId) const
|
||||
{
|
||||
QColor defaultColor;
|
||||
|
||||
if (counterId < 6) {
|
||||
// Preserve legacy colors
|
||||
defaultColor = QColor::fromHsv(counterId * 60, 150, 255);
|
||||
} else {
|
||||
// Future-proof support for more counters with pseudo-random colors
|
||||
int h = (counterId * 37) % 360;
|
||||
int s = 128 + 64 * qSin((counterId * 97) * 0.1); // 64-192
|
||||
int v = 196 + 32 * qSin((counterId * 101) * 0.07); // 164-228
|
||||
|
||||
defaultColor = QColor::fromHsv(h, s, v);
|
||||
}
|
||||
|
||||
return settings.value(QString("cards/counters/%1/color").arg(counterId), defaultColor).value<QColor>();
|
||||
}
|
||||
|
||||
QString CardCounterSettings::displayName(int counterId) const
|
||||
{
|
||||
// Currently, card counters name are fixed to A, B, ..., Z, AA, AB, ...
|
||||
|
||||
auto nChars = 1 + counterId / 26;
|
||||
QString str;
|
||||
str.resize(nChars);
|
||||
|
||||
for (auto it = str.rbegin(); it != str.rend(); ++it) {
|
||||
*it = QChar('A' + (counterId) % 26);
|
||||
counterId /= 26;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
29
cockatrice/src/settings/card_counter_settings.h
Normal file
29
cockatrice/src/settings/card_counter_settings.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef CARD_COUNTER_SETTINGS_H
|
||||
#define CARD_COUNTER_SETTINGS_H
|
||||
|
||||
#include "settings_manager.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QSettings;
|
||||
class QColor;
|
||||
|
||||
class CardCounterSettings : public SettingsManager
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CardCounterSettings(const QString &settingsPath, QObject *parent = nullptr);
|
||||
|
||||
QColor color(int counterId) const;
|
||||
|
||||
QString displayName(int counterId) const;
|
||||
|
||||
public slots:
|
||||
void setColor(int counterId, const QColor &color);
|
||||
|
||||
signals:
|
||||
void colorChanged(int counterId, const QColor &color);
|
||||
};
|
||||
|
||||
#endif // CARD_COUNTER_SETTINGS_H
|
||||
|
|
@ -284,31 +284,58 @@ private:
|
|||
{"DeckViewContainer/forceStartGameButton", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Force Start"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Game_Lobby)},
|
||||
{"Player/aCCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Green Counter"),
|
||||
{"Player/aCCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (F)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aRCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (F)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aSCMagenta", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (F)..."),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aCCPurple", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (E)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aRCPurple", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (E)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aSCPurple", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (E)..."),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aCCCyan", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter(D)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aRCCyan", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (D)"),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aSCCyan", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (D)..."),
|
||||
parseSequenceString(""),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aCCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (C)"),
|
||||
parseSequenceString("Ctrl+>"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aRCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Green Counter"),
|
||||
{"Player/aRCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (C)"),
|
||||
parseSequenceString("Ctrl+<"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aSCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Green Counters..."),
|
||||
{"Player/aSCGreen", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (C)..."),
|
||||
parseSequenceString("Ctrl+?"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aCCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Yellow Counter"),
|
||||
{"Player/aCCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (B)"),
|
||||
parseSequenceString("Ctrl+."),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aRCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Yellow Counter"),
|
||||
{"Player/aRCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (B)"),
|
||||
parseSequenceString("Ctrl+,"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aSCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Yellow Counters..."),
|
||||
{"Player/aSCYellow", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (B)..."),
|
||||
parseSequenceString("Ctrl+/"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aCCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Red Counter"),
|
||||
{"Player/aCCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card Counter (A)"),
|
||||
parseSequenceString("Alt+."),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aRCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Red Counter"),
|
||||
{"Player/aRCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Remove Card Counter (A)"),
|
||||
parseSequenceString("Alt+,"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aSCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Red Counters..."),
|
||||
{"Player/aSCRed", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Set Card Counters (A)..."),
|
||||
parseSequenceString("Alt+/"),
|
||||
ShortcutGroup::Card_Counters)},
|
||||
{"Player/aInc", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Life Counter"),
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
<xs:element type="xs:integer" name="tablerow" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="xs:boolean" name="cipt" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="xs:boolean" name="upsidedown" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="xs:boolean" name="landscapeOrientation" minOccurs="0" maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:element name="cockatrice_carddatabase">
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ set(oracle_SOURCES
|
|||
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||
../cockatrice/src/settings/cache_settings.cpp
|
||||
../cockatrice/src/settings/shortcuts_settings.cpp
|
||||
../cockatrice/src/settings/card_counter_settings.cpp
|
||||
../cockatrice/src/settings/card_database_settings.cpp
|
||||
../cockatrice/src/settings/servers_settings.cpp
|
||||
../cockatrice/src/settings/settings_manager.cpp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue