From 70b0bb4fc0648681328f0065e7b5295dee6215ea Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Wed, 17 Sep 2025 10:51:11 -0700 Subject: [PATCH] ConfigControl: Fix font styling bugs Fix two bugs with bold and italic labels when a non-Base config layer is active. First, when constructing a ConfigControl the label wouldn't be bolded until the next time a ConfigChanged signal was received. This would happen if the user started a game before opening a config window for the first time since starting Dolphin. Second, ConfigRadioInt would bold/italicize every radio button for that setting instead of just the selected radio button. Renames the IsConfigLocal function to ShouldLabelBeBold, since the former name was inaccurate if m_layer wasn't the local layer. --- .../Config/ConfigControls/ConfigControl.h | 27 +++++++++++++++---- .../Config/ConfigControls/ConfigRadio.cpp | 19 +++++++++++-- .../Config/ConfigControls/ConfigRadio.h | 3 +++ .../DolphinQt/Config/GameConfigWidget.cpp | 18 +++++++++++-- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/Source/Core/DolphinQt/Config/ConfigControls/ConfigControl.h b/Source/Core/DolphinQt/Config/ConfigControls/ConfigControl.h index fb37d3119f..814f02a853 100644 --- a/Source/Core/DolphinQt/Config/ConfigControls/ConfigControl.h +++ b/Source/Core/DolphinQt/Config/ConfigControls/ConfigControl.h @@ -17,6 +17,8 @@ class Info; struct Location; } // namespace Config +class QShowEvent; + template class ConfigControl : public Derived { @@ -44,9 +46,7 @@ protected: void ConnectConfig() { Derived::connect(&Settings::Instance(), &Settings::ConfigChanged, this, [this] { - QFont bf = Derived::font(); - bf.setBold(IsConfigLocal()); - Derived::setFont(bf); + UpdateBoldness(); // This isn't signal blocked because the UI may need to be updated. m_updating = true; @@ -92,8 +92,14 @@ protected: virtual void OnConfigChanged() {} -private: - bool IsConfigLocal() const + void UpdateBoldness() + { + QFont bf = Derived::font(); + bf.setBold(ShouldLabelBeBold()); + Derived::setFont(bf); + } + + virtual bool ShouldLabelBeBold() const { if (m_layer != nullptr) return m_layer->Exists(m_location); @@ -101,6 +107,17 @@ private: return Config::GetActiveLayerForConfig(m_location) != Config::LayerType::Base; } + void showEvent(QShowEvent* const event) override + { + // Call this here instead of in the constructor because virtual function calls are disabled in + // constructors, since base classes are constructed before derived classes and so the derived + // function would potentially use uninitialized data (as would be the case for + // ConfigRadioInt::UpdateBoldness). + UpdateBoldness(); + Derived::showEvent(event); + } + +private: void mousePressEvent(QMouseEvent* event) override { if (m_layer != nullptr && event->button() == Qt::RightButton) diff --git a/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.cpp b/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.cpp index eba9de283c..9e72b110cd 100644 --- a/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.cpp +++ b/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.cpp @@ -7,11 +7,16 @@ ConfigRadioInt::ConfigRadioInt(const QString& label, const Config::Info& se Config::Layer* layer) : ConfigControl(label, setting.GetLocation(), layer), m_setting(setting), m_value(value) { - setChecked(ReadValue(setting) == value); + setChecked(IsSelected()); connect(this, &QRadioButton::toggled, this, &ConfigRadioInt::Update); } +int ConfigRadioInt::GetValue() const +{ + return m_value; +} + void ConfigRadioInt::Update() { if (isChecked()) @@ -26,7 +31,17 @@ void ConfigRadioInt::Update() } } +bool ConfigRadioInt::IsSelected() const +{ + return ReadValue(m_setting) == m_value; +} + void ConfigRadioInt::OnConfigChanged() { - setChecked(ReadValue(m_setting) == m_value); + setChecked(IsSelected()); +} + +bool ConfigRadioInt::ShouldLabelBeBold() const +{ + return IsSelected() && ConfigControl::ShouldLabelBeBold(); } diff --git a/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.h b/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.h index b0dbd91416..7c9a150370 100644 --- a/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.h +++ b/Source/Core/DolphinQt/Config/ConfigControls/ConfigRadio.h @@ -14,6 +14,7 @@ class ConfigRadioInt final : public ConfigControl public: ConfigRadioInt(const QString& label, const Config::Info& setting, int value, Config::Layer* layer = nullptr); + int GetValue() const; signals: // Since selecting a new radio button deselects the old one, ::toggled will generate two signals. @@ -23,9 +24,11 @@ signals: protected: void OnConfigChanged() override; + bool ShouldLabelBeBold() const override; private: void Update(); + bool IsSelected() const; const Config::Info m_setting; int m_value; diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp index efaae69c62..cb9ca4120f 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp @@ -3,6 +3,8 @@ #include "DolphinQt/Config/GameConfigWidget.h" +#include + #include #include #include @@ -341,13 +343,25 @@ void GameConfigWidget::SetItalics() italics(config); for (auto* config : findChildren()) italics(config); - for (auto* config : findChildren()) - italics(config); for (auto* config : findChildren()) italics(config); for (auto* config : findChildren()) italics(config); + for (auto* const config : findChildren()) + { + const std::optional global_value_opt = m_global_layer->Get(config->GetLocation()); + if (!global_value_opt.has_value()) + continue; + + if (global_value_opt.value() != config->GetValue()) + continue; + + QFont italicized_font = config->font(); + italicized_font.setItalic(true); + config->setFont(italicized_font); + } + for (auto* config : findChildren()) { std::pair location = config->GetLocation();