From 60773194a039fced8cf2da308e1b8220d08a1636 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 5 Jun 2023 21:05:22 -0400 Subject: settings: Add a registry of settings LoadString: Sanitize input settings: Handle empty string, remove redundant category settings: Rename Input to Controls, FS to DataStorage settings: Fix Controls groups information settings: Move use_docked_mode to System (again) settings: Document settings: Add type identification function settings: Move registry into values settings: Move global_reset_registry into values settings: Separate AdvGraphics from Renderer settings: More document squash settings: Use linkage object uisettings: Move registry into settings Probably wont build without uisettings: Use settings linkage object config: Load settings with a map Uses the new all_settings vector to load settings. qt-config: Rename settings category qt config: Rename to read category config: Read/write contols category with for_each This is extremely limited due to the complexity of the Controls group, but this handles the the settings that use the interface. qt-config: Use new settings registry qt-config: Read/write advgrphics qt-config: Use settings linkage object yuzu_cmd: Load setting off of vector cmd-config: Finish settings rename config: Read controls settings group with for_each cmd/config: Move registry into values cmd: Read adv graphics cmd-config: Use settings linkage object --- src/yuzu/configuration/configuration_shared.cpp | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index ac42cc7fc..8fd12c9e8 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -43,25 +43,6 @@ void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) { widget->show(); } -void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, - const Settings::SwitchableSetting& setting, - CheckState& tracker) { - if (setting.UsingGlobal()) { - tracker = CheckState::Global; - } else { - tracker = (setting.GetValue() == setting.GetValue(true)) ? CheckState::On : CheckState::Off; - } - SetHighlight(checkbox, tracker != CheckState::Global); - QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, setting, &tracker] { - tracker = static_cast((static_cast(tracker) + 1) % - static_cast(CheckState::Count)); - if (tracker == CheckState::Global) { - checkbox->setChecked(setting.GetValue(true)); - } - SetHighlight(checkbox, tracker != CheckState::Global); - }); -} - void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state, CheckState& tracker) { if (global) { -- cgit v1.2.3 From e5b981e1e45be66c66c5592019b85928a34efbd7 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Fri, 5 May 2023 19:49:51 -0400 Subject: configuration_shared: Create Tab base class --- src/yuzu/configuration/configuration_shared.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 8fd12c9e8..ce12f55a2 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -4,10 +4,19 @@ #include #include #include +#include #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_per_game.h" +namespace ConfigurationShared { + +Tab::Tab(QWidget* parent) : QWidget(parent) {} + +Tab::~Tab() {} + +} // namespace ConfigurationShared + void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting* setting, const QCheckBox* checkbox, const CheckState& tracker) { -- cgit v1.2.3 From d3b94d64d492407dcd43acf79cd1e94d57630109 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Fri, 5 May 2023 23:30:59 -0400 Subject: configuration: Add base class to tabs Tabs that largely configure SwitchableSetting's are now Tabs and grouped together. --- src/yuzu/configuration/configuration_shared.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index ce12f55a2..72b7957e0 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include #include @@ -11,9 +12,14 @@ namespace ConfigurationShared { -Tab::Tab(QWidget* parent) : QWidget(parent) {} +Tab::Tab(std::shared_ptr> group_, QWidget* parent) + : QWidget(parent), group{group_} { + if (group != nullptr) { + group->push_front(this); + } +} -Tab::~Tab() {} +Tab::~Tab() = default; } // namespace ConfigurationShared -- cgit v1.2.3 From a007ac6b9ccc23861f5a5c6967d535220ed794b0 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Sun, 7 May 2023 09:48:26 -0400 Subject: configure_graphics_advance: Generate UI at runtime We can iterate through the AdvancedGraphics settings and generate the UI during runtime. This doesn't help runtime efficiency, but it helps a ton in reducing the amount of work a developer needs in order to add a new setting. --- src/yuzu/configuration/configuration_shared.cpp | 153 ++++++++++++++++++++++++ 1 file changed, 153 insertions(+) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 72b7957e0..44222718c 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -3,14 +3,167 @@ #include #include +#include +#include #include #include #include +#include #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_per_game.h" +#include "yuzu/configuration/shared_translation.h" namespace ConfigurationShared { +static std::pair> CreateCheckBox(Settings::BasicSetting* setting, + const QString& label, + QWidget* parent, + std::list& trackers) { + QCheckBox* checkbox = new QCheckBox(label, parent); + checkbox->setObjectName(QString::fromStdString(setting->GetLabel())); + checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked + : Qt::CheckState::Unchecked); + + CheckState* tracker{}; + + // Per-game config highlight + if (setting->Switchable() && !Settings::IsConfiguringGlobal()) { + bool global_state = setting->ToStringGlobal() == "true"; + bool state = setting->ToString() == "true"; + bool global = setting->UsingGlobal(); + tracker = &trackers.emplace_front(CheckState{}); + SetColoredTristate(checkbox, global, state, global_state, *tracker); + } + + auto load_func = [checkbox, setting, tracker]() { + if (Settings::IsConfiguringGlobal()) { + setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); + } + + if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { + return; + } + + if (*tracker != CheckState::Global) { + setting->SetGlobal(false); + setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); + } else { + setting->SetGlobal(true); + } + }; + + return {checkbox, load_func}; +} + +static std::pair> CreateCombobox(Settings::BasicSetting* setting, + const QString& label, + QWidget* parent) { + const auto type = setting->TypeId(); + + QWidget* group = new QWidget(parent); + group->setObjectName(QString::fromStdString(setting->GetLabel())); + QLayout* combobox_layout = new QHBoxLayout(group); + + QLabel* qt_label = new QLabel(label, parent); + QComboBox* combobox = new QComboBox(parent); + + std::forward_list combobox_enumerations = ComboboxEnumeration(type, parent); + for (const auto& item : combobox_enumerations) { + combobox->addItem(item); + } + + combobox_layout->addWidget(qt_label); + combobox_layout->addWidget(combobox); + + combobox_layout->setSpacing(6); + combobox_layout->setContentsMargins(0, 0, 0, 0); + + if (setting->Switchable() && !Settings::IsConfiguringGlobal()) { + int current = std::stoi(setting->ToString()); + int global_value = std::stoi(setting->ToStringGlobal()); + SetColoredComboBox(combobox, group, global_value); + if (setting->UsingGlobal()) { + combobox->setCurrentIndex(USE_GLOBAL_INDEX); + } else { + SetHighlight(group, true); + combobox->setCurrentIndex(current + USE_GLOBAL_OFFSET); + } + } else { + combobox->setCurrentIndex(std::stoi(setting->ToString())); + } + + const auto load_func = [combobox, setting]() { + if (Settings::IsConfiguringGlobal()) { + setting->LoadString(std::to_string(combobox->currentIndex())); + } + + if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { + return; + } + + bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX; + int index = combobox->currentIndex() - USE_GLOBAL_OFFSET; + + setting->SetGlobal(using_global); + if (!using_global) { + setting->LoadString(std::to_string(index)); + } + }; + + return {group, load_func}; +} + +QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& translations, + QWidget* parent, bool runtime_lock, + std::forward_list>& apply_funcs, + std::list& trackers) { + const auto type = setting->TypeId(); + QWidget* widget{nullptr}; + + std::function load_func; + + const auto [label, tooltip] = [&]() { + const auto& setting_label = setting->GetLabel(); + if (translations.contains(setting_label)) { + return std::pair{translations.at(setting_label).first, + translations.at(setting_label).second}; + } + LOG_ERROR(Frontend, "Translation map lacks entry for \"{}\"", setting_label); + return std::pair{QString::fromStdString(setting_label), QStringLiteral("")}; + }(); + + if (type == typeid(bool)) { + auto pair = CreateCheckBox(setting, label, parent, trackers); + widget = pair.first; + load_func = pair.second; + } else if (setting->IsEnum()) { + auto pair = CreateCombobox(setting, label, parent); + widget = pair.first; + load_func = pair.second; + } + + if (widget == nullptr) { + LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel()); + return widget; + } + + apply_funcs.push_front([load_func, setting](bool powered_on) { + if (setting->RuntimeModfiable() || !powered_on) { + load_func(); + } + }); + + bool enable = runtime_lock || setting->RuntimeModfiable(); + enable &= + setting->Switchable() && !(Settings::IsConfiguringGlobal() && !setting->UsingGlobal()); + + widget->setEnabled(enable); + widget->setVisible(Settings::IsConfiguringGlobal() || setting->Switchable()); + + widget->setToolTip(tooltip); + + return widget; +} Tab::Tab(std::shared_ptr> group_, QWidget* parent) : QWidget(parent), group{group_} { -- cgit v1.2.3 From 75d7e40113c03ec6a2a83fb8cfa736a17c6862a3 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Sun, 7 May 2023 10:35:28 -0400 Subject: settings: Recategorize a bit Will help with generating config UI later. --- src/yuzu/configuration/configuration_shared.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 44222718c..dc11a318a 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -128,10 +128,16 @@ QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& tra return std::pair{translations.at(setting_label).first, translations.at(setting_label).second}; } - LOG_ERROR(Frontend, "Translation map lacks entry for \"{}\"", setting_label); + 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 widget; + } + if (type == typeid(bool)) { auto pair = CreateCheckBox(setting, label, parent, trackers); widget = pair.first; -- cgit v1.2.3 From f8435d676f0073dee4d2ea87c84767a53911fbe6 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Sun, 7 May 2023 12:03:40 -0400 Subject: configure_graphics: Partial runtime implementation --- src/yuzu/configuration/configuration_shared.cpp | 72 +++++++++++++++++++------ 1 file changed, 57 insertions(+), 15 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index dc11a318a..575d239eb 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -55,9 +56,8 @@ static std::pair> CreateCheckBox(Settings::Basic return {checkbox, load_func}; } -static std::pair> CreateCombobox(Settings::BasicSetting* setting, - const QString& label, - QWidget* parent) { +static std::tuple> CreateCombobox( + Settings::BasicSetting* setting, const QString& label, QWidget* parent) { const auto type = setting->TypeId(); QWidget* group = new QWidget(parent); @@ -110,15 +110,34 @@ static std::pair> CreateCombobox(Settings::Basic } }; - return {group, load_func}; + return {group, combobox, load_func}; +} + +static std::tuple> CreateLineEdit( + Settings::BasicSetting* setting, const QString& label, QWidget* parent) { + QWidget* widget = new QWidget(parent); + QHBoxLayout* layout = new QHBoxLayout(widget); + + QLabel* q_label = new QLabel(label, widget); + QLineEdit* line_edit = new QLineEdit(widget); + + layout->addWidget(q_label); + layout->addStretch(); + layout->addWidget(line_edit); + + layout->setContentsMargins(0, 0, 0, 0); + + return {widget, line_edit, []() {}}; } -QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& translations, - QWidget* parent, bool runtime_lock, - std::forward_list>& apply_funcs, - std::list& trackers) { +std::pair CreateWidget(Settings::BasicSetting* setting, + const TranslationMap& translations, QWidget* parent, + bool runtime_lock, + std::forward_list>& apply_funcs, + std::list& trackers, RequestType request) { const auto type = setting->TypeId(); QWidget* widget{nullptr}; + void* extra{nullptr}; std::function load_func; @@ -135,7 +154,7 @@ QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& tra if (label == QStringLiteral("")) { LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...", setting->GetLabel()); - return widget; + return {nullptr, nullptr}; } if (type == typeid(bool)) { @@ -143,14 +162,36 @@ QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& tra widget = pair.first; load_func = pair.second; } else if (setting->IsEnum()) { - auto pair = CreateCombobox(setting, label, parent); - widget = pair.first; - load_func = pair.second; + auto tuple = CreateCombobox(setting, label, parent); + widget = std::get<0>(tuple); + extra = std::get<1>(tuple); + load_func = std::get<2>(tuple); + } else if (type == typeid(u32) || type == typeid(int)) { + switch (request) { + case RequestType::Default: { + auto tuple = CreateLineEdit(setting, label, parent); + widget = std::get<0>(tuple); + extra = std::get<1>(tuple); + load_func = std::get<2>(tuple); + break; + } + case RequestType::ComboBox: { + auto tuple = CreateCombobox(setting, label, parent); + widget = std::get<0>(tuple); + extra = std::get<1>(tuple); + load_func = std::get<2>(tuple); + break; + } + case RequestType::SpinBox: + case RequestType::Slider: + case RequestType::MaxEnum: + break; + } } if (widget == nullptr) { LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel()); - return widget; + return {nullptr, nullptr}; } apply_funcs.push_front([load_func, setting](bool powered_on) { @@ -162,13 +203,14 @@ QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& tra bool enable = runtime_lock || setting->RuntimeModfiable(); enable &= setting->Switchable() && !(Settings::IsConfiguringGlobal() && !setting->UsingGlobal()); - + enable |= !setting->Switchable() && Settings::IsConfiguringGlobal() && runtime_lock; widget->setEnabled(enable); + widget->setVisible(Settings::IsConfiguringGlobal() || setting->Switchable()); widget->setToolTip(tooltip); - return widget; + return {widget, extra}; } Tab::Tab(std::shared_ptr> group_, QWidget* parent) -- cgit v1.2.3 From cfb63c68dbdc2c8add45cddb2cedf371059af6c4 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Sun, 7 May 2023 13:28:52 -0400 Subject: shared_translation: Finish using int ids --- src/yuzu/configuration/configuration_shared.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 575d239eb..54fbce53a 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -136,6 +136,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, std::forward_list>& apply_funcs, std::list& trackers, RequestType request) { const auto type = setting->TypeId(); + const int id = setting->Id(); QWidget* widget{nullptr}; void* extra{nullptr}; @@ -143,9 +144,8 @@ std::pair CreateWidget(Settings::BasicSetting* setting, const auto [label, tooltip] = [&]() { const auto& setting_label = setting->GetLabel(); - if (translations.contains(setting_label)) { - return std::pair{translations.at(setting_label).first, - translations.at(setting_label).second}; + 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("")}; -- cgit v1.2.3 From 05c26411a399d415793fcc1c729ea00f87416b46 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 8 May 2023 09:33:23 -0400 Subject: configuration_shared: Fix blank state hiding check box --- src/yuzu/configuration/configuration_shared.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 54fbce53a..80637f3a2 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -253,8 +253,7 @@ void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) { widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }") .arg(widget->objectName())); } else { - widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,0,0,0) }") - .arg(widget->objectName())); + widget->setStyleSheet(QStringLiteral("")); } widget->show(); } -- cgit v1.2.3 From 9a844bbf0cb14c9de33225ded27a78852e044df6 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 8 May 2023 10:04:44 -0400 Subject: configure_graphics: More complete reimplementation --- src/yuzu/configuration/configuration_shared.cpp | 107 +++++++++++++++++------- 1 file changed, 77 insertions(+), 30 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 80637f3a2..8d5ab8b4c 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" @@ -57,7 +58,7 @@ static std::pair> CreateCheckBox(Settings::Basic } static std::tuple> CreateCombobox( - Settings::BasicSetting* setting, const QString& label, QWidget* parent) { + Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed) { const auto type = setting->TypeId(); QWidget* group = new QWidget(parent); @@ -78,7 +79,7 @@ static std::tuple> CreateCombobox( combobox_layout->setSpacing(6); combobox_layout->setContentsMargins(0, 0, 0, 0); - if (setting->Switchable() && !Settings::IsConfiguringGlobal()) { + if (setting->Switchable() && !Settings::IsConfiguringGlobal() && managed) { int current = std::stoi(setting->ToString()); int global_value = std::stoi(setting->ToStringGlobal()); SetColoredComboBox(combobox, group, global_value); @@ -92,23 +93,26 @@ static std::tuple> CreateCombobox( combobox->setCurrentIndex(std::stoi(setting->ToString())); } - const auto load_func = [combobox, setting]() { - if (Settings::IsConfiguringGlobal()) { - setting->LoadString(std::to_string(combobox->currentIndex())); - } - - if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { - return; - } - - bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX; - int index = combobox->currentIndex() - USE_GLOBAL_OFFSET; - - setting->SetGlobal(using_global); - if (!using_global) { - setting->LoadString(std::to_string(index)); - } - }; + std::function load_func = []() {}; + if (managed) { + load_func = [combobox, setting]() { + if (Settings::IsConfiguringGlobal()) { + setting->LoadString(std::to_string(combobox->currentIndex())); + } + + if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { + return; + } + + bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX; + int index = combobox->currentIndex() - USE_GLOBAL_OFFSET; + + setting->SetGlobal(using_global); + if (!using_global) { + setting->LoadString(std::to_string(index)); + } + }; + } return {group, combobox, load_func}; } @@ -116,25 +120,68 @@ static std::tuple> CreateCombobox( static std::tuple> CreateLineEdit( Settings::BasicSetting* setting, const QString& label, QWidget* parent) { 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 load_func; - QLabel* q_label = new QLabel(label, widget); - QLineEdit* line_edit = new QLineEdit(widget); + // setSizePolicy lets widget expand and take an equal part of the space as the line edit + if (Settings::IsConfiguringGlobal()) { + QLabel* q_label = new QLabel(label, widget); + q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + layout->addWidget(q_label); + + load_func = [&]() { + std::string load_text = line_edit->text().toStdString(); + setting->LoadString(load_text); + }; + } else { + QCheckBox* checkbox = new QCheckBox(label, parent); + checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + layout->addWidget(checkbox); + + const auto highlight_func = [widget, line_edit](int state) { + bool using_global = state != Qt::Checked; + SetHighlight(widget, !using_global); + line_edit->setEnabled(!using_global); + }; + + QObject::connect(checkbox, qOverload(&QCheckBox::stateChanged), widget, + highlight_func); + + checkbox->setCheckState(setting->UsingGlobal() ? Qt::Unchecked : Qt::Checked); + highlight_func(checkbox->checkState()); + + load_func = [&]() { + if (checkbox->checkState() == Qt::Checked) { + setting->SetGlobal(false); + + std::string load_text = line_edit->text().toStdString(); + setting->LoadString(load_text); + } else { + setting->SetGlobal(true); + } + }; + } - layout->addWidget(q_label); - layout->addStretch(); layout->addWidget(line_edit); layout->setContentsMargins(0, 0, 0, 0); - return {widget, line_edit, []() {}}; + return {widget, line_edit, load_func}; } std::pair CreateWidget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, bool runtime_lock, std::forward_list>& apply_funcs, - std::list& trackers, RequestType request) { + std::list& trackers, RequestType request, + bool managed) { const auto type = setting->TypeId(); const int id = setting->Id(); QWidget* widget{nullptr}; @@ -162,7 +209,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, widget = pair.first; load_func = pair.second; } else if (setting->IsEnum()) { - auto tuple = CreateCombobox(setting, label, parent); + auto tuple = CreateCombobox(setting, label, parent, managed); widget = std::get<0>(tuple); extra = std::get<1>(tuple); load_func = std::get<2>(tuple); @@ -176,7 +223,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, break; } case RequestType::ComboBox: { - auto tuple = CreateCombobox(setting, label, parent); + auto tuple = CreateCombobox(setting, label, parent, managed); widget = std::get<0>(tuple); extra = std::get<1>(tuple); load_func = std::get<2>(tuple); @@ -201,9 +248,9 @@ std::pair CreateWidget(Settings::BasicSetting* setting, }); bool enable = runtime_lock || setting->RuntimeModfiable(); - enable &= - setting->Switchable() && !(Settings::IsConfiguringGlobal() && !setting->UsingGlobal()); - enable |= !setting->Switchable() && Settings::IsConfiguringGlobal() && runtime_lock; + if (setting->Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) { + enable &= !setting->UsingGlobal(); + } widget->setEnabled(enable); widget->setVisible(Settings::IsConfiguringGlobal() || setting->Switchable()); -- cgit v1.2.3 From 39a1ffbb91a026fd3842f55ebca222db50afea41 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 8 May 2023 14:11:45 -0400 Subject: configuration: Use buttons instead of highlights Only for updated configs at the moment --- src/yuzu/configuration/configuration_shared.cpp | 177 +++++++++++++++--------- 1 file changed, 108 insertions(+), 69 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 8d5ab8b4c..45165c2e9 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -2,119 +2,151 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include #include #include #include +#include #include +#include #include +#include #include +#include #include +#include #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_per_game.h" #include "yuzu/configuration/shared_translation.h" namespace ConfigurationShared { + +static QPushButton* CreateClearGlobalButton(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::pair> CreateCheckBox(Settings::BasicSetting* setting, const QString& label, QWidget* parent, std::list& trackers) { + 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); - CheckState* tracker{}; - - // Per-game config highlight - if (setting->Switchable() && !Settings::IsConfiguringGlobal()) { - bool global_state = setting->ToStringGlobal() == "true"; - bool state = setting->ToString() == "true"; - bool global = setting->UsingGlobal(); - tracker = &trackers.emplace_front(CheckState{}); - SetColoredTristate(checkbox, global, state, global_state, *tracker); - } + std::function load_func; - auto load_func = [checkbox, setting, tracker]() { - if (Settings::IsConfiguringGlobal()) { + layout->addWidget(checkbox); + if (Settings::IsConfiguringGlobal()) { + load_func = [setting, checkbox]() { setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); - } - - if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { - return; - } + }; + } else { + auto* button = CreateClearGlobalButton(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"); + } + }; + } - if (*tracker != CheckState::Global) { - setting->SetGlobal(false); - setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); - } else { - setting->SetGlobal(true); - } - }; + layout->setContentsMargins(0, 0, 0, 0); - return {checkbox, load_func}; + return {widget, load_func}; } -static std::tuple> CreateCombobox( +static std::tuple> 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* combobox_layout = new QHBoxLayout(group); + QLayout* layout = new QHBoxLayout(group); QLabel* qt_label = new QLabel(label, parent); QComboBox* combobox = new QComboBox(parent); + QPushButton* button{nullptr}; + std::forward_list combobox_enumerations = ComboboxEnumeration(type, parent); for (const auto& item : combobox_enumerations) { combobox->addItem(item); } - combobox_layout->addWidget(qt_label); - combobox_layout->addWidget(combobox); + layout->addWidget(qt_label); + layout->addWidget(combobox); - combobox_layout->setSpacing(6); - combobox_layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(6); + layout->setContentsMargins(0, 0, 0, 0); - if (setting->Switchable() && !Settings::IsConfiguringGlobal() && managed) { - int current = std::stoi(setting->ToString()); - int global_value = std::stoi(setting->ToStringGlobal()); - SetColoredComboBox(combobox, group, global_value); - if (setting->UsingGlobal()) { - combobox->setCurrentIndex(USE_GLOBAL_INDEX); - } else { - SetHighlight(group, true); - combobox->setCurrentIndex(current + USE_GLOBAL_OFFSET); - } - } else { - combobox->setCurrentIndex(std::stoi(setting->ToString())); - } + combobox->setCurrentIndex(std::stoi(setting->ToString())); std::function load_func = []() {}; - if (managed) { - load_func = [combobox, setting]() { - if (Settings::IsConfiguringGlobal()) { - setting->LoadString(std::to_string(combobox->currentIndex())); - } - if (Settings::IsConfiguringGlobal() || !setting->Switchable()) { - return; - } + if (Settings::IsConfiguringGlobal() && managed) { + load_func = [setting, combobox]() { + setting->LoadString(std::to_string(combobox->currentIndex())); + }; + } else if (managed) { + button = CreateClearGlobalButton(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())); + }); - bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX; - int index = combobox->currentIndex() - USE_GLOBAL_OFFSET; + QObject::connect(combobox, QOverload::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(index)); + setting->LoadString(std::to_string(combobox->currentIndex())); } }; } - return {group, combobox, load_func}; + return {group, combobox, button, load_func}; } static std::tuple> CreateLineEdit( @@ -136,7 +168,7 @@ static std::tuple> CreateLineEdit( q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); layout->addWidget(q_label); - load_func = [&]() { + load_func = [line_edit, setting]() { std::string load_text = line_edit->text().toStdString(); setting->LoadString(load_text); }; @@ -157,7 +189,7 @@ static std::tuple> CreateLineEdit( checkbox->setCheckState(setting->UsingGlobal() ? Qt::Unchecked : Qt::Checked); highlight_func(checkbox->checkState()); - load_func = [&]() { + load_func = [checkbox, setting, line_edit]() { if (checkbox->checkState() == Qt::Checked) { setting->SetGlobal(false); @@ -176,12 +208,15 @@ static std::tuple> CreateLineEdit( return {widget, line_edit, load_func}; } -std::pair CreateWidget(Settings::BasicSetting* setting, - const TranslationMap& translations, QWidget* parent, - bool runtime_lock, - std::forward_list>& apply_funcs, - std::list& trackers, RequestType request, - bool managed) { +std::tuple CreateWidget( + Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, + bool runtime_lock, std::forward_list>& apply_funcs, + std::list& trackers, RequestType request, bool managed) { + 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}; @@ -201,9 +236,11 @@ std::pair CreateWidget(Settings::BasicSetting* setting, if (label == QStringLiteral("")) { LOG_DEBUG(Frontend, "Translation table has emtpy entry for \"{}\", skipping...", setting->GetLabel()); - return {nullptr, nullptr}; + return {nullptr, nullptr, nullptr}; } + QPushButton* button; + if (type == typeid(bool)) { auto pair = CreateCheckBox(setting, label, parent, trackers); widget = pair.first; @@ -212,7 +249,8 @@ std::pair CreateWidget(Settings::BasicSetting* setting, auto tuple = CreateCombobox(setting, label, parent, managed); widget = std::get<0>(tuple); extra = std::get<1>(tuple); - load_func = std::get<2>(tuple); + button = std::get<2>(tuple); + load_func = std::get<3>(tuple); } else if (type == typeid(u32) || type == typeid(int)) { switch (request) { case RequestType::Default: { @@ -226,7 +264,8 @@ std::pair CreateWidget(Settings::BasicSetting* setting, auto tuple = CreateCombobox(setting, label, parent, managed); widget = std::get<0>(tuple); extra = std::get<1>(tuple); - load_func = std::get<2>(tuple); + button = std::get<2>(tuple); + load_func = std::get<3>(tuple); break; } case RequestType::SpinBox: @@ -238,7 +277,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, if (widget == nullptr) { LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel()); - return {nullptr, nullptr}; + return {nullptr, nullptr, nullptr}; } apply_funcs.push_front([load_func, setting](bool powered_on) { @@ -257,7 +296,7 @@ std::pair CreateWidget(Settings::BasicSetting* setting, widget->setToolTip(tooltip); - return {widget, extra}; + return {widget, extra, button}; } Tab::Tab(std::shared_ptr> group_, QWidget* parent) -- cgit v1.2.3 From d35577d3ed0bfc56ddf85a2e8b163d9d02bec809 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 8 May 2023 17:33:10 -0400 Subject: configuration: Implement slider --- src/yuzu/configuration/configuration_shared.cpp | 203 +++++++++++++++++++----- 1 file changed, 159 insertions(+), 44 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 45165c2e9..076d9cc0d 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -13,10 +13,14 @@ #include #include #include +#include +#include #include #include #include +#include #include +#include #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_per_game.h" @@ -24,7 +28,7 @@ namespace ConfigurationShared { -static QPushButton* CreateClearGlobalButton(QWidget* parent, Settings::BasicSetting* setting) { +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); @@ -40,10 +44,8 @@ static QPushButton* CreateClearGlobalButton(QWidget* parent, Settings::BasicSett return button; } -static std::pair> CreateCheckBox(Settings::BasicSetting* setting, - const QString& label, - QWidget* parent, - std::list& trackers) { +static std::tuple> CreateCheckBox( + Settings::BasicSetting* setting, const QString& label, QWidget* parent) { QWidget* widget = new QWidget(parent); QHBoxLayout* layout = new QHBoxLayout(widget); @@ -54,13 +56,15 @@ static std::pair> CreateCheckBox(Settings::Basic std::function load_func; + QPushButton* button{nullptr}; + layout->addWidget(checkbox); if (Settings::IsConfiguringGlobal()) { load_func = [setting, checkbox]() { setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); }; } else { - auto* button = CreateClearGlobalButton(parent, setting); + button = CreateRestoreGlobalButton(parent, setting); layout->addWidget(button); QObject::connect(checkbox, &QCheckBox::stateChanged, [button](int) { @@ -86,7 +90,7 @@ static std::pair> CreateCheckBox(Settings::Basic layout->setContentsMargins(0, 0, 0, 0); - return {widget, load_func}; + return {widget, checkbox, button, load_func}; } static std::tuple> CreateCombobox( @@ -122,7 +126,7 @@ static std::tuple> Cre setting->LoadString(std::to_string(combobox->currentIndex())); }; } else if (managed) { - button = CreateClearGlobalButton(parent, setting); + button = CreateRestoreGlobalButton(parent, setting); layout->addWidget(button); QObject::connect(button, &QAbstractButton::clicked, [button, combobox, setting](bool) { @@ -149,8 +153,8 @@ static std::tuple> Cre return {group, combobox, button, load_func}; } -static std::tuple> CreateLineEdit( - Settings::BasicSetting* setting, const QString& label, QWidget* parent) { +static std::tuple> CreateLineEdit( + Settings::BasicSetting* setting, const QString& label, QWidget* parent, bool managed = true) { QWidget* widget = new QWidget(parent); widget->setObjectName(label); @@ -160,58 +164,140 @@ static std::tuple> CreateLineEdit( const QString text = QString::fromStdString(setting->ToString()); line_edit->setText(text); - std::function load_func; + std::function 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 - if (Settings::IsConfiguringGlobal()) { - QLabel* q_label = new QLabel(label, widget); - q_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - layout->addWidget(q_label); + 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 { - QCheckBox* checkbox = new QCheckBox(label, parent); - checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - layout->addWidget(checkbox); - - const auto highlight_func = [widget, line_edit](int state) { - bool using_global = state != Qt::Checked; - SetHighlight(widget, !using_global); - line_edit->setEnabled(!using_global); - }; + } else if (!managed) { + button = CreateRestoreGlobalButton(parent, setting); + layout->addWidget(button); - QObject::connect(checkbox, qOverload(&QCheckBox::stateChanged), widget, - highlight_func); + QObject::connect(button, &QAbstractButton::clicked, [=](bool) { + button->setEnabled(false); + button->setVisible(false); - checkbox->setCheckState(setting->UsingGlobal() ? Qt::Unchecked : Qt::Checked); - highlight_func(checkbox->checkState()); + line_edit->setText(QString::fromStdString(setting->ToStringGlobal())); + }); - load_func = [checkbox, setting, line_edit]() { - if (checkbox->checkState() == Qt::Checked) { - setting->SetGlobal(false); + QObject::connect(line_edit, &QLineEdit::textChanged, [=](QString) { + button->setEnabled(true); + button->setVisible(true); + }); - std::string load_text = line_edit->text().toStdString(); - setting->LoadString(load_text); - } else { - setting->SetGlobal(true); + load_func = [=]() { + bool using_global = !button->isEnabled(); + setting->SetGlobal(using_global); + if (!using_global) { + setting->LoadString(line_edit->text().toStdString()); } }; } - layout->addWidget(line_edit); + layout->setContentsMargins(0, 0, 0, 0); + + return {widget, line_edit, button, load_func}; +} + +static std::tuple> 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); - return {widget, line_edit, load_func}; + 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 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> +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(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 CreateWidget( Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, bool runtime_lock, std::forward_list>& apply_funcs, - std::list& trackers, RequestType request, bool managed) { + 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}; @@ -242,9 +328,27 @@ std::tuple CreateWidget( QPushButton* button; if (type == typeid(bool)) { - auto pair = CreateCheckBox(setting, label, parent, trackers); - widget = pair.first; - load_func = pair.second; + 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); @@ -253,11 +357,13 @@ std::tuple CreateWidget( 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); - load_func = std::get<2>(tuple); + button = std::get<2>(tuple); + load_func = std::get<3>(tuple); break; } case RequestType::ComboBox: { @@ -268,8 +374,17 @@ std::tuple CreateWidget( load_func = std::get<3>(tuple); break; } - case RequestType::SpinBox: 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; } -- cgit v1.2.3 From f66d617107e45f8213643f2bbaa5f58878c3d3a6 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 8 May 2023 22:37:03 -0400 Subject: configuration: Move CreateWidget to a class We were passing so many objects between the function and the caller that it needed to be redesigned. --- src/yuzu/configuration/configuration_shared.cpp | 386 ------------------------ 1 file changed, 386 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 076d9cc0d..dff70f04b 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -28,392 +28,6 @@ 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> 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 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> 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 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 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::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> 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 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> 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 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> -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(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 CreateWidget( - Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, - bool runtime_lock, std::forward_list>& 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 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> group_, QWidget* parent) : QWidget(parent), group{group_} { if (group != nullptr) { -- cgit v1.2.3 From 333725074644f0e6cf13b29dc24e654b07617380 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 18 May 2023 22:56:48 -0400 Subject: configuration_shared: Remove old custom config setup functions --- src/yuzu/configuration/configuration_shared.cpp | 75 ------------------------- 1 file changed, 75 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index dff70f04b..624d9ba1b 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -38,78 +38,3 @@ Tab::Tab(std::shared_ptr> group_, QWidget* parent) Tab::~Tab() = default; } // namespace ConfigurationShared - -void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting* setting, - const QCheckBox* checkbox, - const CheckState& tracker) { - if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) { - setting->SetValue(checkbox->checkState()); - } else if (!Settings::IsConfiguringGlobal()) { - if (tracker == CheckState::Global) { - setting->SetGlobal(true); - } else { - setting->SetGlobal(false); - setting->SetValue(checkbox->checkState()); - } - } -} - -void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox, - const Settings::SwitchableSetting* setting) { - if (setting->UsingGlobal()) { - checkbox->setCheckState(Qt::PartiallyChecked); - } else { - checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked); - } -} - -void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) { - if (highlighted) { - widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }") - .arg(widget->objectName())); - } else { - widget->setStyleSheet(QStringLiteral("")); - } - widget->show(); -} - -void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, bool global, bool state, - bool global_state, CheckState& tracker) { - if (global) { - tracker = CheckState::Global; - } else { - tracker = (state == global_state) ? CheckState::On : CheckState::Off; - } - SetHighlight(checkbox, tracker != CheckState::Global); - QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, global_state, &tracker] { - tracker = static_cast((static_cast(tracker) + 1) % - static_cast(CheckState::Count)); - if (tracker == CheckState::Global) { - checkbox->setChecked(global_state); - } - SetHighlight(checkbox, tracker != CheckState::Global); - }); -} - -void ConfigurationShared::SetColoredComboBox(QComboBox* combobox, QWidget* target, int global) { - InsertGlobalItem(combobox, global); - QObject::connect(combobox, qOverload(&QComboBox::activated), target, - [target](int index) { SetHighlight(target, index != 0); }); -} - -void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index) { - const QString use_global_text = - ConfigurePerGame::tr("Use global configuration (%1)").arg(combobox->itemText(global_index)); - combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text); - combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX); -} - -int ConfigurationShared::GetComboboxIndex(int global_setting_index, const QComboBox* combobox) { - if (Settings::IsConfiguringGlobal()) { - return combobox->currentIndex(); - } - if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { - return global_setting_index; - } - return combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET; -} -- cgit v1.2.3 From 217fa040809c083a8b680962589da264f8d8e4c4 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 18 May 2023 23:05:21 -0400 Subject: configuration: Clean up includes a bit --- src/yuzu/configuration/configuration_shared.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 624d9ba1b..d3cfacf48 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -2,29 +2,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common/settings.h" +#include #include "yuzu/configuration/configuration_shared.h" -#include "yuzu/configuration/configure_per_game.h" -#include "yuzu/configuration/shared_translation.h" namespace ConfigurationShared { -- cgit v1.2.3 From 02c48a80f6f8f88716cdacbfb62643d04632949a Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Tue, 20 Jun 2023 19:34:50 -0400 Subject: config_shared: Remove storing the group from tab --- src/yuzu/configuration/configuration_shared.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index d3cfacf48..8c12d063e 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -7,8 +7,7 @@ namespace ConfigurationShared { -Tab::Tab(std::shared_ptr> group_, QWidget* parent) - : QWidget(parent), group{group_} { +Tab::Tab(std::shared_ptr> group, QWidget* parent) : QWidget(parent) { if (group != nullptr) { group->push_front(this); } -- cgit v1.2.3 From 17b9c1e1715a16bebcdd92c02ce7f7e503212462 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Fri, 21 Jul 2023 23:09:09 -0400 Subject: common,qt-config: Remove usage of forward_list --- src/yuzu/configuration/configuration_shared.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/yuzu/configuration/configuration_shared.cpp') diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 8c12d063e..0ed6146a0 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -3,13 +3,14 @@ #include #include +#include #include "yuzu/configuration/configuration_shared.h" namespace ConfigurationShared { -Tab::Tab(std::shared_ptr> group, QWidget* parent) : QWidget(parent) { +Tab::Tab(std::shared_ptr> group, QWidget* parent) : QWidget(parent) { if (group != nullptr) { - group->push_front(this); + group->push_back(this); } } -- cgit v1.2.3