summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar lat9nq2023-05-08 22:37:03 -0400
committerGravatar lat9nq2023-07-21 10:56:07 -0400
commitf66d617107e45f8213643f2bbaa5f58878c3d3a6 (patch)
treedce6687605ba2f3d195d75aec44a92769e95455f
parentconfiguration: Implement slider (diff)
downloadyuzu-f66d617107e45f8213643f2bbaa5f58878c3d3a6.tar.gz
yuzu-f66d617107e45f8213643f2bbaa5f58878c3d3a6.tar.xz
yuzu-f66d617107e45f8213643f2bbaa5f58878c3d3a6.zip
configuration: Move CreateWidget to a class
We were passing so many objects between the function and the caller that it needed to be redesigned.
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/configuration/config.cpp3
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp386
-rw-r--r--src/yuzu/configuration/configuration_shared.h18
-rw-r--r--src/yuzu/configuration/configure_general.cpp63
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp55
-rw-r--r--src/yuzu/configuration/configure_graphics.h1
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp8
-rw-r--r--src/yuzu/configuration/shared_widget.cpp360
-rw-r--r--src/yuzu/configuration/shared_widget.h64
10 files changed, 507 insertions, 453 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 8b54e1268..899b75871 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -145,6 +145,8 @@ add_executable(yuzu
145 configuration/input_profiles.h 145 configuration/input_profiles.h
146 configuration/shared_translation.cpp 146 configuration/shared_translation.cpp
147 configuration/shared_translation.h 147 configuration/shared_translation.h
148 configuration/shared_widget.cpp
149 configuration/shared_widget.h
148 debugger/console.cpp 150 debugger/console.cpp
149 debugger/console.h 151 debugger/console.h
150 debugger/controller.cpp 152 debugger/controller.cpp
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index c6a34e787..08aa20859 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -1346,8 +1346,11 @@ void Config::ReadSettingGeneric(Settings::BasicSetting* const setting) {
1346 1346
1347void Config::WriteSettingGeneric(Settings::BasicSetting* const setting) const { 1347void Config::WriteSettingGeneric(Settings::BasicSetting* const setting) const {
1348 if (!setting->Save()) { 1348 if (!setting->Save()) {
1349 LOG_DEBUG(Frontend, "Skipping \"{}\" marked for not saving", setting->GetLabel());
1349 return; 1350 return;
1350 } 1351 }
1352 LOG_DEBUG(Frontend, "Saving {} setting \"{}\"...", global ? "global" : "custom",
1353 setting->GetLabel());
1351 const QVariant value = QVariant::fromValue(QString::fromStdString(setting->ToString())); 1354 const QVariant value = QVariant::fromValue(QString::fromStdString(setting->ToString()));
1352 const QVariant default_value = 1355 const QVariant default_value =
1353 QVariant::fromValue(QString::fromStdString(setting->DefaultToString())); 1356 QVariant::fromValue(QString::fromStdString(setting->DefaultToString()));
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index 076d9cc0d..dff70f04b 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -28,392 +28,6 @@
28 28
29namespace ConfigurationShared { 29namespace ConfigurationShared {
30 30
31static QPushButton* CreateRestoreGlobalButton(QWidget* parent, Settings::BasicSetting* setting) {
32 QStyle* style = parent->style();
33 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton));
34 QPushButton* button = new QPushButton(*icon, QStringLiteral(""), parent);
35 button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
36
37 QSizePolicy sp_retain = button->sizePolicy();
38 sp_retain.setRetainSizeWhenHidden(true);
39 button->setSizePolicy(sp_retain);
40
41 button->setEnabled(!setting->UsingGlobal());
42 button->setVisible(!setting->UsingGlobal());
43
44 return button;
45}
46
47static std::tuple<QWidget*, void*, QPushButton*, std::function<void()>> CreateCheckBox(
48 Settings::BasicSetting* setting, const QString& label, QWidget* parent) {
49 QWidget* widget = new QWidget(parent);
50 QHBoxLayout* layout = new QHBoxLayout(widget);
51
52 QCheckBox* checkbox = new QCheckBox(label, parent);
53 checkbox->setObjectName(QString::fromStdString(setting->GetLabel()));
54 checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked
55 : Qt::CheckState::Unchecked);
56
57 std::function<void()> load_func;
58
59 QPushButton* button{nullptr};
60
61 layout->addWidget(checkbox);
62 if (Settings::IsConfiguringGlobal()) {
63 load_func = [setting, checkbox]() {
64 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
65 };
66 } else {
67 button = CreateRestoreGlobalButton(parent, setting);
68 layout->addWidget(button);
69
70 QObject::connect(checkbox, &QCheckBox::stateChanged, [button](int) {
71 button->setVisible(true);
72 button->setEnabled(true);
73 });
74
75 QObject::connect(button, &QAbstractButton::clicked, [checkbox, setting, button](bool) {
76 checkbox->setCheckState(setting->ToStringGlobal() == "true" ? Qt::Checked
77 : Qt::Unchecked);
78 button->setEnabled(false);
79 button->setVisible(false);
80 });
81
82 load_func = [setting, checkbox, button]() {
83 bool using_global = !button->isEnabled();
84 setting->SetGlobal(using_global);
85 if (!using_global) {
86 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
87 }
88 };
89 }
90
91 layout->setContentsMargins(0, 0, 0, 0);
92
93 return {widget, checkbox, button, load_func};
94}
95
96static std::tuple<QWidget*, QComboBox*, QPushButton*, std::function<void()>> CreateCombobox(
97 Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed) {
98 const auto type = setting->TypeId();
99
100 QWidget* group = new QWidget(parent);
101 group->setObjectName(QString::fromStdString(setting->GetLabel()));
102 QLayout* layout = new QHBoxLayout(group);
103
104 QLabel* qt_label = new QLabel(label, parent);
105 QComboBox* combobox = new QComboBox(parent);
106
107 QPushButton* button{nullptr};
108
109 std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, parent);
110 for (const auto& item : combobox_enumerations) {
111 combobox->addItem(item);
112 }
113
114 layout->addWidget(qt_label);
115 layout->addWidget(combobox);
116
117 layout->setSpacing(6);
118 layout->setContentsMargins(0, 0, 0, 0);
119
120 combobox->setCurrentIndex(std::stoi(setting->ToString()));
121
122 std::function<void()> load_func = []() {};
123
124 if (Settings::IsConfiguringGlobal() && managed) {
125 load_func = [setting, combobox]() {
126 setting->LoadString(std::to_string(combobox->currentIndex()));
127 };
128 } else if (managed) {
129 button = CreateRestoreGlobalButton(parent, setting);
130 layout->addWidget(button);
131
132 QObject::connect(button, &QAbstractButton::clicked, [button, combobox, setting](bool) {
133 button->setEnabled(false);
134 button->setVisible(false);
135
136 combobox->setCurrentIndex(std::stoi(setting->ToStringGlobal()));
137 });
138
139 QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated), [=](int) {
140 button->setEnabled(true);
141 button->setVisible(true);
142 });
143
144 load_func = [setting, combobox, button]() {
145 bool using_global = !button->isEnabled();
146 setting->SetGlobal(using_global);
147 if (!using_global) {
148 setting->LoadString(std::to_string(combobox->currentIndex()));
149 }
150 };
151 }
152
153 return {group, combobox, button, load_func};
154}
155
156static std::tuple<QWidget*, void*, QPushButton*, std::function<void()>> CreateLineEdit(
157 Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed = true) {
158 QWidget* widget = new QWidget(parent);
159 widget->setObjectName(label);
160
161 QHBoxLayout* layout = new QHBoxLayout(widget);
162 QLineEdit* line_edit = new QLineEdit(parent);
163
164 const QString text = QString::fromStdString(setting->ToString());
165 line_edit->setText(text);
166
167 std::function<void()> load_func = []() {};
168
169 QLabel* q_label = new QLabel(label, widget);
170 // setSizePolicy lets widget expand and take an equal part of the space as the line edit
171 q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
172 layout->addWidget(q_label);
173
174 layout->addWidget(line_edit);
175
176 QPushButton* button{nullptr};
177
178 if (Settings::IsConfiguringGlobal() && !managed) {
179 load_func = [line_edit, setting]() {
180 std::string load_text = line_edit->text().toStdString();
181 setting->LoadString(load_text);
182 };
183 } else if (!managed) {
184 button = CreateRestoreGlobalButton(parent, setting);
185 layout->addWidget(button);
186
187 QObject::connect(button, &QAbstractButton::clicked, [=](bool) {
188 button->setEnabled(false);
189 button->setVisible(false);
190
191 line_edit->setText(QString::fromStdString(setting->ToStringGlobal()));
192 });
193
194 QObject::connect(line_edit, &QLineEdit::textChanged, [=](QString) {
195 button->setEnabled(true);
196 button->setVisible(true);
197 });
198
199 load_func = [=]() {
200 bool using_global = !button->isEnabled();
201 setting->SetGlobal(using_global);
202 if (!using_global) {
203 setting->LoadString(line_edit->text().toStdString());
204 }
205 };
206 }
207
208 layout->setContentsMargins(0, 0, 0, 0);
209
210 return {widget, line_edit, button, load_func};
211}
212
213static std::tuple<QWidget*, void*, QPushButton*, std::function<void()>> CreateSlider(
214 Settings::BasicSetting* setting, const QString& name, QWidget* parent, bool reversed,
215 float multiplier) {
216 QWidget* widget = new QWidget(parent);
217 QHBoxLayout* layout = new QHBoxLayout(widget);
218 QSlider* slider = new QSlider(Qt::Horizontal, widget);
219 QLabel* label = new QLabel(name, widget);
220 QPushButton* button{nullptr};
221 QLabel* feedback = new QLabel(widget);
222
223 layout->addWidget(label);
224 layout->addWidget(slider);
225 layout->addWidget(feedback);
226
227 label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
228
229 layout->setContentsMargins(0, 0, 0, 0);
230
231 int max_val = std::stoi(setting->MaxVal());
232
233 QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) {
234 int present = (reversed ? max_val - value : value) * multiplier;
235 feedback->setText(
236 QStringLiteral("%1%").arg(QString::fromStdString(std::to_string(present))));
237 });
238
239 slider->setValue(std::stoi(setting->ToString()));
240 slider->setMinimum(std::stoi(setting->MinVal()));
241 slider->setMaximum(max_val);
242
243 if (reversed) {
244 slider->setInvertedAppearance(true);
245 }
246
247 std::function<void()> load_func;
248
249 if (Settings::IsConfiguringGlobal()) {
250 load_func = [=]() { setting->LoadString(std::to_string(slider->value())); };
251 } else {
252 button = CreateRestoreGlobalButton(parent, setting);
253 layout->addWidget(button);
254
255 QObject::connect(button, &QAbstractButton::clicked, [=](bool) {
256 slider->setValue(std::stoi(setting->ToStringGlobal()));
257
258 button->setEnabled(false);
259 button->setVisible(false);
260 });
261
262 QObject::connect(slider, &QAbstractSlider::sliderMoved, [=](int) {
263 button->setEnabled(true);
264 button->setVisible(true);
265 });
266
267 load_func = [=]() {
268 bool using_global = !button->isEnabled();
269 setting->SetGlobal(using_global);
270 if (!using_global) {
271 setting->LoadString(std::to_string(slider->value()));
272 }
273 };
274 }
275
276 return {widget, slider, button, []() {}};
277}
278
279static std::tuple<QWidget*, void*, void*, QPushButton*, std::function<void()>>
280CreateCheckBoxWithLineEdit(Settings::BasicSetting* setting, const QString& label, QWidget* parent) {
281 auto tuple = CreateCheckBox(setting, label, parent);
282 auto* widget = std::get<0>(tuple);
283 auto* checkbox = std::get<1>(tuple);
284 auto* button = std::get<2>(tuple);
285 auto load_func = std::get<3>(tuple);
286 QHBoxLayout* layout = dynamic_cast<QHBoxLayout*>(widget->layout());
287
288 auto line_edit_tuple = CreateLineEdit(setting, label, parent, false);
289 auto* line_edit_widget = std::get<0>(line_edit_tuple);
290 auto* line_edit = std::get<1>(line_edit_tuple);
291
292 layout->insertWidget(1, line_edit_widget);
293
294 return {widget, checkbox, line_edit, button, load_func};
295}
296
297std::tuple<QWidget*, void*, QPushButton*> CreateWidget(
298 Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
299 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
300 RequestType request, bool managed, float multiplier, const std::string& text_box_default) {
301 if (!Settings::IsConfiguringGlobal() && !setting->Switchable()) {
302 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting->GetLabel());
303 return {nullptr, nullptr, nullptr};
304 }
305
306 const auto type = setting->TypeId();
307 const int id = setting->Id();
308 QWidget* widget{nullptr};
309 void* extra{nullptr};
310
311 std::function<void()> load_func;
312
313 const auto [label, tooltip] = [&]() {
314 const auto& setting_label = setting->GetLabel();
315 if (translations.contains(id)) {
316 return std::pair{translations.at(id).first, translations.at(id).second};
317 }
318 LOG_ERROR(Frontend, "Translation table lacks entry for \"{}\"", setting_label);
319 return std::pair{QString::fromStdString(setting_label), QStringLiteral("")};
320 }();
321
322 if (label == QStringLiteral("")) {
323 LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...",
324 setting->GetLabel());
325 return {nullptr, nullptr, nullptr};
326 }
327
328 QPushButton* button;
329
330 if (type == typeid(bool)) {
331 switch (request) {
332 case RequestType::Default: {
333 auto tuple = CreateCheckBox(setting, label, parent);
334 widget = std::get<0>(tuple);
335 extra = std::get<1>(tuple);
336 button = std::get<2>(tuple);
337 load_func = std::get<3>(tuple);
338 break;
339 }
340 case RequestType::LineEdit: {
341 auto tuple = CreateCheckBoxWithLineEdit(setting, label, parent);
342 widget = std::get<0>(tuple);
343 break;
344 }
345 case RequestType::ComboBox:
346 case RequestType::SpinBox:
347 case RequestType::Slider:
348 case RequestType::ReverseSlider:
349 case RequestType::MaxEnum:
350 break;
351 }
352 } else if (setting->IsEnum()) {
353 auto tuple = CreateCombobox(setting, label, parent, managed);
354 widget = std::get<0>(tuple);
355 extra = std::get<1>(tuple);
356 button = std::get<2>(tuple);
357 load_func = std::get<3>(tuple);
358 } else if (type == typeid(u32) || type == typeid(int)) {
359 switch (request) {
360 case RequestType::LineEdit:
361 case RequestType::Default: {
362 auto tuple = CreateLineEdit(setting, label, parent);
363 widget = std::get<0>(tuple);
364 extra = std::get<1>(tuple);
365 button = std::get<2>(tuple);
366 load_func = std::get<3>(tuple);
367 break;
368 }
369 case RequestType::ComboBox: {
370 auto tuple = CreateCombobox(setting, label, parent, managed);
371 widget = std::get<0>(tuple);
372 extra = std::get<1>(tuple);
373 button = std::get<2>(tuple);
374 load_func = std::get<3>(tuple);
375 break;
376 }
377 case RequestType::Slider:
378 case RequestType::ReverseSlider: {
379 auto tuple = CreateSlider(setting, label, parent, request == RequestType::ReverseSlider,
380 multiplier);
381 widget = std::get<0>(tuple);
382 extra = std::get<1>(tuple);
383 button = std::get<2>(tuple);
384 load_func = std::get<3>(tuple);
385 break;
386 }
387 case RequestType::SpinBox:
388 case RequestType::MaxEnum:
389 break;
390 }
391 }
392
393 if (widget == nullptr) {
394 LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel());
395 return {nullptr, nullptr, nullptr};
396 }
397
398 apply_funcs.push_front([load_func, setting](bool powered_on) {
399 if (setting->RuntimeModfiable() || !powered_on) {
400 load_func();
401 }
402 });
403
404 bool enable = runtime_lock || setting->RuntimeModfiable();
405 if (setting->Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) {
406 enable &= !setting->UsingGlobal();
407 }
408 widget->setEnabled(enable);
409
410 widget->setVisible(Settings::IsConfiguringGlobal() || setting->Switchable());
411
412 widget->setToolTip(tooltip);
413
414 return {widget, extra, button};
415}
416
417Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent) 31Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent)
418 : QWidget(parent), group{group_} { 32 : QWidget(parent), group{group_} {
419 if (group != nullptr) { 33 if (group != nullptr) {
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index ef3b7c9a9..0a0a92ae5 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -13,8 +13,6 @@
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
18namespace ConfigurationShared { 16namespace ConfigurationShared {
19 17
20class Tab : public QWidget { 18class Tab : public QWidget {
@@ -43,22 +41,6 @@ enum class CheckState {
43 Count, // Simply the number of states, not a valid checkbox state 41 Count, // Simply the number of states, not a valid checkbox state
44}; 42};
45 43
46enum class RequestType {
47 Default,
48 ComboBox,
49 SpinBox,
50 Slider,
51 ReverseSlider,
52 LineEdit,
53 MaxEnum,
54};
55
56std::tuple<QWidget*, void*, QPushButton*> CreateWidget(
57 Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
58 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
59 RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f,
60 const std::string& text_box_default = "");
61
62// Global-aware apply and set functions 44// Global-aware apply and set functions
63 45
64// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting 46// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 8c6fee2a5..764ff68b3 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -21,10 +21,10 @@ ConfigureGeneral::ConfigureGeneral(
21 21
22 SetConfiguration(); 22 SetConfiguration();
23 23
24 if (Settings::IsConfiguringGlobal()) { 24 // if (Settings::IsConfiguringGlobal()) {
25 connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, 25 // connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit,
26 [this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); }); 26 // [this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); });
27 } 27 // }
28 28
29 connect(ui->button_reset_defaults, &QPushButton::clicked, this, 29 connect(ui->button_reset_defaults, &QPushButton::clicked, this,
30 &ConfigureGeneral::ResetDefaults); 30 &ConfigureGeneral::ResetDefaults);
@@ -46,17 +46,17 @@ void ConfigureGeneral::SetConfiguration() {
46 ui->toggle_controller_applet_disabled->setChecked( 46 ui->toggle_controller_applet_disabled->setChecked(
47 UISettings::values.controller_applet_disabled.GetValue()); 47 UISettings::values.controller_applet_disabled.GetValue());
48 48
49 ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue()); 49 // ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
50 ui->speed_limit->setValue(Settings::values.speed_limit.GetValue()); 50 // ui->speed_limit->setValue(Settings::values.speed_limit.GetValue());
51 51
52 ui->button_reset_defaults->setEnabled(runtime_lock); 52 ui->button_reset_defaults->setEnabled(runtime_lock);
53 53
54 if (Settings::IsConfiguringGlobal()) { 54 // if (Settings::IsConfiguringGlobal()) {
55 ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue()); 55 // ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue());
56 } else { 56 // } else {
57 ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() && 57 // ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() &&
58 use_speed_limit != ConfigurationShared::CheckState::Global); 58 // use_speed_limit != ConfigurationShared::CheckState::Global);
59 } 59 // }
60} 60}
61 61
62// Called to set the callback when resetting settings to defaults 62// Called to set the callback when resetting settings to defaults
@@ -91,20 +91,20 @@ void ConfigureGeneral::ApplyConfiguration() {
91 ui->toggle_controller_applet_disabled->isChecked(); 91 ui->toggle_controller_applet_disabled->isChecked();
92 92
93 // Guard if during game and set to game-specific value 93 // Guard if during game and set to game-specific value
94 if (Settings::values.use_speed_limit.UsingGlobal()) { 94 // if (Settings::values.use_speed_limit.UsingGlobal()) {
95 Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() == 95 // Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
96 Qt::Checked); 96 // Qt::Checked);
97 Settings::values.speed_limit.SetValue(ui->speed_limit->value()); 97 // Settings::values.speed_limit.SetValue(ui->speed_limit->value());
98 } 98 // }
99 } else { 99 } else {
100 bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global; 100 // bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global;
101 Settings::values.use_speed_limit.SetGlobal(global_speed_limit); 101 // Settings::values.use_speed_limit.SetGlobal(global_speed_limit);
102 Settings::values.speed_limit.SetGlobal(global_speed_limit); 102 // Settings::values.speed_limit.SetGlobal(global_speed_limit);
103 if (!global_speed_limit) { 103 // if (!global_speed_limit) {
104 Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() == 104 // Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
105 Qt::Checked); 105 // Qt::Checked);
106 Settings::values.speed_limit.SetValue(ui->speed_limit->value()); 106 // Settings::values.speed_limit.SetValue(ui->speed_limit->value());
107 } 107 // }
108 } 108 }
109} 109}
110 110
@@ -125,8 +125,8 @@ void ConfigureGeneral::SetupPerGameUI() {
125 // Disables each setting if: 125 // Disables each setting if:
126 // - A game is running (thus settings in use), and 126 // - A game is running (thus settings in use), and
127 // - A non-global setting is applied. 127 // - A non-global setting is applied.
128 ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal()); 128 // ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal());
129 ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal()); 129 // ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal());
130 130
131 return; 131 return;
132 } 132 }
@@ -144,8 +144,9 @@ void ConfigureGeneral::SetupPerGameUI() {
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
147 connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() { 147 // connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
148 ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() && 148 // ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
149 (use_speed_limit != ConfigurationShared::CheckState::Global)); 149 // (use_speed_limit !=
150 }); 150 // ConfigurationShared::CheckState::Global));
151 // });
151} 152}
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index d3ca7e8cc..093e33625 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -15,6 +15,7 @@
15#include <QComboBox> 15#include <QComboBox>
16#include <QIcon> 16#include <QIcon>
17#include <QLabel> 17#include <QLabel>
18#include <QLineEdit>
18#include <QPixmap> 19#include <QPixmap>
19#include <QPushButton> 20#include <QPushButton>
20#include <QSlider> 21#include <QSlider>
@@ -35,6 +36,7 @@
35#include "ui_configure_graphics.h" 36#include "ui_configure_graphics.h"
36#include "yuzu/configuration/configuration_shared.h" 37#include "yuzu/configuration/configuration_shared.h"
37#include "yuzu/configuration/configure_graphics.h" 38#include "yuzu/configuration/configure_graphics.h"
39#include "yuzu/configuration/shared_widget.h"
38#include "yuzu/qt_common.h" 40#include "yuzu/qt_common.h"
39#include "yuzu/uisettings.h" 41#include "yuzu/uisettings.h"
40#include "yuzu/vk_device_info.h" 42#include "yuzu/vk_device_info.h"
@@ -219,35 +221,38 @@ void ConfigureGraphics::SetConfiguration() {
219 for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) { 221 for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
220 const auto& setting_label = setting->GetLabel(); 222 const auto& setting_label = setting->GetLabel();
221 223
222 auto [widget, extra, button] = [&]() { 224 ConfigurationShared::Widget* widget = [&]() {
223 if (setting->Id() == Settings::values.vulkan_device.Id() || 225 if (setting->Id() == Settings::values.vulkan_device.Id() ||
224 setting->Id() == Settings::values.shader_backend.Id() || 226 setting->Id() == Settings::values.shader_backend.Id() ||
225 setting->Id() == Settings::values.vsync_mode.Id()) { 227 setting->Id() == Settings::values.vsync_mode.Id()) {
226 return ConfigurationShared::CreateWidget( 228 return new ConfigurationShared::Widget(
227 setting, translations, this, runtime_lock, apply_funcs, 229 setting, translations, this, runtime_lock, apply_funcs,
228 ConfigurationShared::RequestType::ComboBox, false); 230 ConfigurationShared::RequestType::ComboBox, false);
229 } else if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) { 231 } else if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
230 return ConfigurationShared::CreateWidget( 232 return new ConfigurationShared::Widget(
231 setting, translations, this, runtime_lock, apply_funcs, 233 setting, translations, this, runtime_lock, apply_funcs,
232 ConfigurationShared::RequestType::ReverseSlider, true, 0.5f); 234 ConfigurationShared::RequestType::ReverseSlider, true, 0.5f);
233 } else if (setting->Id() == Settings::values.use_speed_limit.Id()) { 235 } else if (setting->Id() == Settings::values.use_speed_limit.Id()) {
234 return ConfigurationShared::CreateWidget( 236 return new ConfigurationShared::Widget(
235 setting, translations, this, runtime_lock, apply_funcs, 237 setting, translations, this, runtime_lock, apply_funcs,
236 ConfigurationShared::RequestType::LineEdit, true, 1.0f, setting->ToString()); 238 ConfigurationShared::RequestType::LineEdit, true, 1.0f,
239 Settings::values.speed_limit.ToString());
237 } else { 240 } else {
238 return ConfigurationShared::CreateWidget(setting, translations, this, runtime_lock, 241 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
239 apply_funcs); 242 apply_funcs);
240 } 243 }
241 }(); 244 }();
242 245
243 if (widget == nullptr) { 246 if (!widget->Valid()) {
247 LOG_DEBUG(Frontend, "Deleted widget for \"{}\"", setting->GetLabel());
248 delete widget;
244 continue; 249 continue;
245 } 250 }
246 251
247 if (setting->Id() == Settings::values.renderer_backend.Id()) { 252 if (setting->Id() == Settings::values.renderer_backend.Id()) {
248 api_grid_layout->addWidget(widget); 253 api_grid_layout->addWidget(widget);
249 api_combobox = reinterpret_cast<QComboBox*>(extra); 254 api_combobox = widget->combobox;
250 api_restore_global_button = button; 255 api_restore_global_button = widget->restore_button;
251 256
252 if (!Settings::IsConfiguringGlobal()) { 257 if (!Settings::IsConfiguringGlobal()) {
253 QObject::connect(api_restore_global_button, &QAbstractButton::clicked, 258 QObject::connect(api_restore_global_button, &QAbstractButton::clicked,
@@ -259,14 +264,33 @@ void ConfigureGraphics::SetConfiguration() {
259 } 264 }
260 } else if (setting->Id() == Settings::values.vulkan_device.Id()) { 265 } else if (setting->Id() == Settings::values.vulkan_device.Id()) {
261 hold_api.push_front(widget); 266 hold_api.push_front(widget);
262 vulkan_device_combobox = reinterpret_cast<QComboBox*>(extra); 267 vulkan_device_combobox = widget->combobox;
263 vulkan_device_widget = widget; 268 vulkan_device_widget = widget;
264 } else if (setting->Id() == Settings::values.shader_backend.Id()) { 269 } else if (setting->Id() == Settings::values.shader_backend.Id()) {
265 hold_api.push_front(widget); 270 hold_api.push_front(widget);
266 shader_backend_combobox = reinterpret_cast<QComboBox*>(extra); 271 shader_backend_combobox = widget->combobox;
267 shader_backend_widget = widget; 272 shader_backend_widget = widget;
273 } else if (setting->Id() == Settings::values.use_speed_limit.Id()) {
274 apply_funcs.push_front([setting, widget](bool powered_on) {
275 if (!setting->RuntimeModfiable() && powered_on) {
276 return;
277 }
278
279 u16 value = QVariant(widget->line_edit->text()).value<u16>();
280 auto& speed_limit = Settings::values.speed_limit;
281 if (Settings::IsConfiguringGlobal()) {
282 speed_limit.SetValue(value);
283 } else {
284 bool using_global = !widget->restore_button->isVisible();
285 speed_limit.SetGlobal(using_global);
286 if (!using_global) {
287 speed_limit.SetValue(value);
288 }
289 }
290 });
291 hold_graphics[setting->IsEnum()][setting_label] = widget;
268 } else if (setting->Id() == Settings::values.vsync_mode.Id()) { 292 } else if (setting->Id() == Settings::values.vsync_mode.Id()) {
269 vsync_mode_combobox = reinterpret_cast<QComboBox*>(extra); 293 vsync_mode_combobox = widget->combobox;
270 hold_graphics[setting->IsEnum()][setting_label] = widget; 294 hold_graphics[setting->IsEnum()][setting_label] = widget;
271 } else { 295 } else {
272 hold_graphics[setting->IsEnum()][setting_label] = widget; 296 hold_graphics[setting->IsEnum()][setting_label] = widget;
@@ -360,6 +384,7 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
360} 384}
361 385
362void ConfigureGraphics::UpdateAPILayout() { 386void ConfigureGraphics::UpdateAPILayout() {
387 bool runtime_lock = !system.IsPoweredOn();
363 if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) { 388 if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) {
364 vulkan_device = Settings::values.vulkan_device.GetValue(true); 389 vulkan_device = Settings::values.vulkan_device.GetValue(true);
365 shader_backend = Settings::values.shader_backend.GetValue(true); 390 shader_backend = Settings::values.shader_backend.GetValue(true);
@@ -368,8 +393,8 @@ void ConfigureGraphics::UpdateAPILayout() {
368 } else { 393 } else {
369 vulkan_device = Settings::values.vulkan_device.GetValue(); 394 vulkan_device = Settings::values.vulkan_device.GetValue();
370 shader_backend = Settings::values.shader_backend.GetValue(); 395 shader_backend = Settings::values.shader_backend.GetValue();
371 vulkan_device_widget->setEnabled(true); 396 vulkan_device_widget->setEnabled(runtime_lock);
372 shader_backend_widget->setEnabled(true); 397 shader_backend_widget->setEnabled(runtime_lock);
373 } 398 }
374 399
375 switch (GetCurrentGraphicsBackend()) { 400 switch (GetCurrentGraphicsBackend()) {
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index a049458a8..4ef551341 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -15,6 +15,7 @@
15#include "vk_device_info.h" 15#include "vk_device_info.h"
16#include "yuzu/configuration/configuration_shared.h" 16#include "yuzu/configuration/configuration_shared.h"
17 17
18class QPushButton;
18class QEvent; 19class QEvent;
19class QObject; 20class QObject;
20class QComboBox; 21class QComboBox;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 4a3868693..4f57a7ae6 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -8,6 +8,7 @@
8#include "ui_configure_graphics_advanced.h" 8#include "ui_configure_graphics_advanced.h"
9#include "yuzu/configuration/configuration_shared.h" 9#include "yuzu/configuration/configuration_shared.h"
10#include "yuzu/configuration/configure_graphics_advanced.h" 10#include "yuzu/configuration/configure_graphics_advanced.h"
11#include "yuzu/configuration/shared_widget.h"
11 12
12ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced( 13ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
13 const Core::System& system_, 14 const Core::System& system_,
@@ -32,10 +33,11 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
32 33
33 for (auto setting : 34 for (auto setting :
34 Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) { 35 Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) {
35 auto [widget, extra, button] = ConfigurationShared::CreateWidget( 36 ConfigurationShared::Widget* widget =
36 setting, translations, this, runtime_lock, apply_funcs); 37 new ConfigurationShared::Widget(setting, translations, this, runtime_lock, apply_funcs);
37 38
38 if (widget == nullptr) { 39 if (!widget->Valid()) {
40 delete widget;
39 continue; 41 continue;
40 } 42 }
41 43
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp
new file mode 100644
index 000000000..0676973a9
--- /dev/null
+++ b/src/yuzu/configuration/shared_widget.cpp
@@ -0,0 +1,360 @@
1#include <functional>
2#include <QCheckBox>
3#include <QHBoxLayout>
4#include <QIcon>
5#include <QLabel>
6#include <QLineEdit>
7#include <QPushButton>
8#include <QSizePolicy>
9#include <QWidget>
10#include <qabstractbutton.h>
11#include "common/settings.h"
12#include "yuzu/configuration/shared_translation.h"
13#include "yuzu/configuration/shared_widget.h"
14
15namespace ConfigurationShared {
16
17void Widget::CreateRestoreGlobalButton() {
18 QStyle* style = this->style();
19 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton));
20 restore_button = new QPushButton(*icon, QStringLiteral(""), this);
21 restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
22
23 QSizePolicy sp_retain = restore_button->sizePolicy();
24 sp_retain.setRetainSizeWhenHidden(true);
25 restore_button->setSizePolicy(sp_retain);
26
27 restore_button->setEnabled(!setting.UsingGlobal());
28 restore_button->setVisible(!setting.UsingGlobal());
29}
30
31void Widget::CreateCheckBox(const QString& label, std::function<void()>& load_func) {
32 created = true;
33
34 QHBoxLayout* layout = new QHBoxLayout(this);
35
36 checkbox = new QCheckBox(label, this);
37 checkbox->setObjectName(QString::fromStdString(setting.GetLabel()));
38 checkbox->setCheckState(setting.ToString() == "true" ? Qt::CheckState::Checked
39 : Qt::CheckState::Unchecked);
40
41 layout->addWidget(checkbox);
42 if (Settings::IsConfiguringGlobal()) {
43 load_func = [=]() {
44 setting.LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
45 };
46 } else {
47 CreateRestoreGlobalButton();
48 layout->addWidget(restore_button);
49
50 QObject::connect(checkbox, &QCheckBox::stateChanged, [&](int) {
51 restore_button->setVisible(true);
52 restore_button->setEnabled(true);
53 });
54
55 QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) {
56 checkbox->setCheckState(setting.ToStringGlobal() == "true" ? Qt::Checked
57 : Qt::Unchecked);
58 restore_button->setEnabled(false);
59 restore_button->setVisible(false);
60 });
61
62 load_func = [=]() {
63 bool using_global = !restore_button->isEnabled();
64 setting.SetGlobal(using_global);
65 if (!using_global) {
66 setting.LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
67 }
68 };
69 }
70
71 layout->setContentsMargins(0, 0, 0, 0);
72}
73
74void Widget::CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func) {
75 created = true;
76
77 const auto type = setting.TypeId();
78
79 QLayout* layout = new QHBoxLayout(this);
80
81 QLabel* qt_label = new QLabel(label, this);
82 combobox = new QComboBox(this);
83
84 std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, this);
85 for (const auto& item : combobox_enumerations) {
86 combobox->addItem(item);
87 }
88
89 layout->addWidget(qt_label);
90 layout->addWidget(combobox);
91
92 layout->setSpacing(6);
93 layout->setContentsMargins(0, 0, 0, 0);
94
95 combobox->setCurrentIndex(std::stoi(setting.ToString()));
96
97 if (Settings::IsConfiguringGlobal() && managed) {
98 load_func = [=]() { setting.LoadString(std::to_string(combobox->currentIndex())); };
99 } else if (managed) {
100 CreateRestoreGlobalButton();
101 layout->addWidget(restore_button);
102
103 QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) {
104 restore_button->setEnabled(false);
105 restore_button->setVisible(false);
106
107 combobox->setCurrentIndex(std::stoi(setting.ToStringGlobal()));
108 });
109
110 QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated), [=](int) {
111 restore_button->setEnabled(true);
112 restore_button->setVisible(true);
113 });
114
115 load_func = [=]() {
116 bool using_global = !restore_button->isEnabled();
117 setting.SetGlobal(using_global);
118 if (!using_global) {
119 setting.LoadString(std::to_string(combobox->currentIndex()));
120 }
121 };
122 }
123}
124
125void Widget::CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func) {
126 created = true;
127
128 QHBoxLayout* layout = new QHBoxLayout(this);
129 line_edit = new QLineEdit(this);
130
131 const QString text = QString::fromStdString(setting.ToString());
132 line_edit->setText(text);
133
134 QLabel* q_label = new QLabel(label, this);
135 // setSizePolicy lets widget expand and take an equal part of the space as the line edit
136 q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
137 layout->addWidget(q_label);
138
139 layout->addWidget(line_edit);
140
141 if (Settings::IsConfiguringGlobal() && !managed) {
142 load_func = [=]() {
143 std::string load_text = line_edit->text().toStdString();
144 setting.LoadString(load_text);
145 };
146 } else if (!managed) {
147 CreateRestoreGlobalButton();
148 layout->addWidget(restore_button);
149
150 QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) {
151 restore_button->setEnabled(false);
152 restore_button->setVisible(false);
153
154 line_edit->setText(QString::fromStdString(setting.ToStringGlobal()));
155 });
156
157 QObject::connect(line_edit, &QLineEdit::textChanged, [&](QString) {
158 restore_button->setEnabled(true);
159 restore_button->setVisible(true);
160 });
161
162 load_func = [=]() {
163 bool using_global = !restore_button->isEnabled();
164 setting.SetGlobal(using_global);
165 if (!using_global) {
166 setting.LoadString(line_edit->text().toStdString());
167 }
168 };
169 }
170
171 layout->setContentsMargins(0, 0, 0, 0);
172}
173
174void Widget::CreateSlider(const QString& name, bool reversed, float multiplier,
175 std::function<void()>& load_func) {
176 created = true;
177
178 QHBoxLayout* layout = new QHBoxLayout(this);
179 slider = new QSlider(Qt::Horizontal, this);
180 QLabel* label = new QLabel(name, this);
181 QLabel* feedback = new QLabel(this);
182
183 layout->addWidget(label);
184 layout->addWidget(slider);
185 layout->addWidget(feedback);
186
187 label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
188
189 layout->setContentsMargins(0, 0, 0, 0);
190
191 int max_val = std::stoi(setting.MaxVal());
192
193 QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) {
194 int present = (reversed ? max_val - value : value) * multiplier;
195 feedback->setText(
196 QStringLiteral("%1%").arg(QString::fromStdString(std::to_string(present))));
197 });
198
199 slider->setValue(std::stoi(setting.ToString()));
200 slider->setMinimum(std::stoi(setting.MinVal()));
201 slider->setMaximum(max_val);
202
203 if (reversed) {
204 slider->setInvertedAppearance(true);
205 }
206
207 if (Settings::IsConfiguringGlobal()) {
208 load_func = [=]() { setting.LoadString(std::to_string(slider->value())); };
209 } else {
210 CreateRestoreGlobalButton();
211 layout->addWidget(restore_button);
212
213 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
214 slider->setValue(std::stoi(setting.ToStringGlobal()));
215
216 restore_button->setEnabled(false);
217 restore_button->setVisible(false);
218 });
219
220 QObject::connect(slider, &QAbstractSlider::sliderMoved, [=](int) {
221 restore_button->setEnabled(true);
222 restore_button->setVisible(true);
223 });
224
225 load_func = [=]() {
226 bool using_global = !restore_button->isEnabled();
227 setting.SetGlobal(using_global);
228 if (!using_global) {
229 setting.LoadString(std::to_string(slider->value()));
230 }
231 };
232 }
233}
234
235void Widget::CreateCheckBoxWithLineEdit(const QString& label, const std::string& text_box_default,
236 std::function<void()>& load_func) {
237 created = true;
238
239 CreateCheckBox(label, load_func);
240
241 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
242
243 line_edit = new QLineEdit(this);
244 line_edit->setText(QString::fromStdString(text_box_default));
245
246 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
247
248 layout->insertWidget(1, line_edit);
249
250 QObject::connect(line_edit, &QLineEdit::textEdited,
251 [=](const QString&) { checkbox->setCheckState(Qt::Checked); });
252
253 if (!Settings::IsConfiguringGlobal()) {
254 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
255 line_edit->setText(QString::fromStdString(text_box_default));
256 });
257
258 QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) {
259 restore_button->setEnabled(true);
260 restore_button->setVisible(true);
261 });
262 }
263}
264
265bool Widget::Valid() {
266 return created;
267}
268
269Widget::~Widget() = default;
270
271Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_,
272 QWidget* parent_, bool runtime_lock,
273 std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request,
274 bool managed, float multiplier, const std::string& text_box_default)
275 : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} {
276 if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) {
277 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel());
278 return;
279 }
280
281 const auto type = setting.TypeId();
282 const int id = setting.Id();
283
284 const auto [label, tooltip] = [&]() {
285 const auto& setting_label = setting.GetLabel();
286 if (translations.contains(id)) {
287 return std::pair{translations.at(id).first, translations.at(id).second};
288 }
289 LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label);
290 return std::pair{QString::fromStdString(setting_label), QStringLiteral("")};
291 }();
292
293 if (label == QStringLiteral("")) {
294 LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...",
295 setting.GetLabel());
296 return;
297 }
298
299 std::function<void()> load_func = []() {};
300
301 if (type == typeid(bool)) {
302 switch (request) {
303 case RequestType::Default:
304 CreateCheckBox(label, load_func);
305 break;
306 case RequestType::LineEdit:
307 case RequestType::SpinBox:
308 CreateCheckBoxWithLineEdit(label, text_box_default, load_func);
309 break;
310 case RequestType::ComboBox:
311 case RequestType::Slider:
312 case RequestType::ReverseSlider:
313 case RequestType::MaxEnum:
314 break;
315 }
316 } else if (setting.IsEnum()) {
317 CreateCombobox(label, managed, load_func);
318 } else if (type == typeid(u32) || type == typeid(int)) {
319 switch (request) {
320 case RequestType::Slider:
321 case RequestType::ReverseSlider:
322 CreateSlider(label, request == RequestType::ReverseSlider, multiplier, load_func);
323 break;
324 case RequestType::LineEdit:
325 case RequestType::Default:
326 CreateLineEdit(label, managed, load_func);
327 break;
328 case RequestType::ComboBox:
329 CreateCombobox(label, managed, load_func);
330 break;
331 case RequestType::SpinBox:
332 case RequestType::MaxEnum:
333 break;
334 }
335 }
336
337 if (!created) {
338 LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting.GetLabel());
339 return;
340 }
341
342 apply_funcs.push_front([load_func, setting_](bool powered_on) {
343 LOG_DEBUG(Frontend, "{}", setting_->GetLabel());
344 if (setting_->RuntimeModfiable() || !powered_on) {
345 load_func();
346 }
347 });
348
349 bool enable = runtime_lock || setting.RuntimeModfiable();
350 if (setting.Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) {
351 enable &= setting.UsingGlobal();
352 }
353 this->setEnabled(enable);
354
355 this->setVisible(Settings::IsConfiguringGlobal() || setting.Switchable());
356
357 this->setToolTip(tooltip);
358}
359
360} // namespace ConfigurationShared
diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h
new file mode 100644
index 000000000..559a27b41
--- /dev/null
+++ b/src/yuzu/configuration/shared_widget.h
@@ -0,0 +1,64 @@
1#include "yuzu/configuration/configuration_shared.h"
2#include "yuzu/configuration/shared_translation.h"
3
4class QPushButton;
5class QComboBox;
6class QLineEdit;
7class QSlider;
8class QCheckBox;
9
10namespace Settings {
11class BasicSetting;
12}
13
14namespace ConfigurationShared {
15
16enum class RequestType {
17 Default,
18 ComboBox,
19 SpinBox,
20 Slider,
21 ReverseSlider,
22 LineEdit,
23 MaxEnum,
24};
25
26class Widget : public QWidget {
27 Q_OBJECT
28
29public:
30 Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
31 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs,
32 RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f,
33 const std::string& text_box_default = "");
34 virtual ~Widget();
35
36 bool Valid();
37
38 QPushButton* restore_button{};
39 QLineEdit* line_edit{};
40 QCheckBox* checkbox{};
41 QSlider* slider{};
42 QComboBox* combobox{};
43
44private:
45 void CreateCheckBox(const QString& label, std::function<void()>& load_func);
46 void CreateCheckBoxWithLineEdit(const QString& label, const std::string& text_box_default,
47 std::function<void()>& load_func);
48 void CreateCheckBoxWithSpinBox(const QString& label, const std::string& text_box_default,
49 std::function<void()>& load_func);
50 void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func);
51 void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func);
52 void CreateSlider(const QString& label, bool reversed, float multiplier,
53 std::function<void()>& load_func);
54
55 void CreateRestoreGlobalButton();
56
57 QWidget* parent;
58 const TranslationMap& translations;
59 Settings::BasicSetting& setting;
60
61 bool created{false};
62};
63
64} // namespace ConfigurationShared