From 39a1ffbb91a026fd3842f55ebca222db50afea41 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 8 May 2023 14:11:45 -0400 Subject: [PATCH] configuration: Use buttons instead of highlights Only for updated configs at the moment --- .../configuration/configuration_shared.cpp | 177 +++++++++++------- src/yuzu/configuration/configuration_shared.h | 14 +- src/yuzu/configuration/configure_general.cpp | 4 +- src/yuzu/configuration/configure_graphics.cpp | 71 +++++-- src/yuzu/configuration/configure_graphics.h | 1 + src/yuzu/configuration/configure_graphics.ui | 20 +- .../configure_graphics_advanced.cpp | 2 +- .../configure_graphics_advanced.ui | 15 +- src/yuzu/configuration/shared_translation.cpp | 3 + 9 files changed, 204 insertions(+), 103 deletions(-) diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 8d5ab8b4c7..45165c2e9b 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -2,119 +2,151 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include #include #include #include +#include #include +#include #include +#include #include +#include #include +#include #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_per_game.h" #include "yuzu/configuration/shared_translation.h" namespace ConfigurationShared { + +static QPushButton* CreateClearGlobalButton(QWidget* parent, Settings::BasicSetting* setting) { + QStyle* style = parent->style(); + QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); + QPushButton* button = new QPushButton(*icon, QStringLiteral(""), parent); + button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + + QSizePolicy sp_retain = button->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + button->setSizePolicy(sp_retain); + + button->setEnabled(!setting->UsingGlobal()); + button->setVisible(!setting->UsingGlobal()); + + return button; +} + static std::pair> CreateCheckBox(Settings::BasicSetting* setting, const QString& label, QWidget* parent, std::list& trackers) { + QWidget* widget = new QWidget(parent); + QHBoxLayout* layout = new QHBoxLayout(widget); + QCheckBox* checkbox = new QCheckBox(label, parent); checkbox->setObjectName(QString::fromStdString(setting->GetLabel())); checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - CheckState* tracker{}; + std::function load_func; - // Per-game config highlight - if (setting->Switchable() && !Settings::IsConfiguringGlobal()) { - bool global_state = setting->ToStringGlobal() == "true"; - bool state = setting->ToString() == "true"; - bool global = setting->UsingGlobal(); - tracker = &trackers.emplace_front(CheckState{}); - SetColoredTristate(checkbox, global, state, global_state, *tracker); + layout->addWidget(checkbox); + if (Settings::IsConfiguringGlobal()) { + load_func = [setting, checkbox]() { + setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); + }; + } else { + auto* button = CreateClearGlobalButton(parent, setting); + layout->addWidget(button); + + QObject::connect(checkbox, &QCheckBox::stateChanged, [button](int) { + button->setVisible(true); + button->setEnabled(true); + }); + + QObject::connect(button, &QAbstractButton::clicked, [checkbox, setting, button](bool) { + checkbox->setCheckState(setting->ToStringGlobal() == "true" ? Qt::Checked + : Qt::Unchecked); + button->setEnabled(false); + button->setVisible(false); + }); + + load_func = [setting, checkbox, button]() { + bool using_global = !button->isEnabled(); + setting->SetGlobal(using_global); + if (!using_global) { + setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); + } + }; } - auto load_func = [checkbox, setting, tracker]() { - if (Settings::IsConfiguringGlobal()) { - setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); - } + layout->setContentsMargins(0, 0, 0, 0); - if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { - return; - } - - if (*tracker != CheckState::Global) { - setting->SetGlobal(false); - setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); - } else { - setting->SetGlobal(true); - } - }; - - return {checkbox, load_func}; + return {widget, load_func}; } -static std::tuple> CreateCombobox( +static std::tuple> CreateCombobox( Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed) { const auto type = setting->TypeId(); QWidget* group = new QWidget(parent); group->setObjectName(QString::fromStdString(setting->GetLabel())); - QLayout* combobox_layout = new QHBoxLayout(group); + QLayout* layout = new QHBoxLayout(group); QLabel* qt_label = new QLabel(label, parent); QComboBox* combobox = new QComboBox(parent); + QPushButton* button{nullptr}; + std::forward_list combobox_enumerations = ComboboxEnumeration(type, parent); for (const auto& item : combobox_enumerations) { combobox->addItem(item); } - combobox_layout->addWidget(qt_label); - combobox_layout->addWidget(combobox); + layout->addWidget(qt_label); + layout->addWidget(combobox); - combobox_layout->setSpacing(6); - combobox_layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(6); + layout->setContentsMargins(0, 0, 0, 0); - if (setting->Switchable() && !Settings::IsConfiguringGlobal() && managed) { - int current = std::stoi(setting->ToString()); - int global_value = std::stoi(setting->ToStringGlobal()); - SetColoredComboBox(combobox, group, global_value); - if (setting->UsingGlobal()) { - combobox->setCurrentIndex(USE_GLOBAL_INDEX); - } else { - SetHighlight(group, true); - combobox->setCurrentIndex(current + USE_GLOBAL_OFFSET); - } - } else { - combobox->setCurrentIndex(std::stoi(setting->ToString())); - } + combobox->setCurrentIndex(std::stoi(setting->ToString())); std::function load_func = []() {}; - if (managed) { - load_func = [combobox, setting]() { - if (Settings::IsConfiguringGlobal()) { - setting->LoadString(std::to_string(combobox->currentIndex())); - } - if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { - return; - } + if (Settings::IsConfiguringGlobal() && managed) { + load_func = [setting, combobox]() { + setting->LoadString(std::to_string(combobox->currentIndex())); + }; + } else if (managed) { + button = CreateClearGlobalButton(parent, setting); + layout->addWidget(button); - bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX; - int index = combobox->currentIndex() - USE_GLOBAL_OFFSET; + QObject::connect(button, &QAbstractButton::clicked, [button, combobox, setting](bool) { + button->setEnabled(false); + button->setVisible(false); + combobox->setCurrentIndex(std::stoi(setting->ToStringGlobal())); + }); + + QObject::connect(combobox, QOverload::of(&QComboBox::activated), [=](int) { + button->setEnabled(true); + button->setVisible(true); + }); + + load_func = [setting, combobox, button]() { + bool using_global = !button->isEnabled(); setting->SetGlobal(using_global); if (!using_global) { - setting->LoadString(std::to_string(index)); + setting->LoadString(std::to_string(combobox->currentIndex())); } }; } - return {group, combobox, load_func}; + return {group, combobox, button, load_func}; } static std::tuple> CreateLineEdit( @@ -136,7 +168,7 @@ static std::tuple> CreateLineEdit( q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); layout->addWidget(q_label); - load_func = [&]() { + load_func = [line_edit, setting]() { std::string load_text = line_edit->text().toStdString(); setting->LoadString(load_text); }; @@ -157,7 +189,7 @@ static std::tuple> CreateLineEdit( checkbox->setCheckState(setting->UsingGlobal() ? Qt::Unchecked : Qt::Checked); highlight_func(checkbox->checkState()); - load_func = [&]() { + load_func = [checkbox, setting, line_edit]() { if (checkbox->checkState() == Qt::Checked) { setting->SetGlobal(false); @@ -176,12 +208,15 @@ static std::tuple> CreateLineEdit( return {widget, line_edit, load_func}; } -std::pair CreateWidget(Settings::BasicSetting* setting, - const TranslationMap& translations, QWidget* parent, - bool runtime_lock, - std::forward_list>& apply_funcs, - std::list& trackers, RequestType request, - bool managed) { +std::tuple CreateWidget( + Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, + bool runtime_lock, std::forward_list>& apply_funcs, + std::list& trackers, RequestType request, bool managed) { + if (!Settings::IsConfiguringGlobal() && !setting->Switchable()) { + LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting->GetLabel()); + return {nullptr, nullptr, nullptr}; + } + const auto type = setting->TypeId(); const int id = setting->Id(); QWidget* widget{nullptr}; @@ -201,9 +236,11 @@ std::pair CreateWidget(Settings::BasicSetting* setting, if (label == QStringLiteral("")) { LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...", setting->GetLabel()); - return {nullptr, nullptr}; + return {nullptr, nullptr, nullptr}; } + QPushButton* button; + if (type == typeid(bool)) { auto pair = CreateCheckBox(setting, label, parent, trackers); widget = pair.first; @@ -212,7 +249,8 @@ std::pair CreateWidget(Settings::BasicSetting* setting, auto tuple = CreateCombobox(setting, label, parent, managed); widget = std::get<0>(tuple); extra = std::get<1>(tuple); - load_func = std::get<2>(tuple); + button = std::get<2>(tuple); + load_func = std::get<3>(tuple); } else if (type == typeid(u32) || type == typeid(int)) { switch (request) { case RequestType::Default: { @@ -226,7 +264,8 @@ std::pair CreateWidget(Settings::BasicSetting* setting, auto tuple = CreateCombobox(setting, label, parent, managed); widget = std::get<0>(tuple); extra = std::get<1>(tuple); - load_func = std::get<2>(tuple); + button = std::get<2>(tuple); + load_func = std::get<3>(tuple); break; } case RequestType::SpinBox: @@ -238,7 +277,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, if (widget == nullptr) { LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel()); - return {nullptr, nullptr}; + return {nullptr, nullptr, nullptr}; } apply_funcs.push_front([load_func, setting](bool powered_on) { @@ -257,7 +296,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, widget->setToolTip(tooltip); - return {widget, extra}; + return {widget, extra, button}; } Tab::Tab(std::shared_ptr> group_, QWidget* parent) diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h index 942af02153..63df11d261 100644 --- a/src/yuzu/configuration/configuration_shared.h +++ b/src/yuzu/configuration/configuration_shared.h @@ -13,6 +13,8 @@ #include "common/settings.h" #include "yuzu/configuration/shared_translation.h" +class QPushButton; + namespace ConfigurationShared { class Tab : public QWidget { @@ -49,13 +51,11 @@ enum class RequestType { MaxEnum, }; -std::pair CreateWidget(Settings::BasicSetting* setting, - const TranslationMap& translations, QWidget* parent, - bool runtime_lock, - std::forward_list>& apply_funcs, - std::list& trackers, - RequestType request = RequestType::Default, - bool managed = true); +std::tuple CreateWidget( + Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, + bool runtime_lock, std::forward_list>& apply_funcs, + std::list& trackers, RequestType request = RequestType::Default, + bool managed = true); // Global-aware apply and set functions diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 03261992a2..8c6fee2a5e 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp @@ -139,8 +139,8 @@ void ConfigureGeneral::SetupPerGameUI() { ui->button_reset_defaults->setVisible(false); - ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit, - Settings::values.use_speed_limit, use_speed_limit); + // ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit, + // Settings::values.use_speed_limit, use_speed_limit); ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core, use_multi_core); diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 37a10ac873..1145b6c43e 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -20,8 +20,11 @@ #include #include #include +#include +#include #include #include +#include #include #include "common/common_types.h" @@ -112,7 +115,7 @@ ConfigureGraphics::ConfigureGraphics( } } - connect(api_combobox, qOverload(&QComboBox::currentIndexChanged), this, [this] { + connect(api_combobox, qOverload(&QComboBox::activated), this, [this] { UpdateAPILayout(); PopulateVSyncModeSelection(); }); @@ -146,6 +149,10 @@ ConfigureGraphics::ConfigureGraphics( } void ConfigureGraphics::PopulateVSyncModeSelection() { + if (!Settings::IsConfiguringGlobal()) { + return; + } + const Settings::RendererBackend backend{GetCurrentGraphicsBackend()}; if (backend == Settings::RendererBackend::Null) { vsync_mode_combobox->setEnabled(false); @@ -204,7 +211,12 @@ ConfigureGraphics::~ConfigureGraphics() = default; void ConfigureGraphics::SetConfiguration() { const bool runtime_lock = !system.IsPoweredOn(); - QLayout& api_layout = *ui->api_widget->layout(); + QLayout* api_layout = ui->api_widget->layout(); + QWidget* api_grid_widget = new QWidget(this); + QVBoxLayout* api_grid_layout = new QVBoxLayout(api_grid_widget); + api_grid_layout->setContentsMargins(0, 0, 0, 0); + api_layout->addWidget(api_grid_widget); + QLayout& graphics_layout = *ui->graphics_widget->layout(); std::map> hold_graphics; @@ -213,7 +225,7 @@ void ConfigureGraphics::SetConfiguration() { for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) { const auto& setting_label = setting->GetLabel(); - auto [widget, extra] = [&]() { + auto [widget, extra, button] = [&]() { if (setting->Id() == Settings::values.vulkan_device.Id() || setting->Id() == Settings::values.shader_backend.Id() || setting->Id() == Settings::values.vsync_mode.Id()) { @@ -230,8 +242,20 @@ void ConfigureGraphics::SetConfiguration() { continue; } - if (setting->Id() == Settings::values.vulkan_device.Id()) { - api_layout.addWidget(widget); + if (setting->Id() == Settings::values.renderer_backend.Id()) { + api_grid_layout->addWidget(widget); + api_combobox = reinterpret_cast(extra); + api_restore_global_button = button; + + if (!Settings::IsConfiguringGlobal()) { + QObject::connect(api_restore_global_button, &QAbstractButton::clicked, + [=](bool) { UpdateAPILayout(); }); + + widget->layout()->removeWidget(api_restore_global_button); + api_layout->addWidget(api_restore_global_button); + } + } else if (setting->Id() == Settings::values.vulkan_device.Id()) { + api_layout->addWidget(widget); api_combobox = reinterpret_cast(extra); } else if (setting->Id() == Settings::values.vulkan_device.Id()) { hold_api.push_front(widget); @@ -256,7 +280,7 @@ void ConfigureGraphics::SetConfiguration() { } for (auto widget : hold_api) { - api_layout.addWidget(widget); + api_grid_layout->addWidget(widget); } } @@ -297,6 +321,25 @@ void ConfigureGraphics::ApplyConfiguration() { const auto vsync_mode = PresentModeToSetting(mode); Settings::values.vsync_mode.SetValue(vsync_mode); } + + Settings::values.shader_backend.SetGlobal(true); + Settings::values.vulkan_device.SetGlobal(true); + if (!Settings::IsConfiguringGlobal() && api_restore_global_button->isEnabled()) { + auto backend = static_cast(api_combobox->currentIndex()); + switch (backend) { + case Settings::RendererBackend::OpenGL: + Settings::values.shader_backend.SetGlobal(false); + Settings::values.shader_backend.SetValue( + static_cast(shader_backend_combobox->currentIndex())); + break; + case Settings::RendererBackend::Vulkan: + Settings::values.vulkan_device.SetGlobal(false); + Settings::values.vulkan_device.SetValue(vulkan_device_combobox->currentIndex()); + break; + case Settings::RendererBackend::Null: + break; + } + } } void ConfigureGraphics::changeEvent(QEvent* event) { @@ -322,8 +365,7 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) { } void ConfigureGraphics::UpdateAPILayout() { - if (!Settings::IsConfiguringGlobal() && - api_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { + if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) { vulkan_device = Settings::values.vulkan_device.GetValue(true); shader_backend = Settings::values.shader_backend.GetValue(true); vulkan_device_widget->setEnabled(false); @@ -371,15 +413,8 @@ void ConfigureGraphics::RetrieveVulkanDevices() { } Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { - if (Settings::IsConfiguringGlobal()) { - return static_cast(api_combobox->currentIndex()); + if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) { + return Settings::values.renderer_backend.GetValue(true); } - - if (api_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { - Settings::values.renderer_backend.SetGlobal(true); - return Settings::values.renderer_backend.GetValue(); - } - Settings::values.renderer_backend.SetGlobal(false); - return static_cast(api_combobox->currentIndex() - - ConfigurationShared::USE_GLOBAL_OFFSET); + return static_cast(api_combobox->currentIndex()); } diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index c226e825be..12a588127b 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -85,6 +85,7 @@ private: const Core::System& system; const ConfigurationShared::TranslationMap& translations; + QPushButton* api_restore_global_button; QComboBox* vulkan_device_combobox; QComboBox* api_combobox; QComboBox* shader_backend_combobox; diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 565429c987..1f6ffea1a8 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui @@ -27,7 +27,7 @@ - + 0 @@ -40,9 +40,6 @@ 0 - - 6 - @@ -63,7 +60,20 @@ - + + + 0 + + + 0 + + + 0 + + + 0 + + diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 3a207e2cd7..8a53ad1111 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -32,7 +32,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { for (auto setting : Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) { - auto [widget, extra] = ConfigurationShared::CreateWidget( + auto [widget, extra, button] = ConfigurationShared::CreateWidget( setting, translations, this, runtime_lock, apply_funcs, trackers); if (widget == nullptr) { diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index 113fbc010d..37a854ca3f 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -27,7 +27,20 @@ - + + + 0 + + + 0 + + + 0 + + + 0 + + diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index 5a2071781c..a13636af62 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -93,6 +93,9 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { "Enable compute pipelines, required by some games.\nThis setting only exists for Intel " "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled " "on all other drivers."); + INSERT(use_reactive_flushing, "Enable Reactive Flushing", + "Uses reactive flushing instead of predictive flushing, allowing more accurate memory " + "syncing."); // Renderer (Debug)