diff options
Diffstat (limited to 'src/yuzu/configuration')
18 files changed, 874 insertions, 31 deletions
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 343f3b8e5..c11d1c8b3 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -124,6 +124,10 @@ void Config::Initialize(const std::string& config_name) { } } +bool Config::IsCustomConfig() { + return type == ConfigType::PerGameConfig; +} + /* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their * usages later in this file. This allows explicit definition of some types that don't work * nicely with the general version. @@ -194,8 +198,20 @@ void Config::ReadPlayerValue(std::size_t player_index) { }(); auto& player = Settings::values.players.GetValue()[player_index]; + if (IsCustomConfig()) { + const auto profile_name = + qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{}) + .toString() + .toStdString(); + if (profile_name.empty()) { + // Use the global input config + player = Settings::values.players.GetValue(true)[player_index]; + return; + } + player.profile_name = profile_name; + } - if (player_prefix.isEmpty()) { + if (player_prefix.isEmpty() && Settings::IsConfiguringGlobal()) { const auto controller = static_cast<Settings::ControllerType>( qt_config ->value(QStringLiteral("%1type").arg(player_prefix), @@ -388,9 +404,26 @@ void Config::ReadAudioValues() { void Config::ReadControlValues() { qt_config->beginGroup(QStringLiteral("Controls")); + Settings::values.players.SetGlobal(!IsCustomConfig()); for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { ReadPlayerValue(p); } + ReadGlobalSetting(Settings::values.use_docked_mode); + + // Disable docked mode if handheld is selected + 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); + } + + ReadGlobalSetting(Settings::values.vibration_enabled); + ReadGlobalSetting(Settings::values.enable_accurate_vibrations); + ReadGlobalSetting(Settings::values.motion_enabled); + if (IsCustomConfig()) { + qt_config->endGroup(); + return; + } ReadDebugValues(); ReadKeyboardValues(); ReadMouseValues(); @@ -412,18 +445,6 @@ void Config::ReadControlValues() { ReadBasicSetting(Settings::values.tas_loop); ReadBasicSetting(Settings::values.pause_tas_on_load); - ReadGlobalSetting(Settings::values.use_docked_mode); - - // Disable docked mode if handheld is selected - const auto controller_type = Settings::values.players.GetValue()[0].controller_type; - if (controller_type == Settings::ControllerType::Handheld) { - Settings::values.use_docked_mode.SetValue(false); - } - - ReadGlobalSetting(Settings::values.vibration_enabled); - ReadGlobalSetting(Settings::values.enable_accurate_vibrations); - ReadGlobalSetting(Settings::values.motion_enabled); - ReadBasicSetting(Settings::values.controller_navigation); qt_config->endGroup(); @@ -672,6 +693,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.aspect_ratio); ReadGlobalSetting(Settings::values.resolution_setup); ReadGlobalSetting(Settings::values.scaling_filter); + ReadGlobalSetting(Settings::values.fsr_sharpening_slider); ReadGlobalSetting(Settings::values.anti_aliasing); ReadGlobalSetting(Settings::values.max_anisotropy); ReadGlobalSetting(Settings::values.use_speed_limit); @@ -904,7 +926,6 @@ void Config::ReadMultiplayerValues() { void Config::ReadValues() { if (global) { - ReadControlValues(); ReadDataStorageValues(); ReadDebuggingValues(); ReadDisabledAddOnValues(); @@ -913,6 +934,7 @@ void Config::ReadValues() { ReadWebServiceValues(); ReadMiscellaneousValues(); } + ReadControlValues(); ReadCoreValues(); ReadCpuValues(); ReadRendererValues(); @@ -931,12 +953,20 @@ void Config::SavePlayerValue(std::size_t player_index) { }(); const auto& player = Settings::values.players.GetValue()[player_index]; + if (IsCustomConfig()) { + if (player.profile_name.empty()) { + // No custom profile selected + return; + } + WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix), + QString::fromStdString(player.profile_name), QString{}); + } WriteSetting(QStringLiteral("%1type").arg(player_prefix), static_cast<u8>(player.controller_type), static_cast<u8>(Settings::ControllerType::ProController)); - if (!player_prefix.isEmpty()) { + if (!player_prefix.isEmpty() || !Settings::IsConfiguringGlobal()) { WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, player_index == 0); WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix), @@ -1054,7 +1084,6 @@ void Config::SaveIrCameraValues() { void Config::SaveValues() { if (global) { - SaveControlValues(); SaveDataStorageValues(); SaveDebuggingValues(); SaveDisabledAddOnValues(); @@ -1063,6 +1092,7 @@ void Config::SaveValues() { SaveWebServiceValues(); SaveMiscellaneousValues(); } + SaveControlValues(); SaveCoreValues(); SaveCpuValues(); SaveRendererValues(); @@ -1087,9 +1117,14 @@ void Config::SaveAudioValues() { void Config::SaveControlValues() { qt_config->beginGroup(QStringLiteral("Controls")); + Settings::values.players.SetGlobal(!IsCustomConfig()); for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { SavePlayerValue(p); } + if (IsCustomConfig()) { + qt_config->endGroup(); + return; + } SaveDebugValues(); SaveMouseValues(); SaveTouchscreenValues(); @@ -1282,6 +1317,10 @@ void Config::SaveRendererValues() { static_cast<u32>(Settings::values.scaling_filter.GetValue(global)), static_cast<u32>(Settings::values.scaling_filter.GetDefault()), Settings::values.scaling_filter.UsingGlobal()); + WriteSetting(QString::fromStdString(Settings::values.fsr_sharpening_slider.GetLabel()), + static_cast<u32>(Settings::values.fsr_sharpening_slider.GetValue(global)), + static_cast<u32>(Settings::values.fsr_sharpening_slider.GetDefault()), + Settings::values.fsr_sharpening_slider.UsingGlobal()); WriteSetting(QString::fromStdString(Settings::values.anti_aliasing.GetLabel()), static_cast<u32>(Settings::values.anti_aliasing.GetValue(global)), static_cast<u32>(Settings::values.anti_aliasing.GetDefault()), @@ -1574,6 +1613,13 @@ void Config::SaveControlPlayerValue(std::size_t player_index) { qt_config->endGroup(); } +void Config::ClearControlPlayerValues() { + qt_config->beginGroup(QStringLiteral("Controls")); + // If key is an empty string, all keys in the current group() are removed. + qt_config->remove(QString{}); + qt_config->endGroup(); +} + const std::string& Config::GetConfigFilePath() const { return qt_config_loc; } diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 06fa7d2d0..7d26e9ab6 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -34,6 +34,7 @@ public: void ReadControlPlayerValue(std::size_t player_index); void SaveControlPlayerValue(std::size_t player_index); + void ClearControlPlayerValues(); const std::string& GetConfigFilePath() const; @@ -58,6 +59,7 @@ public: private: void Initialize(const std::string& config_name); + bool IsCustomConfig(); void ReadValues(); void ReadPlayerValue(std::size_t player_index); diff --git a/src/yuzu/configuration/configure_camera.cpp b/src/yuzu/configuration/configure_camera.cpp index 2a61de2a1..d95e96696 100644 --- a/src/yuzu/configuration/configure_camera.cpp +++ b/src/yuzu/configuration/configure_camera.cpp @@ -2,8 +2,11 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include <memory> +#include <QtCore> +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA #include <QCameraImageCapture> #include <QCameraInfo> +#endif #include <QStandardItemModel> #include <QTimer> @@ -33,6 +36,7 @@ ConfigureCamera::ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* i ConfigureCamera::~ConfigureCamera() = default; void ConfigureCamera::PreviewCamera() { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA const auto index = ui->ir_sensor_combo_box->currentIndex(); bool camera_found = false; const QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); @@ -101,6 +105,7 @@ void ConfigureCamera::PreviewCamera() { }); camera_timer->start(250); +#endif } void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) { @@ -133,11 +138,13 @@ void ConfigureCamera::LoadConfiguration() { ui->ir_sensor_combo_box->clear(); input_devices.push_back("Auto"); ui->ir_sensor_combo_box->addItem(tr("Auto")); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA const auto cameras = QCameraInfo::availableCameras(); for (const QCameraInfo& cameraInfo : cameras) { input_devices.push_back(cameraInfo.deviceName().toStdString()); ui->ir_sensor_combo_box->addItem(cameraInfo.description()); } +#endif const auto current_device = Settings::values.ir_sensor_device.GetValue(); diff --git a/src/yuzu/configuration/configure_camera.h b/src/yuzu/configuration/configure_camera.h index db9833b5c..9a90512b3 100644 --- a/src/yuzu/configuration/configure_camera.h +++ b/src/yuzu/configuration/configure_camera.h @@ -46,8 +46,10 @@ private: bool is_virtual_camera; int pending_snapshots; +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA std::unique_ptr<QCamera> camera; std::unique_ptr<QCameraImageCapture> camera_capture; +#endif std::unique_ptr<QTimer> camera_timer; std::vector<std::string> input_devices; std::unique_ptr<Ui::ConfigureCamera> ui; diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index bd69d04a6..8ca683966 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -63,6 +63,11 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren ui->api_widget->isEnabled()); ui->bg_label->setVisible(Settings::IsConfiguringGlobal()); ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal()); + + connect(ui->fsr_sharpening_slider, &QSlider::valueChanged, this, + &ConfigureGraphics::SetFSRIndicatorText); + ui->fsr_sharpening_combobox->setVisible(!Settings::IsConfiguringGlobal()); + ui->fsr_sharpening_label->setVisible(Settings::IsConfiguringGlobal()); } void ConfigureGraphics::UpdateDeviceSelection(int device) { @@ -110,6 +115,7 @@ void ConfigureGraphics::SetConfiguration() { static_cast<int>(Settings::values.resolution_setup.GetValue())); ui->scaling_filter_combobox->setCurrentIndex( static_cast<int>(Settings::values.scaling_filter.GetValue())); + ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue()); ui->anti_aliasing_combobox->setCurrentIndex( static_cast<int>(Settings::values.anti_aliasing.GetValue())); } else { @@ -147,6 +153,15 @@ void ConfigureGraphics::SetConfiguration() { ConfigurationShared::SetHighlight(ui->anti_aliasing_label, !Settings::values.anti_aliasing.UsingGlobal()); + ui->fsr_sharpening_combobox->setCurrentIndex( + Settings::values.fsr_sharpening_slider.UsingGlobal() ? 0 : 1); + ui->fsr_sharpening_slider->setEnabled( + !Settings::values.fsr_sharpening_slider.UsingGlobal()); + ui->fsr_sharpening_value->setEnabled(!Settings::values.fsr_sharpening_slider.UsingGlobal()); + ConfigurationShared::SetHighlight(ui->fsr_sharpening_layout, + !Settings::values.fsr_sharpening_slider.UsingGlobal()); + ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue()); + ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1); ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal()); ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal()); @@ -155,6 +170,12 @@ void ConfigureGraphics::SetConfiguration() { Settings::values.bg_green.GetValue(), Settings::values.bg_blue.GetValue())); UpdateAPILayout(); + SetFSRIndicatorText(ui->fsr_sharpening_slider->sliderPosition()); +} + +void ConfigureGraphics::SetFSRIndicatorText(int percentage) { + ui->fsr_sharpening_value->setText( + tr("%1%", "FSR sharpening percentage (e.g. 50%)").arg(100 - (percentage / 2))); } void ConfigureGraphics::ApplyConfiguration() { @@ -210,6 +231,7 @@ void ConfigureGraphics::ApplyConfiguration() { if (Settings::values.anti_aliasing.UsingGlobal()) { Settings::values.anti_aliasing.SetValue(anti_aliasing); } + Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value()); } else { if (ui->resolution_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { Settings::values.resolution_setup.SetGlobal(true); @@ -238,6 +260,7 @@ void ConfigureGraphics::ApplyConfiguration() { Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend()); switch (GetCurrentGraphicsBackend()) { case Settings::RendererBackend::OpenGL: + case Settings::RendererBackend::Null: Settings::values.shader_backend.SetGlobal(false); Settings::values.vulkan_device.SetGlobal(true); Settings::values.shader_backend.SetValue(shader_backend); @@ -269,6 +292,13 @@ void ConfigureGraphics::ApplyConfiguration() { Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green())); Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue())); } + + if (ui->fsr_sharpening_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { + Settings::values.fsr_sharpening_slider.SetGlobal(true); + } else { + Settings::values.fsr_sharpening_slider.SetGlobal(false); + Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value()); + } } } @@ -319,6 +349,10 @@ void ConfigureGraphics::UpdateAPILayout() { ui->device_widget->setVisible(true); ui->backend_widget->setVisible(false); break; + case Settings::RendererBackend::Null: + ui->device_widget->setVisible(false); + ui->backend_widget->setVisible(false); + break; } } @@ -331,7 +365,7 @@ void ConfigureGraphics::RetrieveVulkanDevices() try { vk::InstanceDispatch dld; const Common::DynamicLibrary library = OpenLibrary(); - const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_0); + const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_1); const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); vulkan_devices.clear(); @@ -380,6 +414,7 @@ void ConfigureGraphics::SetupPerGameUI() { ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal()); ui->resolution_combobox->setEnabled(Settings::values.resolution_setup.UsingGlobal()); ui->scaling_filter_combobox->setEnabled(Settings::values.scaling_filter.UsingGlobal()); + ui->fsr_sharpening_slider->setEnabled(Settings::values.fsr_sharpening_slider.UsingGlobal()); ui->anti_aliasing_combobox->setEnabled(Settings::values.anti_aliasing.UsingGlobal()); ui->use_asynchronous_gpu_emulation->setEnabled( Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()); @@ -387,6 +422,7 @@ void ConfigureGraphics::SetupPerGameUI() { ui->accelerate_astc->setEnabled(Settings::values.accelerate_astc.UsingGlobal()); ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal()); ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal()); + ui->fsr_slider_layout->setEnabled(Settings::values.fsr_sharpening_slider.UsingGlobal()); return; } @@ -396,6 +432,13 @@ void ConfigureGraphics::SetupPerGameUI() { ConfigurationShared::SetHighlight(ui->bg_layout, index == 1); }); + connect(ui->fsr_sharpening_combobox, qOverload<int>(&QComboBox::activated), this, + [this](int index) { + ui->fsr_sharpening_slider->setEnabled(index == 1); + ui->fsr_sharpening_value->setEnabled(index == 1); + ConfigurationShared::SetHighlight(ui->fsr_sharpening_layout, index == 1); + }); + ConfigurationShared::SetColoredTristate( ui->use_disk_shader_cache, Settings::values.use_disk_shader_cache, use_disk_shader_cache); ConfigurationShared::SetColoredTristate(ui->accelerate_astc, Settings::values.accelerate_astc, diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 70034eb1b..d98d6624e 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -42,6 +42,8 @@ private: void RetrieveVulkanDevices(); + void SetFSRIndicatorText(int percentage); + void SetupPerGameUI(); Settings::RendererBackend GetCurrentGraphicsBackend() const; diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index fdbb33372..f78396690 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui @@ -139,6 +139,11 @@ <string notr="true">Vulkan</string> </property> </item> + <item> + <property name="text"> + <string>None</string> + </property> + </item> </widget> </item> </layout> @@ -152,6 +157,12 @@ </item> <item> <widget class="QGroupBox" name="groupBox"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> <property name="title"> <string>Graphics Settings</string> </property> @@ -482,6 +493,146 @@ </widget> </item> <item> + <widget class="QWidget" name="fsr_sharpening_layout" native="true"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="fsr_sharpening_label_group"> + <item> + <widget class="QComboBox" name="fsr_sharpening_combobox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <item> + <property name="text"> + <string>Use global FSR Sharpness</string> + </property> + </item> + <item> + <property name="text"> + <string>Set FSR Sharpness</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QLabel" name="fsr_sharpening_label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>FSR Sharpness:</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="fsr_slider_layout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <widget class="QSlider" name="fsr_sharpening_slider"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximum"> + <number>200</number> + </property> + <property name="sliderPosition"> + <number>25</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="invertedAppearance"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="fsr_sharpening_value"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>100%</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> <widget class="QWidget" name="bg_layout" native="true"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 10f841b98..235b813d9 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -194,4 +194,8 @@ void ConfigureInputAdvanced::UpdateUIEnabled() { ui->mouse_panning->setEnabled(!ui->mouse_enabled->isChecked()); ui->mouse_panning_sensitivity->setEnabled(!ui->mouse_enabled->isChecked()); ui->ring_controller_configure->setEnabled(ui->enable_ring_controller->isChecked()); +#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) || !defined(YUZU_USE_QT_MULTIMEDIA) + ui->enable_ir_sensor->setEnabled(false); + ui->camera_configure->setEnabled(false); +#endif } diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp new file mode 100644 index 000000000..78e65d468 --- /dev/null +++ b/src/yuzu/configuration/configure_input_per_game.cpp @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/settings.h" +#include "core/core.h" +#include "core/hid/emulated_controller.h" +#include "core/hid/hid_core.h" +#include "ui_configure_input_per_game.h" +#include "yuzu/configuration/config.h" +#include "yuzu/configuration/configure_input_per_game.h" +#include "yuzu/configuration/input_profiles.h" + +ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, Config* config_, + QWidget* parent) + : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()), + profiles(std::make_unique<InputProfiles>()), system{system_}, config{config_} { + ui->setupUi(this); + const std::array labels = { + ui->label_player_1, ui->label_player_2, ui->label_player_3, ui->label_player_4, + ui->label_player_5, ui->label_player_6, ui->label_player_7, ui->label_player_8, + }; + profile_comboboxes = { + ui->profile_player_1, ui->profile_player_2, ui->profile_player_3, ui->profile_player_4, + ui->profile_player_5, ui->profile_player_6, ui->profile_player_7, ui->profile_player_8, + }; + + Settings::values.players.SetGlobal(false); + + const auto& profile_names = profiles->GetInputProfileNames(); + const auto populate_profiles = [this, &profile_names](size_t player_index) { + const auto previous_profile = + Settings::values.players.GetValue()[player_index].profile_name; + + auto* const player_combobox = profile_comboboxes[player_index]; + player_combobox->addItem(tr("Use global input configuration")); + + for (size_t index = 0; index < profile_names.size(); ++index) { + const auto& profile_name = profile_names[index]; + player_combobox->addItem(QString::fromStdString(profile_name)); + if (profile_name == previous_profile) { + // offset by 1 since the first element is the global config + player_combobox->setCurrentIndex(static_cast<int>(index + 1)); + } + } + }; + for (size_t index = 0; index < profile_comboboxes.size(); ++index) { + labels[index]->setText(tr("Player %1 profile").arg(index + 1)); + populate_profiles(index); + } + + LoadConfiguration(); +} + +void ConfigureInputPerGame::ApplyConfiguration() { + LoadConfiguration(); + SaveConfiguration(); +} + +void ConfigureInputPerGame::LoadConfiguration() { + static constexpr size_t HANDHELD_INDEX = 8; + + auto& hid_core = system.HIDCore(); + for (size_t player_index = 0; player_index < profile_comboboxes.size(); ++player_index) { + Settings::values.players.SetGlobal(false); + + auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index); + auto* const player_combobox = profile_comboboxes[player_index]; + + const auto selection_index = player_combobox->currentIndex(); + if (selection_index == 0) { + Settings::values.players.GetValue()[player_index].profile_name = ""; + if (player_index == 0) { + Settings::values.players.GetValue()[HANDHELD_INDEX] = {}; + } + Settings::values.players.SetGlobal(true); + emulated_controller->ReloadFromSettings(); + continue; + } + const auto profile_name = player_combobox->itemText(selection_index).toStdString(); + if (profile_name.empty()) { + continue; + } + auto& player = Settings::values.players.GetValue()[player_index]; + player.profile_name = profile_name; + // Read from the profile into the custom player settings + profiles->LoadProfile(profile_name, player_index); + // Make sure the controller is connected + player.connected = true; + + emulated_controller->ReloadFromSettings(); + + if (player_index > 0) { + continue; + } + // Handle Handheld cases + auto& handheld_player = Settings::values.players.GetValue()[HANDHELD_INDEX]; + auto* handheld_controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); + if (player.controller_type == Settings::ControllerType::Handheld) { + handheld_player = player; + } else { + handheld_player = {}; + } + handheld_controller->ReloadFromSettings(); + } +} + +void ConfigureInputPerGame::SaveConfiguration() { + Settings::values.players.SetGlobal(false); + + // Clear all controls from the config in case the user reverted back to globals + config->ClearControlPlayerValues(); + for (size_t index = 0; index < Settings::values.players.GetValue().size(); ++index) { + config->SaveControlPlayerValue(index); + } +} diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h new file mode 100644 index 000000000..660faf574 --- /dev/null +++ b/src/yuzu/configuration/configure_input_per_game.h @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <memory> + +#include <QWidget> + +#include "ui_configure_input_per_game.h" +#include "yuzu/configuration/input_profiles.h" + +class QComboBox; + +namespace Core { +class System; +} // namespace Core + +class Config; + +class ConfigureInputPerGame : public QWidget { + Q_OBJECT + +public: + explicit ConfigureInputPerGame(Core::System& system_, Config* config_, + QWidget* parent = nullptr); + + /// Load and Save configurations to settings file. + void ApplyConfiguration(); + +private: + /// Load configuration from settings file. + void LoadConfiguration(); + + /// Save configuration to settings file. + void SaveConfiguration(); + + std::unique_ptr<Ui::ConfigureInputPerGame> ui; + std::unique_ptr<InputProfiles> profiles; + + std::array<QComboBox*, 8> profile_comboboxes; + + Core::System& system; + Config* config; +}; diff --git a/src/yuzu/configuration/configure_input_per_game.ui b/src/yuzu/configuration/configure_input_per_game.ui new file mode 100644 index 000000000..fbd8eab1c --- /dev/null +++ b/src/yuzu/configuration/configure_input_per_game.ui @@ -0,0 +1,333 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConfigureInputPerGame</class> + <widget class="QWidget" name="PerGameInput"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>541</width> + <height>759</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="accessibleName"> + <string>Graphics</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_1"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Input Profiles</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QWidget" name="player_1" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_1"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_1"> + <property name="text"> + <string>Player 1 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_1"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_2" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_2"> + <property name="text"> + <string>Player 2 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_3" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_3"> + <property name="text"> + <string>Player 3 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_4" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_4"> + <property name="text"> + <string>Player 4 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_5" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_5"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_5"> + <property name="text"> + <string>Player 5 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_5"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_6" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_6"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_6"> + <property name="text"> + <string>Player 6 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_6"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_7" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_7"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_7"> + <property name="text"> + <string>Player 7 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_7"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_8" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_8"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_8"> + <property name="text"> + <string>Player 8 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_8"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 9e5a40fe7..ed21f4b92 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -1553,6 +1553,7 @@ void ConfigureInputPlayer::LoadProfile() { } void ConfigureInputPlayer::SaveProfile() { + static constexpr size_t HANDHELD_INDEX = 8; const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex()); if (profile_name.isEmpty()) { @@ -1561,7 +1562,12 @@ void ConfigureInputPlayer::SaveProfile() { ApplyConfiguration(); - if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) { + // When we're in handheld mode, only the handheld emulated controller bindings are updated + const bool is_handheld = player_index == 0 && emulated_controller->GetNpadIdType() == + Core::HID::NpadIdType::Handheld; + const auto profile_player_index = is_handheld ? HANDHELD_INDEX : player_index; + + if (!profiles->SaveProfile(profile_name.toStdString(), profile_player_index)) { QMessageBox::critical(this, tr("Save Input Profile"), tr("Failed to save the input profile \"%1\"").arg(profile_name)); UpdateInputProfiles(); diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index 79434fdd8..26f60d121 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h @@ -38,7 +38,7 @@ enum class InputType; namespace Ui { class ConfigureInputPlayer; -} +} // namespace Ui namespace Core::HID { class HIDCore; diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index c3cb8f61d..93db47cfd 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -28,7 +28,7 @@ #include "yuzu/configuration/configure_general.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/configure_graphics_advanced.h" -#include "yuzu/configuration/configure_input.h" +#include "yuzu/configuration/configure_input_per_game.h" #include "yuzu/configuration/configure_per_game.h" #include "yuzu/configuration/configure_per_game_addons.h" #include "yuzu/configuration/configure_system.h" @@ -50,6 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st general_tab = std::make_unique<ConfigureGeneral>(system_, this); graphics_tab = std::make_unique<ConfigureGraphics>(system_, this); graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); + input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); system_tab = std::make_unique<ConfigureSystem>(system_, this); ui->setupUi(this); @@ -61,6 +62,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); + ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); setFocusPolicy(Qt::ClickFocus); setWindowTitle(tr("Properties")); @@ -91,6 +93,7 @@ void ConfigurePerGame::ApplyConfiguration() { graphics_tab->ApplyConfiguration(); graphics_advanced_tab->ApplyConfiguration(); audio_tab->ApplyConfiguration(); + input_tab->ApplyConfiguration(); system.ApplySettings(); Settings::LogSettings(); diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index 17a98a0f3..4ecc43541 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -16,12 +16,17 @@ namespace Core { class System; } +namespace InputCommon { +class InputSubsystem; +} + class ConfigurePerGameAddons; class ConfigureAudio; class ConfigureCpu; class ConfigureGeneral; class ConfigureGraphics; class ConfigureGraphicsAdvanced; +class ConfigureInputPerGame; class ConfigureSystem; class QGraphicsScene; @@ -72,5 +77,6 @@ private: std::unique_ptr<ConfigureGeneral> general_tab; std::unique_ptr<ConfigureGraphics> graphics_tab; std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; + std::unique_ptr<ConfigureInputPerGame> input_tab; std::unique_ptr<ConfigureSystem> system_tab; }; diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index 5c0217ba8..a47089988 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp @@ -2,6 +2,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <algorithm> +#include <functional> +#include <QDialog> +#include <QDialogButtonBox> #include <QFileDialog> #include <QGraphicsItem> #include <QHeaderView> @@ -108,9 +111,12 @@ ConfigureProfileManager::ConfigureProfileManager(const Core::System& system_, QW connect(ui->pm_add, &QPushButton::clicked, this, &ConfigureProfileManager::AddUser); connect(ui->pm_rename, &QPushButton::clicked, this, &ConfigureProfileManager::RenameUser); - connect(ui->pm_remove, &QPushButton::clicked, this, &ConfigureProfileManager::DeleteUser); + connect(ui->pm_remove, &QPushButton::clicked, this, + &ConfigureProfileManager::ConfirmDeleteUser); connect(ui->pm_set_image, &QPushButton::clicked, this, &ConfigureProfileManager::SetUserImage); + confirm_dialog = new ConfigureProfileManagerDeleteDialog(this); + scene = new QGraphicsScene; ui->current_user_icon->setScene(scene); @@ -230,26 +236,23 @@ void ConfigureProfileManager::RenameUser() { UpdateCurrentUser(); } -void ConfigureProfileManager::DeleteUser() { +void ConfigureProfileManager::ConfirmDeleteUser() { const auto index = tree_view->currentIndex().row(); const auto uuid = profile_manager->GetUser(index); ASSERT(uuid); const auto username = GetAccountUsername(*profile_manager, *uuid); - const auto confirm = QMessageBox::question( - this, tr("Confirm Delete"), - tr("You are about to delete user with name \"%1\". Are you sure?").arg(username)); - - if (confirm == QMessageBox::No) { - return; - } + confirm_dialog->SetInfo(username, *uuid, [this, uuid]() { DeleteUser(*uuid); }); + confirm_dialog->show(); +} +void ConfigureProfileManager::DeleteUser(const Common::UUID& uuid) { if (Settings::values.current_user.GetValue() == tree_view->currentIndex().row()) { Settings::values.current_user = 0; } UpdateCurrentUser(); - if (!profile_manager->RemoveUser(*uuid)) { + if (!profile_manager->RemoveUser(uuid)) { return; } @@ -319,3 +322,47 @@ void ConfigureProfileManager::SetUserImage() { new QStandardItem{GetIcon(*uuid), FormatUserEntryText(username, *uuid)}); UpdateCurrentUser(); } + +ConfigureProfileManagerDeleteDialog::ConfigureProfileManagerDeleteDialog(QWidget* parent) + : QDialog{parent} { + auto dialog_vbox_layout = new QVBoxLayout(this); + dialog_button_box = + new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::No, Qt::Horizontal, parent); + auto label_message = + new QLabel(tr("Delete this user? All of the user's save data will be deleted."), this); + label_info = new QLabel(this); + auto dialog_hbox_layout_widget = new QWidget(this); + auto dialog_hbox_layout = new QHBoxLayout(dialog_hbox_layout_widget); + icon_scene = new QGraphicsScene(0, 0, 64, 64, this); + auto icon_view = new QGraphicsView(icon_scene, this); + + dialog_hbox_layout_widget->setLayout(dialog_hbox_layout); + icon_view->setMaximumSize(64, 64); + icon_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + icon_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + this->setLayout(dialog_vbox_layout); + this->setWindowTitle(tr("Confirm Delete")); + this->setSizeGripEnabled(false); + dialog_vbox_layout->addWidget(label_message); + dialog_vbox_layout->addWidget(dialog_hbox_layout_widget); + dialog_vbox_layout->addWidget(dialog_button_box); + dialog_hbox_layout->addWidget(icon_view); + dialog_hbox_layout->addWidget(label_info); + + connect(dialog_button_box, &QDialogButtonBox::rejected, this, [this]() { close(); }); +} + +ConfigureProfileManagerDeleteDialog::~ConfigureProfileManagerDeleteDialog() = default; + +void ConfigureProfileManagerDeleteDialog::SetInfo(const QString& username, const Common::UUID& uuid, + std::function<void()> accept_callback) { + label_info->setText( + tr("Name: %1\nUUID: %2").arg(username, QString::fromStdString(uuid.FormattedString()))); + icon_scene->clear(); + icon_scene->addPixmap(GetIcon(uuid)); + + connect(dialog_button_box, &QDialogButtonBox::accepted, this, [this, accept_callback]() { + close(); + accept_callback(); + }); +} diff --git a/src/yuzu/configuration/configure_profile_manager.h b/src/yuzu/configuration/configure_profile_manager.h index fe9033779..c4b1a334e 100644 --- a/src/yuzu/configuration/configure_profile_manager.h +++ b/src/yuzu/configuration/configure_profile_manager.h @@ -3,16 +3,24 @@ #pragma once +#include <functional> #include <memory> +#include <QDialog> #include <QList> #include <QWidget> +namespace Common { +struct UUID; +} + namespace Core { class System; } class QGraphicsScene; +class QDialogButtonBox; +class QLabel; class QStandardItem; class QStandardItemModel; class QTreeView; @@ -26,6 +34,20 @@ namespace Ui { class ConfigureProfileManager; } +class ConfigureProfileManagerDeleteDialog : public QDialog { +public: + explicit ConfigureProfileManagerDeleteDialog(QWidget* parent); + ~ConfigureProfileManagerDeleteDialog(); + + void SetInfo(const QString& username, const Common::UUID& uuid, + std::function<void()> accept_callback); + +private: + QDialogButtonBox* dialog_button_box; + QGraphicsScene* icon_scene; + QLabel* label_info; +}; + class ConfigureProfileManager : public QWidget { Q_OBJECT @@ -47,7 +69,8 @@ private: void SelectUser(const QModelIndex& index); void AddUser(); void RenameUser(); - void DeleteUser(); + void ConfirmDeleteUser(); + void DeleteUser(const Common::UUID& uuid); void SetUserImage(); QVBoxLayout* layout; @@ -55,6 +78,8 @@ private: QStandardItemModel* item_model; QGraphicsScene* scene; + ConfigureProfileManagerDeleteDialog* confirm_dialog; + std::vector<QList<QStandardItem*>> list_items; std::unique_ptr<Ui::ConfigureProfileManager> ui; diff --git a/src/yuzu/configuration/configure_profile_manager.ui b/src/yuzu/configuration/configure_profile_manager.ui index cfe7478c8..bd6dea4f4 100644 --- a/src/yuzu/configuration/configure_profile_manager.ui +++ b/src/yuzu/configuration/configure_profile_manager.ui @@ -57,6 +57,12 @@ <height>48</height> </size> </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> <property name="verticalScrollBarPolicy"> <enum>Qt::ScrollBarAlwaysOff</enum> </property> |