diff --git a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp index 4c38459c6..be2d5735e 100644 --- a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -84,10 +85,9 @@ AppearanceSettingsPage::AppearanceSettingsPage() const QString currentStyle = cfg.styleName; const int styleSeedIdx = currentStyle.isEmpty() ? 0 : styleCombo.findData(currentStyle); styleCombo.setCurrentIndex(styleSeedIdx >= 0 ? styleSeedIdx : 0); + previousStyle = styleCombo.currentData().toString(); - connect(&styleCombo, &QComboBox::currentIndexChanged, this, - [this] { themeManager->setStyleName(styleCombo.currentData().toString()); }); - connect(&styleCombo, &QComboBox::currentIndexChanged, this, &AppearanceSettingsPage::updateStyleWarning); + connect(&styleCombo, &QComboBox::currentIndexChanged, this, &AppearanceSettingsPage::styleComboChanged); connect(themeManager, &ThemeManager::themeChanged, this, [this, dirPath] { const QString newDir = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName()); @@ -104,6 +104,7 @@ AppearanceSettingsPage::AppearanceSettingsPage() const int styleIdx = currentStyle.isEmpty() ? 0 : styleCombo.findData(currentStyle); styleCombo.setCurrentIndex(styleIdx >= 0 ? styleIdx : 0); styleCombo.blockSignals(false); + previousStyle = styleCombo.currentData().toString(); updateStyleWarning(); }); @@ -467,12 +468,88 @@ void AppearanceSettingsPage::updateHomeTabSettingsVisibility() homeTabDisplayCardNameCheckBox.setVisible(visible); } +static bool isBrokenStyle(const QString &style) +{ + return style.compare("windows11", Qt::CaseInsensitive) == 0 || + style.compare("windowsvista", Qt::CaseInsensitive) == 0; +} + +static int findFusionIndex(const QComboBox &combo) +{ + int fusionIdx = combo.findData(QStringLiteral("Fusion")); + if (fusionIdx >= 0) { + return fusionIdx; + } + for (int i = 0; i < combo.count(); ++i) { + if (combo.itemData(i).toString().compare(QStringLiteral("Fusion"), Qt::CaseInsensitive) == 0) { + return i; + } + } + return -1; +} + void AppearanceSettingsPage::updateStyleWarning() { - const QString style = styleCombo.currentData().toString(); - const bool broken = - style.compare("windows11", Qt::CaseInsensitive) == 0 || style.compare("windowsvista", Qt::CaseInsensitive) == 0; - styleWarningLabel.setVisible(broken); + styleWarningLabel.setVisible(isBrokenStyle(styleCombo.currentData().toString())); +} + +void AppearanceSettingsPage::styleComboChanged(int index) +{ + if (index < 0) { + return; + } + + const QString newStyle = styleCombo.itemData(index).toString(); + if (!isBrokenStyle(newStyle)) { + themeManager->setStyleName(newStyle); + previousStyle = newStyle; + updateStyleWarning(); + return; + } + + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Broken style")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setText(tr("The \"%1\" style is broken and can break the game view: dragging cards across zones can " + "shrink the board to a tiny grey window that can only be fixed by rejoining the game.") + .arg(newStyle)); + msgBox.setInformativeText( + tr("It can also render controls such as combo boxes unreadable, especially in dark mode.\n\n" + "Fusion is the recommended style on every platform. Switch to Fusion instead?")); + + int fusionIdx = findFusionIndex(styleCombo); + QPushButton *fusionButton = nullptr; + if (fusionIdx >= 0) { + fusionButton = msgBox.addButton(tr("Use Fusion instead"), QMessageBox::AcceptRole); + } + QPushButton *keepButton = msgBox.addButton(tr("Use %1 anyway").arg(newStyle), QMessageBox::DestructiveRole); + msgBox.addButton(QMessageBox::Cancel); + if (fusionButton != nullptr) { + msgBox.setDefaultButton(fusionButton); + } else { + msgBox.setDefaultButton(keepButton); + } + + msgBox.exec(); + + const QAbstractButton *clicked = msgBox.clickedButton(); + if (fusionButton != nullptr && clicked == fusionButton) { + styleCombo.setCurrentIndex(fusionIdx); + return; + } + if (clicked == keepButton) { + themeManager->setStyleName(newStyle); + previousStyle = newStyle; + updateStyleWarning(); + return; + } + + // Cancel: revert to the previously applied style without re-prompting + styleCombo.blockSignals(true); + const int previousIdx = styleCombo.findData(previousStyle); + styleCombo.setCurrentIndex(previousIdx >= 0 ? previousIdx : 0); + styleCombo.blockSignals(false); + updateStyleWarning(); } void AppearanceSettingsPage::showShortcutsChanged(QT_STATE_CHANGED_T value) @@ -538,9 +615,10 @@ void AppearanceSettingsPage::retranslateUi() styleComboLabel.setText(tr("Active theme style:")); styleCombo.setToolTip(tr("Qt widget style saved to this theme (\"System\" lets the application decide)")); styleWarningLabel.setText( - tr("Warning: the Windows 11 and Windows Vista styles are buggy and can render controls such as combo boxes " - "unreadable, especially in dark mode. Fusion is the recommended style on every platform: it is Qt's " - "cross-platform style and the one Cockatrice is developed against.")); + tr("Warning: the Windows 11 and Windows Vista styles are broken and can break the game view (dragging " + "cards can shrink the board to a tiny grey window that requires rejoining to fix), and can render " + "controls such as combo boxes unreadable, especially in dark mode. Fusion is the recommended style on " + "every platform: it is Qt's cross-platform style and the one Cockatrice is developed against.")); updateStyleWarning(); editPaletteButton.setText(tr("Edit theme palette")); diff --git a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h index 8afd326a3..f919a2a2f 100644 --- a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h @@ -23,6 +23,7 @@ private slots: void editPalette(); void updateHomeTabSettingsVisibility(); void updateStyleWarning(); + void styleComboChanged(int index); void showShortcutsChanged(QT_STATE_CHANGED_T enabled); void overrideAllCardArtWithPersonalPreferenceToggled(QT_STATE_CHANGED_T enabled); @@ -40,6 +41,7 @@ private: QComboBox styleCombo; QLabel styleWarningLabel; QPushButton editPaletteButton; + QString previousStyle; QLabel homeTabBackgroundSourceLabel; QComboBox homeTabBackgroundSourceBox;