diff options
| -rw-r--r-- | src/yuzu/configuration/shared_widget.cpp | 157 | ||||
| -rw-r--r-- | src/yuzu/configuration/shared_widget.h | 8 |
2 files changed, 134 insertions, 31 deletions
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index d63093985..e5e071386 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp | |||
| @@ -151,7 +151,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer, | |||
| 151 | return -1; | 151 | return -1; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | const u32 setting_value = std::stoi(setting.ToString()); | 154 | const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0); |
| 155 | combobox->setCurrentIndex(find_index(setting_value)); | 155 | combobox->setCurrentIndex(find_index(setting_value)); |
| 156 | 156 | ||
| 157 | serializer = [this, enumeration]() { | 157 | serializer = [this, enumeration]() { |
| @@ -160,7 +160,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer, | |||
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | restore_func = [this, find_index]() { | 162 | restore_func = [this, find_index]() { |
| 163 | const u32 global_value = std::stoi(RelevantDefault(setting)); | 163 | const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0); |
| 164 | combobox->setCurrentIndex(find_index(global_value)); | 164 | combobox->setCurrentIndex(find_index(global_value)); |
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| @@ -209,7 +209,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer, | |||
| 209 | } | 209 | } |
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | const u32 setting_value = std::stoi(setting.ToString()); | 212 | const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0); |
| 213 | set_index(setting_value); | 213 | set_index(setting_value); |
| 214 | 214 | ||
| 215 | serializer = [get_selected]() { | 215 | serializer = [get_selected]() { |
| @@ -218,7 +218,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer, | |||
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | restore_func = [this, set_index]() { | 220 | restore_func = [this, set_index]() { |
| 221 | const u32 global_value = std::stoi(RelevantDefault(setting)); | 221 | const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0); |
| 222 | set_index(global_value); | 222 | set_index(global_value); |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
| @@ -255,6 +255,58 @@ QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer, | |||
| 255 | return line_edit; | 255 | return line_edit; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | static void CreateIntSlider(Settings::BasicSetting& setting, bool reversed, float multiplier, | ||
| 259 | QLabel* feedback, const QString& use_format, QSlider* slider, | ||
| 260 | std::function<std::string()>& serializer, | ||
| 261 | std::function<void()>& restore_func) { | ||
| 262 | int max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0); | ||
| 263 | |||
| 264 | const auto update_feedback = [=](int value) { | ||
| 265 | int present = (reversed ? max_val - value : value) * multiplier + 0.5f; | ||
| 266 | feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||
| 267 | }; | ||
| 268 | |||
| 269 | QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback); | ||
| 270 | update_feedback(std::strtol(setting.ToString().c_str(), nullptr, 0)); | ||
| 271 | |||
| 272 | slider->setMinimum(std::strtol(setting.MinVal().c_str(), nullptr, 0)); | ||
| 273 | slider->setMaximum(max_val); | ||
| 274 | slider->setValue(std::strtol(setting.ToString().c_str(), nullptr, 0)); | ||
| 275 | |||
| 276 | serializer = [slider]() { return std::to_string(slider->value()); }; | ||
| 277 | restore_func = [slider, &setting]() { | ||
| 278 | slider->setValue(std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)); | ||
| 279 | }; | ||
| 280 | } | ||
| 281 | |||
| 282 | static void CreateFloatSlider(Settings::BasicSetting& setting, bool reversed, float multiplier, | ||
| 283 | QLabel* feedback, const QString& use_format, QSlider* slider, | ||
| 284 | std::function<std::string()>& serializer, | ||
| 285 | std::function<void()>& restore_func) { | ||
| 286 | float max_val = std::strtof(setting.MaxVal().c_str(), nullptr); | ||
| 287 | float min_val = std::strtof(setting.MinVal().c_str(), nullptr); | ||
| 288 | float use_multiplier = multiplier == default_multiplier ? default_float_multiplier : multiplier; | ||
| 289 | |||
| 290 | const auto update_feedback = [=](float value) { | ||
| 291 | int present = (reversed ? max_val - value : value) + 0.5f; | ||
| 292 | feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||
| 293 | }; | ||
| 294 | |||
| 295 | QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback); | ||
| 296 | update_feedback(std::strtof(setting.ToString().c_str(), nullptr)); | ||
| 297 | |||
| 298 | slider->setMinimum(min_val * use_multiplier); | ||
| 299 | slider->setMaximum(max_val * use_multiplier); | ||
| 300 | slider->setValue(std::strtof(setting.ToString().c_str(), nullptr) * use_multiplier); | ||
| 301 | |||
| 302 | serializer = [slider, use_multiplier]() { | ||
| 303 | return std::to_string(slider->value() / use_multiplier); | ||
| 304 | }; | ||
| 305 | restore_func = [slider, &setting, use_multiplier]() { | ||
| 306 | slider->setValue(std::strtof(RelevantDefault(setting).c_str(), nullptr) * use_multiplier); | ||
| 307 | }; | ||
| 308 | } | ||
| 309 | |||
| 258 | QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, | 310 | QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, |
| 259 | std::function<std::string()>& serializer, | 311 | std::function<std::string()>& serializer, |
| 260 | std::function<void()>& restore_func, | 312 | std::function<void()>& restore_func, |
| @@ -278,27 +330,20 @@ QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& gi | |||
| 278 | 330 | ||
| 279 | layout->setContentsMargins(0, 0, 0, 0); | 331 | layout->setContentsMargins(0, 0, 0, 0); |
| 280 | 332 | ||
| 281 | int max_val = std::stoi(setting.MaxVal()); | ||
| 282 | |||
| 283 | QString suffix = | 333 | QString suffix = |
| 284 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; | 334 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; |
| 285 | 335 | ||
| 286 | const QString use_format = QStringLiteral("%1").append(suffix); | 336 | const QString use_format = QStringLiteral("%1").append(suffix); |
| 287 | 337 | ||
| 288 | QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) { | 338 | if (setting.IsIntegral()) { |
| 289 | int present = (reversed ? max_val - value : value) * multiplier + 0.5f; | 339 | CreateIntSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer, |
| 290 | feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | 340 | restore_func); |
| 291 | }); | 341 | } else { |
| 292 | 342 | CreateFloatSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer, | |
| 293 | slider->setMinimum(std::stoi(setting.MinVal())); | 343 | restore_func); |
| 294 | slider->setMaximum(max_val); | 344 | } |
| 295 | slider->setValue(std::stoi(setting.ToString())); | ||
| 296 | 345 | ||
| 297 | slider->setInvertedAppearance(reversed); | 346 | slider->setInvertedAppearance(reversed); |
| 298 | slider->setInvertedControls(reversed); | ||
| 299 | |||
| 300 | serializer = [this]() { return std::to_string(slider->value()); }; | ||
| 301 | restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); }; | ||
| 302 | 347 | ||
| 303 | if (!Settings::IsConfiguringGlobal()) { | 348 | if (!Settings::IsConfiguringGlobal()) { |
| 304 | QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); | 349 | QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); |
| @@ -311,11 +356,9 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||
| 311 | std::function<std::string()>& serializer, | 356 | std::function<std::string()>& serializer, |
| 312 | std::function<void()>& restore_func, | 357 | std::function<void()>& restore_func, |
| 313 | const std::function<void()>& touch) { | 358 | const std::function<void()>& touch) { |
| 314 | const int min_val = | 359 | const auto min_val = std::strtol(setting.MinVal().c_str(), nullptr, 0); |
| 315 | setting.Ranged() ? std::stoi(setting.MinVal()) : std::numeric_limits<int>::min(); | 360 | const auto max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0); |
| 316 | const int max_val = | 361 | const auto default_val = std::strtol(setting.ToString().c_str(), nullptr, 0); |
| 317 | setting.Ranged() ? std::stoi(setting.MaxVal()) : std::numeric_limits<int>::max(); | ||
| 318 | const int default_val = std::stoi(setting.ToString()); | ||
| 319 | 362 | ||
| 320 | QString suffix = | 363 | QString suffix = |
| 321 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; | 364 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; |
| @@ -329,13 +372,13 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||
| 329 | serializer = [this]() { return std::to_string(spinbox->value()); }; | 372 | serializer = [this]() { return std::to_string(spinbox->value()); }; |
| 330 | 373 | ||
| 331 | restore_func = [this]() { | 374 | restore_func = [this]() { |
| 332 | auto value{std::stol(RelevantDefault(setting))}; | 375 | auto value{std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)}; |
| 333 | spinbox->setValue(value); | 376 | spinbox->setValue(value); |
| 334 | }; | 377 | }; |
| 335 | 378 | ||
| 336 | if (!Settings::IsConfiguringGlobal()) { | 379 | if (!Settings::IsConfiguringGlobal()) { |
| 337 | QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { | 380 | QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { |
| 338 | if (spinbox->value() != std::stoi(setting.ToStringGlobal())) { | 381 | if (spinbox->value() != std::strtol(setting.ToStringGlobal().c_str(), nullptr, 0)) { |
| 339 | touch(); | 382 | touch(); |
| 340 | } | 383 | } |
| 341 | }); | 384 | }); |
| @@ -344,6 +387,43 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||
| 344 | return spinbox; | 387 | return spinbox; |
| 345 | } | 388 | } |
| 346 | 389 | ||
| 390 | QWidget* Widget::CreateDoubleSpinBox(const QString& given_suffix, | ||
| 391 | std::function<std::string()>& serializer, | ||
| 392 | std::function<void()>& restore_func, | ||
| 393 | const std::function<void()>& touch) { | ||
| 394 | const auto min_val = std::strtod(setting.MinVal().c_str(), nullptr); | ||
| 395 | const auto max_val = std::strtod(setting.MaxVal().c_str(), nullptr); | ||
| 396 | const auto default_val = std::strtod(setting.ToString().c_str(), nullptr); | ||
| 397 | |||
| 398 | QString suffix = | ||
| 399 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; | ||
| 400 | |||
| 401 | double_spinbox = new QDoubleSpinBox(this); | ||
| 402 | double_spinbox->setRange(min_val, max_val); | ||
| 403 | double_spinbox->setValue(default_val); | ||
| 404 | double_spinbox->setSuffix(suffix); | ||
| 405 | double_spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||
| 406 | |||
| 407 | serializer = [this]() { return fmt::format("{:f}", double_spinbox->value()); }; | ||
| 408 | |||
| 409 | restore_func = [this]() { | ||
| 410 | auto value{std::strtod(RelevantDefault(setting).c_str(), nullptr)}; | ||
| 411 | double_spinbox->setValue(value); | ||
| 412 | }; | ||
| 413 | |||
| 414 | if (!Settings::IsConfiguringGlobal()) { | ||
| 415 | QObject::connect(double_spinbox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), | ||
| 416 | [this, touch]() { | ||
| 417 | if (double_spinbox->value() != | ||
| 418 | std::strtod(setting.ToStringGlobal().c_str(), nullptr)) { | ||
| 419 | touch(); | ||
| 420 | } | ||
| 421 | }); | ||
| 422 | } | ||
| 423 | |||
| 424 | return double_spinbox; | ||
| 425 | } | ||
| 426 | |||
| 347 | QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | 427 | QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, |
| 348 | std::function<void()>& restore_func, | 428 | std::function<void()>& restore_func, |
| 349 | const std::function<void()>& touch) { | 429 | const std::function<void()>& touch) { |
| @@ -353,7 +433,8 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | |||
| 353 | } | 433 | } |
| 354 | 434 | ||
| 355 | auto to_hex = [=](const std::string& input) { | 435 | auto to_hex = [=](const std::string& input) { |
| 356 | return QString::fromStdString(fmt::format("{:08x}", std::stoul(input))); | 436 | return QString::fromStdString( |
| 437 | fmt::format("{:08x}", std::strtoul(input.c_str(), nullptr, 0))); | ||
| 357 | }; | 438 | }; |
| 358 | 439 | ||
| 359 | QRegularExpressionValidator* regex = new QRegularExpressionValidator( | 440 | QRegularExpressionValidator* regex = new QRegularExpressionValidator( |
| @@ -366,7 +447,7 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | |||
| 366 | line_edit->setValidator(regex); | 447 | line_edit->setValidator(regex); |
| 367 | 448 | ||
| 368 | auto hex_to_dec = [this]() -> std::string { | 449 | auto hex_to_dec = [this]() -> std::string { |
| 369 | return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16)); | 450 | return std::to_string(std::strtoul(line_edit->text().toStdString().c_str(), nullptr, 16)); |
| 370 | }; | 451 | }; |
| 371 | 452 | ||
| 372 | serializer = [hex_to_dec]() { return hex_to_dec(); }; | 453 | serializer = [hex_to_dec]() { return hex_to_dec(); }; |
| @@ -386,7 +467,8 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict, | |||
| 386 | std::function<void()>& restore_func, | 467 | std::function<void()>& restore_func, |
| 387 | const std::function<void()>& touch) { | 468 | const std::function<void()>& touch) { |
| 388 | const long long current_time = QDateTime::currentSecsSinceEpoch(); | 469 | const long long current_time = QDateTime::currentSecsSinceEpoch(); |
| 389 | const s64 the_time = disabled ? current_time : std::stoll(setting.ToString()); | 470 | const s64 the_time = |
| 471 | disabled ? current_time : std::strtoll(setting.ToString().c_str(), nullptr, 0); | ||
| 390 | const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); | 472 | const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); |
| 391 | 473 | ||
| 392 | date_time_edit = new QDateTimeEdit(this); | 474 | date_time_edit = new QDateTimeEdit(this); |
| @@ -399,7 +481,7 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict, | |||
| 399 | auto get_clear_val = [this, restrict, current_time]() { | 481 | auto get_clear_val = [this, restrict, current_time]() { |
| 400 | return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { | 482 | return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { |
| 401 | if (restrict && checkbox->checkState() == Qt::Checked) { | 483 | if (restrict && checkbox->checkState() == Qt::Checked) { |
| 402 | return std::stoll(RelevantDefault(setting)); | 484 | return std::strtoll(RelevantDefault(setting).c_str(), nullptr, 0); |
| 403 | } | 485 | } |
| 404 | return current_time; | 486 | return current_time; |
| 405 | }()); | 487 | }()); |
| @@ -506,8 +588,7 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu | |||
| 506 | } else { | 588 | } else { |
| 507 | data_component = CreateCombobox(serializer, restore_func, touch); | 589 | data_component = CreateCombobox(serializer, restore_func, touch); |
| 508 | } | 590 | } |
| 509 | } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || | 591 | } else if (setting.IsIntegral()) { |
| 510 | type == typeid(s64) || type == typeid(u8)) { | ||
| 511 | switch (request) { | 592 | switch (request) { |
| 512 | case RequestType::Slider: | 593 | case RequestType::Slider: |
| 513 | case RequestType::ReverseSlider: | 594 | case RequestType::ReverseSlider: |
| @@ -534,6 +615,20 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu | |||
| 534 | default: | 615 | default: |
| 535 | UNIMPLEMENTED(); | 616 | UNIMPLEMENTED(); |
| 536 | } | 617 | } |
| 618 | } else if (setting.IsFloatingPoint()) { | ||
| 619 | switch (request) { | ||
| 620 | case RequestType::Default: | ||
| 621 | case RequestType::SpinBox: | ||
| 622 | data_component = CreateDoubleSpinBox(suffix, serializer, restore_func, touch); | ||
| 623 | break; | ||
| 624 | case RequestType::Slider: | ||
| 625 | case RequestType::ReverseSlider: | ||
| 626 | data_component = CreateSlider(request == RequestType::ReverseSlider, multiplier, suffix, | ||
| 627 | serializer, restore_func, touch); | ||
| 628 | break; | ||
| 629 | default: | ||
| 630 | UNIMPLEMENTED(); | ||
| 631 | } | ||
| 537 | } else if (type == typeid(std::string)) { | 632 | } else if (type == typeid(std::string)) { |
| 538 | switch (request) { | 633 | switch (request) { |
| 539 | case RequestType::Default: | 634 | case RequestType::Default: |
diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index 5303dd898..86edaacc8 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h | |||
| @@ -22,6 +22,7 @@ class QObject; | |||
| 22 | class QPushButton; | 22 | class QPushButton; |
| 23 | class QSlider; | 23 | class QSlider; |
| 24 | class QSpinBox; | 24 | class QSpinBox; |
| 25 | class QDoubleSpinBox; | ||
| 25 | class QRadioButton; | 26 | class QRadioButton; |
| 26 | 27 | ||
| 27 | namespace Settings { | 28 | namespace Settings { |
| @@ -43,6 +44,9 @@ enum class RequestType { | |||
| 43 | MaxEnum, | 44 | MaxEnum, |
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 47 | constexpr const float default_multiplier{1.f}; | ||
| 48 | constexpr const float default_float_multiplier{100.f}; | ||
| 49 | |||
| 46 | class Widget : public QWidget { | 50 | class Widget : public QWidget { |
| 47 | Q_OBJECT | 51 | Q_OBJECT |
| 48 | 52 | ||
| @@ -89,6 +93,7 @@ public: | |||
| 89 | QPushButton* restore_button{}; ///< Restore button for custom configurations | 93 | QPushButton* restore_button{}; ///< Restore button for custom configurations |
| 90 | QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit | 94 | QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit |
| 91 | QSpinBox* spinbox{}; | 95 | QSpinBox* spinbox{}; |
| 96 | QDoubleSpinBox* double_spinbox{}; | ||
| 92 | QCheckBox* checkbox{}; | 97 | QCheckBox* checkbox{}; |
| 93 | QSlider* slider{}; | 98 | QSlider* slider{}; |
| 94 | QComboBox* combobox{}; | 99 | QComboBox* combobox{}; |
| @@ -126,6 +131,9 @@ private: | |||
| 126 | const std::function<void()>& touch); | 131 | const std::function<void()>& touch); |
| 127 | QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, | 132 | QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, |
| 128 | std::function<void()>& restore_func, const std::function<void()>& touch); | 133 | std::function<void()>& restore_func, const std::function<void()>& touch); |
| 134 | QWidget* CreateDoubleSpinBox(const QString& suffix, std::function<std::string()>& serializer, | ||
| 135 | std::function<void()>& restore_func, | ||
| 136 | const std::function<void()>& touch); | ||
| 129 | 137 | ||
| 130 | QWidget* parent; | 138 | QWidget* parent; |
| 131 | const TranslationMap& translations; | 139 | const TranslationMap& translations; |