summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar lat9nq2023-05-08 14:11:45 -0400
committerGravatar lat9nq2023-07-21 10:56:07 -0400
commit39a1ffbb91a026fd3842f55ebca222db50afea41 (patch)
tree98b15c5936b3a909edddb5b956d4e7dd680e7f49 /src
parentshared_translations: Re flow strings (diff)
downloadyuzu-39a1ffbb91a026fd3842f55ebca222db50afea41.tar.gz
yuzu-39a1ffbb91a026fd3842f55ebca222db50afea41.tar.xz
yuzu-39a1ffbb91a026fd3842f55ebca222db50afea41.zip
configuration: Use buttons instead of highlights
Only for updated configs at the moment
Diffstat (limited to 'src')
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp177
-rw-r--r--src/yuzu/configuration/configuration_shared.h14
-rw-r--r--src/yuzu/configuration/configure_general.cpp4
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp71
-rw-r--r--src/yuzu/configuration/configure_graphics.h1
-rw-r--r--src/yuzu/configuration/configure_graphics.ui20
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui15
-rw-r--r--src/yuzu/configuration/shared_translation.cpp3
9 files changed, 204 insertions, 103 deletions
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index 8d5ab8b4c..45165c2e9 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -2,119 +2,151 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <memory> 4#include <memory>
5#include <QBoxLayout>
5#include <QCheckBox> 6#include <QCheckBox>
6#include <QHBoxLayout> 7#include <QHBoxLayout>
7#include <QLabel> 8#include <QLabel>
8#include <QLineEdit> 9#include <QLineEdit>
9#include <QObject> 10#include <QObject>
11#include <QPushButton>
10#include <QString> 12#include <QString>
13#include <QStyle>
11#include <QWidget> 14#include <QWidget>
15#include <qabstractbutton.h>
12#include <qcheckbox.h> 16#include <qcheckbox.h>
17#include <qcombobox.h>
13#include <qnamespace.h> 18#include <qnamespace.h>
19#include <qsizepolicy.h>
14#include "common/settings.h" 20#include "common/settings.h"
15#include "yuzu/configuration/configuration_shared.h" 21#include "yuzu/configuration/configuration_shared.h"
16#include "yuzu/configuration/configure_per_game.h" 22#include "yuzu/configuration/configure_per_game.h"
17#include "yuzu/configuration/shared_translation.h" 23#include "yuzu/configuration/shared_translation.h"
18 24
19namespace ConfigurationShared { 25namespace ConfigurationShared {
26
27static QPushButton* CreateClearGlobalButton(QWidget* parent, Settings::BasicSetting* setting) {
28 QStyle* style = parent->style();
29 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton));
30 QPushButton* button = new QPushButton(*icon, QStringLiteral(""), parent);
31 button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
32
33 QSizePolicy sp_retain = button->sizePolicy();
34 sp_retain.setRetainSizeWhenHidden(true);
35 button->setSizePolicy(sp_retain);
36
37 button->setEnabled(!setting->UsingGlobal());
38 button->setVisible(!setting->UsingGlobal());
39
40 return button;
41}
42
20static std::pair<QWidget*, std::function<void()>> CreateCheckBox(Settings::BasicSetting* setting, 43static std::pair<QWidget*, std::function<void()>> CreateCheckBox(Settings::BasicSetting* setting,
21 const QString& label, 44 const QString& label,
22 QWidget* parent, 45 QWidget* parent,
23 std::list<CheckState>& trackers) { 46 std::list<CheckState>& trackers) {
47 QWidget* widget = new QWidget(parent);
48 QHBoxLayout* layout = new QHBoxLayout(widget);
49
24 QCheckBox* checkbox = new QCheckBox(label, parent); 50 QCheckBox* checkbox = new QCheckBox(label, parent);
25 checkbox->setObjectName(QString::fromStdString(setting->GetLabel())); 51 checkbox->setObjectName(QString::fromStdString(setting->GetLabel()));
26 checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked 52 checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked
27 : Qt::CheckState::Unchecked); 53 : Qt::CheckState::Unchecked);
28 54
29 CheckState* tracker{}; 55 std::function<void()> load_func;
30
31 // Per-game config highlight
32 if (setting->Switchable() && !Settings::IsConfiguringGlobal()) {
33 bool global_state = setting->ToStringGlobal() == "true";
34 bool state = setting->ToString() == "true";
35 bool global = setting->UsingGlobal();
36 tracker = &trackers.emplace_front(CheckState{});
37 SetColoredTristate(checkbox, global, state, global_state, *tracker);
38 }
39 56
40 auto load_func = [checkbox, setting, tracker]() { 57 layout->addWidget(checkbox);
41 if (Settings::IsConfiguringGlobal()) { 58 if (Settings::IsConfiguringGlobal()) {
59 load_func = [setting, checkbox]() {
42 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); 60 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
43 } 61 };
44 62 } else {
45 if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { 63 auto* button = CreateClearGlobalButton(parent, setting);
46 return; 64 layout->addWidget(button);
47 } 65
66 QObject::connect(checkbox, &QCheckBox::stateChanged, [button](int) {
67 button->setVisible(true);
68 button->setEnabled(true);
69 });
70
71 QObject::connect(button, &QAbstractButton::clicked, [checkbox, setting, button](bool) {
72 checkbox->setCheckState(setting->ToStringGlobal() == "true" ? Qt::Checked
73 : Qt::Unchecked);
74 button->setEnabled(false);
75 button->setVisible(false);
76 });
77
78 load_func = [setting, checkbox, button]() {
79 bool using_global = !button->isEnabled();
80 setting->SetGlobal(using_global);
81 if (!using_global) {
82 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
83 }
84 };
85 }
48 86
49 if (*tracker != CheckState::Global) { 87 layout->setContentsMargins(0, 0, 0, 0);
50 setting->SetGlobal(false);
51 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
52 } else {
53 setting->SetGlobal(true);
54 }
55 };
56 88
57 return {checkbox, load_func}; 89 return {widget, load_func};
58} 90}
59 91
60static std::tuple<QWidget*, void*, std::function<void()>> CreateCombobox( 92static std::tuple<QWidget*, QComboBox*, QPushButton*, std::function<void()>> CreateCombobox(
61 Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed) { 93 Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed) {
62 const auto type = setting->TypeId(); 94 const auto type = setting->TypeId();
63 95
64 QWidget* group = new QWidget(parent); 96 QWidget* group = new QWidget(parent);
65 group->setObjectName(QString::fromStdString(setting->GetLabel())); 97 group->setObjectName(QString::fromStdString(setting->GetLabel()));
66 QLayout* combobox_layout = new QHBoxLayout(group); 98 QLayout* layout = new QHBoxLayout(group);
67 99
68 QLabel* qt_label = new QLabel(label, parent); 100 QLabel* qt_label = new QLabel(label, parent);
69 QComboBox* combobox = new QComboBox(parent); 101 QComboBox* combobox = new QComboBox(parent);
70 102
103 QPushButton* button{nullptr};
104
71 std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, parent); 105 std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, parent);
72 for (const auto& item : combobox_enumerations) { 106 for (const auto& item : combobox_enumerations) {
73 combobox->addItem(item); 107 combobox->addItem(item);
74 } 108 }
75 109
76 combobox_layout->addWidget(qt_label); 110 layout->addWidget(qt_label);
77 combobox_layout->addWidget(combobox); 111 layout->addWidget(combobox);
78 112
79 combobox_layout->setSpacing(6); 113 layout->setSpacing(6);
80 combobox_layout->setContentsMargins(0, 0, 0, 0); 114 layout->setContentsMargins(0, 0, 0, 0);
81 115
82 if (setting->Switchable() && !Settings::IsConfiguringGlobal() && managed) { 116 combobox->setCurrentIndex(std::stoi(setting->ToString()));
83 int current = std::stoi(setting->ToString());
84 int global_value = std::stoi(setting->ToStringGlobal());
85 SetColoredComboBox(combobox, group, global_value);
86 if (setting->UsingGlobal()) {
87 combobox->setCurrentIndex(USE_GLOBAL_INDEX);
88 } else {
89 SetHighlight(group, true);
90 combobox->setCurrentIndex(current + USE_GLOBAL_OFFSET);
91 }
92 } else {
93 combobox->setCurrentIndex(std::stoi(setting->ToString()));
94 }
95 117
96 std::function<void()> load_func = []() {}; 118 std::function<void()> load_func = []() {};
97 if (managed) {
98 load_func = [combobox, setting]() {
99 if (Settings::IsConfiguringGlobal()) {
100 setting->LoadString(std::to_string(combobox->currentIndex()));
101 }
102 119
103 if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { 120 if (Settings::IsConfiguringGlobal() && managed) {
104 return; 121 load_func = [setting, combobox]() {
105 } 122 setting->LoadString(std::to_string(combobox->currentIndex()));
123 };
124 } else if (managed) {
125 button = CreateClearGlobalButton(parent, setting);
126 layout->addWidget(button);
127
128 QObject::connect(button, &QAbstractButton::clicked, [button, combobox, setting](bool) {
129 button->setEnabled(false);
130 button->setVisible(false);
131
132 combobox->setCurrentIndex(std::stoi(setting->ToStringGlobal()));
133 });
106 134
107 bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX; 135 QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated), [=](int) {
108 int index = combobox->currentIndex() - USE_GLOBAL_OFFSET; 136 button->setEnabled(true);
137 button->setVisible(true);
138 });
109 139
140 load_func = [setting, combobox, button]() {
141 bool using_global = !button->isEnabled();
110 setting->SetGlobal(using_global); 142 setting->SetGlobal(using_global);
111 if (!using_global) { 143 if (!using_global) {
112 setting->LoadString(std::to_string(index)); 144 setting->LoadString(std::to_string(combobox->currentIndex()));
113 } 145 }
114 }; 146 };
115 } 147 }
116 148
117 return {group, combobox, load_func}; 149 return {group, combobox, button, load_func};
118} 150}
119 151
120static std::tuple<QWidget*, void*, std::function<void()>> CreateLineEdit( 152static std::tuple<QWidget*, void*, std::function<void()>> CreateLineEdit(
@@ -136,7 +168,7 @@ static std::tuple<QWidget*, void*, std::function<void()>> CreateLineEdit(
136 q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 168 q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
137 layout->addWidget(q_label); 169 layout->addWidget(q_label);
138 170
139 load_func = [&]() { 171 load_func = [line_edit, setting]() {
140 std::string load_text = line_edit->text().toStdString(); 172 std::string load_text = line_edit->text().toStdString();
141 setting->LoadString(load_text); 173 setting->LoadString(load_text);
142 }; 174 };
@@ -157,7 +189,7 @@ static std::tuple<QWidget*, void*, std::function<void()>> CreateLineEdit(
157 checkbox->setCheckState(setting->UsingGlobal() ? Qt::Unchecked : Qt::Checked); 189 checkbox->setCheckState(setting->UsingGlobal() ? Qt::Unchecked : Qt::Checked);
158 highlight_func(checkbox->checkState()); 190 highlight_func(checkbox->checkState());
159 191
160 load_func = [&]() { 192 load_func = [checkbox, setting, line_edit]() {
161 if (checkbox->checkState() == Qt::Checked) { 193 if (checkbox->checkState() == Qt::Checked) {
162 setting->SetGlobal(false); 194 setting->SetGlobal(false);
163 195
@@ -176,12 +208,15 @@ static std::tuple<QWidget*, void*, std::function<void()>> CreateLineEdit(
176 return {widget, line_edit, load_func}; 208 return {widget, line_edit, load_func};
177} 209}
178 210
179std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting, 211std::tuple<QWidget*, void*, QPushButton*> CreateWidget(
180 const TranslationMap& translations, QWidget* parent, 212 Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
181 bool runtime_lock, 213 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
182 std::forward_list<std::function<void(bool)>>& apply_funcs, 214 std::list<CheckState>& trackers, RequestType request, bool managed) {
183 std::list<CheckState>& trackers, RequestType request, 215 if (!Settings::IsConfiguringGlobal() && !setting->Switchable()) {
184 bool managed) { 216 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting->GetLabel());
217 return {nullptr, nullptr, nullptr};
218 }
219
185 const auto type = setting->TypeId(); 220 const auto type = setting->TypeId();
186 const int id = setting->Id(); 221 const int id = setting->Id();
187 QWidget* widget{nullptr}; 222 QWidget* widget{nullptr};
@@ -201,9 +236,11 @@ std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting,
201 if (label == QStringLiteral("")) { 236 if (label == QStringLiteral("")) {
202 LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...", 237 LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...",
203 setting->GetLabel()); 238 setting->GetLabel());
204 return {nullptr, nullptr}; 239 return {nullptr, nullptr, nullptr};
205 } 240 }
206 241
242 QPushButton* button;
243
207 if (type == typeid(bool)) { 244 if (type == typeid(bool)) {
208 auto pair = CreateCheckBox(setting, label, parent, trackers); 245 auto pair = CreateCheckBox(setting, label, parent, trackers);
209 widget = pair.first; 246 widget = pair.first;
@@ -212,7 +249,8 @@ std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting,
212 auto tuple = CreateCombobox(setting, label, parent, managed); 249 auto tuple = CreateCombobox(setting, label, parent, managed);
213 widget = std::get<0>(tuple); 250 widget = std::get<0>(tuple);
214 extra = std::get<1>(tuple); 251 extra = std::get<1>(tuple);
215 load_func = std::get<2>(tuple); 252 button = std::get<2>(tuple);
253 load_func = std::get<3>(tuple);
216 } else if (type == typeid(u32) || type == typeid(int)) { 254 } else if (type == typeid(u32) || type == typeid(int)) {
217 switch (request) { 255 switch (request) {
218 case RequestType::Default: { 256 case RequestType::Default: {
@@ -226,7 +264,8 @@ std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting,
226 auto tuple = CreateCombobox(setting, label, parent, managed); 264 auto tuple = CreateCombobox(setting, label, parent, managed);
227 widget = std::get<0>(tuple); 265 widget = std::get<0>(tuple);
228 extra = std::get<1>(tuple); 266 extra = std::get<1>(tuple);
229 load_func = std::get<2>(tuple); 267 button = std::get<2>(tuple);
268 load_func = std::get<3>(tuple);
230 break; 269 break;
231 } 270 }
232 case RequestType::SpinBox: 271 case RequestType::SpinBox:
@@ -238,7 +277,7 @@ std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting,
238 277
239 if (widget == nullptr) { 278 if (widget == nullptr) {
240 LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel()); 279 LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel());
241 return {nullptr, nullptr}; 280 return {nullptr, nullptr, nullptr};
242 } 281 }
243 282
244 apply_funcs.push_front([load_func, setting](bool powered_on) { 283 apply_funcs.push_front([load_func, setting](bool powered_on) {
@@ -257,7 +296,7 @@ std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting,
257 296
258 widget->setToolTip(tooltip); 297 widget->setToolTip(tooltip);
259 298
260 return {widget, extra}; 299 return {widget, extra, button};
261} 300}
262 301
263Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent) 302Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent)
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index 942af0215..63df11d26 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -13,6 +13,8 @@
13#include "common/settings.h" 13#include "common/settings.h"
14#include "yuzu/configuration/shared_translation.h" 14#include "yuzu/configuration/shared_translation.h"
15 15
16class QPushButton;
17
16namespace ConfigurationShared { 18namespace ConfigurationShared {
17 19
18class Tab : public QWidget { 20class Tab : public QWidget {
@@ -49,13 +51,11 @@ enum class RequestType {
49 MaxEnum, 51 MaxEnum,
50}; 52};
51 53
52std::pair<QWidget*, void*> CreateWidget(Settings::BasicSetting* setting, 54std::tuple<QWidget*, void*, QPushButton*> CreateWidget(
53 const TranslationMap& translations, QWidget* parent, 55 Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
54 bool runtime_lock, 56 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
55 std::forward_list<std::function<void(bool)>>& apply_funcs, 57 std::list<CheckState>& trackers, RequestType request = RequestType::Default,
56 std::list<CheckState>& trackers, 58 bool managed = true);
57 RequestType request = RequestType::Default,
58 bool managed = true);
59 59
60// Global-aware apply and set functions 60// Global-aware apply and set functions
61 61
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 03261992a..8c6fee2a5 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -139,8 +139,8 @@ void ConfigureGeneral::SetupPerGameUI() {
139 139
140 ui->button_reset_defaults->setVisible(false); 140 ui->button_reset_defaults->setVisible(false);
141 141
142 ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit, 142 // ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit,
143 Settings::values.use_speed_limit, use_speed_limit); 143 // Settings::values.use_speed_limit, use_speed_limit);
144 ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core, 144 ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
145 use_multi_core); 145 use_multi_core);
146 146
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 37a10ac87..1145b6c43 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -20,8 +20,11 @@
20#include <QSlider> 20#include <QSlider>
21#include <QStringLiteral> 21#include <QStringLiteral>
22#include <QtCore/qobjectdefs.h> 22#include <QtCore/qobjectdefs.h>
23#include <qabstractbutton.h>
24#include <qboxlayout.h>
23#include <qcoreevent.h> 25#include <qcoreevent.h>
24#include <qglobal.h> 26#include <qglobal.h>
27#include <qgridlayout.h>
25#include <vulkan/vulkan_core.h> 28#include <vulkan/vulkan_core.h>
26 29
27#include "common/common_types.h" 30#include "common/common_types.h"
@@ -112,7 +115,7 @@ ConfigureGraphics::ConfigureGraphics(
112 } 115 }
113 } 116 }
114 117
115 connect(api_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] { 118 connect(api_combobox, qOverload<int>(&QComboBox::activated), this, [this] {
116 UpdateAPILayout(); 119 UpdateAPILayout();
117 PopulateVSyncModeSelection(); 120 PopulateVSyncModeSelection();
118 }); 121 });
@@ -146,6 +149,10 @@ ConfigureGraphics::ConfigureGraphics(
146} 149}
147 150
148void ConfigureGraphics::PopulateVSyncModeSelection() { 151void ConfigureGraphics::PopulateVSyncModeSelection() {
152 if (!Settings::IsConfiguringGlobal()) {
153 return;
154 }
155
149 const Settings::RendererBackend backend{GetCurrentGraphicsBackend()}; 156 const Settings::RendererBackend backend{GetCurrentGraphicsBackend()};
150 if (backend == Settings::RendererBackend::Null) { 157 if (backend == Settings::RendererBackend::Null) {
151 vsync_mode_combobox->setEnabled(false); 158 vsync_mode_combobox->setEnabled(false);
@@ -204,7 +211,12 @@ ConfigureGraphics::~ConfigureGraphics() = default;
204 211
205void ConfigureGraphics::SetConfiguration() { 212void ConfigureGraphics::SetConfiguration() {
206 const bool runtime_lock = !system.IsPoweredOn(); 213 const bool runtime_lock = !system.IsPoweredOn();
207 QLayout& api_layout = *ui->api_widget->layout(); 214 QLayout* api_layout = ui->api_widget->layout();
215 QWidget* api_grid_widget = new QWidget(this);
216 QVBoxLayout* api_grid_layout = new QVBoxLayout(api_grid_widget);
217 api_grid_layout->setContentsMargins(0, 0, 0, 0);
218 api_layout->addWidget(api_grid_widget);
219
208 QLayout& graphics_layout = *ui->graphics_widget->layout(); 220 QLayout& graphics_layout = *ui->graphics_widget->layout();
209 221
210 std::map<bool, std::map<std::string, QWidget*>> hold_graphics; 222 std::map<bool, std::map<std::string, QWidget*>> hold_graphics;
@@ -213,7 +225,7 @@ void ConfigureGraphics::SetConfiguration() {
213 for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) { 225 for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
214 const auto& setting_label = setting->GetLabel(); 226 const auto& setting_label = setting->GetLabel();
215 227
216 auto [widget, extra] = [&]() { 228 auto [widget, extra, button] = [&]() {
217 if (setting->Id() == Settings::values.vulkan_device.Id() || 229 if (setting->Id() == Settings::values.vulkan_device.Id() ||
218 setting->Id() == Settings::values.shader_backend.Id() || 230 setting->Id() == Settings::values.shader_backend.Id() ||
219 setting->Id() == Settings::values.vsync_mode.Id()) { 231 setting->Id() == Settings::values.vsync_mode.Id()) {
@@ -230,8 +242,20 @@ void ConfigureGraphics::SetConfiguration() {
230 continue; 242 continue;
231 } 243 }
232 244
233 if (setting->Id() == Settings::values.vulkan_device.Id()) { 245 if (setting->Id() == Settings::values.renderer_backend.Id()) {
234 api_layout.addWidget(widget); 246 api_grid_layout->addWidget(widget);
247 api_combobox = reinterpret_cast<QComboBox*>(extra);
248 api_restore_global_button = button;
249
250 if (!Settings::IsConfiguringGlobal()) {
251 QObject::connect(api_restore_global_button, &QAbstractButton::clicked,
252 [=](bool) { UpdateAPILayout(); });
253
254 widget->layout()->removeWidget(api_restore_global_button);
255 api_layout->addWidget(api_restore_global_button);
256 }
257 } else if (setting->Id() == Settings::values.vulkan_device.Id()) {
258 api_layout->addWidget(widget);
235 api_combobox = reinterpret_cast<QComboBox*>(extra); 259 api_combobox = reinterpret_cast<QComboBox*>(extra);
236 } else if (setting->Id() == Settings::values.vulkan_device.Id()) { 260 } else if (setting->Id() == Settings::values.vulkan_device.Id()) {
237 hold_api.push_front(widget); 261 hold_api.push_front(widget);
@@ -256,7 +280,7 @@ void ConfigureGraphics::SetConfiguration() {
256 } 280 }
257 281
258 for (auto widget : hold_api) { 282 for (auto widget : hold_api) {
259 api_layout.addWidget(widget); 283 api_grid_layout->addWidget(widget);
260 } 284 }
261} 285}
262 286
@@ -297,6 +321,25 @@ void ConfigureGraphics::ApplyConfiguration() {
297 const auto vsync_mode = PresentModeToSetting(mode); 321 const auto vsync_mode = PresentModeToSetting(mode);
298 Settings::values.vsync_mode.SetValue(vsync_mode); 322 Settings::values.vsync_mode.SetValue(vsync_mode);
299 } 323 }
324
325 Settings::values.shader_backend.SetGlobal(true);
326 Settings::values.vulkan_device.SetGlobal(true);
327 if (!Settings::IsConfiguringGlobal() && api_restore_global_button->isEnabled()) {
328 auto backend = static_cast<Settings::RendererBackend>(api_combobox->currentIndex());
329 switch (backend) {
330 case Settings::RendererBackend::OpenGL:
331 Settings::values.shader_backend.SetGlobal(false);
332 Settings::values.shader_backend.SetValue(
333 static_cast<Settings::ShaderBackend>(shader_backend_combobox->currentIndex()));
334 break;
335 case Settings::RendererBackend::Vulkan:
336 Settings::values.vulkan_device.SetGlobal(false);
337 Settings::values.vulkan_device.SetValue(vulkan_device_combobox->currentIndex());
338 break;
339 case Settings::RendererBackend::Null:
340 break;
341 }
342 }
300} 343}
301 344
302void ConfigureGraphics::changeEvent(QEvent* event) { 345void ConfigureGraphics::changeEvent(QEvent* event) {
@@ -322,8 +365,7 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
322} 365}
323 366
324void ConfigureGraphics::UpdateAPILayout() { 367void ConfigureGraphics::UpdateAPILayout() {
325 if (!Settings::IsConfiguringGlobal() && 368 if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) {
326 api_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
327 vulkan_device = Settings::values.vulkan_device.GetValue(true); 369 vulkan_device = Settings::values.vulkan_device.GetValue(true);
328 shader_backend = Settings::values.shader_backend.GetValue(true); 370 shader_backend = Settings::values.shader_backend.GetValue(true);
329 vulkan_device_widget->setEnabled(false); 371 vulkan_device_widget->setEnabled(false);
@@ -371,15 +413,8 @@ void ConfigureGraphics::RetrieveVulkanDevices() {
371} 413}
372 414
373Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { 415Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
374 if (Settings::IsConfiguringGlobal()) { 416 if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) {
375 return static_cast<Settings::RendererBackend>(api_combobox->currentIndex()); 417 return Settings::values.renderer_backend.GetValue(true);
376 }
377
378 if (api_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
379 Settings::values.renderer_backend.SetGlobal(true);
380 return Settings::values.renderer_backend.GetValue();
381 } 418 }
382 Settings::values.renderer_backend.SetGlobal(false); 419 return static_cast<Settings::RendererBackend>(api_combobox->currentIndex());
383 return static_cast<Settings::RendererBackend>(api_combobox->currentIndex() -
384 ConfigurationShared::USE_GLOBAL_OFFSET);
385} 420}
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index c226e825b..12a588127 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -85,6 +85,7 @@ private:
85 const Core::System& system; 85 const Core::System& system;
86 const ConfigurationShared::TranslationMap& translations; 86 const ConfigurationShared::TranslationMap& translations;
87 87
88 QPushButton* api_restore_global_button;
88 QComboBox* vulkan_device_combobox; 89 QComboBox* vulkan_device_combobox;
89 QComboBox* api_combobox; 90 QComboBox* api_combobox;
90 QComboBox* shader_backend_combobox; 91 QComboBox* shader_backend_combobox;
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 565429c98..1f6ffea1a 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -27,7 +27,7 @@
27 <layout class="QVBoxLayout" name="verticalLayout_3"> 27 <layout class="QVBoxLayout" name="verticalLayout_3">
28 <item> 28 <item>
29 <widget class="QWidget" name="api_widget" native="true"> 29 <widget class="QWidget" name="api_widget" native="true">
30 <layout class="QGridLayout" name="gridLayout"> 30 <layout class="QHBoxLayout" name="horizontalLayout">
31 <property name="leftMargin"> 31 <property name="leftMargin">
32 <number>0</number> 32 <number>0</number>
33 </property> 33 </property>
@@ -40,9 +40,6 @@
40 <property name="bottomMargin"> 40 <property name="bottomMargin">
41 <number>0</number> 41 <number>0</number>
42 </property> 42 </property>
43 <property name="horizontalSpacing">
44 <number>6</number>
45 </property>
46 </layout> 43 </layout>
47 </widget> 44 </widget>
48 </item> 45 </item>
@@ -63,7 +60,20 @@
63 <layout class="QVBoxLayout" name="verticalLayout_4"> 60 <layout class="QVBoxLayout" name="verticalLayout_4">
64 <item> 61 <item>
65 <widget class="QWidget" name="graphics_widget" native="true"> 62 <widget class="QWidget" name="graphics_widget" native="true">
66 <layout class="QVBoxLayout" name="verticalLayout"/> 63 <layout class="QVBoxLayout" name="verticalLayout">
64 <property name="leftMargin">
65 <number>0</number>
66 </property>
67 <property name="topMargin">
68 <number>0</number>
69 </property>
70 <property name="rightMargin">
71 <number>0</number>
72 </property>
73 <property name="bottomMargin">
74 <number>0</number>
75 </property>
76 </layout>
67 </widget> 77 </widget>
68 </item> 78 </item>
69 </layout> 79 </layout>
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 3a207e2cd..8a53ad111 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -32,7 +32,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
32 32
33 for (auto setting : 33 for (auto setting :
34 Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) { 34 Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) {
35 auto [widget, extra] = ConfigurationShared::CreateWidget( 35 auto [widget, extra, button] = ConfigurationShared::CreateWidget(
36 setting, translations, this, runtime_lock, apply_funcs, trackers); 36 setting, translations, this, runtime_lock, apply_funcs, trackers);
37 37
38 if (widget == nullptr) { 38 if (widget == nullptr) {
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 113fbc010..37a854ca3 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -27,7 +27,20 @@
27 <layout class="QVBoxLayout" name="verticalLayout_3"> 27 <layout class="QVBoxLayout" name="verticalLayout_3">
28 <item> 28 <item>
29 <widget class="QWidget" name="populate_target" native="true"> 29 <widget class="QWidget" name="populate_target" native="true">
30 <layout class="QVBoxLayout" name="verticalLayout"/> 30 <layout class="QVBoxLayout" name="verticalLayout">
31 <property name="leftMargin">
32 <number>0</number>
33 </property>
34 <property name="topMargin">
35 <number>0</number>
36 </property>
37 <property name="rightMargin">
38 <number>0</number>
39 </property>
40 <property name="bottomMargin">
41 <number>0</number>
42 </property>
43 </layout>
31 </widget> 44 </widget>
32 </item> 45 </item>
33 </layout> 46 </layout>
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index 5a2071781..a13636af6 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -93,6 +93,9 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
93 "Enable compute pipelines, required by some games.\nThis setting only exists for Intel " 93 "Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
94 "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled " 94 "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled "
95 "on all other drivers."); 95 "on all other drivers.");
96 INSERT(use_reactive_flushing, "Enable Reactive Flushing",
97 "Uses reactive flushing instead of predictive flushing, allowing more accurate memory "
98 "syncing.");
96 99
97 // Renderer (Debug) 100 // Renderer (Debug)
98 101