mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
* [Client] Add [AppColors] application palette roles The home-tab buttons' gradient over the static theme background was hardcoded, and accent-derived fallbacks could not be themed or edited: QPalette's role set is closed, so any application-specific color has to live in Cockatrice's own palette layer. - Add an AppColor::Role enum (AccentStrong / AccentSoft) stored on PaletteConfig and round-tripped from palette-<scheme>.toml under a new [AppColors] section. - Cache the applied app colors in ThemeManager and expose appColor(Role) with a palette-accent-derived fallback; emit paletteChanged() from applyStyleAndPalette so previews, scheme switches and OS dark mode repaint palette-driven widgets. - Fill both app roles in PaletteGenerator::fromAccent and surface them as a dedicated section in the palette editor. - Drive the home-tab buttons from appColor() whenever the background source is the theme (any theme, not just built-ins). - Ship AccentStrong / AccentSoft values in the Fusion and Default default palettes so the static home-tab buttons keep their classic greens. # Conflicts: # cockatrice/src/interface/widgets/general/home_widget.cpp * [AppColors] Address review comments - PaletteEditorDialog::onSave(): compare whole PaletteConfig (colors and appColors) so a change to only AccentStrong/AccentSoft writes the file; add PaletteConfig::operator==. - appColor(): derive both roles from QPalette::Highlight unconditionally. The Fusion palettes pin Accent to near-Window values, and QPalette::Accent only exists on Qt 6.6+, so keying on it made identical themes render very differently across Qt versions. - themeChangedSlot(): merge the theme default's [AppColors] into a custom palette that predates the section instead of all-or-nothing per file; hasPalette() now counts an appColors-only file as a palette. - Add Default/palette-default-light.toml so the Default theme's Light scheme keeps the classic greens instead of falling back to the OS accent. - home_widget: restore the isBuiltInTheme() half of the Automatic condition; non-built-in themes extract button colors from their own background art. - palette_grid_widget: use appEnum.value(i) for the role cast (3 sites), append appHeader to headerLabels, fix the 'Lighted' typo. * [Themes] Route theme writes to the user themes directory setColorScheme()/setStyleName() and the palette editor wrote directly to the resolved theme directory, which for built-in themes is the read-only system (install) location. Changes therefore landed in the install dir and were lost on upgrade. Add ThemeManager::writableThemeDir(), which always resolves to the user themes directory, and route all theme writes through it. The palette editor reuses the same helper, dropping its private writability probe. * [Home] Replace 'Automatic' button color with explicit theme colors default The Automatic option gated on isBuiltInTheme(): built-in themes used the theme's accent colors, while non-built-in themes extracted colors from their own background art. That made the result depend on the theme's origin rather than what the user actually sees. Remove Automatic and expose two explicit choices: 'From theme colors' (always the theme's identity accents, now the default) and 'Extract from background' (always sample the painted background). Drop the now-unused isBuiltInTheme() helper. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
563 lines
26 KiB
C++
563 lines
26 KiB
C++
#include "appearance_settings_page.h"
|
|
|
|
#include "../../../client/settings/cache_settings.h"
|
|
#include "../../../client/settings/card_counter_settings.h"
|
|
#include "../../client/settings/card_counter_settings.h"
|
|
#include "../../palette_editor/palette_editor_dialog.h"
|
|
#include "../dialogs/override_printing_warning.h"
|
|
#include "../general/home_tab_button_color.h"
|
|
#include "../interface/theme_manager.h"
|
|
#include "../interface/widgets/general/background_sources.h"
|
|
#include "../playmat/playmat_collection_dialog.h"
|
|
#include "../playmat/playmat_settings_dialog.h"
|
|
|
|
#include <QApplication>
|
|
#include <QColorDialog>
|
|
#include <QDesktopServices>
|
|
#include <QGridLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QMessageBox>
|
|
#include <QStyleFactory>
|
|
#include <QTimer>
|
|
#include <libcockatrice/settings/appearance_settings.h>
|
|
#include <libcockatrice/settings/cards_display_settings.h>
|
|
#include <libcockatrice/settings/interface_settings.h>
|
|
#include <libcockatrice/settings/paths_settings.h>
|
|
#include <libcockatrice/settings/personal_settings.h>
|
|
|
|
AppearanceSettingsPage::AppearanceSettingsPage()
|
|
{
|
|
SettingsCache &settings = SettingsCache::instance();
|
|
|
|
// Theme settings
|
|
QString themeName = SettingsCache::instance().getThemeName();
|
|
|
|
QStringList themeDirs = themeManager->getAvailableThemes().keys();
|
|
for (int i = 0; i < themeDirs.size(); i++) {
|
|
themeBox.addItem(themeDirs[i]);
|
|
if (themeDirs[i] == themeName) {
|
|
themeBox.setCurrentIndex(i);
|
|
}
|
|
}
|
|
|
|
connect(&themeBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppearanceSettingsPage::themeBoxChanged);
|
|
connect(&openThemeButton, &QPushButton::clicked, this, &AppearanceSettingsPage::openThemeLocation);
|
|
|
|
schemeCombo.addItem(tr("Light"), QStringLiteral("Light"));
|
|
schemeCombo.addItem(tr("Dark"), QStringLiteral("Dark"));
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
|
schemeCombo.addItem(tr("System"), QStringLiteral("System"));
|
|
#endif
|
|
|
|
// Seed from whatever the current theme already has saved
|
|
const QString dirPath = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName());
|
|
const ThemeConfig cfg = ThemeConfig::fromThemeDir(dirPath);
|
|
const QString current = cfg.colorScheme;
|
|
const int seedIdx = schemeCombo.findData(current);
|
|
schemeCombo.setCurrentIndex(seedIdx >= 0 ? seedIdx : 0);
|
|
|
|
connect(&schemeCombo, &QComboBox::currentIndexChanged, this,
|
|
[this] { themeManager->setColorScheme(schemeCombo.currentData().toString()); });
|
|
|
|
// Qt widget style; "Default" lets the application decide
|
|
styleCombo.addItem(tr("Default"), QStringLiteral("Default"));
|
|
for (const QString &key : QStyleFactory::keys()) {
|
|
styleCombo.addItem(key, key);
|
|
}
|
|
|
|
const QString currentStyle = cfg.styleName;
|
|
const int styleSeedIdx = currentStyle.isEmpty() ? 0 : styleCombo.findData(currentStyle);
|
|
styleCombo.setCurrentIndex(styleSeedIdx >= 0 ? styleSeedIdx : 0);
|
|
|
|
connect(&styleCombo, &QComboBox::currentIndexChanged, this,
|
|
[this] { themeManager->setStyleName(styleCombo.currentData().toString()); });
|
|
|
|
connect(themeManager, &ThemeManager::themeChanged, this, [this, dirPath] {
|
|
const QString newDir = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName());
|
|
const ThemeConfig cfg = ThemeConfig::fromThemeDir(newDir);
|
|
const QString current = cfg.colorScheme;
|
|
|
|
schemeCombo.blockSignals(true);
|
|
const int idx = schemeCombo.findData(current);
|
|
schemeCombo.setCurrentIndex(idx >= 0 ? idx : 0);
|
|
schemeCombo.blockSignals(false);
|
|
|
|
styleCombo.blockSignals(true);
|
|
const QString currentStyle = cfg.styleName;
|
|
const int styleIdx = currentStyle.isEmpty() ? 0 : styleCombo.findData(currentStyle);
|
|
styleCombo.setCurrentIndex(styleIdx >= 0 ? styleIdx : 0);
|
|
styleCombo.blockSignals(false);
|
|
});
|
|
|
|
connect(&editPaletteButton, &QPushButton::clicked, this, &AppearanceSettingsPage::editPalette);
|
|
|
|
auto *themeGrid = new QGridLayout;
|
|
themeGrid->addWidget(&themeLabel, 0, 0);
|
|
themeGrid->addWidget(&themeBox, 0, 1);
|
|
themeGrid->addWidget(&openThemeButton, 1, 1);
|
|
themeGrid->addWidget(&schemeComboLabel, 2, 0);
|
|
themeGrid->addWidget(&schemeCombo, 2, 1);
|
|
themeGrid->addWidget(&styleComboLabel, 3, 0);
|
|
themeGrid->addWidget(&styleCombo, 3, 1);
|
|
themeGrid->addWidget(&editPaletteButton, 4, 1);
|
|
|
|
themeGroupBox = new QGroupBox;
|
|
themeGroupBox->setLayout(themeGrid);
|
|
|
|
// Home tab settings
|
|
for (const auto &entry : BackgroundSources::all()) {
|
|
homeTabBackgroundSourceBox.addItem(QObject::tr(entry.trKey), QVariant::fromValue(entry.type));
|
|
}
|
|
|
|
QString homeTabBackgroundSource = settings.appearance().getHomeTabBackgroundSource();
|
|
int homeTabBackgroundSourceId =
|
|
homeTabBackgroundSourceBox.findData(BackgroundSources::fromId(homeTabBackgroundSource));
|
|
if (homeTabBackgroundSourceId != -1) {
|
|
homeTabBackgroundSourceBox.setCurrentIndex(homeTabBackgroundSourceId);
|
|
}
|
|
|
|
connect(&homeTabBackgroundSourceBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() {
|
|
auto type = homeTabBackgroundSourceBox.currentData().value<BackgroundSources::Type>();
|
|
SettingsCache::instance().appearance().setHomeTabBackgroundSource(BackgroundSources::toId(type));
|
|
updateHomeTabSettingsVisibility();
|
|
});
|
|
|
|
homeTabBackgroundShuffleFrequencySpinBox.setRange(0, 3600);
|
|
homeTabBackgroundShuffleFrequencySpinBox.setSuffix(tr(" seconds"));
|
|
homeTabBackgroundShuffleFrequencySpinBox.setValue(settings.appearance().getHomeTabBackgroundShuffleFrequency());
|
|
connect(&homeTabBackgroundShuffleFrequencySpinBox, qOverload<int>(&QSpinBox::valueChanged), &settings.appearance(),
|
|
&AppearanceSettings::setHomeTabBackgroundShuffleFrequency);
|
|
|
|
homeTabDisplayCardNameCheckBox.setChecked(settings.appearance().getHomeTabDisplayCardName());
|
|
connect(&homeTabDisplayCardNameCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.appearance(),
|
|
&AppearanceSettings::setHomeTabDisplayCardName);
|
|
|
|
for (const auto &entry : HomeTabButtonColor::all()) {
|
|
homeTabButtonColorSourceBox.addItem(QObject::tr(entry.trKey));
|
|
}
|
|
|
|
homeTabButtonColorSourceBox.setCurrentIndex(settings.appearance().getHomeTabButtonColorSourceIndex());
|
|
connect(&homeTabButtonColorSourceBox, QOverload<int>::of(&QComboBox::currentIndexChanged), &settings.appearance(),
|
|
&AppearanceSettings::setHomeTabButtonColorSourceIndex);
|
|
|
|
updateHomeTabSettingsVisibility();
|
|
|
|
auto *homeTabGrid = new QGridLayout;
|
|
homeTabGrid->addWidget(&homeTabBackgroundSourceLabel, 0, 0);
|
|
homeTabGrid->addWidget(&homeTabBackgroundSourceBox, 0, 1);
|
|
homeTabGrid->addWidget(&homeTabBackgroundShuffleFrequencyLabel, 1, 0);
|
|
homeTabGrid->addWidget(&homeTabBackgroundShuffleFrequencySpinBox, 1, 1);
|
|
homeTabGrid->addWidget(&homeTabDisplayCardNameCheckBox, 2, 0, 1, 2);
|
|
homeTabGrid->addWidget(&homeTabButtonColorSourceLabel, 3, 0);
|
|
homeTabGrid->addWidget(&homeTabButtonColorSourceBox, 3, 1);
|
|
|
|
homeTabGroupBox = new QGroupBox;
|
|
homeTabGroupBox->setLayout(homeTabGrid);
|
|
|
|
// Playmat settings
|
|
playmatVisibilityCombo.addItem(tr("Show all playmats"), PlaymatVisibilityAll);
|
|
playmatVisibilityCombo.addItem(tr("Show own playmat only"), PlaymatVisibilityOwnOnly);
|
|
playmatVisibilityCombo.addItem(tr("Don't use playmats"), PlaymatVisibilityNone);
|
|
int visIdx = playmatVisibilityCombo.findData(settings.userInterface().getPlaymatVisibility());
|
|
if (visIdx >= 0) {
|
|
playmatVisibilityCombo.setCurrentIndex(visIdx);
|
|
}
|
|
connect(&playmatVisibilityCombo, qOverload<int>(&QComboBox::currentIndexChanged), this, [this](int index) {
|
|
SettingsCache::instance().userInterface().setPlaymatVisibility(playmatVisibilityCombo.itemData(index).toInt());
|
|
});
|
|
playmatVisibilityLabel.setBuddy(&playmatVisibilityCombo);
|
|
|
|
// Playmat mode: Override / Fallback / Deck-only
|
|
playmatModeCombo.addItem(tr("Override deck playmat"), PlaymatModeOverrideDeck);
|
|
playmatModeCombo.addItem(tr("Fallback if deck has none"), PlaymatModeFallback);
|
|
playmatModeCombo.addItem(tr("Deck only, ignore collection"), PlaymatModeDeckOnly);
|
|
int modeIdx = playmatModeCombo.findData(settings.userInterface().getPlaymatMode());
|
|
if (modeIdx >= 0) {
|
|
playmatModeCombo.setCurrentIndex(modeIdx);
|
|
}
|
|
connect(&playmatModeCombo, qOverload<int>(&QComboBox::currentIndexChanged), this, [this](int index) {
|
|
SettingsCache::instance().userInterface().setPlaymatMode(playmatModeCombo.itemData(index).toInt());
|
|
});
|
|
playmatModeLabel.setBuddy(&playmatModeCombo);
|
|
|
|
// User-level playmat settings: fallback collection.
|
|
connect(&playmatDefaultEditButton, &QPushButton::clicked, this,
|
|
&AppearanceSettingsPage::openPlaymatCollectionDialog);
|
|
|
|
auto *playmatGrid = new QGridLayout;
|
|
playmatGrid->addWidget(&playmatVisibilityLabel, 0, 0, 1, 1);
|
|
playmatGrid->addWidget(&playmatVisibilityCombo, 0, 1, 1, 1);
|
|
playmatGrid->addWidget(&playmatModeLabel, 1, 0, 1, 1);
|
|
playmatGrid->addWidget(&playmatModeCombo, 1, 1, 1, 1);
|
|
playmatGrid->addWidget(&playmatDefaultLabel, 2, 0, 1, 1);
|
|
playmatGrid->addWidget(&playmatDefaultEditButton, 2, 1, 1, 1);
|
|
|
|
playmatGroupBox = new QGroupBox;
|
|
playmatGroupBox->setLayout(playmatGrid);
|
|
|
|
// Styling settings
|
|
styleUserListCheckBox.setChecked(settings.appearance().getStyleUserList());
|
|
connect(&styleUserListCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.appearance(),
|
|
&AppearanceSettings::setStyleUserList);
|
|
|
|
auto stylingTabGrid = new QGridLayout;
|
|
stylingTabGrid->addWidget(&styleUserListCheckBox, 0, 0, 1, 2);
|
|
|
|
stylingGroupBox = new QGroupBox;
|
|
stylingGroupBox->setLayout(stylingTabGrid);
|
|
|
|
// Menu settings
|
|
showShortcutsCheckBox.setChecked(settings.userInterface().getShowShortcuts());
|
|
connect(&showShortcutsCheckBox, &QCheckBox::QT_STATE_CHANGED, this, &AppearanceSettingsPage::showShortcutsChanged);
|
|
|
|
showGameSelectorFilterToolbarCheckBox.setChecked(settings.userInterface().getShowGameSelectorFilterToolbar());
|
|
connect(&showGameSelectorFilterToolbarCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.userInterface(),
|
|
&InterfaceSettings::setShowGameSelectorFilterToolbar);
|
|
|
|
auto *menuGrid = new QGridLayout;
|
|
menuGrid->addWidget(&showShortcutsCheckBox, 0, 0);
|
|
menuGrid->addWidget(&showGameSelectorFilterToolbarCheckBox, 1, 0);
|
|
|
|
menuGroupBox = new QGroupBox;
|
|
menuGroupBox->setLayout(menuGrid);
|
|
|
|
// Printings settings
|
|
overrideAllCardArtWithPersonalPreferenceCheckBox.setChecked(
|
|
settings.cardsDisplay().getOverrideAllCardArtWithPersonalPreference());
|
|
connect(&overrideAllCardArtWithPersonalPreferenceCheckBox, &QCheckBox::QT_STATE_CHANGED, this,
|
|
&AppearanceSettingsPage::overrideAllCardArtWithPersonalPreferenceToggled);
|
|
|
|
bumpSetsWithCardsInDeckToTopCheckBox.setChecked(settings.cardsDisplay().getBumpSetsWithCardsInDeckToTop());
|
|
connect(&bumpSetsWithCardsInDeckToTopCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.cardsDisplay(),
|
|
&CardsDisplaySettings::setBumpSetsWithCardsInDeckToTop);
|
|
|
|
auto *printingsGrid = new QGridLayout;
|
|
printingsGrid->addWidget(&overrideAllCardArtWithPersonalPreferenceCheckBox, 0, 0, 1, 2);
|
|
printingsGrid->addWidget(&bumpSetsWithCardsInDeckToTopCheckBox, 1, 0, 1, 2);
|
|
|
|
printingsGroupBox = new QGroupBox;
|
|
printingsGroupBox->setLayout(printingsGrid);
|
|
|
|
// Card rendering
|
|
displayCardNamesCheckBox.setChecked(settings.cardsDisplay().getDisplayCardNames());
|
|
connect(&displayCardNamesCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.cardsDisplay(),
|
|
&CardsDisplaySettings::setDisplayCardNames);
|
|
|
|
autoRotateSidewaysLayoutCardsCheckBox.setChecked(settings.cardsDisplay().getAutoRotateSidewaysLayoutCards());
|
|
connect(&autoRotateSidewaysLayoutCardsCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.cardsDisplay(),
|
|
&CardsDisplaySettings::setAutoRotateSidewaysLayoutCards);
|
|
|
|
cardScalingCheckBox.setChecked(settings.cardsDisplay().getScaleCards());
|
|
connect(&cardScalingCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.cardsDisplay(),
|
|
&CardsDisplaySettings::setCardScaling);
|
|
|
|
roundCardCornersCheckBox.setChecked(settings.cardsDisplay().getRoundCardCorners());
|
|
connect(&roundCardCornersCheckBox, &QAbstractButton::toggled, &settings.cardsDisplay(),
|
|
&CardsDisplaySettings::setRoundCardCorners);
|
|
|
|
connect(&maxFontSizeForCardsEdit, qOverload<int>(&QSpinBox::valueChanged), &settings.appearance(),
|
|
&AppearanceSettings::setMaxFontSize);
|
|
maxFontSizeForCardsEdit.setValue(settings.appearance().getMaxFontSize());
|
|
maxFontSizeForCardsLabel.setBuddy(&maxFontSizeForCardsEdit);
|
|
maxFontSizeForCardsEdit.setMinimum(9);
|
|
maxFontSizeForCardsEdit.setMaximum(100);
|
|
|
|
auto *cardsGrid = new QGridLayout;
|
|
cardsGrid->addWidget(&displayCardNamesCheckBox, 0, 0, 1, 2);
|
|
cardsGrid->addWidget(&autoRotateSidewaysLayoutCardsCheckBox, 1, 0, 1, 2);
|
|
cardsGrid->addWidget(&cardScalingCheckBox, 2, 0, 1, 2);
|
|
cardsGrid->addWidget(&roundCardCornersCheckBox, 3, 0, 1, 2);
|
|
cardsGrid->addWidget(&maxFontSizeForCardsLabel, 4, 0, 1, 1);
|
|
cardsGrid->addWidget(&maxFontSizeForCardsEdit, 4, 1, 1, 1);
|
|
|
|
cardsGroupBox = new QGroupBox;
|
|
cardsGroupBox->setLayout(cardsGrid);
|
|
|
|
// Card layout
|
|
verticalCardOverlapPercentBox.setValue(settings.cardsDisplay().getStackCardOverlapPercent());
|
|
verticalCardOverlapPercentBox.setRange(0, 80);
|
|
connect(&verticalCardOverlapPercentBox, qOverload<int>(&QSpinBox::valueChanged), &settings.cardsDisplay(),
|
|
&CardsDisplaySettings::setStackCardOverlapPercent);
|
|
|
|
cardViewInitialRowsMaxBox.setRange(1, 999);
|
|
cardViewInitialRowsMaxBox.setValue(SettingsCache::instance().userInterface().getCardViewInitialRowsMax());
|
|
connect(&cardViewInitialRowsMaxBox, qOverload<int>(&QSpinBox::valueChanged), this,
|
|
&AppearanceSettingsPage::cardViewInitialRowsMaxChanged);
|
|
|
|
cardViewExpandedRowsMaxBox.setRange(1, 999);
|
|
cardViewExpandedRowsMaxBox.setValue(SettingsCache::instance().userInterface().getCardViewExpandedRowsMax());
|
|
connect(&cardViewExpandedRowsMaxBox, qOverload<int>(&QSpinBox::valueChanged), this,
|
|
&AppearanceSettingsPage::cardViewExpandedRowsMaxChanged);
|
|
|
|
auto *cardLayoutGrid = new QGridLayout;
|
|
cardLayoutGrid->addWidget(&verticalCardOverlapPercentLabel, 0, 0, 1, 1);
|
|
cardLayoutGrid->addWidget(&verticalCardOverlapPercentBox, 0, 1, 1, 1);
|
|
cardLayoutGrid->addWidget(&cardViewInitialRowsMaxLabel, 1, 0);
|
|
cardLayoutGrid->addWidget(&cardViewInitialRowsMaxBox, 1, 1);
|
|
cardLayoutGrid->addWidget(&cardViewExpandedRowsMaxLabel, 2, 0);
|
|
cardLayoutGrid->addWidget(&cardViewExpandedRowsMaxBox, 2, 1);
|
|
|
|
cardLayoutGroupBox = new QGroupBox;
|
|
cardLayoutGroupBox->setLayout(cardLayoutGrid);
|
|
|
|
// 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.userInterface().getHorizontalHand());
|
|
connect(&horizontalHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.userInterface(),
|
|
&InterfaceSettings::setHorizontalHand);
|
|
|
|
leftJustifiedHandCheckBox.setChecked(settings.userInterface().getLeftJustified());
|
|
connect(&leftJustifiedHandCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.userInterface(),
|
|
&InterfaceSettings::setLeftJustified);
|
|
|
|
auto *handGrid = new QGridLayout;
|
|
handGrid->addWidget(&horizontalHandCheckBox, 0, 0, 1, 2);
|
|
handGrid->addWidget(&leftJustifiedHandCheckBox, 1, 0, 1, 2);
|
|
|
|
handGroupBox = new QGroupBox;
|
|
handGroupBox->setLayout(handGrid);
|
|
|
|
// table grid layout
|
|
invertVerticalCoordinateCheckBox.setChecked(settings.userInterface().getInvertVerticalCoordinate());
|
|
connect(&invertVerticalCoordinateCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.userInterface(),
|
|
&InterfaceSettings::setInvertVerticalCoordinate);
|
|
|
|
minPlayersForMultiColumnLayoutEdit.setMinimum(2);
|
|
minPlayersForMultiColumnLayoutEdit.setValue(settings.userInterface().getMinPlayersForMultiColumnLayout());
|
|
connect(&minPlayersForMultiColumnLayoutEdit, qOverload<int>(&QSpinBox::valueChanged), &settings.userInterface(),
|
|
&InterfaceSettings::setMinPlayersForMultiColumnLayout);
|
|
minPlayersForMultiColumnLayoutLabel.setBuddy(&minPlayersForMultiColumnLayoutEdit);
|
|
|
|
auto *tableGrid = new QGridLayout;
|
|
tableGrid->addWidget(&invertVerticalCoordinateCheckBox, 0, 0, 1, 2);
|
|
tableGrid->addWidget(&minPlayersForMultiColumnLayoutLabel, 1, 0, 1, 1);
|
|
tableGrid->addWidget(&minPlayersForMultiColumnLayoutEdit, 1, 1, 1, 1);
|
|
|
|
tableGroupBox = new QGroupBox;
|
|
tableGroupBox->setLayout(tableGrid);
|
|
|
|
// putting it all together
|
|
auto *mainLayout = new QVBoxLayout;
|
|
mainLayout->addWidget(themeGroupBox);
|
|
mainLayout->addWidget(homeTabGroupBox);
|
|
mainLayout->addWidget(playmatGroupBox);
|
|
mainLayout->addWidget(stylingGroupBox);
|
|
mainLayout->addWidget(menuGroupBox);
|
|
mainLayout->addWidget(printingsGroupBox);
|
|
mainLayout->addWidget(cardsGroupBox);
|
|
mainLayout->addWidget(cardLayoutGroupBox);
|
|
mainLayout->addWidget(cardCountersGroupBox);
|
|
mainLayout->addWidget(handGroupBox);
|
|
mainLayout->addWidget(tableGroupBox);
|
|
mainLayout->addStretch();
|
|
|
|
setLayout(mainLayout);
|
|
|
|
connect(&SettingsCache::instance().personal(), &PersonalSettings::langChanged, this,
|
|
&AppearanceSettingsPage::retranslateUi);
|
|
retranslateUi();
|
|
}
|
|
|
|
void AppearanceSettingsPage::themeBoxChanged(int index)
|
|
{
|
|
QStringList themeDirs = themeManager->getAvailableThemes().keys();
|
|
if (index >= 0 && index < themeDirs.count()) {
|
|
SettingsCache::instance().setThemeName(themeDirs.at(index));
|
|
}
|
|
}
|
|
|
|
void AppearanceSettingsPage::openThemeLocation()
|
|
{
|
|
QString dir = SettingsCache::instance().paths().getThemesPath();
|
|
QDir dirDir = dir;
|
|
dirDir.cdUp();
|
|
// open if dir exists, create if parent dir does exist
|
|
if (dirDir.exists() && dirDir.mkpath(dir)) {
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
|
|
} else {
|
|
QMessageBox::critical(this, tr("Error"), tr("Could not create themes directory at '%1'.").arg(dir));
|
|
}
|
|
}
|
|
|
|
void AppearanceSettingsPage::editPalette()
|
|
{
|
|
PaletteEditorDialog dlg(themeManager->getCurrentThemePath(), SettingsCache::instance().getThemeName(), this);
|
|
dlg.exec();
|
|
}
|
|
|
|
void AppearanceSettingsPage::updateHomeTabSettingsVisibility()
|
|
{
|
|
QString sourceId = SettingsCache::instance().appearance().getHomeTabBackgroundSource();
|
|
bool visible = BackgroundSources::fromId(sourceId) != BackgroundSources::Theme;
|
|
|
|
homeTabBackgroundShuffleFrequencyLabel.setVisible(visible);
|
|
homeTabBackgroundShuffleFrequencySpinBox.setVisible(visible);
|
|
homeTabDisplayCardNameCheckBox.setVisible(visible);
|
|
}
|
|
|
|
void AppearanceSettingsPage::showShortcutsChanged(QT_STATE_CHANGED_T value)
|
|
{
|
|
SettingsCache::instance().userInterface().setShowShortcuts(value);
|
|
qApp->setAttribute(Qt::AA_DontShowShortcutsInContextMenus, value == 0); // 0 = unchecked
|
|
}
|
|
|
|
void AppearanceSettingsPage::overrideAllCardArtWithPersonalPreferenceToggled(QT_STATE_CHANGED_T value)
|
|
{
|
|
bool enable = static_cast<bool>(value);
|
|
|
|
bool accepted = OverridePrintingWarning::execMessageBox(this, enable);
|
|
|
|
if (!accepted) {
|
|
// If user cancels, revert the checkbox/state back
|
|
QTimer::singleShot(0, this, [this, enable]() {
|
|
overrideAllCardArtWithPersonalPreferenceCheckBox.blockSignals(true);
|
|
overrideAllCardArtWithPersonalPreferenceCheckBox.setChecked(!enable);
|
|
overrideAllCardArtWithPersonalPreferenceCheckBox.blockSignals(false);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the settings for cardViewInitialRowsMax.
|
|
* Forces expanded rows max to always be >= initial rows max
|
|
* @param value The new value
|
|
*/
|
|
void AppearanceSettingsPage::cardViewInitialRowsMaxChanged(int value)
|
|
{
|
|
SettingsCache::instance().userInterface().setCardViewInitialRowsMax(value);
|
|
if (cardViewExpandedRowsMaxBox.value() < value) {
|
|
cardViewExpandedRowsMaxBox.setValue(value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the settings for cardViewExpandedRowsMax.
|
|
* Forces initial rows max to always be <= expanded rows max
|
|
* @param value The new value
|
|
*/
|
|
void AppearanceSettingsPage::cardViewExpandedRowsMaxChanged(int value)
|
|
{
|
|
SettingsCache::instance().userInterface().setCardViewExpandedRowsMax(value);
|
|
if (cardViewInitialRowsMaxBox.value() > value) {
|
|
cardViewInitialRowsMaxBox.setValue(value);
|
|
}
|
|
}
|
|
|
|
void AppearanceSettingsPage::openPlaymatCollectionDialog()
|
|
{
|
|
PlaymatCollectionDialog dialog(this);
|
|
dialog.exec();
|
|
}
|
|
|
|
void AppearanceSettingsPage::retranslateUi()
|
|
{
|
|
themeGroupBox->setTitle(tr("Theme settings"));
|
|
themeLabel.setText(tr("Current theme:"));
|
|
openThemeButton.setText(tr("Open themes folder"));
|
|
schemeComboLabel.setText(tr("Active theme palette:"));
|
|
styleComboLabel.setText(tr("Active theme style:"));
|
|
styleCombo.setToolTip(tr("Qt widget style saved to this theme (\"Default\" lets the application decide)"));
|
|
editPaletteButton.setText(tr("Edit theme palette"));
|
|
|
|
homeTabGroupBox->setTitle(tr("Home tab settings"));
|
|
homeTabBackgroundSourceLabel.setText(tr("Home tab background source:"));
|
|
homeTabBackgroundShuffleFrequencyLabel.setText(tr("Home tab background shuffle frequency:"));
|
|
homeTabBackgroundShuffleFrequencySpinBox.setSpecialValueText(tr("Disabled"));
|
|
homeTabDisplayCardNameCheckBox.setText(tr("Display card name of background in bottom right"));
|
|
homeTabButtonColorSourceLabel.setText(tr("Home tab button color:"));
|
|
homeTabButtonColorSourceBox.setToolTip(
|
|
tr("Use the theme's identity accent colors, or extract colors from the background image"));
|
|
|
|
playmatGroupBox->setTitle(tr("Playmat settings"));
|
|
playmatVisibilityLabel.setText(tr("Playmat visibility:"));
|
|
playmatModeLabel.setText(tr("Default collection behavior:"));
|
|
playmatDefaultLabel.setText(tr("Default playmat collection:"));
|
|
playmatDefaultEditButton.setText(tr("Edit..."));
|
|
|
|
stylingGroupBox->setTitle(tr("Styling settings"));
|
|
styleUserListCheckBox.setText(tr("Style user list"));
|
|
|
|
menuGroupBox->setTitle(tr("Menu settings"));
|
|
showShortcutsCheckBox.setText(tr("Show keyboard shortcuts in right-click menus"));
|
|
showGameSelectorFilterToolbarCheckBox.setText(tr("Show game filter toolbar above list in room tab"));
|
|
|
|
printingsGroupBox->setTitle(tr("Card printings"));
|
|
overrideAllCardArtWithPersonalPreferenceCheckBox.setText(
|
|
tr("Override all card art with personal set preference (Pre-ProviderID change behavior)"));
|
|
bumpSetsWithCardsInDeckToTopCheckBox.setText(
|
|
tr("Bump sets that the deck contains cards from to the top in the printing selector"));
|
|
|
|
cardsGroupBox->setTitle(tr("Card rendering"));
|
|
displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture"));
|
|
autoRotateSidewaysLayoutCardsCheckBox.setText(tr("Auto-Rotate cards with sideways layout"));
|
|
cardScalingCheckBox.setText(tr("Scale cards on mouse over"));
|
|
roundCardCornersCheckBox.setText(tr("Use rounded card corners"));
|
|
maxFontSizeForCardsLabel.setText(tr("Maximum font size for information displayed on cards:"));
|
|
|
|
cardLayoutGroupBox->setTitle(tr("Card layout"));
|
|
verticalCardOverlapPercentLabel.setText(
|
|
tr("Minimum overlap percentage of cards on the stack and in vertical hand"));
|
|
cardViewInitialRowsMaxLabel.setText(tr("Maximum initial height for card view window:"));
|
|
cardViewInitialRowsMaxBox.setSuffix(tr(" rows"));
|
|
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"));
|
|
|
|
tableGroupBox->setTitle(tr("Table grid layout"));
|
|
invertVerticalCoordinateCheckBox.setText(tr("Invert vertical coordinate"));
|
|
minPlayersForMultiColumnLayoutLabel.setText(tr("Minimum player count for multi-column layout:"));
|
|
}
|