summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar lat9nq2023-06-09 16:53:26 -0400
committerGravatar lat9nq2023-07-21 10:56:07 -0400
commit4ff8255e4a985e69046e453a9bd38adf80346548 (patch)
tree9d665f43b79639047e11dfda63f4036885619204 /src
parentsettings, uisettings: Initialize linkage counter (diff)
downloadyuzu-4ff8255e4a985e69046e453a9bd38adf80346548.tar.gz
yuzu-4ff8255e4a985e69046e453a9bd38adf80346548.tar.xz
yuzu-4ff8255e4a985e69046e453a9bd38adf80346548.zip
shared_widget: Refactor helpers
Makes checkbox creation an option as opposed to a label.
Diffstat (limited to 'src')
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp9
-rw-r--r--src/yuzu/configuration/configure_graphics.h4
-rw-r--r--src/yuzu/configuration/configure_system.cpp23
-rw-r--r--src/yuzu/configuration/shared_translation.cpp8
-rw-r--r--src/yuzu/configuration/shared_widget.cpp395
-rw-r--r--src/yuzu/configuration/shared_widget.h35
6 files changed, 254 insertions, 220 deletions
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 977aed42d..2354323b8 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -165,6 +165,11 @@ void ConfigureGraphics::PopulateVSyncModeSelection() {
165 : vsync_mode_combobox_enum_map[current_index]; 165 : vsync_mode_combobox_enum_map[current_index];
166 int index{}; 166 int index{};
167 const int device{vulkan_device_combobox->currentIndex()}; //< current selected Vulkan device 167 const int device{vulkan_device_combobox->currentIndex()}; //< current selected Vulkan device
168 if (device == -1) {
169 // Invalid device
170 return;
171 }
172
168 const auto& present_modes = //< relevant vector of present modes for the selected device or API 173 const auto& present_modes = //< relevant vector of present modes for the selected device or API
169 backend == Settings::RendererBackend::Vulkan ? device_present_modes[device] 174 backend == Settings::RendererBackend::Vulkan ? device_present_modes[device]
170 : default_present_modes; 175 : default_present_modes;
@@ -236,11 +241,11 @@ void ConfigureGraphics::Setup() {
236 return new ConfigurationShared::Widget( 241 return new ConfigurationShared::Widget(
237 setting, translations, this, runtime_lock, apply_funcs, 242 setting, translations, this, runtime_lock, apply_funcs,
238 ConfigurationShared::RequestType::ReverseSlider, true, 0.5f); 243 ConfigurationShared::RequestType::ReverseSlider, true, 0.5f);
239 } else if (setting->Id() == Settings::values.use_speed_limit.Id()) { 244 } else if (setting->Id() == Settings::values.speed_limit.Id()) {
240 return new ConfigurationShared::Widget( 245 return new ConfigurationShared::Widget(
241 setting, translations, this, runtime_lock, apply_funcs, 246 setting, translations, this, runtime_lock, apply_funcs,
242 ConfigurationShared::RequestType::SpinBox, true, 1.0f, 247 ConfigurationShared::RequestType::SpinBox, true, 1.0f,
243 &Settings::values.speed_limit, "%"); 248 &Settings::values.use_speed_limit, "%");
244 } else { 249 } else {
245 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, 250 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
246 apply_funcs); 251 apply_funcs);
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index 61eb2f2fc..f36495ed3 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -77,8 +77,8 @@ private:
77 std::vector<QString> vulkan_devices; 77 std::vector<QString> vulkan_devices;
78 std::vector<std::vector<VkPresentModeKHR>> device_present_modes; 78 std::vector<std::vector<VkPresentModeKHR>> device_present_modes;
79 std::vector<VkPresentModeKHR> 79 std::vector<VkPresentModeKHR>
80 vsync_mode_combobox_enum_map; //< Keeps track of which present mode corresponds to which 80 vsync_mode_combobox_enum_map{}; //< Keeps track of which present mode corresponds to which
81 // selection in the combobox 81 // selection in the combobox
82 u32 vulkan_device{}; 82 u32 vulkan_device{};
83 Settings::ShaderBackend shader_backend{}; 83 Settings::ShaderBackend shader_backend{};
84 const std::function<void()>& expose_compute_option; 84 const std::function<void()>& expose_compute_option;
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index dedbad57f..128860800 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -117,17 +117,18 @@ void ConfigureSystem::Setup() {
117 push(Settings::values.linkage.by_category[Settings::Category::System]); 117 push(Settings::values.linkage.by_category[Settings::Category::System]);
118 118
119 for (auto setting : settings) { 119 for (auto setting : settings) {
120 [[maybe_unused]] std::string label = setting->GetLabel();
120 ConfigurationShared::Widget* widget = [=]() { 121 ConfigurationShared::Widget* widget = [=]() {
121 if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) { 122 if (setting->Id() == Settings::values.custom_rtc.Id()) {
122 return new ConfigurationShared::Widget( 123 return new ConfigurationShared::Widget(
123 setting, translations, this, runtime_lock, apply_funcs, 124 setting, translations, this, runtime_lock, apply_funcs,
124 ConfigurationShared::RequestType::DateTimeEdit, true, 1.0f, 125 ConfigurationShared::RequestType::DateTimeEdit, true, 1.0f,
125 &Settings::values.custom_rtc); 126 &Settings::values.custom_rtc_enabled);
126 } else if (setting->Id() == Settings::values.rng_seed_enabled.Id()) { 127 } else if (setting->Id() == Settings::values.rng_seed.Id()) {
127 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, 128 return new ConfigurationShared::Widget(
128 apply_funcs, 129 setting, translations, this, runtime_lock, apply_funcs,
129 ConfigurationShared::RequestType::HexEdit, 130 ConfigurationShared::RequestType::HexEdit, true, 1.0f,
130 true, 1.0f, &Settings::values.rng_seed); 131 &Settings::values.rng_seed_enabled);
131 } else { 132 } else {
132 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, 133 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock,
133 134
@@ -140,14 +141,12 @@ void ConfigureSystem::Setup() {
140 continue; 141 continue;
141 } 142 }
142 143
143 if (setting->Id() == Settings::values.rng_seed_enabled.Id()) { 144 if (setting->Id() == Settings::values.rng_seed.Id()) {
144 rng_seed_checkbox = widget->checkbox; 145 rng_seed_checkbox = widget->checkbox;
145 rng_seed_edit = widget->line_edit; 146 rng_seed_edit = widget->line_edit;
146 147
147 if (!Settings::values.rng_seed_enabled.GetValue()) { 148 rng_seed_edit->setEnabled(Settings::values.rng_seed_enabled.GetValue());
148 rng_seed_edit->setEnabled(false); 149 } else if (setting->Id() == Settings::values.custom_rtc.Id()) {
149 }
150 } else if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) {
151 custom_rtc_checkbox = widget->checkbox; 150 custom_rtc_checkbox = widget->checkbox;
152 custom_rtc_edit = widget->date_time_edit; 151 custom_rtc_edit = widget->date_time_edit;
153 152
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index dc9f15cdd..6038e8c25 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -108,11 +108,11 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
108 INSERT(Settings, speed_limit, "Limit Speed Percent", ""); 108 INSERT(Settings, speed_limit, "Limit Speed Percent", "");
109 109
110 // System 110 // System
111 INSERT(Settings, rng_seed_enabled, "RNG Seed", ""); 111 INSERT(Settings, rng_seed, "RNG Seed", "");
112 INSERT(Settings, rng_seed, "", ""); 112 INSERT(Settings, rng_seed_enabled, "", "");
113 INSERT(Settings, device_name, "Device Name", ""); 113 INSERT(Settings, device_name, "Device Name", "");
114 INSERT(Settings, custom_rtc_enabled, "Custom RTC", ""); 114 INSERT(Settings, custom_rtc, "Custom RTC", "");
115 INSERT(Settings, custom_rtc, "", ""); 115 INSERT(Settings, custom_rtc_enabled, "", "");
116 INSERT(Settings, language_index, "Language:", ""); 116 INSERT(Settings, language_index, "Language:", "");
117 INSERT(Settings, region_index, "Region:", ""); 117 INSERT(Settings, region_index, "Region:", "");
118 INSERT(Settings, time_zone_index, "Time Zone:", ""); 118 INSERT(Settings, time_zone_index, "Time Zone:", "");
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp
index 0d553c67f..3ef2c25c6 100644
--- a/src/yuzu/configuration/shared_widget.cpp
+++ b/src/yuzu/configuration/shared_widget.cpp
@@ -12,7 +12,9 @@
12#include <QWidget> 12#include <QWidget>
13#include <qabstractbutton.h> 13#include <qabstractbutton.h>
14#include <qabstractspinbox.h> 14#include <qabstractspinbox.h>
15#include <qboxlayout.h>
15#include <qnamespace.h> 16#include <qnamespace.h>
17#include <qpushbutton.h>
16#include <qvalidator.h> 18#include <qvalidator.h>
17#include "common/common_types.h" 19#include "common/common_types.h"
18#include "common/settings.h" 20#include "common/settings.h"
@@ -22,10 +24,6 @@
22 24
23namespace ConfigurationShared { 25namespace ConfigurationShared {
24 26
25static bool IsInt(const std::type_index& type) {
26 return type == typeid(u32) || type == typeid(s32) || type == typeid(u16) || type == typeid(s16);
27}
28
29QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting, QWidget* parent) { 27QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting, QWidget* parent) {
30 QStyle* style = parent->style(); 28 QStyle* style = parent->style();
31 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); 29 QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton));
@@ -42,50 +40,65 @@ QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting,
42 return restore_button; 40 return restore_button;
43} 41}
44 42
45void Widget::CreateCheckBox(const QString& label, std::function<void()>& load_func) { 43QLabel* Widget::CreateLabel(const QString& text) {
44 QLabel* qt_label = new QLabel(text, this->parent);
45 qt_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
46 return qt_label;
47}
48
49QHBoxLayout* Widget::CreateCheckBox(Settings::BasicSetting* bool_setting, const QString& label,
50 std::function<void()>& load_func, bool managed) {
46 created = true; 51 created = true;
47 52
48 QHBoxLayout* layout = new QHBoxLayout(this); 53 QHBoxLayout* layout = new QHBoxLayout(this);
49 54
50 checkbox = new QCheckBox(label, this); 55 checkbox = new QCheckBox(label, this);
51 checkbox->setObjectName(QString::fromStdString(setting.GetLabel())); 56 checkbox->setCheckState(bool_setting->ToString() == "true" ? Qt::CheckState::Checked
52 checkbox->setCheckState(setting.ToString() == "true" ? Qt::CheckState::Checked 57 : Qt::CheckState::Unchecked);
53 : Qt::CheckState::Unchecked); 58 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
54 59
55 layout->addWidget(checkbox); 60 layout->addWidget(checkbox);
61
62 layout->setContentsMargins(0, 0, 0, 0);
63
64 if (!managed) {
65 return layout;
66 }
67
56 if (Settings::IsConfiguringGlobal()) { 68 if (Settings::IsConfiguringGlobal()) {
57 load_func = [=]() { 69 load_func = [=]() {
58 setting.LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); 70 bool_setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
59 }; 71 };
60 } else { 72 } else {
61 restore_button = CreateRestoreGlobalButton(setting, this); 73 restore_button = CreateRestoreGlobalButton(*bool_setting, this);
62 layout->addWidget(restore_button); 74 layout->addWidget(restore_button);
63 75
64 QObject::connect(checkbox, &QCheckBox::stateChanged, [&](int) { 76 QObject::connect(checkbox, &QCheckBox::stateChanged, [=](int) {
65 restore_button->setVisible(true); 77 restore_button->setVisible(true);
66 restore_button->setEnabled(true); 78 restore_button->setEnabled(true);
67 }); 79 });
68 80
69 QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) { 81 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
70 checkbox->setCheckState(setting.ToStringGlobal() == "true" ? Qt::Checked 82 checkbox->setCheckState(bool_setting->ToStringGlobal() == "true" ? Qt::Checked
71 : Qt::Unchecked); 83 : Qt::Unchecked);
72 restore_button->setEnabled(false); 84 restore_button->setEnabled(false);
73 restore_button->setVisible(false); 85 restore_button->setVisible(false);
74 }); 86 });
75 87
76 load_func = [=]() { 88 load_func = [=]() {
77 bool using_global = !restore_button->isEnabled(); 89 bool using_global = !restore_button->isEnabled();
78 setting.SetGlobal(using_global); 90 bool_setting->SetGlobal(using_global);
79 if (!using_global) { 91 if (!using_global) {
80 setting.LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); 92 bool_setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
81 } 93 }
82 }; 94 };
83 } 95 }
84 96
85 layout->setContentsMargins(0, 0, 0, 0); 97 return layout;
86} 98}
87 99
88void Widget::CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func) { 100void Widget::CreateCombobox(const QString& label, std::function<void()>& load_func, bool managed,
101 Settings::BasicSetting* const other_setting) {
89 created = true; 102 created = true;
90 103
91 const auto type = setting.TypeId(); 104 const auto type = setting.TypeId();
@@ -108,9 +121,13 @@ void Widget::CreateCombobox(const QString& label, bool managed, std::function<vo
108 121
109 combobox->setCurrentIndex(std::stoi(setting.ToString())); 122 combobox->setCurrentIndex(std::stoi(setting.ToString()));
110 123
111 if (Settings::IsConfiguringGlobal() && managed) { 124 if (!managed) {
125 return;
126 }
127
128 if (Settings::IsConfiguringGlobal()) {
112 load_func = [=]() { setting.LoadString(std::to_string(combobox->currentIndex())); }; 129 load_func = [=]() { setting.LoadString(std::to_string(combobox->currentIndex())); };
113 } else if (managed) { 130 } else {
114 restore_button = CreateRestoreGlobalButton(setting, this); 131 restore_button = CreateRestoreGlobalButton(setting, this);
115 layout->addWidget(restore_button); 132 layout->addWidget(restore_button);
116 133
@@ -136,30 +153,50 @@ void Widget::CreateCombobox(const QString& label, bool managed, std::function<vo
136 } 153 }
137} 154}
138 155
139void Widget::CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func) { 156void Widget::CreateLineEdit(const QString& label, std::function<void()>& load_func, bool managed,
157 Settings::BasicSetting* other_setting) {
158 const bool has_checkbox = other_setting != nullptr;
159 if (has_checkbox && other_setting->TypeId() != typeid(bool)) {
160 LOG_WARNING(Frontend, "Extra setting requested but setting is not boolean");
161 return;
162 }
163
140 created = true; 164 created = true;
141 165
142 QHBoxLayout* layout = new QHBoxLayout(this); 166 QHBoxLayout* layout{nullptr};
143 line_edit = new QLineEdit(this); 167 std::function<void()> checkbox_load_func = []() {};
168
169 if (has_checkbox) {
170 layout = CreateCheckBox(other_setting, label, checkbox_load_func, managed);
171 } else {
172 layout = new QHBoxLayout(this);
173 layout->setContentsMargins(0, 0, 0, 0);
174 QLabel* q_label = CreateLabel(label);
175 layout->addWidget(q_label);
176 }
144 177
145 const QString text = QString::fromStdString(setting.ToString()); 178 const QString text = QString::fromStdString(setting.ToString());
179 line_edit = new QLineEdit(this);
146 line_edit->setText(text); 180 line_edit->setText(text);
147 181
148 QLabel* q_label = new QLabel(label, this);
149 // setSizePolicy lets widget expand and take an equal part of the space as the line edit
150 q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
151 layout->addWidget(q_label);
152
153 layout->addWidget(line_edit); 182 layout->addWidget(line_edit);
154 183
155 if (Settings::IsConfiguringGlobal() && !managed) { 184 if (!managed) {
185 return;
186 }
187
188 if (Settings::IsConfiguringGlobal()) {
156 load_func = [=]() { 189 load_func = [=]() {
190 checkbox_load_func();
191
157 std::string load_text = line_edit->text().toStdString(); 192 std::string load_text = line_edit->text().toStdString();
158 setting.LoadString(load_text); 193 setting.LoadString(load_text);
159 }; 194 };
160 } else if (!managed) { 195 } else {
161 restore_button = CreateRestoreGlobalButton(setting, this); 196 if (!has_checkbox) {
162 layout->addWidget(restore_button); 197 restore_button = CreateRestoreGlobalButton(setting, this);
198 layout->addWidget(restore_button);
199 }
163 200
164 QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) { 201 QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) {
165 restore_button->setEnabled(false); 202 restore_button->setEnabled(false);
@@ -174,6 +211,8 @@ void Widget::CreateLineEdit(const QString& label, bool managed, std::function<vo
174 }); 211 });
175 212
176 load_func = [=]() { 213 load_func = [=]() {
214 checkbox_load_func();
215
177 bool using_global = !restore_button->isEnabled(); 216 bool using_global = !restore_button->isEnabled();
178 setting.SetGlobal(using_global); 217 setting.SetGlobal(using_global);
179 if (!using_global) { 218 if (!using_global) {
@@ -181,24 +220,23 @@ void Widget::CreateLineEdit(const QString& label, bool managed, std::function<vo
181 } 220 }
182 }; 221 };
183 } 222 }
184
185 layout->setContentsMargins(0, 0, 0, 0);
186} 223}
187 224
188void Widget::CreateSlider(const QString& name, bool reversed, float multiplier, 225void Widget::CreateSlider(const QString& label, bool reversed, float multiplier,
189 std::function<void()>& load_func) { 226 std::function<void()>& load_func, bool managed,
227 Settings::BasicSetting* const other_setting) {
190 created = true; 228 created = true;
191 229
192 QHBoxLayout* layout = new QHBoxLayout(this); 230 QHBoxLayout* layout = new QHBoxLayout(this);
193 slider = new QSlider(Qt::Horizontal, this); 231 slider = new QSlider(Qt::Horizontal, this);
194 QLabel* label = new QLabel(name, this); 232 QLabel* qt_label = new QLabel(label, this);
195 QLabel* feedback = new QLabel(this); 233 QLabel* feedback = new QLabel(this);
196 234
197 layout->addWidget(label); 235 layout->addWidget(qt_label);
198 layout->addWidget(slider); 236 layout->addWidget(slider);
199 layout->addWidget(feedback); 237 layout->addWidget(feedback);
200 238
201 label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 239 qt_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
202 240
203 layout->setContentsMargins(0, 0, 0, 0); 241 layout->setContentsMargins(0, 0, 0, 0);
204 242
@@ -214,8 +252,10 @@ void Widget::CreateSlider(const QString& name, bool reversed, float multiplier,
214 slider->setMinimum(std::stoi(setting.MinVal())); 252 slider->setMinimum(std::stoi(setting.MinVal()));
215 slider->setMaximum(max_val); 253 slider->setMaximum(max_val);
216 254
217 if (reversed) { 255 slider->setInvertedAppearance(reversed);
218 slider->setInvertedAppearance(true); 256
257 if (!managed) {
258 return;
219 } 259 }
220 260
221 if (Settings::IsConfiguringGlobal()) { 261 if (Settings::IsConfiguringGlobal()) {
@@ -246,51 +286,54 @@ void Widget::CreateSlider(const QString& name, bool reversed, float multiplier,
246 } 286 }
247} 287}
248 288
249void Widget::CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting, 289void Widget::CreateSpinBox(const QString& label, std::function<void()>& load_func, bool managed,
250 std::function<void()>& load_func) { 290 const std::string& suffix, Settings::BasicSetting* other_setting) {
251 if (other_setting == nullptr) { 291 const bool has_checkbox = other_setting != nullptr;
252 LOG_WARNING(Frontend, "Extra setting is null or not an integer"); 292 if (has_checkbox && other_setting->TypeId() != typeid(bool)) {
293 LOG_WARNING(Frontend, "Extra setting requested but setting is not boolean");
253 return; 294 return;
254 } 295 }
255 created = true; 296 created = true;
256 297
257 std::function<void()> checkbox_load_func; 298 QHBoxLayout* layout{nullptr};
258 CreateCheckBox(label, checkbox_load_func); 299 std::function<void()> checkbox_load_func = []() {};
259 300 QLabel* q_label{nullptr};
260 auto to_hex = [=](const std::string& input) {
261 return QString::fromStdString(fmt::format("{:08x}", std::stoi(input)));
262 };
263
264 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
265 const QString default_val = to_hex(other_setting->ToString());
266 301
267 line_edit = new QLineEdit(this); 302 if (has_checkbox) {
268 line_edit->setText(default_val); 303 layout = CreateCheckBox(other_setting, label, checkbox_load_func, managed);
269 304 } else {
270 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 305 layout = new QHBoxLayout(this);
306 layout->setContentsMargins(0, 0, 0, 0);
307 q_label = CreateLabel(label);
308 layout->addWidget(q_label);
309 }
271 310
272 layout->insertWidget(1, line_edit); 311 const int min_val = std::stoi(setting.MinVal());
312 const int max_val = std::stoi(setting.MaxVal());
313 const int default_val = std::stoi(setting.ToString());
273 314
274 line_edit->setMaxLength(8); 315 spinbox = new QSpinBox(this);
275 QRegExpValidator* regex = 316 spinbox->setRange(min_val, max_val);
276 new QRegExpValidator{QRegExp{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit}; 317 spinbox->setValue(default_val);
277 line_edit->setValidator(regex); 318 spinbox->setSuffix(QString::fromStdString(suffix));
319 spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
278 320
279 auto hex_to_dec = [=]() -> std::string { 321 layout->insertWidget(1, spinbox);
280 return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16));
281 };
282 322
283 if (Settings::IsConfiguringGlobal()) { 323 if (Settings::IsConfiguringGlobal()) {
284 load_func = [=]() { 324 load_func = [=]() {
285 checkbox_load_func(); 325 checkbox_load_func();
286 other_setting->LoadString(hex_to_dec()); 326 setting.LoadString(std::to_string(spinbox->value()));
287 }; 327 };
288 } else { 328 } else {
289 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { 329 if (!has_checkbox) {
290 line_edit->setText(to_hex(other_setting->ToStringGlobal())); 330 restore_button = CreateRestoreGlobalButton(setting, this);
291 }); 331 }
332
333 QObject::connect(restore_button, &QAbstractButton::clicked,
334 [this](bool) { spinbox->setValue(std::stoi(setting.ToStringGlobal())); });
292 335
293 QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { 336 QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this](int) {
294 restore_button->setEnabled(true); 337 restore_button->setEnabled(true);
295 restore_button->setVisible(true); 338 restore_button->setVisible(true);
296 }); 339 });
@@ -299,148 +342,122 @@ void Widget::CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSett
299 checkbox_load_func(); 342 checkbox_load_func();
300 343
301 const bool using_global = !restore_button->isEnabled(); 344 const bool using_global = !restore_button->isEnabled();
302 other_setting->SetGlobal(using_global); 345 setting.SetGlobal(using_global);
303 if (!using_global) { 346 if (!using_global) {
304 other_setting->LoadString(hex_to_dec()); 347 setting.LoadString(std::to_string(spinbox->value()));
305 } 348 }
306 }; 349 };
307 } 350 }
308} 351}
309 352
310void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, 353void Widget::CreateHexEdit(const QString& label, std::function<void()>& load_func, bool managed,
311 std::function<void()>& load_func) { 354 Settings::BasicSetting* const other_setting) {
312 if (other_setting == nullptr) { 355 CreateLineEdit(label, load_func, false, other_setting);
313 LOG_WARNING(Frontend, "Extra setting is null or not an integer"); 356 if (!created || !managed) {
314 return; 357 return;
315 } 358 }
316 created = true;
317 359
318 std::function<void()> checkbox_load_func; 360 QLayout* layout = this->layout();
319 CreateCheckBox(label, checkbox_load_func); 361
362 auto to_hex = [=](const std::string& input) {
363 return QString::fromStdString(fmt::format("{:08x}", std::stoi(input)));
364 };
365
366 QRegExpValidator* regex =
367 new QRegExpValidator{QRegExp{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit};
320 368
321 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout()); 369 const QString default_val = to_hex(setting.ToString());
322 const QString default_val = QString::fromStdString(other_setting->ToString());
323 370
324 line_edit = new QLineEdit(this);
325 line_edit->setText(default_val); 371 line_edit->setText(default_val);
372 line_edit->setMaxLength(8);
373 line_edit->setValidator(regex);
326 374
327 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 375 auto hex_to_dec = [=]() -> std::string {
328 376 return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16));
329 layout->insertWidget(1, line_edit); 377 };
330 378
331 if (Settings::IsConfiguringGlobal()) { 379 if (Settings::IsConfiguringGlobal()) {
332 load_func = [=]() { 380 load_func = [=]() {
333 checkbox_load_func(); 381 other_setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
334 other_setting->LoadString(line_edit->text().toStdString()); 382 setting.LoadString(hex_to_dec());
335 }; 383 };
336 } else { 384 } else {
385 restore_button = CreateRestoreGlobalButton(setting, this);
386 layout->addWidget(restore_button);
387
337 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { 388 QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) {
338 line_edit->setText(QString::fromStdString(other_setting->ToStringGlobal())); 389 line_edit->setText(to_hex(setting.ToStringGlobal()));
390 checkbox->setCheckState(other_setting->ToStringGlobal() == "true" ? Qt::Checked
391 : Qt::Unchecked);
392
393 restore_button->setEnabled(false);
394 restore_button->setVisible(false);
339 }); 395 });
340 396
341 QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { 397 QObject::connect(line_edit, &QLineEdit::textEdited, [&]() {
342 restore_button->setEnabled(true); 398 restore_button->setEnabled(true);
343 restore_button->setVisible(true); 399 restore_button->setVisible(true);
344 }); 400 });
345 401
346 load_func = [=]() { 402 QObject::connect(checkbox, &QAbstractButton::clicked, [&]() {
347 checkbox_load_func();
348
349 const bool using_global = !restore_button->isEnabled();
350 other_setting->SetGlobal(using_global);
351 if (!using_global) {
352 other_setting->LoadString(line_edit->text().toStdString());
353 }
354 };
355 }
356}
357
358void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting,
359 std::function<void()>& load_func,
360 const std::string& suffix) {
361 if (other_setting == nullptr && IsInt(other_setting->TypeId())) {
362 LOG_WARNING(Frontend, "Extra setting is null or not an integer");
363 return;
364 }
365 created = true;
366
367 std::function<void()> checkbox_load_func;
368 CreateCheckBox(label, checkbox_load_func);
369 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
370
371 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout());
372
373 spinbox = new QSpinBox(this);
374 const int min_val = std::stoi(other_setting->MinVal());
375 const int max_val = std::stoi(other_setting->MaxVal());
376 const int default_val = std::stoi(other_setting->ToString());
377 spinbox->setRange(min_val, max_val);
378 spinbox->setValue(default_val);
379 spinbox->setSuffix(QString::fromStdString(suffix));
380 spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
381
382 layout->insertWidget(1, spinbox);
383
384 if (Settings::IsConfiguringGlobal()) {
385 load_func = [=]() {
386 checkbox_load_func();
387 other_setting->LoadString(std::to_string(spinbox->value()));
388 };
389 } else {
390 QObject::connect(restore_button, &QAbstractButton::clicked, [this, other_setting](bool) {
391 spinbox->setValue(std::stoi(other_setting->ToStringGlobal()));
392 });
393
394 QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this](int) {
395 restore_button->setEnabled(true); 403 restore_button->setEnabled(true);
396 restore_button->setVisible(true); 404 restore_button->setVisible(true);
397 }); 405 });
398 406
399 load_func = [=]() { 407 load_func = [=]() {
400 checkbox_load_func();
401
402 const bool using_global = !restore_button->isEnabled(); 408 const bool using_global = !restore_button->isEnabled();
403 other_setting->SetGlobal(using_global); 409 other_setting->SetGlobal(using_global);
410 setting.SetGlobal(using_global);
411
404 if (!using_global) { 412 if (!using_global) {
405 other_setting->LoadString(std::to_string(spinbox->value())); 413 other_setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
414 setting.LoadString(hex_to_dec());
406 } 415 }
407 }; 416 };
408 } 417 }
409} 418}
410 419
411// Currently tailored to custom_rtc 420void Widget::CreateDateTimeEdit(const QString& label, std::function<void()>& load_func,
412void Widget::CreateCheckBoxWithDateTimeEdit(const QString& label, 421 bool managed, bool restrict,
413 Settings::BasicSetting* other_setting, 422 Settings::BasicSetting* const other_setting) {
414 std::function<void()>& load_func) { 423 const bool has_checkbox = other_setting != nullptr;
415 if (other_setting == nullptr) { 424 if ((restrict && !has_checkbox) || (has_checkbox && other_setting->TypeId() != typeid(bool))) {
416 LOG_WARNING(Frontend, "Extra setting is null or not an integer"); 425 LOG_WARNING(Frontend, "Extra setting or restrict requested but is not boolean");
417 return; 426 return;
418 } 427 }
419 created = true; 428 created = true;
420 429
421 std::function<void()> checkbox_load_func; 430 QHBoxLayout* layout{nullptr};
422 CreateCheckBox(label, checkbox_load_func); 431 std::function<void()> checkbox_load_func = []() {};
432
433 if (has_checkbox) {
434 layout = CreateCheckBox(other_setting, label, checkbox_load_func, managed);
435 } else {
436 layout = new QHBoxLayout(this);
437 QLabel* q_label = CreateLabel(label);
438 layout->addWidget(q_label);
439 }
423 440
424 QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout()); 441 const bool disabled = other_setting->ToString() != "true";
425 const bool disabled = setting.ToString() != "true";
426 const long long current_time = QDateTime::currentSecsSinceEpoch(); 442 const long long current_time = QDateTime::currentSecsSinceEpoch();
427 const s64 the_time = disabled ? current_time : std::stoll(other_setting->ToString()); 443 const s64 the_time = disabled ? current_time : std::stoll(setting.ToString());
428 const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); 444 const auto default_val = QDateTime::fromSecsSinceEpoch(the_time);
429 445
430 date_time_edit = new QDateTimeEdit(this); 446 date_time_edit = new QDateTimeEdit(this);
431 date_time_edit->setDateTime(default_val); 447 date_time_edit->setDateTime(default_val);
432
433 date_time_edit->setMinimumDateTime(QDateTime::fromSecsSinceEpoch(0)); 448 date_time_edit->setMinimumDateTime(QDateTime::fromSecsSinceEpoch(0));
434
435 date_time_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 449 date_time_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
436 checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
437 450
438 layout->insertWidget(1, date_time_edit); 451 layout->insertWidget(1, date_time_edit);
439 452
453 if (!managed) {
454 return;
455 }
456
440 if (Settings::IsConfiguringGlobal()) { 457 if (Settings::IsConfiguringGlobal()) {
441 load_func = [=]() { 458 load_func = [=]() {
442 checkbox_load_func(); 459 checkbox_load_func();
443 if (checkbox->checkState() == Qt::Unchecked) { 460 if (restrict && checkbox->checkState() == Qt::Unchecked) {
444 return; 461 return;
445 } 462 }
446 463
@@ -448,9 +465,14 @@ void Widget::CreateCheckBoxWithDateTimeEdit(const QString& label,
448 std::to_string(date_time_edit->dateTime().toSecsSinceEpoch())); 465 std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()));
449 }; 466 };
450 } else { 467 } else {
468 if (!has_checkbox) {
469 restore_button = CreateRestoreGlobalButton(setting, this);
470 layout->addWidget(restore_button);
471 }
472
451 auto get_clear_val = [=]() { 473 auto get_clear_val = [=]() {
452 return QDateTime::fromSecsSinceEpoch([=]() { 474 return QDateTime::fromSecsSinceEpoch([=]() {
453 if (checkbox->checkState() == Qt::Checked) { 475 if (restrict && checkbox->checkState() == Qt::Checked) {
454 return std::stoll(other_setting->ToStringGlobal()); 476 return std::stoll(other_setting->ToStringGlobal());
455 } 477 }
456 return current_time; 478 return current_time;
@@ -469,7 +491,7 @@ void Widget::CreateCheckBoxWithDateTimeEdit(const QString& label,
469 491
470 load_func = [=]() { 492 load_func = [=]() {
471 checkbox_load_func(); 493 checkbox_load_func();
472 if (checkbox->checkState() == Qt::Unchecked) { 494 if (restrict && checkbox->checkState() == Qt::Unchecked) {
473 return; 495 return;
474 } 496 }
475 497
@@ -490,11 +512,17 @@ bool Widget::Valid() {
490Widget::~Widget() = default; 512Widget::~Widget() = default;
491 513
492Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_, 514Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_,
515 QWidget* parent_, std::forward_list<std::function<void(bool)>>& apply_funcs_)
516 : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_},
517 apply_funcs{apply_funcs_} {}
518
519Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_,
493 QWidget* parent_, bool runtime_lock, 520 QWidget* parent_, bool runtime_lock,
494 std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request, 521 std::forward_list<std::function<void(bool)>>& apply_funcs_, RequestType request,
495 bool managed, float multiplier, Settings::BasicSetting* other_setting, 522 bool managed, float multiplier, Settings::BasicSetting* other_setting,
496 const std::string& string) 523 const std::string& string)
497 : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} { 524 : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_},
525 apply_funcs{apply_funcs_} {
498 if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) { 526 if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) {
499 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel()); 527 LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel());
500 return; 528 return;
@@ -523,51 +551,44 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati
523 if (type == typeid(bool)) { 551 if (type == typeid(bool)) {
524 switch (request) { 552 switch (request) {
525 case RequestType::Default: 553 case RequestType::Default:
526 CreateCheckBox(label, load_func); 554 CreateCheckBox(&setting, label, load_func, managed);
527 break; 555 break;
528 case RequestType::SpinBox: 556 default:
529 CreateCheckBoxWithSpinBox(label, other_setting, load_func, string); 557 LOG_WARNING(Frontend, "Requested widget is unimplemented.");
530 break;
531 case RequestType::HexEdit:
532 CreateCheckBoxWithHexEdit(label, other_setting, load_func);
533 break;
534 case RequestType::LineEdit:
535 CreateCheckBoxWithLineEdit(label, other_setting, load_func);
536 break;
537 case RequestType::DateTimeEdit:
538 CreateCheckBoxWithDateTimeEdit(label, other_setting, load_func);
539 break;
540 case RequestType::ComboBox:
541 case RequestType::Slider:
542 case RequestType::ReverseSlider:
543 case RequestType::MaxEnum:
544 LOG_DEBUG(Frontend, "Requested widget is unimplemented.");
545 break; 558 break;
546 } 559 }
547 } else if (setting.IsEnum()) { 560 } else if (setting.IsEnum()) {
548 CreateCombobox(label, managed, load_func); 561 CreateCombobox(label, load_func, managed);
549 } else if (type == typeid(u32) || type == typeid(int)) { 562 } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) ||
563 type == typeid(s64)) {
550 switch (request) { 564 switch (request) {
551 case RequestType::Slider: 565 case RequestType::Slider:
552 case RequestType::ReverseSlider: 566 case RequestType::ReverseSlider:
553 CreateSlider(label, request == RequestType::ReverseSlider, multiplier, load_func); 567 CreateSlider(label, request == RequestType::ReverseSlider, multiplier, load_func,
568 managed);
554 break; 569 break;
555 case RequestType::LineEdit: 570 case RequestType::LineEdit:
556 case RequestType::Default: 571 case RequestType::Default:
557 CreateLineEdit(label, managed, load_func); 572 CreateLineEdit(label, load_func, managed);
558 break; 573 break;
559 case RequestType::ComboBox: 574 case RequestType::ComboBox:
560 CreateCombobox(label, managed, load_func); 575 CreateCombobox(label, load_func, managed);
561 break; 576 break;
562 case RequestType::DateTimeEdit: 577 case RequestType::DateTimeEdit:
578 CreateDateTimeEdit(label, load_func, managed, true, other_setting);
579 break;
563 case RequestType::SpinBox: 580 case RequestType::SpinBox:
581 CreateSpinBox(label, load_func, managed, string, other_setting);
582 break;
564 case RequestType::HexEdit: 583 case RequestType::HexEdit:
565 case RequestType::MaxEnum: 584 CreateHexEdit(label, load_func, managed, other_setting);
566 LOG_DEBUG(Frontend, "Requested widget is unimplemented."); 585 break;
586 default:
587 LOG_WARNING(Frontend, "Requested widget is unimplemented.");
567 break; 588 break;
568 } 589 }
569 } else if (type == typeid(std::string)) { 590 } else if (type == typeid(std::string)) {
570 CreateLineEdit(label, managed, load_func); 591 CreateLineEdit(label, load_func, managed);
571 } 592 }
572 593
573 if (!created) { 594 if (!created) {
diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h
index 9923aa2ea..c4e686574 100644
--- a/src/yuzu/configuration/shared_widget.h
+++ b/src/yuzu/configuration/shared_widget.h
@@ -9,6 +9,8 @@ class QComboBox;
9class QLineEdit; 9class QLineEdit;
10class QSlider; 10class QSlider;
11class QCheckBox; 11class QCheckBox;
12class QLabel;
13class QHBoxLayout;
12class QDateTimeEdit; 14class QDateTimeEdit;
13 15
14namespace Settings { 16namespace Settings {
@@ -34,9 +36,11 @@ class Widget : public QWidget {
34 36
35public: 37public:
36 Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, 38 Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent,
37 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs, 39 bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs_,
38 RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, 40 RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f,
39 Settings::BasicSetting* other_setting = nullptr, const std::string& format = ""); 41 Settings::BasicSetting* other_setting = nullptr, const std::string& format = "");
42 Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_, QWidget* parent_,
43 std::forward_list<std::function<void(bool)>>& apply_funcs_);
40 virtual ~Widget(); 44 virtual ~Widget();
41 45
42 bool Valid(); 46 bool Valid();
@@ -53,23 +57,28 @@ public:
53 QDateTimeEdit* date_time_edit{}; 57 QDateTimeEdit* date_time_edit{};
54 58
55private: 59private:
56 void CreateCheckBox(const QString& label, std::function<void()>& load_func); 60 QLabel* CreateLabel(const QString& text);
57 void CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, 61 QHBoxLayout* CreateCheckBox(Settings::BasicSetting* bool_setting, const QString& label,
58 std::function<void()>& load_func); 62 std::function<void()>& load_func, bool managed);
59 void CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting, 63
60 std::function<void()>& load_func); 64 void CreateCombobox(const QString& label, std::function<void()>& load_func, bool managed,
61 void CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, 65 Settings::BasicSetting* const other_setting = nullptr);
62 std::function<void()>& load_func, const std::string& suffix); 66 void CreateLineEdit(const QString& label, std::function<void()>& load_func, bool managed,
63 void CreateCheckBoxWithDateTimeEdit(const QString& label, Settings::BasicSetting* other_setting, 67 Settings::BasicSetting* const other_setting = nullptr);
64 std::function<void()>& load_func); 68 void CreateHexEdit(const QString& label, std::function<void()>& load_func, bool managed,
65 void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func); 69 Settings::BasicSetting* const other_setting = nullptr);
66 void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func);
67 void CreateSlider(const QString& label, bool reversed, float multiplier, 70 void CreateSlider(const QString& label, bool reversed, float multiplier,
68 std::function<void()>& load_func); 71 std::function<void()>& load_func, bool managed,
72 Settings::BasicSetting* const other_setting = nullptr);
73 void CreateDateTimeEdit(const QString& label, std::function<void()>& load_func, bool managed,
74 bool restrict, Settings::BasicSetting* const other_setting = nullptr);
75 void CreateSpinBox(const QString& label, std::function<void()>& load_func, bool managed,
76 const std::string& suffix, Settings::BasicSetting* other_setting = nullptr);
69 77
70 QWidget* parent; 78 QWidget* parent;
71 const TranslationMap& translations; 79 const TranslationMap& translations;
72 Settings::BasicSetting& setting; 80 Settings::BasicSetting& setting;
81 std::forward_list<std::function<void(bool)>>& apply_funcs;
73 82
74 bool created{false}; 83 bool created{false};
75}; 84};