mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 23:06:43 +08:00 
			
		
		
		
	configuration: Move CreateWidget to a class
We were passing so many objects between the function and the caller that it needed to be redesigned.
This commit is contained in:
		
							parent
							
								
									d35577d3ed
								
							
						
					
					
						commit
						f66d617107
					
				| @ -145,6 +145,8 @@ add_executable(yuzu | ||||
|     configuration/input_profiles.h | ||||
|     configuration/shared_translation.cpp | ||||
|     configuration/shared_translation.h | ||||
|     configuration/shared_widget.cpp | ||||
|     configuration/shared_widget.h | ||||
|     debugger/console.cpp | ||||
|     debugger/console.h | ||||
|     debugger/controller.cpp | ||||
|  | ||||
| @ -1346,8 +1346,11 @@ void Config::ReadSettingGeneric(Settings::BasicSetting* const setting) { | ||||
| 
 | ||||
| void Config::WriteSettingGeneric(Settings::BasicSetting* const setting) const { | ||||
|     if (!setting->Save()) { | ||||
|         LOG_DEBUG(Frontend, "Skipping \"{}\" marked for not saving", setting->GetLabel()); | ||||
|         return; | ||||
|     } | ||||
|     LOG_DEBUG(Frontend, "Saving {} setting \"{}\"...", global ? "global" : "custom", | ||||
|               setting->GetLabel()); | ||||
|     const QVariant value = QVariant::fromValue(QString::fromStdString(setting->ToString())); | ||||
|     const QVariant default_value = | ||||
|         QVariant::fromValue(QString::fromStdString(setting->DefaultToString())); | ||||
|  | ||||
| @ -28,392 +28,6 @@ | ||||
| 
 | ||||
| namespace ConfigurationShared { | ||||
| 
 | ||||
| static QPushButton* CreateRestoreGlobalButton(QWidget* parent, Settings::BasicSetting* setting) { | ||||
|     QStyle* style = parent->style(); | ||||
|     QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); | ||||
|     QPushButton* button = new QPushButton(*icon, QStringLiteral(""), parent); | ||||
|     button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); | ||||
| 
 | ||||
|     QSizePolicy sp_retain = button->sizePolicy(); | ||||
|     sp_retain.setRetainSizeWhenHidden(true); | ||||
|     button->setSizePolicy(sp_retain); | ||||
| 
 | ||||
|     button->setEnabled(!setting->UsingGlobal()); | ||||
|     button->setVisible(!setting->UsingGlobal()); | ||||
| 
 | ||||
|     return button; | ||||
| } | ||||
| 
 | ||||
| static std::tuple<QWidget*, void*, QPushButton*, std::function<void()>> CreateCheckBox( | ||||
|     Settings::BasicSetting* setting, const QString& label, QWidget* parent) { | ||||
|     QWidget* widget = new QWidget(parent); | ||||
|     QHBoxLayout* layout = new QHBoxLayout(widget); | ||||
| 
 | ||||
|     QCheckBox* checkbox = new QCheckBox(label, parent); | ||||
|     checkbox->setObjectName(QString::fromStdString(setting->GetLabel())); | ||||
|     checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked | ||||
|                                                           : Qt::CheckState::Unchecked); | ||||
| 
 | ||||
|     std::function<void()> load_func; | ||||
| 
 | ||||
|     QPushButton* button{nullptr}; | ||||
| 
 | ||||
|     layout->addWidget(checkbox); | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         load_func = [setting, checkbox]() { | ||||
|             setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); | ||||
|         }; | ||||
|     } else { | ||||
|         button = CreateRestoreGlobalButton(parent, setting); | ||||
|         layout->addWidget(button); | ||||
| 
 | ||||
|         QObject::connect(checkbox, &QCheckBox::stateChanged, [button](int) { | ||||
|             button->setVisible(true); | ||||
|             button->setEnabled(true); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(button, &QAbstractButton::clicked, [checkbox, setting, button](bool) { | ||||
|             checkbox->setCheckState(setting->ToStringGlobal() == "true" ? Qt::Checked | ||||
|                                                                         : Qt::Unchecked); | ||||
|             button->setEnabled(false); | ||||
|             button->setVisible(false); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [setting, checkbox, button]() { | ||||
|             bool using_global = !button->isEnabled(); | ||||
|             setting->SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| 
 | ||||
|     return {widget, checkbox, button, load_func}; | ||||
| } | ||||
| 
 | ||||
| static std::tuple<QWidget*, QComboBox*, QPushButton*, std::function<void()>> CreateCombobox( | ||||
|     Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed) { | ||||
|     const auto type = setting->TypeId(); | ||||
| 
 | ||||
|     QWidget* group = new QWidget(parent); | ||||
|     group->setObjectName(QString::fromStdString(setting->GetLabel())); | ||||
|     QLayout* layout = new QHBoxLayout(group); | ||||
| 
 | ||||
|     QLabel* qt_label = new QLabel(label, parent); | ||||
|     QComboBox* combobox = new QComboBox(parent); | ||||
| 
 | ||||
|     QPushButton* button{nullptr}; | ||||
| 
 | ||||
|     std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, parent); | ||||
|     for (const auto& item : combobox_enumerations) { | ||||
|         combobox->addItem(item); | ||||
|     } | ||||
| 
 | ||||
|     layout->addWidget(qt_label); | ||||
|     layout->addWidget(combobox); | ||||
| 
 | ||||
|     layout->setSpacing(6); | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| 
 | ||||
|     combobox->setCurrentIndex(std::stoi(setting->ToString())); | ||||
| 
 | ||||
|     std::function<void()> load_func = []() {}; | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal() && managed) { | ||||
|         load_func = [setting, combobox]() { | ||||
|             setting->LoadString(std::to_string(combobox->currentIndex())); | ||||
|         }; | ||||
|     } else if (managed) { | ||||
|         button = CreateRestoreGlobalButton(parent, setting); | ||||
|         layout->addWidget(button); | ||||
| 
 | ||||
|         QObject::connect(button, &QAbstractButton::clicked, [button, combobox, setting](bool) { | ||||
|             button->setEnabled(false); | ||||
|             button->setVisible(false); | ||||
| 
 | ||||
|             combobox->setCurrentIndex(std::stoi(setting->ToStringGlobal())); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated), [=](int) { | ||||
|             button->setEnabled(true); | ||||
|             button->setVisible(true); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [setting, combobox, button]() { | ||||
|             bool using_global = !button->isEnabled(); | ||||
|             setting->SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting->LoadString(std::to_string(combobox->currentIndex())); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     return {group, combobox, button, load_func}; | ||||
| } | ||||
| 
 | ||||
| static std::tuple<QWidget*, void*, QPushButton*, std::function<void()>> CreateLineEdit( | ||||
|     Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed = true) { | ||||
|     QWidget* widget = new QWidget(parent); | ||||
|     widget->setObjectName(label); | ||||
| 
 | ||||
|     QHBoxLayout* layout = new QHBoxLayout(widget); | ||||
|     QLineEdit* line_edit = new QLineEdit(parent); | ||||
| 
 | ||||
|     const QString text = QString::fromStdString(setting->ToString()); | ||||
|     line_edit->setText(text); | ||||
| 
 | ||||
|     std::function<void()> load_func = []() {}; | ||||
| 
 | ||||
|     QLabel* q_label = new QLabel(label, widget); | ||||
|     // setSizePolicy lets widget expand and take an equal part of the space as the line edit
 | ||||
|     q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
|     layout->addWidget(q_label); | ||||
| 
 | ||||
|     layout->addWidget(line_edit); | ||||
| 
 | ||||
|     QPushButton* button{nullptr}; | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal() && !managed) { | ||||
|         load_func = [line_edit, setting]() { | ||||
|             std::string load_text = line_edit->text().toStdString(); | ||||
|             setting->LoadString(load_text); | ||||
|         }; | ||||
|     } else if (!managed) { | ||||
|         button = CreateRestoreGlobalButton(parent, setting); | ||||
|         layout->addWidget(button); | ||||
| 
 | ||||
|         QObject::connect(button, &QAbstractButton::clicked, [=](bool) { | ||||
|             button->setEnabled(false); | ||||
|             button->setVisible(false); | ||||
| 
 | ||||
|             line_edit->setText(QString::fromStdString(setting->ToStringGlobal())); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(line_edit, &QLineEdit::textChanged, [=](QString) { | ||||
|             button->setEnabled(true); | ||||
|             button->setVisible(true); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [=]() { | ||||
|             bool using_global = !button->isEnabled(); | ||||
|             setting->SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting->LoadString(line_edit->text().toStdString()); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| 
 | ||||
|     return {widget, line_edit, button, load_func}; | ||||
| } | ||||
| 
 | ||||
| static std::tuple<QWidget*, void*, QPushButton*, std::function<void()>> CreateSlider( | ||||
|     Settings::BasicSetting* setting, const QString& name, QWidget* parent, bool reversed, | ||||
|     float multiplier) { | ||||
|     QWidget* widget = new QWidget(parent); | ||||
|     QHBoxLayout* layout = new QHBoxLayout(widget); | ||||
|     QSlider* slider = new QSlider(Qt::Horizontal, widget); | ||||
|     QLabel* label = new QLabel(name, widget); | ||||
|     QPushButton* button{nullptr}; | ||||
|     QLabel* feedback = new QLabel(widget); | ||||
| 
 | ||||
|     layout->addWidget(label); | ||||
|     layout->addWidget(slider); | ||||
|     layout->addWidget(feedback); | ||||
| 
 | ||||
|     label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| 
 | ||||
|     int max_val = std::stoi(setting->MaxVal()); | ||||
| 
 | ||||
|     QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) { | ||||
|         int present = (reversed ? max_val - value : value) * multiplier; | ||||
|         feedback->setText( | ||||
|             QStringLiteral("%1%").arg(QString::fromStdString(std::to_string(present)))); | ||||
|     }); | ||||
| 
 | ||||
|     slider->setValue(std::stoi(setting->ToString())); | ||||
|     slider->setMinimum(std::stoi(setting->MinVal())); | ||||
|     slider->setMaximum(max_val); | ||||
| 
 | ||||
|     if (reversed) { | ||||
|         slider->setInvertedAppearance(true); | ||||
|     } | ||||
| 
 | ||||
|     std::function<void()> load_func; | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         load_func = [=]() { setting->LoadString(std::to_string(slider->value())); }; | ||||
|     } else { | ||||
|         button = CreateRestoreGlobalButton(parent, setting); | ||||
|         layout->addWidget(button); | ||||
| 
 | ||||
|         QObject::connect(button, &QAbstractButton::clicked, [=](bool) { | ||||
|             slider->setValue(std::stoi(setting->ToStringGlobal())); | ||||
| 
 | ||||
|             button->setEnabled(false); | ||||
|             button->setVisible(false); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(slider, &QAbstractSlider::sliderMoved, [=](int) { | ||||
|             button->setEnabled(true); | ||||
|             button->setVisible(true); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [=]() { | ||||
|             bool using_global = !button->isEnabled(); | ||||
|             setting->SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting->LoadString(std::to_string(slider->value())); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     return {widget, slider, button, []() {}}; | ||||
| } | ||||
| 
 | ||||
| static std::tuple<QWidget*, void*, void*, QPushButton*, std::function<void()>> | ||||
| CreateCheckBoxWithLineEdit(Settings::BasicSetting* setting, const QString& label, QWidget* parent) { | ||||
|     auto tuple = CreateCheckBox(setting, label, parent); | ||||
|     auto* widget = std::get<0>(tuple); | ||||
|     auto* checkbox = std::get<1>(tuple); | ||||
|     auto* button = std::get<2>(tuple); | ||||
|     auto load_func = std::get<3>(tuple); | ||||
|     QHBoxLayout* layout = dynamic_cast<QHBoxLayout*>(widget->layout()); | ||||
| 
 | ||||
|     auto line_edit_tuple = CreateLineEdit(setting, label, parent, false); | ||||
|     auto* line_edit_widget = std::get<0>(line_edit_tuple); | ||||
|     auto* line_edit = std::get<1>(line_edit_tuple); | ||||
| 
 | ||||
|     layout->insertWidget(1, line_edit_widget); | ||||
| 
 | ||||
|     return {widget, checkbox, line_edit, button, load_func}; | ||||
| } | ||||
| 
 | ||||
| std::tuple<QWidget*, void*, QPushButton*> CreateWidget( | ||||
|     Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, | ||||
|     bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs, | ||||
|     RequestType request, bool managed, float multiplier, const std::string& text_box_default) { | ||||
|     if (!Settings::IsConfiguringGlobal() && !setting->Switchable()) { | ||||
|         LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting->GetLabel()); | ||||
|         return {nullptr, nullptr, nullptr}; | ||||
|     } | ||||
| 
 | ||||
|     const auto type = setting->TypeId(); | ||||
|     const int id = setting->Id(); | ||||
|     QWidget* widget{nullptr}; | ||||
|     void* extra{nullptr}; | ||||
| 
 | ||||
|     std::function<void()> load_func; | ||||
| 
 | ||||
|     const auto [label, tooltip] = [&]() { | ||||
|         const auto& setting_label = setting->GetLabel(); | ||||
|         if (translations.contains(id)) { | ||||
|             return std::pair{translations.at(id).first, translations.at(id).second}; | ||||
|         } | ||||
|         LOG_ERROR(Frontend, "Translation table lacks entry for \"{}\"", setting_label); | ||||
|         return std::pair{QString::fromStdString(setting_label), QStringLiteral("")}; | ||||
|     }(); | ||||
| 
 | ||||
|     if (label == QStringLiteral("")) { | ||||
|         LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...", | ||||
|                   setting->GetLabel()); | ||||
|         return {nullptr, nullptr, nullptr}; | ||||
|     } | ||||
| 
 | ||||
|     QPushButton* button; | ||||
| 
 | ||||
|     if (type == typeid(bool)) { | ||||
|         switch (request) { | ||||
|         case RequestType::Default: { | ||||
|             auto tuple = CreateCheckBox(setting, label, parent); | ||||
|             widget = std::get<0>(tuple); | ||||
|             extra = std::get<1>(tuple); | ||||
|             button = std::get<2>(tuple); | ||||
|             load_func = std::get<3>(tuple); | ||||
|             break; | ||||
|         } | ||||
|         case RequestType::LineEdit: { | ||||
|             auto tuple = CreateCheckBoxWithLineEdit(setting, label, parent); | ||||
|             widget = std::get<0>(tuple); | ||||
|             break; | ||||
|         } | ||||
|         case RequestType::ComboBox: | ||||
|         case RequestType::SpinBox: | ||||
|         case RequestType::Slider: | ||||
|         case RequestType::ReverseSlider: | ||||
|         case RequestType::MaxEnum: | ||||
|             break; | ||||
|         } | ||||
|     } else if (setting->IsEnum()) { | ||||
|         auto tuple = CreateCombobox(setting, label, parent, managed); | ||||
|         widget = std::get<0>(tuple); | ||||
|         extra = std::get<1>(tuple); | ||||
|         button = std::get<2>(tuple); | ||||
|         load_func = std::get<3>(tuple); | ||||
|     } else if (type == typeid(u32) || type == typeid(int)) { | ||||
|         switch (request) { | ||||
|         case RequestType::LineEdit: | ||||
|         case RequestType::Default: { | ||||
|             auto tuple = CreateLineEdit(setting, label, parent); | ||||
|             widget = std::get<0>(tuple); | ||||
|             extra = std::get<1>(tuple); | ||||
|             button = std::get<2>(tuple); | ||||
|             load_func = std::get<3>(tuple); | ||||
|             break; | ||||
|         } | ||||
|         case RequestType::ComboBox: { | ||||
|             auto tuple = CreateCombobox(setting, label, parent, managed); | ||||
|             widget = std::get<0>(tuple); | ||||
|             extra = std::get<1>(tuple); | ||||
|             button = std::get<2>(tuple); | ||||
|             load_func = std::get<3>(tuple); | ||||
|             break; | ||||
|         } | ||||
|         case RequestType::Slider: | ||||
|         case RequestType::ReverseSlider: { | ||||
|             auto tuple = CreateSlider(setting, label, parent, request == RequestType::ReverseSlider, | ||||
|                                       multiplier); | ||||
|             widget = std::get<0>(tuple); | ||||
|             extra = std::get<1>(tuple); | ||||
|             button = std::get<2>(tuple); | ||||
|             load_func = std::get<3>(tuple); | ||||
|             break; | ||||
|         } | ||||
|         case RequestType::SpinBox: | ||||
|         case RequestType::MaxEnum: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (widget == nullptr) { | ||||
|         LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel()); | ||||
|         return {nullptr, nullptr, nullptr}; | ||||
|     } | ||||
| 
 | ||||
|     apply_funcs.push_front([load_func, setting](bool powered_on) { | ||||
|         if (setting->RuntimeModfiable() || !powered_on) { | ||||
|             load_func(); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     bool enable = runtime_lock || setting->RuntimeModfiable(); | ||||
|     if (setting->Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) { | ||||
|         enable &= !setting->UsingGlobal(); | ||||
|     } | ||||
|     widget->setEnabled(enable); | ||||
| 
 | ||||
|     widget->setVisible(Settings::IsConfiguringGlobal() || setting->Switchable()); | ||||
| 
 | ||||
|     widget->setToolTip(tooltip); | ||||
| 
 | ||||
|     return {widget, extra, button}; | ||||
| } | ||||
| 
 | ||||
| Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent) | ||||
|     : QWidget(parent), group{group_} { | ||||
|     if (group != nullptr) { | ||||
|  | ||||
| @ -13,8 +13,6 @@ | ||||
| #include "common/settings.h" | ||||
| #include "yuzu/configuration/shared_translation.h" | ||||
| 
 | ||||
| class QPushButton; | ||||
| 
 | ||||
| namespace ConfigurationShared { | ||||
| 
 | ||||
| class Tab : public QWidget { | ||||
| @ -43,22 +41,6 @@ enum class CheckState { | ||||
|     Count,  // Simply the number of states, not a valid checkbox state
 | ||||
| }; | ||||
| 
 | ||||
| enum class RequestType { | ||||
|     Default, | ||||
|     ComboBox, | ||||
|     SpinBox, | ||||
|     Slider, | ||||
|     ReverseSlider, | ||||
|     LineEdit, | ||||
|     MaxEnum, | ||||
| }; | ||||
| 
 | ||||
| std::tuple<QWidget*, void*, QPushButton*> CreateWidget( | ||||
|     Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, | ||||
|     bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs, | ||||
|     RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, | ||||
|     const std::string& text_box_default = ""); | ||||
| 
 | ||||
| // Global-aware apply and set functions
 | ||||
| 
 | ||||
| // ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
 | ||||
|  | ||||
| @ -21,10 +21,10 @@ ConfigureGeneral::ConfigureGeneral( | ||||
| 
 | ||||
|     SetConfiguration(); | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, | ||||
|                 [this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); }); | ||||
|     } | ||||
|     // if (Settings::IsConfiguringGlobal()) {
 | ||||
|     //     connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit,
 | ||||
|     //             [this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); });
 | ||||
|     // }
 | ||||
| 
 | ||||
|     connect(ui->button_reset_defaults, &QPushButton::clicked, this, | ||||
|             &ConfigureGeneral::ResetDefaults); | ||||
| @ -46,17 +46,17 @@ void ConfigureGeneral::SetConfiguration() { | ||||
|     ui->toggle_controller_applet_disabled->setChecked( | ||||
|         UISettings::values.controller_applet_disabled.GetValue()); | ||||
| 
 | ||||
|     ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue()); | ||||
|     ui->speed_limit->setValue(Settings::values.speed_limit.GetValue()); | ||||
|     // ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
 | ||||
|     // ui->speed_limit->setValue(Settings::values.speed_limit.GetValue());
 | ||||
| 
 | ||||
|     ui->button_reset_defaults->setEnabled(runtime_lock); | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue()); | ||||
|     } else { | ||||
|         ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() && | ||||
|                                     use_speed_limit != ConfigurationShared::CheckState::Global); | ||||
|     } | ||||
|     // if (Settings::IsConfiguringGlobal()) {
 | ||||
|     //     ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue());
 | ||||
|     // } else {
 | ||||
|     //     ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() &&
 | ||||
|     //                                 use_speed_limit != ConfigurationShared::CheckState::Global);
 | ||||
|     // }
 | ||||
| } | ||||
| 
 | ||||
| // Called to set the callback when resetting settings to defaults
 | ||||
| @ -91,20 +91,20 @@ void ConfigureGeneral::ApplyConfiguration() { | ||||
|             ui->toggle_controller_applet_disabled->isChecked(); | ||||
| 
 | ||||
|         // Guard if during game and set to game-specific value
 | ||||
|         if (Settings::values.use_speed_limit.UsingGlobal()) { | ||||
|             Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() == | ||||
|                                                       Qt::Checked); | ||||
|             Settings::values.speed_limit.SetValue(ui->speed_limit->value()); | ||||
|         } | ||||
|         // if (Settings::values.use_speed_limit.UsingGlobal()) {
 | ||||
|         //     Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
 | ||||
|         //                                               Qt::Checked);
 | ||||
|         //     Settings::values.speed_limit.SetValue(ui->speed_limit->value());
 | ||||
|         // }
 | ||||
|     } else { | ||||
|         bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global; | ||||
|         Settings::values.use_speed_limit.SetGlobal(global_speed_limit); | ||||
|         Settings::values.speed_limit.SetGlobal(global_speed_limit); | ||||
|         if (!global_speed_limit) { | ||||
|             Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() == | ||||
|                                                       Qt::Checked); | ||||
|             Settings::values.speed_limit.SetValue(ui->speed_limit->value()); | ||||
|         } | ||||
|         // bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global;
 | ||||
|         // Settings::values.use_speed_limit.SetGlobal(global_speed_limit);
 | ||||
|         // Settings::values.speed_limit.SetGlobal(global_speed_limit);
 | ||||
|         // if (!global_speed_limit) {
 | ||||
|         //     Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
 | ||||
|         //                                               Qt::Checked);
 | ||||
|         //     Settings::values.speed_limit.SetValue(ui->speed_limit->value());
 | ||||
|         // }
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -125,8 +125,8 @@ void ConfigureGeneral::SetupPerGameUI() { | ||||
|         // Disables each setting if:
 | ||||
|         //  - A game is running (thus settings in use), and
 | ||||
|         //  - A non-global setting is applied.
 | ||||
|         ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal()); | ||||
|         ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal()); | ||||
|         // ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal());
 | ||||
|         // ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal());
 | ||||
| 
 | ||||
|         return; | ||||
|     } | ||||
| @ -144,8 +144,9 @@ void ConfigureGeneral::SetupPerGameUI() { | ||||
|     ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core, | ||||
|                                             use_multi_core); | ||||
| 
 | ||||
|     connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() { | ||||
|         ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() && | ||||
|                                     (use_speed_limit != ConfigurationShared::CheckState::Global)); | ||||
|     }); | ||||
|     // connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
 | ||||
|     //     ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
 | ||||
|     //                                 (use_speed_limit !=
 | ||||
|     //                                 ConfigurationShared::CheckState::Global));
 | ||||
|     // });
 | ||||
| } | ||||
|  | ||||
| @ -15,6 +15,7 @@ | ||||
| #include <QComboBox> | ||||
| #include <QIcon> | ||||
| #include <QLabel> | ||||
| #include <QLineEdit> | ||||
| #include <QPixmap> | ||||
| #include <QPushButton> | ||||
| #include <QSlider> | ||||
| @ -35,6 +36,7 @@ | ||||
| #include "ui_configure_graphics.h" | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| #include "yuzu/configuration/configure_graphics.h" | ||||
| #include "yuzu/configuration/shared_widget.h" | ||||
| #include "yuzu/qt_common.h" | ||||
| #include "yuzu/uisettings.h" | ||||
| #include "yuzu/vk_device_info.h" | ||||
| @ -219,35 +221,38 @@ void ConfigureGraphics::SetConfiguration() { | ||||
|     for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) { | ||||
|         const auto& setting_label = setting->GetLabel(); | ||||
| 
 | ||||
|         auto [widget, extra, button] = [&]() { | ||||
|         ConfigurationShared::Widget* widget = [&]() { | ||||
|             if (setting->Id() == Settings::values.vulkan_device.Id() || | ||||
|                 setting->Id() == Settings::values.shader_backend.Id() || | ||||
|                 setting->Id() == Settings::values.vsync_mode.Id()) { | ||||
|                 return ConfigurationShared::CreateWidget( | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::ComboBox, false); | ||||
|             } else if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) { | ||||
|                 return ConfigurationShared::CreateWidget( | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::ReverseSlider, true, 0.5f); | ||||
|             } else if (setting->Id() == Settings::values.use_speed_limit.Id()) { | ||||
|                 return ConfigurationShared::CreateWidget( | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::LineEdit, true, 1.0f, setting->ToString()); | ||||
|                     ConfigurationShared::RequestType::LineEdit, true, 1.0f, | ||||
|                     Settings::values.speed_limit.ToString()); | ||||
|             } else { | ||||
|                 return ConfigurationShared::CreateWidget(setting, translations, this, runtime_lock, | ||||
|                                                          apply_funcs); | ||||
|                 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, | ||||
|                                                        apply_funcs); | ||||
|             } | ||||
|         }(); | ||||
| 
 | ||||
|         if (widget == nullptr) { | ||||
|         if (!widget->Valid()) { | ||||
|             LOG_DEBUG(Frontend, "Deleted widget for \"{}\"", setting->GetLabel()); | ||||
|             delete widget; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (setting->Id() == Settings::values.renderer_backend.Id()) { | ||||
|             api_grid_layout->addWidget(widget); | ||||
|             api_combobox = reinterpret_cast<QComboBox*>(extra); | ||||
|             api_restore_global_button = button; | ||||
|             api_combobox = widget->combobox; | ||||
|             api_restore_global_button = widget->restore_button; | ||||
| 
 | ||||
|             if (!Settings::IsConfiguringGlobal()) { | ||||
|                 QObject::connect(api_restore_global_button, &QAbstractButton::clicked, | ||||
| @ -259,14 +264,33 @@ void ConfigureGraphics::SetConfiguration() { | ||||
|             } | ||||
|         } else if (setting->Id() == Settings::values.vulkan_device.Id()) { | ||||
|             hold_api.push_front(widget); | ||||
|             vulkan_device_combobox = reinterpret_cast<QComboBox*>(extra); | ||||
|             vulkan_device_combobox = widget->combobox; | ||||
|             vulkan_device_widget = widget; | ||||
|         } else if (setting->Id() == Settings::values.shader_backend.Id()) { | ||||
|             hold_api.push_front(widget); | ||||
|             shader_backend_combobox = reinterpret_cast<QComboBox*>(extra); | ||||
|             shader_backend_combobox = widget->combobox; | ||||
|             shader_backend_widget = widget; | ||||
|         } else if (setting->Id() == Settings::values.use_speed_limit.Id()) { | ||||
|             apply_funcs.push_front([setting, widget](bool powered_on) { | ||||
|                 if (!setting->RuntimeModfiable() && powered_on) { | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 u16 value = QVariant(widget->line_edit->text()).value<u16>(); | ||||
|                 auto& speed_limit = Settings::values.speed_limit; | ||||
|                 if (Settings::IsConfiguringGlobal()) { | ||||
|                     speed_limit.SetValue(value); | ||||
|                 } else { | ||||
|                     bool using_global = !widget->restore_button->isVisible(); | ||||
|                     speed_limit.SetGlobal(using_global); | ||||
|                     if (!using_global) { | ||||
|                         speed_limit.SetValue(value); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|             hold_graphics[setting->IsEnum()][setting_label] = widget; | ||||
|         } else if (setting->Id() == Settings::values.vsync_mode.Id()) { | ||||
|             vsync_mode_combobox = reinterpret_cast<QComboBox*>(extra); | ||||
|             vsync_mode_combobox = widget->combobox; | ||||
|             hold_graphics[setting->IsEnum()][setting_label] = widget; | ||||
|         } else { | ||||
|             hold_graphics[setting->IsEnum()][setting_label] = widget; | ||||
| @ -360,6 +384,7 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) { | ||||
| } | ||||
| 
 | ||||
| void ConfigureGraphics::UpdateAPILayout() { | ||||
|     bool runtime_lock = !system.IsPoweredOn(); | ||||
|     if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) { | ||||
|         vulkan_device = Settings::values.vulkan_device.GetValue(true); | ||||
|         shader_backend = Settings::values.shader_backend.GetValue(true); | ||||
| @ -368,8 +393,8 @@ void ConfigureGraphics::UpdateAPILayout() { | ||||
|     } else { | ||||
|         vulkan_device = Settings::values.vulkan_device.GetValue(); | ||||
|         shader_backend = Settings::values.shader_backend.GetValue(); | ||||
|         vulkan_device_widget->setEnabled(true); | ||||
|         shader_backend_widget->setEnabled(true); | ||||
|         vulkan_device_widget->setEnabled(runtime_lock); | ||||
|         shader_backend_widget->setEnabled(runtime_lock); | ||||
|     } | ||||
| 
 | ||||
|     switch (GetCurrentGraphicsBackend()) { | ||||
|  | ||||
| @ -15,6 +15,7 @@ | ||||
| #include "vk_device_info.h" | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| 
 | ||||
| class QPushButton; | ||||
| class QEvent; | ||||
| class QObject; | ||||
| class QComboBox; | ||||
|  | ||||
| @ -8,6 +8,7 @@ | ||||
| #include "ui_configure_graphics_advanced.h" | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| #include "yuzu/configuration/configure_graphics_advanced.h" | ||||
| #include "yuzu/configuration/shared_widget.h" | ||||
| 
 | ||||
| ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced( | ||||
|     const Core::System& system_, | ||||
| @ -32,10 +33,11 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { | ||||
| 
 | ||||
|     for (auto setting : | ||||
|          Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) { | ||||
|         auto [widget, extra, button] = ConfigurationShared::CreateWidget( | ||||
|             setting, translations, this, runtime_lock, apply_funcs); | ||||
|         ConfigurationShared::Widget* widget = | ||||
|             new ConfigurationShared::Widget(setting, translations, this, runtime_lock, apply_funcs); | ||||
| 
 | ||||
|         if (widget == nullptr) { | ||||
|         if (!widget->Valid()) { | ||||
|             delete widget; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										360
									
								
								src/yuzu/configuration/shared_widget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								src/yuzu/configuration/shared_widget.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,360 @@ | ||||
| #include <functional> | ||||
| #include <QCheckBox> | ||||
| #include <QHBoxLayout> | ||||
| #include <QIcon> | ||||
| #include <QLabel> | ||||
| #include <QLineEdit> | ||||
| #include <QPushButton> | ||||
| #include <QSizePolicy> | ||||
| #include <QWidget> | ||||
| #include <qabstractbutton.h> | ||||
| #include "common/settings.h" | ||||
| #include "yuzu/configuration/shared_translation.h" | ||||
| #include "yuzu/configuration/shared_widget.h" | ||||
| 
 | ||||
| namespace ConfigurationShared { | ||||
| 
 | ||||
| void Widget::CreateRestoreGlobalButton() { | ||||
|     QStyle* style = this->style(); | ||||
|     QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); | ||||
|     restore_button = new QPushButton(*icon, QStringLiteral(""), this); | ||||
|     restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); | ||||
| 
 | ||||
|     QSizePolicy sp_retain = restore_button->sizePolicy(); | ||||
|     sp_retain.setRetainSizeWhenHidden(true); | ||||
|     restore_button->setSizePolicy(sp_retain); | ||||
| 
 | ||||
|     restore_button->setEnabled(!setting.UsingGlobal()); | ||||
|     restore_button->setVisible(!setting.UsingGlobal()); | ||||
| } | ||||
| 
 | ||||
| void Widget::CreateCheckBox(const QString& label, std::function<void()>& load_func) { | ||||
|     created = true; | ||||
| 
 | ||||
|     QHBoxLayout* layout = new QHBoxLayout(this); | ||||
| 
 | ||||
|     checkbox = new QCheckBox(label, this); | ||||
|     checkbox->setObjectName(QString::fromStdString(setting.GetLabel())); | ||||
|     checkbox->setCheckState(setting.ToString() == "true" ? Qt::CheckState::Checked | ||||
|                                                          : Qt::CheckState::Unchecked); | ||||
| 
 | ||||
|     layout->addWidget(checkbox); | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         load_func = [=]() { | ||||
|             setting.LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); | ||||
|         }; | ||||
|     } else { | ||||
|         CreateRestoreGlobalButton(); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(checkbox, &QCheckBox::stateChanged, [&](int) { | ||||
|             restore_button->setVisible(true); | ||||
|             restore_button->setEnabled(true); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) { | ||||
|             checkbox->setCheckState(setting.ToStringGlobal() == "true" ? Qt::Checked | ||||
|                                                                        : Qt::Unchecked); | ||||
|             restore_button->setEnabled(false); | ||||
|             restore_button->setVisible(false); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [=]() { | ||||
|             bool using_global = !restore_button->isEnabled(); | ||||
|             setting.SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting.LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| void Widget::CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func) { | ||||
|     created = true; | ||||
| 
 | ||||
|     const auto type = setting.TypeId(); | ||||
| 
 | ||||
|     QLayout* layout = new QHBoxLayout(this); | ||||
| 
 | ||||
|     QLabel* qt_label = new QLabel(label, this); | ||||
|     combobox = new QComboBox(this); | ||||
| 
 | ||||
|     std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, this); | ||||
|     for (const auto& item : combobox_enumerations) { | ||||
|         combobox->addItem(item); | ||||
|     } | ||||
| 
 | ||||
|     layout->addWidget(qt_label); | ||||
|     layout->addWidget(combobox); | ||||
| 
 | ||||
|     layout->setSpacing(6); | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| 
 | ||||
|     combobox->setCurrentIndex(std::stoi(setting.ToString())); | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal() && managed) { | ||||
|         load_func = [=]() { setting.LoadString(std::to_string(combobox->currentIndex())); }; | ||||
|     } else if (managed) { | ||||
|         CreateRestoreGlobalButton(); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) { | ||||
|             restore_button->setEnabled(false); | ||||
|             restore_button->setVisible(false); | ||||
| 
 | ||||
|             combobox->setCurrentIndex(std::stoi(setting.ToStringGlobal())); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated), [=](int) { | ||||
|             restore_button->setEnabled(true); | ||||
|             restore_button->setVisible(true); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [=]() { | ||||
|             bool using_global = !restore_button->isEnabled(); | ||||
|             setting.SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting.LoadString(std::to_string(combobox->currentIndex())); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Widget::CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func) { | ||||
|     created = true; | ||||
| 
 | ||||
|     QHBoxLayout* layout = new QHBoxLayout(this); | ||||
|     line_edit = new QLineEdit(this); | ||||
| 
 | ||||
|     const QString text = QString::fromStdString(setting.ToString()); | ||||
|     line_edit->setText(text); | ||||
| 
 | ||||
|     QLabel* q_label = new QLabel(label, this); | ||||
|     // setSizePolicy lets widget expand and take an equal part of the space as the line edit
 | ||||
|     q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
|     layout->addWidget(q_label); | ||||
| 
 | ||||
|     layout->addWidget(line_edit); | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal() && !managed) { | ||||
|         load_func = [=]() { | ||||
|             std::string load_text = line_edit->text().toStdString(); | ||||
|             setting.LoadString(load_text); | ||||
|         }; | ||||
|     } else if (!managed) { | ||||
|         CreateRestoreGlobalButton(); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) { | ||||
|             restore_button->setEnabled(false); | ||||
|             restore_button->setVisible(false); | ||||
| 
 | ||||
|             line_edit->setText(QString::fromStdString(setting.ToStringGlobal())); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(line_edit, &QLineEdit::textChanged, [&](QString) { | ||||
|             restore_button->setEnabled(true); | ||||
|             restore_button->setVisible(true); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [=]() { | ||||
|             bool using_global = !restore_button->isEnabled(); | ||||
|             setting.SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting.LoadString(line_edit->text().toStdString()); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| void Widget::CreateSlider(const QString& name, bool reversed, float multiplier, | ||||
|                           std::function<void()>& load_func) { | ||||
|     created = true; | ||||
| 
 | ||||
|     QHBoxLayout* layout = new QHBoxLayout(this); | ||||
|     slider = new QSlider(Qt::Horizontal, this); | ||||
|     QLabel* label = new QLabel(name, this); | ||||
|     QLabel* feedback = new QLabel(this); | ||||
| 
 | ||||
|     layout->addWidget(label); | ||||
|     layout->addWidget(slider); | ||||
|     layout->addWidget(feedback); | ||||
| 
 | ||||
|     label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
| 
 | ||||
|     int max_val = std::stoi(setting.MaxVal()); | ||||
| 
 | ||||
|     QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) { | ||||
|         int present = (reversed ? max_val - value : value) * multiplier; | ||||
|         feedback->setText( | ||||
|             QStringLiteral("%1%").arg(QString::fromStdString(std::to_string(present)))); | ||||
|     }); | ||||
| 
 | ||||
|     slider->setValue(std::stoi(setting.ToString())); | ||||
|     slider->setMinimum(std::stoi(setting.MinVal())); | ||||
|     slider->setMaximum(max_val); | ||||
| 
 | ||||
|     if (reversed) { | ||||
|         slider->setInvertedAppearance(true); | ||||
|     } | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         load_func = [=]() { setting.LoadString(std::to_string(slider->value())); }; | ||||
|     } else { | ||||
|         CreateRestoreGlobalButton(); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { | ||||
|             slider->setValue(std::stoi(setting.ToStringGlobal())); | ||||
| 
 | ||||
|             restore_button->setEnabled(false); | ||||
|             restore_button->setVisible(false); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(slider, &QAbstractSlider::sliderMoved, [=](int) { | ||||
|             restore_button->setEnabled(true); | ||||
|             restore_button->setVisible(true); | ||||
|         }); | ||||
| 
 | ||||
|         load_func = [=]() { | ||||
|             bool using_global = !restore_button->isEnabled(); | ||||
|             setting.SetGlobal(using_global); | ||||
|             if (!using_global) { | ||||
|                 setting.LoadString(std::to_string(slider->value())); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Widget::CreateCheckBoxWithLineEdit(const QString& label, const std::string& text_box_default, | ||||
|                                         std::function<void()>& load_func) { | ||||
|     created = true; | ||||
| 
 | ||||
|     CreateCheckBox(label, load_func); | ||||
| 
 | ||||
|     QHBoxLayout* layout = reinterpret_cast<QHBoxLayout*>(this->layout()); | ||||
| 
 | ||||
|     line_edit = new QLineEdit(this); | ||||
|     line_edit->setText(QString::fromStdString(text_box_default)); | ||||
| 
 | ||||
|     checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
| 
 | ||||
|     layout->insertWidget(1, line_edit); | ||||
| 
 | ||||
|     QObject::connect(line_edit, &QLineEdit::textEdited, | ||||
|                      [=](const QString&) { checkbox->setCheckState(Qt::Checked); }); | ||||
| 
 | ||||
|     if (!Settings::IsConfiguringGlobal()) { | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { | ||||
|             line_edit->setText(QString::fromStdString(text_box_default)); | ||||
|         }); | ||||
| 
 | ||||
|         QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { | ||||
|             restore_button->setEnabled(true); | ||||
|             restore_button->setVisible(true); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool Widget::Valid() { | ||||
|     return created; | ||||
| } | ||||
| 
 | ||||
| Widget::~Widget() = default; | ||||
| 
 | ||||
| Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_, | ||||
|                QWidget* parent_, bool runtime_lock, | ||||
|                std::forward_list<std::function<void(bool)>>& apply_funcs, RequestType request, | ||||
|                bool managed, float multiplier, const std::string& text_box_default) | ||||
|     : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} { | ||||
|     if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) { | ||||
|         LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto type = setting.TypeId(); | ||||
|     const int id = setting.Id(); | ||||
| 
 | ||||
|     const auto [label, tooltip] = [&]() { | ||||
|         const auto& setting_label = setting.GetLabel(); | ||||
|         if (translations.contains(id)) { | ||||
|             return std::pair{translations.at(id).first, translations.at(id).second}; | ||||
|         } | ||||
|         LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label); | ||||
|         return std::pair{QString::fromStdString(setting_label), QStringLiteral("")}; | ||||
|     }(); | ||||
| 
 | ||||
|     if (label == QStringLiteral("")) { | ||||
|         LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...", | ||||
|                   setting.GetLabel()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     std::function<void()> load_func = []() {}; | ||||
| 
 | ||||
|     if (type == typeid(bool)) { | ||||
|         switch (request) { | ||||
|         case RequestType::Default: | ||||
|             CreateCheckBox(label, load_func); | ||||
|             break; | ||||
|         case RequestType::LineEdit: | ||||
|         case RequestType::SpinBox: | ||||
|             CreateCheckBoxWithLineEdit(label, text_box_default, load_func); | ||||
|             break; | ||||
|         case RequestType::ComboBox: | ||||
|         case RequestType::Slider: | ||||
|         case RequestType::ReverseSlider: | ||||
|         case RequestType::MaxEnum: | ||||
|             break; | ||||
|         } | ||||
|     } else if (setting.IsEnum()) { | ||||
|         CreateCombobox(label, managed, load_func); | ||||
|     } else if (type == typeid(u32) || type == typeid(int)) { | ||||
|         switch (request) { | ||||
|         case RequestType::Slider: | ||||
|         case RequestType::ReverseSlider: | ||||
|             CreateSlider(label, request == RequestType::ReverseSlider, multiplier, load_func); | ||||
|             break; | ||||
|         case RequestType::LineEdit: | ||||
|         case RequestType::Default: | ||||
|             CreateLineEdit(label, managed, load_func); | ||||
|             break; | ||||
|         case RequestType::ComboBox: | ||||
|             CreateCombobox(label, managed, load_func); | ||||
|             break; | ||||
|         case RequestType::SpinBox: | ||||
|         case RequestType::MaxEnum: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (!created) { | ||||
|         LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting.GetLabel()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     apply_funcs.push_front([load_func, setting_](bool powered_on) { | ||||
|         LOG_DEBUG(Frontend, "{}", setting_->GetLabel()); | ||||
|         if (setting_->RuntimeModfiable() || !powered_on) { | ||||
|             load_func(); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     bool enable = runtime_lock || setting.RuntimeModfiable(); | ||||
|     if (setting.Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) { | ||||
|         enable &= setting.UsingGlobal(); | ||||
|     } | ||||
|     this->setEnabled(enable); | ||||
| 
 | ||||
|     this->setVisible(Settings::IsConfiguringGlobal() || setting.Switchable()); | ||||
| 
 | ||||
|     this->setToolTip(tooltip); | ||||
| } | ||||
| 
 | ||||
| } // namespace ConfigurationShared
 | ||||
							
								
								
									
										64
									
								
								src/yuzu/configuration/shared_widget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/yuzu/configuration/shared_widget.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| #include "yuzu/configuration/shared_translation.h" | ||||
| 
 | ||||
| class QPushButton; | ||||
| class QComboBox; | ||||
| class QLineEdit; | ||||
| class QSlider; | ||||
| class QCheckBox; | ||||
| 
 | ||||
| namespace Settings { | ||||
| class BasicSetting; | ||||
| } | ||||
| 
 | ||||
| namespace ConfigurationShared { | ||||
| 
 | ||||
| enum class RequestType { | ||||
|     Default, | ||||
|     ComboBox, | ||||
|     SpinBox, | ||||
|     Slider, | ||||
|     ReverseSlider, | ||||
|     LineEdit, | ||||
|     MaxEnum, | ||||
| }; | ||||
| 
 | ||||
| class Widget : public QWidget { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, | ||||
|            bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs, | ||||
|            RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, | ||||
|            const std::string& text_box_default = ""); | ||||
|     virtual ~Widget(); | ||||
| 
 | ||||
|     bool Valid(); | ||||
| 
 | ||||
|     QPushButton* restore_button{}; | ||||
|     QLineEdit* line_edit{}; | ||||
|     QCheckBox* checkbox{}; | ||||
|     QSlider* slider{}; | ||||
|     QComboBox* combobox{}; | ||||
| 
 | ||||
| private: | ||||
|     void CreateCheckBox(const QString& label, std::function<void()>& load_func); | ||||
|     void CreateCheckBoxWithLineEdit(const QString& label, const std::string& text_box_default, | ||||
|                                     std::function<void()>& load_func); | ||||
|     void CreateCheckBoxWithSpinBox(const QString& label, const std::string& text_box_default, | ||||
|                                    std::function<void()>& load_func); | ||||
|     void CreateCombobox(const QString& label, bool managed, std::function<void()>& load_func); | ||||
|     void CreateLineEdit(const QString& label, bool managed, std::function<void()>& load_func); | ||||
|     void CreateSlider(const QString& label, bool reversed, float multiplier, | ||||
|                       std::function<void()>& load_func); | ||||
| 
 | ||||
|     void CreateRestoreGlobalButton(); | ||||
| 
 | ||||
|     QWidget* parent; | ||||
|     const TranslationMap& translations; | ||||
|     Settings::BasicSetting& setting; | ||||
| 
 | ||||
|     bool created{false}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace ConfigurationShared
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user