diff options
author | lat9nq <22451773+lat9nq@users.noreply.github.com> | 2023-05-07 09:48:26 -0400 |
---|---|---|
committer | lat9nq <22451773+lat9nq@users.noreply.github.com> | 2023-07-21 10:56:07 -0400 |
commit | a007ac6b9ccc23861f5a5c6967d535220ed794b0 (patch) | |
tree | 934c66c124dd77a17fae07ae919335efb1107255 /src/yuzu/configuration/configuration_shared.cpp | |
parent | b11b4be7cb764bc0c1aa6c563ccf41a3d1b335dd (diff) |
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.
Diffstat (limited to 'src/yuzu/configuration/configuration_shared.cpp')
-rw-r--r-- | src/yuzu/configuration/configuration_shared.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
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 <memory> #include <QCheckBox> +#include <QHBoxLayout> +#include <QLabel> #include <QObject> #include <QString> #include <QWidget> +#include <qnamespace.h> #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<QWidget*, std::function<void()>> CreateCheckBox(Settings::BasicSetting* setting, + const QString& label, + QWidget* parent, + std::list<CheckState>& 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<QWidget*, std::function<void()>> 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<QString> 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<std::function<void(bool)>>& apply_funcs, + std::list<CheckState>& trackers) { + const auto type = setting->TypeId(); + QWidget* widget{nullptr}; + + std::function<void()> 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<std::forward_list<Tab*>> group_, QWidget* parent) : QWidget(parent), group{group_} { |