diff --git a/Source/Core/DolphinQt/Config/ToolTipControls/BalloonTip.cpp b/Source/Core/DolphinQt/Config/ToolTipControls/BalloonTip.cpp index ccec65c374..435b60e462 100644 --- a/Source/Core/DolphinQt/Config/ToolTipControls/BalloonTip.cpp +++ b/Source/Core/DolphinQt/Config/ToolTipControls/BalloonTip.cpp @@ -133,7 +133,7 @@ void BalloonTip::UpdateBoundsAndRedraw(const QPoint& pos, ShowArrow show_arrow) const QRect screen_rect = screen->geometry(); QSize sh = sizeHint(); - // The look should resemble the default tooltip style set in Settings::SetCurrentUserStyle() + // The look should resemble the default tooltip style set in Settings::ApplyStyle() const int border = 1; const int arrow_height = 18; const int arrow_width = 18; diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 39aa5c6f1f..30922f1c63 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -247,7 +247,7 @@ int main(int argc, char* argv[]) Settings::Instance().InitDefaultPalette(); Settings::Instance().UpdateSystemDark(); - Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); + Settings::Instance().ApplyStyle(); MainWindow win{std::move(boot), static_cast(options.get("movie"))}; win.Show(); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 3e9596f72e..7df52cdebf 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -240,9 +240,7 @@ MainWindow::MainWindow(std::unique_ptr boot_parameters, #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, - [](Qt::ColorScheme colorScheme) { - Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); - }); + [](Qt::ColorScheme colorScheme) { Settings::Instance().ApplyStyle(); }); #endif connect(m_cheats_manager, &CheatsManager::OpenGeneralSettings, this, @@ -1739,7 +1737,7 @@ bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr settings.UpdateSystemDark(); if (settings.IsSystemDark() != was_dark_before) { - settings.SetCurrentUserStyle(settings.GetCurrentUserStyle()); + settings.ApplyStyle(); // force the colors in the Skylander window to update if (m_skylander_window) diff --git a/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp b/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp index 704e5a8f7f..6c595c0e2d 100644 --- a/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp +++ b/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp @@ -14,7 +14,7 @@ void SetQWidgetWindowDecorations(QWidget* widget) { #ifdef _WIN32 - if (!Settings::Instance().IsSystemDark()) + if (!Settings::Instance().IsThemeDark()) return; BOOL use_dark_title_bar = TRUE; diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index ebcf90ee8e..2e21835b6f 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -123,7 +123,7 @@ void Settings::SetThemeName(const QString& theme_name) emit ThemeChanged(); } -QString Settings::GetCurrentUserStyle() const +QString Settings::GetUserStyleName() const { if (GetQSettings().contains(QStringLiteral("userstyle/name"))) return GetQSettings().value(QStringLiteral("userstyle/name")).toString(); @@ -132,6 +132,11 @@ QString Settings::GetCurrentUserStyle() const return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName(); } +void Settings::SetUserStyleName(const QString& stylesheet_name) +{ + GetQSettings().setValue(QStringLiteral("userstyle/name"), stylesheet_name); +} + void Settings::InitDefaultPalette() { s_default_palette = std::make_unique(qApp->palette()); @@ -169,12 +174,14 @@ bool Settings::IsThemeDark() } // Calling this before the main window has been created breaks the style of some widgets. -void Settings::SetCurrentUserStyle(const QString& stylesheet_name) +void Settings::ApplyStyle() { + const StyleType style_type = GetStyleType(); + const QString stylesheet_name = GetUserStyleName(); QString stylesheet_contents; // If we haven't found one, we continue with an empty (default) style - if (!stylesheet_name.isEmpty() && AreUserStylesEnabled()) + if (!stylesheet_name.isEmpty() && style_type == StyleType::User) { // Load custom user stylesheet QDir directory = QDir(QString::fromStdString(File::GetUserPath(D_STYLES_IDX))); @@ -191,7 +198,7 @@ void Settings::SetCurrentUserStyle(const QString& stylesheet_name) // which would select Qt's default theme, but unlike other OSes we don't automatically get a // default dark theme on Windows when the user has selected dark mode in the Windows settings. // So manually check if the user wants dark mode and, if yes, load our embedded dark theme. - if (IsSystemDark()) + if (style_type == StyleType::Dark || (style_type != StyleType::Light && IsSystemDark())) { QFile file(QStringLiteral(":/dolphin_dark_win/dark.qss")); if (file.open(QFile::ReadOnly)) @@ -243,18 +250,32 @@ void Settings::SetCurrentUserStyle(const QString& stylesheet_name) } qApp->setStyleSheet(stylesheet_contents); - - GetQSettings().setValue(QStringLiteral("userstyle/name"), stylesheet_name); } -bool Settings::AreUserStylesEnabled() const +Settings::StyleType Settings::GetStyleType() const { - return GetQSettings().value(QStringLiteral("userstyle/enabled"), false).toBool(); + if (GetQSettings().contains(QStringLiteral("userstyle/styletype"))) + { + bool ok = false; + const int type_int = GetQSettings().value(QStringLiteral("userstyle/styletype")).toInt(&ok); + if (ok && type_int >= static_cast(StyleType::MinValue) && + type_int <= static_cast(StyleType::MaxValue)) + { + return static_cast(type_int); + } + } + + // if the style type is unset or invalid, try the old enabled flag instead + const bool enabled = GetQSettings().value(QStringLiteral("userstyle/enabled"), false).toBool(); + return enabled ? StyleType::User : StyleType::System; } -void Settings::SetUserStylesEnabled(bool enabled) +void Settings::SetStyleType(StyleType type) { - GetQSettings().setValue(QStringLiteral("userstyle/enabled"), enabled); + GetQSettings().setValue(QStringLiteral("userstyle/styletype"), static_cast(type)); + + // also set the old setting so that the config is correctly intepreted by older Dolphin builds + GetQSettings().setValue(QStringLiteral("userstyle/enabled"), type == StyleType::User); } void Settings::GetToolTipStyle(QColor& window_color, QColor& text_color, diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index 5583ed0628..fdc9f0a940 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -57,11 +57,26 @@ public: void SetSystemDark(bool dark); bool IsSystemDark(); bool IsThemeDark(); - void SetCurrentUserStyle(const QString& stylesheet_name); - QString GetCurrentUserStyle() const; - void SetUserStylesEnabled(bool enabled); - bool AreUserStylesEnabled() const; + void SetUserStyleName(const QString& stylesheet_name); + QString GetUserStyleName() const; + + enum class StyleType : int + { + System = 0, + Light = 1, + Dark = 2, + User = 3, + + MinValue = 0, + MaxValue = 3, + }; + + void SetStyleType(StyleType type); + StyleType GetStyleType() const; + + // this evaluates the current stylesheet settings and refreshes the GUI with them + void ApplyStyle(); void GetToolTipStyle(QColor& window_color, QColor& text_color, QColor& emphasis_text_color, QColor& border_color, const QPalette& palette, diff --git a/Source/Core/DolphinQt/Settings/InterfacePane.cpp b/Source/Core/DolphinQt/Settings/InterfacePane.cpp index ef0985bfd4..51e09c7fa7 100644 --- a/Source/Core/DolphinQt/Settings/InterfacePane.cpp +++ b/Source/Core/DolphinQt/Settings/InterfacePane.cpp @@ -128,12 +128,18 @@ void InterfacePane::CreateUI() // User Style Combobox m_combobox_userstyle = new QComboBox; - m_label_userstyle = new QLabel(tr("User Style:")); + m_label_userstyle = new QLabel(tr("Style:")); combobox_layout->addRow(m_label_userstyle, m_combobox_userstyle); auto userstyle_search_results = Common::DoFileSearch({File::GetUserPath(D_STYLES_IDX)}); - m_combobox_userstyle->addItem(tr("(None)"), QString{}); + m_combobox_userstyle->addItem(tr("(System)"), static_cast(Settings::StyleType::System)); + + // TODO: Support forcing light/dark on other OSes too. +#ifdef _WIN32 + m_combobox_userstyle->addItem(tr("(Light)"), static_cast(Settings::StyleType::Light)); + m_combobox_userstyle->addItem(tr("(Dark)"), static_cast(Settings::StyleType::Dark)); +#endif for (const std::string& path : userstyle_search_results) { @@ -143,7 +149,6 @@ void InterfacePane::CreateUI() // Checkboxes m_checkbox_use_builtin_title_database = new QCheckBox(tr("Use Built-In Database of Game Names")); - m_checkbox_use_userstyle = new QCheckBox(tr("Use Custom User Style")); m_checkbox_use_covers = new QCheckBox(tr("Download Game Covers from GameTDB.com for Use in Grid Mode")); m_checkbox_show_debugging_ui = new QCheckBox(tr("Enable Debugging UI")); @@ -151,7 +156,6 @@ void InterfacePane::CreateUI() m_checkbox_disable_screensaver = new QCheckBox(tr("Inhibit Screensaver During Emulation")); groupbox_layout->addWidget(m_checkbox_use_builtin_title_database); - groupbox_layout->addWidget(m_checkbox_use_userstyle); groupbox_layout->addWidget(m_checkbox_use_covers); groupbox_layout->addWidget(m_checkbox_show_debugging_ui); groupbox_layout->addWidget(m_checkbox_focused_hotkeys); @@ -238,7 +242,6 @@ void InterfacePane::ConnectLayout() &InterfacePane::OnCursorVisibleAlways); connect(m_checkbox_lock_mouse, &QCheckBox::toggled, &Settings::Instance(), &Settings::SetLockCursor); - connect(m_checkbox_use_userstyle, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig); } void InterfacePane::LoadConfig() @@ -254,19 +257,15 @@ void InterfacePane::LoadConfig() ->setCurrentIndex( m_combobox_theme->findText(QString::fromStdString(Config::Get(Config::MAIN_THEME_NAME)))); - const QString userstyle = Settings::Instance().GetCurrentUserStyle(); - const int index = m_combobox_userstyle->findData(QFileInfo(userstyle).fileName()); + const Settings::StyleType style_type = Settings::Instance().GetStyleType(); + const QString userstyle = Settings::Instance().GetUserStyleName(); + const int index = style_type == Settings::StyleType::User ? + m_combobox_userstyle->findData(userstyle) : + m_combobox_userstyle->findData(static_cast(style_type)); if (index > 0) SignalBlocking(m_combobox_userstyle)->setCurrentIndex(index); - SignalBlocking(m_checkbox_use_userstyle)->setChecked(Settings::Instance().AreUserStylesEnabled()); - - const bool visible = m_checkbox_use_userstyle->isChecked(); - - m_combobox_userstyle->setVisible(visible); - m_label_userstyle->setVisible(visible); - // Render Window Options SignalBlocking(m_checkbox_top_window) ->setChecked(Settings::Instance().IsKeepWindowOnTopEnabled()); @@ -297,13 +296,15 @@ void InterfacePane::OnSaveConfig() Config::SetBase(Config::MAIN_USE_BUILT_IN_TITLE_DATABASE, m_checkbox_use_builtin_title_database->isChecked()); Settings::Instance().SetDebugModeEnabled(m_checkbox_show_debugging_ui->isChecked()); - Settings::Instance().SetUserStylesEnabled(m_checkbox_use_userstyle->isChecked()); - Settings::Instance().SetCurrentUserStyle(m_combobox_userstyle->currentData().toString()); - - const bool visible = m_checkbox_use_userstyle->isChecked(); - - m_combobox_userstyle->setVisible(visible); - m_label_userstyle->setVisible(visible); + const auto selected_style = m_combobox_userstyle->currentData(); + bool is_builtin_type = false; + const int style_type_int = selected_style.toInt(&is_builtin_type); + Settings::Instance().SetStyleType(is_builtin_type ? + static_cast(style_type_int) : + Settings::StyleType::User); + if (!is_builtin_type) + Settings::Instance().SetUserStyleName(selected_style.toString()); + Settings::Instance().ApplyStyle(); // Render Window Options Settings::Instance().SetKeepWindowOnTop(m_checkbox_top_window->isChecked()); diff --git a/Source/Core/DolphinQt/Settings/InterfacePane.h b/Source/Core/DolphinQt/Settings/InterfacePane.h index d751c507c5..ffa09c3f72 100644 --- a/Source/Core/DolphinQt/Settings/InterfacePane.h +++ b/Source/Core/DolphinQt/Settings/InterfacePane.h @@ -36,7 +36,6 @@ private: QLabel* m_label_userstyle; QCheckBox* m_checkbox_top_window; QCheckBox* m_checkbox_use_builtin_title_database; - QCheckBox* m_checkbox_use_userstyle; QCheckBox* m_checkbox_show_debugging_ui; QCheckBox* m_checkbox_focused_hotkeys; QCheckBox* m_checkbox_use_covers;