forked from eden-emu/eden
		
	configure_audio: Implement ui generation
Needs a considerable amount of management specific to some of the comoboboxes due to the audio engine configuration. general: Partial audio config implmentation configure_audio: Implement ui generation Needs a considerable amount of management specific to some of the comoboboxes due to the audio engine configuration. general: Partial audio config implmentation settings: Make audio settings as enums
This commit is contained in:
		
							parent
							
								
									88d3de4e85
								
							
						
					
					
						commit
						432f68ad29
					
				
					 14 changed files with 221 additions and 331 deletions
				
			
		|  | @ -15,6 +15,7 @@ | |||
| #endif | ||||
| #include "audio_core/sink/null_sink.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/settings_enums.h" | ||||
| 
 | ||||
| namespace AudioCore::Sink { | ||||
| namespace { | ||||
|  | @ -24,7 +25,7 @@ struct SinkDetails { | |||
|     using LatencyFn = u32 (*)(); | ||||
| 
 | ||||
|     /// Name for this sink.
 | ||||
|     std::string_view id; | ||||
|     Settings::AudioEngine id; | ||||
|     /// A method to call to construct an instance of this type of sink.
 | ||||
|     FactoryFn factory; | ||||
|     /// A method to call to list available devices.
 | ||||
|  | @ -37,7 +38,7 @@ struct SinkDetails { | |||
| constexpr SinkDetails sink_details[] = { | ||||
| #ifdef HAVE_CUBEB | ||||
|     SinkDetails{ | ||||
|         "cubeb", | ||||
|         Settings::AudioEngine::Cubeb, | ||||
|         [](std::string_view device_id) -> std::unique_ptr<Sink> { | ||||
|             return std::make_unique<CubebSink>(device_id); | ||||
|         }, | ||||
|  | @ -47,7 +48,7 @@ constexpr SinkDetails sink_details[] = { | |||
| #endif | ||||
| #ifdef HAVE_SDL2 | ||||
|     SinkDetails{ | ||||
|         "sdl2", | ||||
|         Settings::AudioEngine::Sdl2, | ||||
|         [](std::string_view device_id) -> std::unique_ptr<Sink> { | ||||
|             return std::make_unique<SDLSink>(device_id); | ||||
|         }, | ||||
|  | @ -55,46 +56,46 @@ constexpr SinkDetails sink_details[] = { | |||
|         &GetSDLLatency, | ||||
|     }, | ||||
| #endif | ||||
|     SinkDetails{"null", | ||||
|     SinkDetails{Settings::AudioEngine::Null, | ||||
|                 [](std::string_view device_id) -> std::unique_ptr<Sink> { | ||||
|                     return std::make_unique<NullSink>(device_id); | ||||
|                 }, | ||||
|                 [](bool capture) { return std::vector<std::string>{"null"}; }, []() { return 0u; }}, | ||||
| }; | ||||
| 
 | ||||
| const SinkDetails& GetOutputSinkDetails(std::string_view sink_id) { | ||||
|     const auto find_backend{[](std::string_view id) { | ||||
| const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) { | ||||
|     const auto find_backend{[](Settings::AudioEngine id) { | ||||
|         return std::find_if(std::begin(sink_details), std::end(sink_details), | ||||
|                             [&id](const auto& sink_detail) { return sink_detail.id == id; }); | ||||
|     }}; | ||||
| 
 | ||||
|     auto iter = find_backend(sink_id); | ||||
| 
 | ||||
|     if (sink_id == "auto") { | ||||
|     if (sink_id == Settings::AudioEngine::Auto) { | ||||
|         // Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
 | ||||
|         // causes audio issues, in that case go with SDL.
 | ||||
| #if defined(HAVE_CUBEB) && defined(HAVE_SDL2) | ||||
|         iter = find_backend("cubeb"); | ||||
|         iter = find_backend(Settings::AudioEngine::Cubeb); | ||||
|         if (iter->latency() > TargetSampleCount * 3) { | ||||
|             iter = find_backend("sdl2"); | ||||
|             iter = find_backend(Settings::AudioEngine::Sdl2); | ||||
|         } | ||||
| #else | ||||
|         iter = std::begin(sink_details); | ||||
| #endif | ||||
|         LOG_INFO(Service_Audio, "Auto-selecting the {} backend", iter->id); | ||||
|         LOG_INFO(Service_Audio, "Auto-selecting the {} backend", Settings::TranslateEnum(iter->id)); | ||||
|     } | ||||
| 
 | ||||
|     if (iter == std::end(sink_details)) { | ||||
|         LOG_ERROR(Audio, "Invalid sink_id {}", sink_id); | ||||
|         iter = find_backend("null"); | ||||
|         LOG_ERROR(Audio, "Invalid sink_id {}", Settings::TranslateEnum(sink_id)); | ||||
|         iter = find_backend(Settings::AudioEngine::Null); | ||||
|     } | ||||
| 
 | ||||
|     return *iter; | ||||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| std::vector<std::string_view> GetSinkIDs() { | ||||
|     std::vector<std::string_view> sink_ids(std::size(sink_details)); | ||||
| std::vector<Settings::AudioEngine> GetSinkIDs() { | ||||
|     std::vector<Settings::AudioEngine> sink_ids(std::size(sink_details)); | ||||
| 
 | ||||
|     std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids), | ||||
|                    [](const auto& sink) { return sink.id; }); | ||||
|  | @ -102,11 +103,11 @@ std::vector<std::string_view> GetSinkIDs() { | |||
|     return sink_ids; | ||||
| } | ||||
| 
 | ||||
| std::vector<std::string> GetDeviceListForSink(std::string_view sink_id, bool capture) { | ||||
| std::vector<std::string> GetDeviceListForSink(Settings::AudioEngine sink_id, bool capture) { | ||||
|     return GetOutputSinkDetails(sink_id).list_devices(capture); | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id) { | ||||
| std::unique_ptr<Sink> CreateSinkFromID(Settings::AudioEngine sink_id, std::string_view device_id) { | ||||
|     return GetOutputSinkDetails(sink_id).factory(device_id); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,9 @@ | |||
| #include <string_view> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace Settings { | ||||
| enum class AudioEngine : u32; | ||||
| } | ||||
| namespace AudioCore { | ||||
| class AudioManager; | ||||
| 
 | ||||
|  | @ -19,7 +22,7 @@ class Sink; | |||
|  * | ||||
|  * @return Vector of available sink names. | ||||
|  */ | ||||
| std::vector<std::string_view> GetSinkIDs(); | ||||
| std::vector<Settings::AudioEngine> GetSinkIDs(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the list of devices for a particular sink identified by the given ID. | ||||
|  | @ -28,7 +31,7 @@ std::vector<std::string_view> GetSinkIDs(); | |||
|  * @param capture - Get capture (input) devices, or output devices? | ||||
|  * @return Vector of device names. | ||||
|  */ | ||||
| std::vector<std::string> GetDeviceListForSink(std::string_view sink_id, bool capture); | ||||
| std::vector<std::string> GetDeviceListForSink(Settings::AudioEngine sink_id, bool capture); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates an audio sink identified by the given device ID. | ||||
|  | @ -37,7 +40,7 @@ std::vector<std::string> GetDeviceListForSink(std::string_view sink_id, bool cap | |||
|  * @param device_id - Name of the device to create. | ||||
|  * @return Pointer to the created sink. | ||||
|  */ | ||||
| std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id); | ||||
| std::unique_ptr<Sink> CreateSinkFromID(Settings::AudioEngine sink_id, std::string_view device_id); | ||||
| 
 | ||||
| } // namespace Sink
 | ||||
| } // namespace AudioCore
 | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ void LogSettings() { | |||
|     log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); | ||||
|     log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); | ||||
|     log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); | ||||
|     log_setting("Audio_OutputEngine", values.sink_id.GetValue()); | ||||
|     log_setting("Audio_OutputEngine", Settings::TranslateEnum(values.sink_id.GetValue())); | ||||
|     log_setting("Audio_OutputDevice", values.audio_output_device_id.GetValue()); | ||||
|     log_setting("Audio_InputDevice", values.audio_input_device_id.GetValue()); | ||||
|     log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue()); | ||||
|  |  | |||
|  | @ -244,6 +244,8 @@ protected: | |||
|             return value_.has_value() ? std::to_string(*value_) : "none"; | ||||
|         } else if constexpr (std::is_same<Type, bool>()) { | ||||
|             return value_ ? "true" : "false"; | ||||
|         } else if (std::is_same<Type, AudioEngine>()) { | ||||
|             return TranslateEnum(value_); | ||||
|         } else { | ||||
|             return std::to_string(static_cast<u64>(value_)); | ||||
|         } | ||||
|  | @ -309,6 +311,8 @@ public: | |||
|                 this->SetValue(static_cast<u32>(std::stoul(input))); | ||||
|             } else if constexpr (std::is_same<Type, bool>()) { | ||||
|                 this->SetValue(input == "true"); | ||||
|             } else if constexpr (std::is_same<Type, AudioEngine>()) { | ||||
|                 this->SetValue(ToEnum<Type>(input)); | ||||
|             } else { | ||||
|                 this->SetValue(static_cast<Type>(std::stoll(input))); | ||||
|             } | ||||
|  | @ -542,7 +546,7 @@ struct Values { | |||
|     Linkage linkage{}; | ||||
| 
 | ||||
|     // Audio
 | ||||
|     Setting<std::string> sink_id{linkage, "auto", "output_engine", Category::Audio}; | ||||
|     Setting<AudioEngine> sink_id{linkage, AudioEngine::Auto, "output_engine", Category::Audio}; | ||||
|     Setting<std::string> audio_output_device_id{linkage, "auto", "output_device", Category::Audio}; | ||||
|     Setting<std::string> audio_input_device_id{linkage, "auto", "input_device", Category::Audio}; | ||||
|     Setting<bool, false> audio_muted{linkage, false, "audio_muted", Category::Audio, false}; | ||||
|  | @ -731,8 +735,9 @@ struct Values { | |||
|     SwitchableSetting<TimeZone, true> time_zone_index{linkage,           TimeZone::Auto, | ||||
|                                                       TimeZone::Auto,    TimeZone::Zulu, | ||||
|                                                       "time_zone_index", Category::System}; | ||||
|     SwitchableSetting<s32, true> sound_index{ | ||||
|         linkage, 1, 0, 2, "sound_index", Category::SystemAudio}; | ||||
|     SwitchableSetting<AudioMode, true> sound_index{linkage,         AudioMode::Stereo, | ||||
|                                                    AudioMode::Mono, AudioMode::Surround, | ||||
|                                                    "sound_index",   Category::SystemAudio}; | ||||
| 
 | ||||
|     SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -254,7 +254,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader, | |||
| 
 | ||||
|     // Log user configuration information
 | ||||
|     constexpr auto field_type = Telemetry::FieldType::UserConfig; | ||||
|     AddField(field_type, "Audio_SinkId", Settings::values.sink_id.GetValue()); | ||||
|     AddField(field_type, "Audio_SinkId", | ||||
|              Settings::TranslateEnum(Settings::values.sink_id.GetValue())); | ||||
|     AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue()); | ||||
|     AddField(field_type, "Renderer_Backend", | ||||
|              TranslateRenderer(Settings::values.renderer_backend.GetValue())); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include <forward_list> | ||||
| #include <memory> | ||||
| 
 | ||||
| #include "audio_core/sink/sink.h" | ||||
|  | @ -10,80 +11,105 @@ | |||
| #include "ui_configure_audio.h" | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| #include "yuzu/configuration/configure_audio.h" | ||||
| #include "yuzu/configuration/shared_translation.h" | ||||
| #include "yuzu/configuration/shared_widget.h" | ||||
| #include "yuzu/uisettings.h" | ||||
| 
 | ||||
| ConfigureAudio::ConfigureAudio(const Core::System& system_, | ||||
|                                std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, | ||||
|                                const ConfigurationShared::TranslationMap& translations_, | ||||
|                                QWidget* parent) | ||||
|     : Tab(group, parent), ui(std::make_unique<Ui::ConfigureAudio>()), system{system_} { | ||||
|     : Tab(group, parent), | ||||
|       ui(std::make_unique<Ui::ConfigureAudio>()), system{system_}, translations{translations_} { | ||||
|     ui->setupUi(this); | ||||
| 
 | ||||
|     InitializeAudioSinkComboBox(); | ||||
| 
 | ||||
|     connect(ui->volume_slider, &QSlider::valueChanged, this, | ||||
|             &ConfigureAudio::SetVolumeIndicatorText); | ||||
|     connect(ui->sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, | ||||
|             &ConfigureAudio::UpdateAudioDevices); | ||||
| 
 | ||||
|     ui->volume_label->setVisible(Settings::IsConfiguringGlobal()); | ||||
|     ui->volume_combo_box->setVisible(!Settings::IsConfiguringGlobal()); | ||||
| 
 | ||||
|     SetupPerGameUI(); | ||||
|     Setup(); | ||||
| 
 | ||||
|     SetConfiguration(); | ||||
| 
 | ||||
|     const bool is_powered_on = system_.IsPoweredOn(); | ||||
|     ui->sink_combo_box->setEnabled(!is_powered_on); | ||||
|     ui->output_combo_box->setEnabled(!is_powered_on); | ||||
|     ui->input_combo_box->setEnabled(!is_powered_on); | ||||
| } | ||||
| 
 | ||||
| ConfigureAudio::~ConfigureAudio() = default; | ||||
| 
 | ||||
| void ConfigureAudio::Setup() { | ||||
|     const bool runtime_lock = !system.IsPoweredOn(); | ||||
|     auto& layout = *ui->audio_widget->layout(); | ||||
| 
 | ||||
|     std::forward_list<Settings::BasicSetting*> settings; | ||||
| 
 | ||||
|     auto push = [&](Settings::Category category) { | ||||
|         for (auto* setting : Settings::values.linkage.by_category[category]) { | ||||
|             settings.push_front(setting); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     push(Settings::Category::Audio); | ||||
|     push(Settings::Category::SystemAudio); | ||||
| 
 | ||||
|     for (auto* setting : settings) { | ||||
|         auto* widget = [&]() { | ||||
|             if (setting->Id() == Settings::values.volume.Id()) { | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::Slider, true, 1.0f, nullptr, | ||||
|                     tr("%1%", "Volume percentage (e.g. 50%)")); | ||||
|             } else if (setting->Id() == Settings::values.audio_output_device_id.Id() || | ||||
|                        setting->Id() == Settings::values.audio_input_device_id.Id() || | ||||
|                        setting->Id() == Settings::values.sink_id.Id()) { | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::ComboBox, false); | ||||
|             } else { | ||||
|                 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, | ||||
|                                                        apply_funcs); | ||||
|             } | ||||
|         }(); | ||||
| 
 | ||||
|         if (!widget->Valid()) { | ||||
|             delete widget; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         layout.addWidget(widget); | ||||
| 
 | ||||
|         if (setting->Id() == Settings::values.sink_id.Id()) { | ||||
|             sink_combo_box = widget->combobox; | ||||
|             InitializeAudioSinkComboBox(); | ||||
| 
 | ||||
|             connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, | ||||
|                     &ConfigureAudio::UpdateAudioDevices); | ||||
|         } else if (setting->Id() == Settings::values.audio_output_device_id.Id()) { | ||||
|             output_device_combo_box = widget->combobox; | ||||
|         } else if (setting->Id() == Settings::values.audio_input_device_id.Id()) { | ||||
|             input_device_combo_box = widget->combobox; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::SetConfiguration() { | ||||
|     if (!Settings::IsConfiguringGlobal()) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     SetOutputSinkFromSinkID(); | ||||
| 
 | ||||
|     // The device list cannot be pre-populated (nor listed) until the output sink is known.
 | ||||
|     UpdateAudioDevices(ui->sink_combo_box->currentIndex()); | ||||
|     UpdateAudioDevices(sink_combo_box->currentIndex()); | ||||
| 
 | ||||
|     SetAudioDevicesFromDeviceID(); | ||||
| 
 | ||||
|     const auto volume_value = static_cast<int>(Settings::values.volume.GetValue()); | ||||
|     ui->volume_slider->setValue(volume_value); | ||||
|     ui->toggle_background_mute->setChecked(UISettings::values.mute_when_in_background.GetValue()); | ||||
| 
 | ||||
|     if (!Settings::IsConfiguringGlobal()) { | ||||
|         if (Settings::values.volume.UsingGlobal()) { | ||||
|             ui->volume_combo_box->setCurrentIndex(0); | ||||
|             ui->volume_slider->setEnabled(false); | ||||
|         } else { | ||||
|             ui->volume_combo_box->setCurrentIndex(1); | ||||
|             ui->volume_slider->setEnabled(true); | ||||
|         } | ||||
|         ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index); | ||||
|         ConfigurationShared::SetHighlight(ui->mode_label, | ||||
|                                           !Settings::values.sound_index.UsingGlobal()); | ||||
|         ConfigurationShared::SetHighlight(ui->volume_layout, | ||||
|                                           !Settings::values.volume.UsingGlobal()); | ||||
|     } else { | ||||
|         ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue()); | ||||
|     } | ||||
|     SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::SetOutputSinkFromSinkID() { | ||||
|     [[maybe_unused]] const QSignalBlocker blocker(ui->sink_combo_box); | ||||
|     [[maybe_unused]] const QSignalBlocker blocker(sink_combo_box); | ||||
| 
 | ||||
|     int new_sink_index = 0; | ||||
|     const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue()); | ||||
|     for (int index = 0; index < ui->sink_combo_box->count(); index++) { | ||||
|         if (ui->sink_combo_box->itemText(index) == sink_id) { | ||||
|     const QString sink_id = QString::fromStdString(Settings::values.sink_id.ToString()); | ||||
|     for (int index = 0; index < sink_combo_box->count(); index++) { | ||||
|         if (sink_combo_box->itemText(index) == sink_id) { | ||||
|             new_sink_index = index; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ui->sink_combo_box->setCurrentIndex(new_sink_index); | ||||
|     sink_combo_box->setCurrentIndex(new_sink_index); | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::SetAudioDevicesFromDeviceID() { | ||||
|  | @ -91,57 +117,42 @@ void ConfigureAudio::SetAudioDevicesFromDeviceID() { | |||
| 
 | ||||
|     const QString output_device_id = | ||||
|         QString::fromStdString(Settings::values.audio_output_device_id.GetValue()); | ||||
|     for (int index = 0; index < ui->output_combo_box->count(); index++) { | ||||
|         if (ui->output_combo_box->itemText(index) == output_device_id) { | ||||
|     for (int index = 0; index < output_device_combo_box->count(); index++) { | ||||
|         if (output_device_combo_box->itemText(index) == output_device_id) { | ||||
|             new_device_index = index; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ui->output_combo_box->setCurrentIndex(new_device_index); | ||||
|     output_device_combo_box->setCurrentIndex(new_device_index); | ||||
| 
 | ||||
|     new_device_index = -1; | ||||
|     const QString input_device_id = | ||||
|         QString::fromStdString(Settings::values.audio_input_device_id.GetValue()); | ||||
|     for (int index = 0; index < ui->input_combo_box->count(); index++) { | ||||
|         if (ui->input_combo_box->itemText(index) == input_device_id) { | ||||
|     for (int index = 0; index < input_device_combo_box->count(); index++) { | ||||
|         if (input_device_combo_box->itemText(index) == input_device_id) { | ||||
|             new_device_index = index; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ui->input_combo_box->setCurrentIndex(new_device_index); | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::SetVolumeIndicatorText(int percentage) { | ||||
|     ui->volume_indicator->setText(tr("%1%", "Volume percentage (e.g. 50%)").arg(percentage)); | ||||
|     input_device_combo_box->setCurrentIndex(new_device_index); | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::ApplyConfiguration() { | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound); | ||||
|     const bool is_powered_on = system.IsPoweredOn(); | ||||
|     for (const auto& apply_func : apply_funcs) { | ||||
|         apply_func(is_powered_on); | ||||
|     } | ||||
| 
 | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         Settings::values.sink_id = | ||||
|             ui->sink_combo_box->itemText(ui->sink_combo_box->currentIndex()).toStdString(); | ||||
|         Settings::values.sink_id.LoadString( | ||||
|             sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString()); | ||||
|         Settings::values.audio_output_device_id.SetValue( | ||||
|             ui->output_combo_box->itemText(ui->output_combo_box->currentIndex()).toStdString()); | ||||
|             output_device_combo_box->itemText(output_device_combo_box->currentIndex()) | ||||
|                 .toStdString()); | ||||
|         Settings::values.audio_input_device_id.SetValue( | ||||
|             ui->input_combo_box->itemText(ui->input_combo_box->currentIndex()).toStdString()); | ||||
|         UISettings::values.mute_when_in_background = ui->toggle_background_mute->isChecked(); | ||||
| 
 | ||||
|         // Guard if during game and set to game-specific value
 | ||||
|         if (Settings::values.volume.UsingGlobal()) { | ||||
|             const auto volume = static_cast<u8>(ui->volume_slider->value()); | ||||
|             Settings::values.volume.SetValue(volume); | ||||
|         } | ||||
|     } else { | ||||
|         if (ui->volume_combo_box->currentIndex() == 0) { | ||||
|             Settings::values.volume.SetGlobal(true); | ||||
|         } else { | ||||
|             Settings::values.volume.SetGlobal(false); | ||||
|             const auto volume = static_cast<u8>(ui->volume_slider->value()); | ||||
|             Settings::values.volume.SetValue(volume); | ||||
|         } | ||||
|             input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -154,54 +165,31 @@ void ConfigureAudio::changeEvent(QEvent* event) { | |||
| } | ||||
| 
 | ||||
| void ConfigureAudio::UpdateAudioDevices(int sink_index) { | ||||
|     ui->output_combo_box->clear(); | ||||
|     ui->output_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||
|     output_device_combo_box->clear(); | ||||
|     output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||
| 
 | ||||
|     const std::string sink_id = ui->sink_combo_box->itemText(sink_index).toStdString(); | ||||
|     const auto sink_id = | ||||
|         Settings::ToEnum<Settings::AudioEngine>(sink_combo_box->itemText(sink_index).toStdString()); | ||||
|     for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, false)) { | ||||
|         ui->output_combo_box->addItem(QString::fromStdString(device)); | ||||
|         output_device_combo_box->addItem(QString::fromStdString(device)); | ||||
|     } | ||||
| 
 | ||||
|     ui->input_combo_box->clear(); | ||||
|     ui->input_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||
|     input_device_combo_box->clear(); | ||||
|     input_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||
|     for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) { | ||||
|         ui->input_combo_box->addItem(QString::fromStdString(device)); | ||||
|         input_device_combo_box->addItem(QString::fromStdString(device)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::InitializeAudioSinkComboBox() { | ||||
|     ui->sink_combo_box->clear(); | ||||
|     ui->sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||
|     sink_combo_box->clear(); | ||||
|     sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||
| 
 | ||||
|     for (const auto& id : AudioCore::Sink::GetSinkIDs()) { | ||||
|         ui->sink_combo_box->addItem(QString::fromUtf8(id.data(), static_cast<s32>(id.length()))); | ||||
|         sink_combo_box->addItem(QString::fromStdString(Settings::TranslateEnum(id))); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::RetranslateUI() { | ||||
|     ui->retranslateUi(this); | ||||
|     SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); | ||||
| } | ||||
| 
 | ||||
| void ConfigureAudio::SetupPerGameUI() { | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal()); | ||||
|         ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     ConfigurationShared::SetColoredComboBox(ui->combo_sound, ui->mode_label, | ||||
|                                             Settings::values.sound_index.GetValue(true)); | ||||
| 
 | ||||
|     connect(ui->volume_combo_box, qOverload<int>(&QComboBox::activated), this, [this](int index) { | ||||
|         ui->volume_slider->setEnabled(index == 1); | ||||
|         ConfigurationShared::SetHighlight(ui->volume_layout, index == 1); | ||||
|     }); | ||||
| 
 | ||||
|     ui->sink_combo_box->setVisible(false); | ||||
|     ui->sink_label->setVisible(false); | ||||
|     ui->output_combo_box->setVisible(false); | ||||
|     ui->output_label->setVisible(false); | ||||
|     ui->input_combo_box->setVisible(false); | ||||
|     ui->input_label->setVisible(false); | ||||
| } | ||||
|  |  | |||
|  | @ -3,9 +3,14 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <forward_list> | ||||
| #include <functional> | ||||
| #include <memory> | ||||
| #include <QWidget> | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| #include "yuzu/configuration/shared_translation.h" | ||||
| 
 | ||||
| class QPushButton; | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
|  | @ -19,6 +24,7 @@ class ConfigureAudio : public ConfigurationShared::Tab { | |||
| public: | ||||
|     explicit ConfigureAudio(const Core::System& system_, | ||||
|                             std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, | ||||
|                             const ConfigurationShared::TranslationMap& translations_, | ||||
|                             QWidget* parent = nullptr); | ||||
|     ~ConfigureAudio() override; | ||||
| 
 | ||||
|  | @ -36,11 +42,17 @@ private: | |||
| 
 | ||||
|     void SetOutputSinkFromSinkID(); | ||||
|     void SetAudioDevicesFromDeviceID(); | ||||
|     void SetVolumeIndicatorText(int percentage); | ||||
| 
 | ||||
|     void SetupPerGameUI(); | ||||
|     void Setup(); | ||||
| 
 | ||||
|     std::unique_ptr<Ui::ConfigureAudio> ui; | ||||
| 
 | ||||
|     const Core::System& system; | ||||
|     const ConfigurationShared::TranslationMap& translations; | ||||
| 
 | ||||
|     std::forward_list<std::function<void(bool)>> apply_funcs{}; | ||||
| 
 | ||||
|     QComboBox* sink_combo_box; | ||||
|     QComboBox* output_device_combo_box; | ||||
|     QComboBox* input_device_combo_box; | ||||
| }; | ||||
|  |  | |||
|  | @ -21,80 +21,14 @@ | |||
|      </property> | ||||
|      <layout class="QVBoxLayout"> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="engine_layout"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="sink_label"> | ||||
|           <property name="text"> | ||||
|            <string>Output Engine:</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QComboBox" name="sink_combo_box"/> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="output_layout"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="output_label"> | ||||
|           <property name="text"> | ||||
|            <string>Output Device:</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QComboBox" name="output_combo_box"/> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="input_layout"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="input_label"> | ||||
|           <property name="text"> | ||||
|            <string>Input Device:</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QComboBox" name="input_combo_box"/> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|        <item> | ||||
|        <layout class="QHBoxLayout" name="mode_layout"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="mode_label"> | ||||
|           <property name="text"> | ||||
|            <string>Sound Output Mode:</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|           <widget class="QComboBox" name="combo_sound"> | ||||
|             <item> | ||||
|               <property name="text"> | ||||
|                 <string>Mono</string> | ||||
|               </property> | ||||
|             </item> | ||||
|             <item> | ||||
|               <property name="text"> | ||||
|                 <string>Stereo</string> | ||||
|               </property> | ||||
|             </item> | ||||
|             <item> | ||||
|               <property name="text"> | ||||
|                 <string>Surround</string> | ||||
|               </property> | ||||
|             </item> | ||||
|           </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QWidget" name="volume_layout" native="true"> | ||||
|         <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||||
|        <widget class="QWidget" name="audio_widget" native="true"> | ||||
|         <property name="maximumSize"> | ||||
|          <size> | ||||
|           <width>16777215</width> | ||||
|           <height>16777213</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|          <property name="leftMargin"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|  | @ -107,89 +41,9 @@ | |||
|          <property name="bottomMargin"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|          <item> | ||||
|           <widget class="QComboBox" name="volume_combo_box"> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>Use global volume</string> | ||||
|             </property> | ||||
|            </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>Set volume:</string> | ||||
|             </property> | ||||
|            </item> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="volume_label"> | ||||
|            <property name="text"> | ||||
|             <string>Volume:</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <spacer name="horizontalSpacer"> | ||||
|            <property name="orientation"> | ||||
|             <enum>Qt::Horizontal</enum> | ||||
|            </property> | ||||
|            <property name="sizeHint" stdset="0"> | ||||
|             <size> | ||||
|              <width>30</width> | ||||
|              <height>20</height> | ||||
|             </size> | ||||
|            </property> | ||||
|           </spacer> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QSlider" name="volume_slider"> | ||||
|            <property name="sizePolicy"> | ||||
|             <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||
|              <horstretch>0</horstretch> | ||||
|              <verstretch>0</verstretch> | ||||
|             </sizepolicy> | ||||
|            </property> | ||||
|            <property name="maximum"> | ||||
|             <number>200</number> | ||||
|            </property> | ||||
|            <property name="pageStep"> | ||||
|             <number>5</number> | ||||
|            </property> | ||||
|            <property name="orientation"> | ||||
|             <enum>Qt::Horizontal</enum> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="volume_indicator"> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>32</width> | ||||
|              <height>0</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>0 %</string> | ||||
|            </property> | ||||
|            <property name="alignment"> | ||||
|             <set>Qt::AlignCenter</set> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="mute_layout"> | ||||
|          <item> | ||||
|            <widget class="QCheckBox" name="toggle_background_mute"> | ||||
|              <property name="text"> | ||||
|                <string>Mute audio when in background</string> | ||||
|              </property> | ||||
|            </widget> | ||||
|          </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </widget> | ||||
|    </item> | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, | |||
|     : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, | ||||
|       registry(registry_), system{system_}, | ||||
|       translations{ConfigurationShared::InitializeTranslations(this)}, | ||||
|       audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, this)}, | ||||
|       audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, *translations, this)}, | ||||
|       cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, this)}, | ||||
|       debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, | ||||
|       filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, | ||||
|  |  | |||
|  | @ -240,12 +240,14 @@ void ConfigureGraphics::Setup() { | |||
|             } else if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) { | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::ReverseSlider, true, 0.5f); | ||||
|                     ConfigurationShared::RequestType::ReverseSlider, true, 0.5f, nullptr, | ||||
|                     tr("%1%", "FSR sharpening percentage (e.g. 50%)")); | ||||
|             } else if (setting->Id() == Settings::values.speed_limit.Id()) { | ||||
|                 return new ConfigurationShared::Widget( | ||||
|                     setting, translations, this, runtime_lock, apply_funcs, | ||||
|                     ConfigurationShared::RequestType::SpinBox, true, 1.0f, | ||||
|                     &Settings::values.use_speed_limit, "%"); | ||||
|                     &Settings::values.use_speed_limit, | ||||
|                     tr("%", "Limit speed percentage (e.g. 50%)")); | ||||
|             } else { | ||||
|                 return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, | ||||
|                                                        apply_funcs); | ||||
|  | @ -304,7 +306,7 @@ void ConfigureGraphics::Setup() { | |||
|         }); | ||||
|     } else { | ||||
|         QPushButton* bg_restore_button = ConfigurationShared::Widget::CreateRestoreGlobalButton( | ||||
|             Settings::values.bg_red, ui->bg_widget); | ||||
|             Settings::values.bg_red.UsingGlobal(), ui->bg_widget); | ||||
|         ui->bg_widget->layout()->addWidget(bg_restore_button); | ||||
| 
 | ||||
|         QObject::connect(bg_restore_button, &QAbstractButton::clicked, | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
|     game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig); | ||||
| 
 | ||||
|     addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this); | ||||
|     audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, this); | ||||
|     audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *translations, this); | ||||
|     cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, this); | ||||
|     graphics_advanced_tab = | ||||
|         std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, *translations, this); | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
|     INSERT(Settings, audio_input_device_id, "Input Device:", ""); | ||||
|     INSERT(Settings, audio_muted, "Mute audio when in background", ""); | ||||
|     INSERT(Settings, volume, "Volume:", ""); | ||||
|     INSERT(Settings, dump_audio_commands, "", ""); | ||||
| 
 | ||||
|     // Core
 | ||||
|     INSERT(Settings, use_multi_core, "Multicore CPU Emulation", ""); | ||||
|  | @ -270,6 +271,12 @@ std::forward_list<QString> ComboboxEnumeration(std::type_index type, QWidget* pa | |||
|             tr("ROC"),     tr("ROK"),       tr("Singapore"), tr("Turkey"),    tr("UCT"), | ||||
|             tr("W-SU"),    tr("WET"),       tr("Zulu"), | ||||
|         }; | ||||
|     } else if (type == typeid(Settings::AudioMode)) { | ||||
|         return { | ||||
|             tr("Mono"), | ||||
|             tr("Stereo"), | ||||
|             tr("Surround"), | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     return {}; | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ | |||
| 
 | ||||
| namespace ConfigurationShared { | ||||
| 
 | ||||
| QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting, QWidget* parent) { | ||||
| QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) { | ||||
|     QStyle* style = parent->style(); | ||||
|     QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton)); | ||||
|     QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent); | ||||
|  | @ -34,8 +34,8 @@ QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting, | |||
|     sp_retain.setRetainSizeWhenHidden(true); | ||||
|     restore_button->setSizePolicy(sp_retain); | ||||
| 
 | ||||
|     restore_button->setEnabled(!setting.UsingGlobal()); | ||||
|     restore_button->setVisible(!setting.UsingGlobal()); | ||||
|     restore_button->setEnabled(!using_global); | ||||
|     restore_button->setVisible(!using_global); | ||||
| 
 | ||||
|     return restore_button; | ||||
| } | ||||
|  | @ -57,6 +57,10 @@ QHBoxLayout* Widget::CreateCheckBox(Settings::BasicSetting* bool_setting, const | |||
|                                                                : Qt::CheckState::Unchecked); | ||||
|     checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
| 
 | ||||
|     if (!bool_setting->Save() && !Settings::IsConfiguringGlobal() && runtime_lock) { | ||||
|         checkbox->setEnabled(false); | ||||
|     } | ||||
| 
 | ||||
|     layout->addWidget(checkbox); | ||||
| 
 | ||||
|     layout->setContentsMargins(0, 0, 0, 0); | ||||
|  | @ -70,7 +74,8 @@ QHBoxLayout* Widget::CreateCheckBox(Settings::BasicSetting* bool_setting, const | |||
|             bool_setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false"); | ||||
|         }; | ||||
|     } else { | ||||
|         restore_button = CreateRestoreGlobalButton(*bool_setting, this); | ||||
|         restore_button = | ||||
|             CreateRestoreGlobalButton(bool_setting->UsingGlobal() && setting.UsingGlobal(), this); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(checkbox, &QCheckBox::stateChanged, [=](int) { | ||||
|  | @ -128,7 +133,7 @@ void Widget::CreateCombobox(const QString& label, std::function<void()>& load_fu | |||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         load_func = [=]() { setting.LoadString(std::to_string(combobox->currentIndex())); }; | ||||
|     } else { | ||||
|         restore_button = CreateRestoreGlobalButton(setting, this); | ||||
|         restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [&](bool) { | ||||
|  | @ -194,7 +199,7 @@ void Widget::CreateLineEdit(const QString& label, std::function<void()>& load_fu | |||
|         }; | ||||
|     } else { | ||||
|         if (!has_checkbox) { | ||||
|             restore_button = CreateRestoreGlobalButton(setting, this); | ||||
|             restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this); | ||||
|             layout->addWidget(restore_button); | ||||
|         } | ||||
| 
 | ||||
|  | @ -223,7 +228,7 @@ void Widget::CreateLineEdit(const QString& label, std::function<void()>& load_fu | |||
| } | ||||
| 
 | ||||
| void Widget::CreateSlider(const QString& label, bool reversed, float multiplier, | ||||
|                           std::function<void()>& load_func, bool managed, | ||||
|                           std::function<void()>& load_func, bool managed, const QString& format, | ||||
|                           Settings::BasicSetting* const other_setting) { | ||||
|     created = true; | ||||
| 
 | ||||
|  | @ -242,15 +247,16 @@ void Widget::CreateSlider(const QString& label, bool reversed, float multiplier, | |||
| 
 | ||||
|     int max_val = std::stoi(setting.MaxVal()); | ||||
| 
 | ||||
|     const QString use_format = format == QStringLiteral("") ? QStringLiteral("%1") : format; | ||||
| 
 | ||||
|     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)))); | ||||
|         int present = (reversed ? max_val - value : value) * multiplier + 0.5f; | ||||
|         feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||||
|     }); | ||||
| 
 | ||||
|     slider->setValue(std::stoi(setting.ToString())); | ||||
|     slider->setMinimum(std::stoi(setting.MinVal())); | ||||
|     slider->setMaximum(max_val); | ||||
|     slider->setValue(std::stoi(setting.ToString())); | ||||
| 
 | ||||
|     slider->setInvertedAppearance(reversed); | ||||
| 
 | ||||
|  | @ -261,7 +267,7 @@ void Widget::CreateSlider(const QString& label, bool reversed, float multiplier, | |||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         load_func = [=]() { setting.LoadString(std::to_string(slider->value())); }; | ||||
|     } else { | ||||
|         restore_button = CreateRestoreGlobalButton(setting, this); | ||||
|         restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { | ||||
|  | @ -287,7 +293,7 @@ void Widget::CreateSlider(const QString& label, bool reversed, float multiplier, | |||
| } | ||||
| 
 | ||||
| void Widget::CreateSpinBox(const QString& label, std::function<void()>& load_func, bool managed, | ||||
|                            const std::string& suffix, Settings::BasicSetting* other_setting) { | ||||
|                            const QString& suffix, Settings::BasicSetting* other_setting) { | ||||
|     const bool has_checkbox = other_setting != nullptr; | ||||
|     if (has_checkbox && other_setting->TypeId() != typeid(bool)) { | ||||
|         LOG_WARNING(Frontend, "Extra setting requested but setting is not boolean"); | ||||
|  | @ -315,7 +321,7 @@ void Widget::CreateSpinBox(const QString& label, std::function<void()>& load_fun | |||
|     spinbox = new QSpinBox(this); | ||||
|     spinbox->setRange(min_val, max_val); | ||||
|     spinbox->setValue(default_val); | ||||
|     spinbox->setSuffix(QString::fromStdString(suffix)); | ||||
|     spinbox->setSuffix(suffix); | ||||
|     spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||
| 
 | ||||
|     layout->insertWidget(1, spinbox); | ||||
|  | @ -327,7 +333,8 @@ void Widget::CreateSpinBox(const QString& label, std::function<void()>& load_fun | |||
|         }; | ||||
|     } else { | ||||
|         if (!has_checkbox) { | ||||
|             restore_button = CreateRestoreGlobalButton(setting, this); | ||||
|             restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this); | ||||
|             layout->addWidget(restore_button); | ||||
|         } | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, | ||||
|  | @ -382,7 +389,7 @@ void Widget::CreateHexEdit(const QString& label, std::function<void()>& load_fun | |||
|             setting.LoadString(hex_to_dec()); | ||||
|         }; | ||||
|     } else { | ||||
|         restore_button = CreateRestoreGlobalButton(setting, this); | ||||
|         restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this); | ||||
|         layout->addWidget(restore_button); | ||||
| 
 | ||||
|         QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { | ||||
|  | @ -465,7 +472,7 @@ void Widget::CreateDateTimeEdit(const QString& label, std::function<void()>& loa | |||
|         }; | ||||
|     } else { | ||||
|         if (!has_checkbox) { | ||||
|             restore_button = CreateRestoreGlobalButton(setting, this); | ||||
|             restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this); | ||||
|             layout->addWidget(restore_button); | ||||
|         } | ||||
| 
 | ||||
|  | @ -515,12 +522,12 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati | |||
|       apply_funcs{apply_funcs_} {} | ||||
| 
 | ||||
| Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_, | ||||
|                QWidget* parent_, bool runtime_lock, | ||||
|                QWidget* parent_, bool runtime_lock_, | ||||
|                std::forward_list<std::function<void(bool)>>& apply_funcs_, RequestType request, | ||||
|                bool managed, float multiplier, Settings::BasicSetting* other_setting, | ||||
|                const std::string& string) | ||||
|                const QString& string) | ||||
|     : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_}, | ||||
|       apply_funcs{apply_funcs_} { | ||||
|       apply_funcs{apply_funcs_}, runtime_lock{runtime_lock_} { | ||||
|     if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) { | ||||
|         LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel()); | ||||
|         return; | ||||
|  | @ -547,23 +554,16 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati | |||
|     std::function<void()> load_func = []() {}; | ||||
| 
 | ||||
|     if (type == typeid(bool)) { | ||||
|         switch (request) { | ||||
|         case RequestType::Default: | ||||
|             CreateCheckBox(&setting, label, load_func, managed); | ||||
|             break; | ||||
|         default: | ||||
|             LOG_WARNING(Frontend, "Requested widget is unimplemented."); | ||||
|             break; | ||||
|         } | ||||
|         CreateCheckBox(&setting, label, load_func, managed); | ||||
|     } else if (setting.IsEnum()) { | ||||
|         CreateCombobox(label, load_func, managed); | ||||
|     } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || | ||||
|                type == typeid(s64)) { | ||||
|                type == typeid(s64) || type == typeid(u8)) { | ||||
|         switch (request) { | ||||
|         case RequestType::Slider: | ||||
|         case RequestType::ReverseSlider: | ||||
|             CreateSlider(label, request == RequestType::ReverseSlider, multiplier, load_func, | ||||
|                          managed); | ||||
|                          managed, string); | ||||
|             break; | ||||
|         case RequestType::LineEdit: | ||||
|         case RequestType::Default: | ||||
|  | @ -586,7 +586,23 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati | |||
|             break; | ||||
|         } | ||||
|     } else if (type == typeid(std::string)) { | ||||
|         CreateLineEdit(label, load_func, managed); | ||||
|         switch (request) { | ||||
|         case RequestType::Default: | ||||
|         case RequestType::LineEdit: | ||||
|             CreateLineEdit(label, load_func, managed); | ||||
|             break; | ||||
|         case RequestType::ComboBox: | ||||
|             CreateCombobox(label, load_func, false); | ||||
|             break; | ||||
|         case RequestType::SpinBox: | ||||
|         case RequestType::Slider: | ||||
|         case RequestType::ReverseSlider: | ||||
|         case RequestType::HexEdit: | ||||
|         case RequestType::DateTimeEdit: | ||||
|         case RequestType::MaxEnum: | ||||
|             LOG_WARNING(Frontend, "Requested widget is unimplemented."); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (!created) { | ||||
|  |  | |||
|  | @ -38,15 +38,15 @@ public: | |||
|     Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, | ||||
|            bool runtime_lock, std::forward_list<std::function<void(bool)>>& apply_funcs_, | ||||
|            RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, | ||||
|            Settings::BasicSetting* other_setting = nullptr, const std::string& format = ""); | ||||
|            Settings::BasicSetting* other_setting = nullptr, | ||||
|            const QString& string = QStringLiteral("")); | ||||
|     Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_, QWidget* parent_, | ||||
|            std::forward_list<std::function<void(bool)>>& apply_funcs_); | ||||
|     virtual ~Widget(); | ||||
| 
 | ||||
|     bool Valid(); | ||||
| 
 | ||||
|     [[nodiscard]] static QPushButton* CreateRestoreGlobalButton(Settings::BasicSetting& setting, | ||||
|                                                                 QWidget* parent); | ||||
|     [[nodiscard]] static QPushButton* CreateRestoreGlobalButton(bool using_global, QWidget* parent); | ||||
| 
 | ||||
|     QPushButton* restore_button{}; | ||||
|     QLineEdit* line_edit{}; | ||||
|  | @ -68,12 +68,12 @@ private: | |||
|     void CreateHexEdit(const QString& label, std::function<void()>& load_func, bool managed, | ||||
|                        Settings::BasicSetting* const other_setting = nullptr); | ||||
|     void CreateSlider(const QString& label, bool reversed, float multiplier, | ||||
|                       std::function<void()>& load_func, bool managed, | ||||
|                       std::function<void()>& load_func, bool managed, const QString& format, | ||||
|                       Settings::BasicSetting* const other_setting = nullptr); | ||||
|     void CreateDateTimeEdit(const QString& label, std::function<void()>& load_func, bool managed, | ||||
|                             bool restrict, Settings::BasicSetting* const other_setting = nullptr); | ||||
|     void CreateSpinBox(const QString& label, std::function<void()>& load_func, bool managed, | ||||
|                        const std::string& suffix, Settings::BasicSetting* other_setting = nullptr); | ||||
|                        const QString& suffix, Settings::BasicSetting* other_setting = nullptr); | ||||
| 
 | ||||
|     QWidget* parent; | ||||
|     const TranslationMap& translations; | ||||
|  | @ -81,6 +81,7 @@ private: | |||
|     std::forward_list<std::function<void(bool)>>& apply_funcs; | ||||
| 
 | ||||
|     bool created{false}; | ||||
|     bool runtime_lock{false}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace ConfigurationShared
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 lat9nq
						lat9nq