From 8a4cb3f902ad335a100728462721c8ea02c0dbe9 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:02:31 -0400 Subject: shared_widget: Implement radio groups --- src/yuzu/configuration/shared_widget.cpp | 68 +++++++++++++++++++++++++++++++- src/yuzu/configuration/shared_widget.h | 6 +++ 2 files changed, 73 insertions(+), 1 deletion(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index bdb38c8ea..36d8da5a5 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -171,6 +172,65 @@ QWidget* Widget::CreateCombobox(std::function& serializer, return combobox; } +QWidget* Widget::CreateRadioGroup(std::function& serializer, + std::function& restore_func, + const std::function& touch) { + const auto type = setting.EnumIndex(); + + QWidget* group = new QWidget(this); + QHBoxLayout* layout = new QHBoxLayout(group); + layout->setContentsMargins(0, 0, 0, 0); + group->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + const ComboboxTranslations* enumeration{nullptr}; + if (combobox_enumerations.contains(type)) { + enumeration = &combobox_enumerations.at(type); + for (const auto& [id, name] : *enumeration) { + QRadioButton* radio_button = new QRadioButton(name, group); + layout->addWidget(radio_button); + radio_buttons.push_back({id, radio_button}); + } + } else { + return group; + } + + const auto get_selected = [=]() -> u32 { + for (const auto& [id, button] : radio_buttons) { + if (button->isChecked()) { + return id; + } + } + return -1; + }; + + const auto set_index = [=](u32 value) { + for (const auto& [id, button] : radio_buttons) { + button->setChecked(id == value); + } + }; + + const u32 setting_value = std::stoi(setting.ToString()); + set_index(setting_value); + + serializer = [get_selected]() { + int current = get_selected(); + return std::to_string(current); + }; + + restore_func = [this, set_index]() { + const u32 global_value = std::stoi(RelevantDefault(setting)); + set_index(global_value); + }; + + if (!Settings::IsConfiguringGlobal()) { + for (const auto& [id, button] : radio_buttons) { + QObject::connect(button, &QAbstractButton::clicked, [touch]() { touch(); }); + } + } + + return group; +} + QWidget* Widget::CreateLineEdit(std::function& serializer, std::function& restore_func, const std::function& touch, bool managed) { @@ -410,6 +470,8 @@ void Widget::SetupComponent(const QString& label, std::function& load_fu return RequestType::Slider; case Settings::Specialization::Countable: return RequestType::SpinBox; + case Settings::Specialization::Radio: + return RequestType::RadioGroup; default: break; } @@ -438,7 +500,11 @@ void Widget::SetupComponent(const QString& label, std::function& load_fu if (setting.TypeId() == typeid(bool)) { data_component = CreateCheckBox(&setting, label, serializer, restore_func, touch); } else if (setting.IsEnum()) { - data_component = CreateCombobox(serializer, restore_func, touch); + if (request == RequestType::RadioGroup) { + data_component = CreateRadioGroup(serializer, restore_func, touch); + } else { + data_component = CreateCombobox(serializer, restore_func, touch); + } } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || type == typeid(s64) || type == typeid(u8)) { switch (request) { diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index e64693bab..5303dd898 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h @@ -22,6 +22,7 @@ class QObject; class QPushButton; class QSlider; class QSpinBox; +class QRadioButton; namespace Settings { class BasicSetting; @@ -38,6 +39,7 @@ enum class RequestType { LineEdit, HexEdit, DateTimeEdit, + RadioGroup, MaxEnum, }; @@ -91,6 +93,7 @@ public: QSlider* slider{}; QComboBox* combobox{}; QDateTimeEdit* date_time_edit{}; + std::vector> radio_buttons{}; private: void SetupComponent(const QString& label, std::function& load_func, bool managed, @@ -106,6 +109,9 @@ private: QWidget* CreateCombobox(std::function& serializer, std::function& restore_func, const std::function& touch); + QWidget* CreateRadioGroup(std::function& serializer, + std::function& restore_func, + const std::function& touch); QWidget* CreateLineEdit(std::function& serializer, std::function& restore_func, const std::function& touch, bool managed = true); -- cgit v1.2.3 From 387ede76d2e1e427f6722cbe19a018c95d762748 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:03:30 -0400 Subject: general: Convert use_docked_mode to an enumeration Allows some special interactions with it in the Qt frontend. --- src/yuzu/configuration/config.cpp | 9 +++++---- src/yuzu/configuration/config.h | 3 ++- src/yuzu/configuration/configure_input.cpp | 18 +++++++++++++----- 3 files changed, 20 insertions(+), 10 deletions(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index b22c83303..1de093447 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -9,6 +9,7 @@ #include "common/fs/path_util.h" #include "common/settings.h" #include "common/settings_common.h" +#include "common/settings_enums.h" #include "core/core.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/hid/controllers/npad.h" @@ -85,9 +86,9 @@ const std::map Config::scaling_filter_texts_ma {Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))}, }; -const std::map Config::use_docked_mode_texts_map = { - {true, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))}, - {false, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))}, +const std::map Config::use_docked_mode_texts_map = { + {Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))}, + {Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))}, }; const std::map Config::gpu_accuracy_texts_map = { @@ -376,7 +377,7 @@ void Config::ReadControlValues() { const auto controller_type = Settings::values.players.GetValue()[0].controller_type; if (controller_type == Settings::ControllerType::Handheld) { Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig()); - Settings::values.use_docked_mode.SetValue(false); + Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld); } if (IsCustomConfig()) { diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 0ac74c8e7..727feebfb 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -9,6 +9,7 @@ #include #include #include "common/settings.h" +#include "common/settings_enums.h" #include "yuzu/uisettings.h" class QSettings; @@ -51,7 +52,7 @@ public: static const std::map anti_aliasing_texts_map; static const std::map scaling_filter_texts_map; - static const std::map use_docked_mode_texts_map; + static const std::map use_docked_mode_texts_map; static const std::map gpu_accuracy_texts_map; static const std::map renderer_backend_texts_map; static const std::map shader_backend_texts_map; diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 7fce85bca..78ed8c610 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/settings_enums.h" #include "core/core.h" #include "core/hid/emulated_controller.h" #include "core/hid/hid_core.h" @@ -197,9 +198,14 @@ void ConfigureInput::ApplyConfiguration() { advanced->ApplyConfiguration(); - const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue(); - Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked()); - OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue(), system); + const bool pre_docked_mode = + Settings::values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked; + Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked() + ? Settings::ConsoleMode::Docked + : Settings::ConsoleMode::Handheld); + OnDockedModeChanged( + pre_docked_mode, + Settings::values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked, system); Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked()); Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked()); @@ -267,8 +273,10 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) { ui->radioDocked->setEnabled(!is_handheld); ui->radioUndocked->setEnabled(!is_handheld); - ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue()); - ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue()); + ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue() == + Settings::ConsoleMode::Docked); + ui->radioUndocked->setChecked(Settings::values.use_docked_mode.GetValue() == + Settings::ConsoleMode::Handheld); // Also force into undocked mode if the controller type is handheld. if (is_handheld) { -- cgit v1.2.3 From 6ed5b581f0ae8f335e5ee9f02a94919cd4b7e4a3 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:03:46 -0400 Subject: shared_translation: Define use_docked_mode texts --- src/yuzu/configuration/shared_translation.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index 335810788..276bdbaba 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -135,7 +135,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT(Settings, region_index, "Region:", ""); INSERT(Settings, time_zone_index, "Time Zone:", ""); INSERT(Settings, sound_index, "Sound Output Mode:", ""); - INSERT(Settings, use_docked_mode, "", ""); + INSERT(Settings, use_docked_mode, "Console Mode:", ""); INSERT(Settings, current_user, "", ""); // Controls @@ -379,6 +379,9 @@ std::unique_ptr ComboboxEnumeration(QWidget* parent) { PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"), PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"), }}); + translations->insert( + {Settings::EnumMetadata::Index(), + {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}}); #undef PAIR #undef CTX_PAIR -- cgit v1.2.3 From 7f8335f4ae4c87764faf91c1d866bded95d1e6ad Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:33:56 -0400 Subject: config(qt): Sanitize docked handheld controller --- src/yuzu/configuration/configure_per_game.cpp | 8 ++++++++ src/yuzu/configuration/configure_system.cpp | 5 +++++ 2 files changed, 13 insertions(+) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 4f9e8db08..e371f902e 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -18,6 +18,7 @@ #include "common/fs/fs_util.h" #include "common/settings_enums.h" +#include "common/settings_input.h" #include "configuration/shared_widget.h" #include "core/core.h" #include "core/file_sys/control_metadata.h" @@ -98,6 +99,13 @@ void ConfigurePerGame::ApplyConfiguration() { addons_tab->ApplyConfiguration(); input_tab->ApplyConfiguration(); + if (Settings::values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked && + Settings::values.players.GetValue()[0].controller_type == + Settings::ControllerType::Handheld) { + Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld); + Settings::values.use_docked_mode.SetGlobal(true); + } + system.ApplySettings(); Settings::LogSettings(); diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index c4833f4e7..0c8e5c8b4 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -106,6 +106,11 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) { push(Settings::values.linkage.by_category[Settings::Category::System]); for (auto setting : settings) { + if (setting->Id() == Settings::values.use_docked_mode.Id() && + Settings::IsConfiguringGlobal()) { + continue; + } + ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); if (widget == nullptr) { -- cgit v1.2.3 From 3c45452fae7f33d0534c144c5f588ef98f0a1346 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Tue, 22 Aug 2023 21:58:23 -0400 Subject: general: Use console mode helper across project --- src/yuzu/configuration/configure_input.cpp | 20 ++++++++------------ src/yuzu/configuration/configure_per_game.cpp | 5 ++--- 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 78ed8c610..e8f9ebfd8 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/settings.h" #include "common/settings_enums.h" #include "core/core.h" #include "core/hid/emulated_controller.h" @@ -198,14 +199,11 @@ void ConfigureInput::ApplyConfiguration() { advanced->ApplyConfiguration(); - const bool pre_docked_mode = - Settings::values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked; - Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked() - ? Settings::ConsoleMode::Docked - : Settings::ConsoleMode::Handheld); - OnDockedModeChanged( - pre_docked_mode, - Settings::values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked, system); + const bool pre_docked_mode = Settings::IsDockedMode(); + const bool docked_mode_selected = ui->radioDocked->isChecked(); + Settings::values.use_docked_mode.SetValue( + docked_mode_selected ? Settings::ConsoleMode::Docked : Settings::ConsoleMode::Handheld); + OnDockedModeChanged(pre_docked_mode, docked_mode_selected, system); Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked()); Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked()); @@ -273,10 +271,8 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) { ui->radioDocked->setEnabled(!is_handheld); ui->radioUndocked->setEnabled(!is_handheld); - ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue() == - Settings::ConsoleMode::Docked); - ui->radioUndocked->setChecked(Settings::values.use_docked_mode.GetValue() == - Settings::ConsoleMode::Handheld); + ui->radioDocked->setChecked(Settings::IsDockedMode()); + ui->radioUndocked->setChecked(!Settings::IsDockedMode()); // Also force into undocked mode if the controller type is handheld. if (is_handheld) { diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index e371f902e..b91d6ad4a 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -99,9 +99,8 @@ void ConfigurePerGame::ApplyConfiguration() { addons_tab->ApplyConfiguration(); input_tab->ApplyConfiguration(); - if (Settings::values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked && - Settings::values.players.GetValue()[0].controller_type == - Settings::ControllerType::Handheld) { + if (Settings::IsDockedMode() && Settings::values.players.GetValue()[0].controller_type == + Settings::ControllerType::Handheld) { Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld); Settings::values.use_docked_mode.SetGlobal(true); } -- cgit v1.2.3