From 0b11a14e24ce4fee9bbf05028dc24296ae91c68a Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 1 Jul 2020 00:33:53 +1000 Subject: [PATCH] Qt: Better handling of default settings not in ini --- src/core/host_interface.cpp | 21 ++++----- src/core/settings.cpp | 44 +++++++++++-------- src/core/settings.h | 10 +++++ src/duckstation-qt/advancedsettingswidget.cpp | 3 +- src/duckstation-qt/audiosettingswidget.cpp | 3 +- src/duckstation-qt/consolesettingswidget.cpp | 6 ++- src/duckstation-qt/gpusettingswidget.cpp | 7 +-- .../memorycardsettingswidget.cpp | 8 ++-- src/duckstation-qt/settingwidgetbinder.h | 39 ++++++++++++---- 9 files changed, 94 insertions(+), 47 deletions(-) diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 57343bf07..047d2f717 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -321,7 +321,7 @@ std::string HostInterface::GetShaderCacheDirectory() void HostInterface::SetDefaultSettings(SettingsInterface& si) { - si.SetStringValue("Console", "Region", Settings::GetConsoleRegionName(ConsoleRegion::Auto)); + si.SetStringValue("Console", "Region", Settings::GetConsoleRegionName(Settings::DEFAULT_CONSOLE_REGION)); si.SetFloatValue("Main", "EmulationSpeed", 1.0f); si.SetBoolValue("Main", "SpeedLimiterEnabled", true); @@ -330,7 +330,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("Main", "SaveStateOnExit", true); si.SetBoolValue("Main", "ConfirmPowerOff", true); - si.SetStringValue("CPU", "ExecutionMode", Settings::GetCPUExecutionModeName(CPUExecutionMode::Recompiler)); + si.SetStringValue("CPU", "ExecutionMode", Settings::GetCPUExecutionModeName(Settings::DEFAULT_CPU_EXECUTION_MODE)); si.SetStringValue("GPU", "Renderer", Settings::GetRendererName(Settings::DEFAULT_GPU_RENDERER)); si.SetIntValue("GPU", "ResolutionScale", 1); @@ -341,8 +341,9 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("GPU", "DisableInterlacing", true); si.SetBoolValue("GPU", "ForceNTSCTimings", false); - si.SetStringValue("Display", "CropMode", "Overscan"); - si.SetStringValue("Display", "AspectRatio", "4:3"); + si.SetStringValue("Display", "CropMode", Settings::GetDisplayCropModeName(Settings::DEFAULT_DISPLAY_CROP_MODE)); + si.SetStringValue("Display", "AspectRatio", + Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)); si.SetBoolValue("Display", "LinearFiltering", true); si.SetBoolValue("Display", "IntegerScaling", false); si.SetBoolValue("Display", "ShowOSDMessages", true); @@ -357,7 +358,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("CDROM", "ReadThread", true); si.SetBoolValue("CDROM", "RegionCheck", true); - si.SetStringValue("Audio", "Backend", Settings::GetAudioBackendName(AudioBackend::Cubeb)); + si.SetStringValue("Audio", "Backend", Settings::GetAudioBackendName(Settings::DEFAULT_AUDIO_BACKEND)); si.SetIntValue("Audio", "OutputVolume", 100); si.SetIntValue("Audio", "BufferSize", DEFAULT_AUDIO_BUFFER_SIZE); si.SetIntValue("Audio", "OutputMuted", false); @@ -368,16 +369,16 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("BIOS", "PatchTTYEnable", false); si.SetBoolValue("BIOS", "PatchFastBoot", false); - si.SetStringValue("Controller1", "Type", Settings::GetControllerTypeName(ControllerType::DigitalController)); - si.SetStringValue("Controller2", "Type", Settings::GetControllerTypeName(ControllerType::None)); + si.SetStringValue("Controller1", "Type", Settings::GetControllerTypeName(Settings::DEFAULT_CONTROLLER_1_TYPE)); + si.SetStringValue("Controller2", "Type", Settings::GetControllerTypeName(Settings::DEFAULT_CONTROLLER_2_TYPE)); si.SetBoolValue("MemoryCards", "LoadFromSaveStates", false); - si.SetStringValue("MemoryCards", "Card1Type", Settings::GetMemoryCardTypeName(MemoryCardType::PerGameTitle)); + si.SetStringValue("MemoryCards", "Card1Type", Settings::GetMemoryCardTypeName(Settings::DEFAULT_MEMORY_CARD_1_TYPE)); si.SetStringValue("MemoryCards", "Card1Path", "memcards/shared_card_1.mcd"); - si.SetStringValue("MemoryCards", "Card2Type", "None"); + si.SetStringValue("MemoryCards", "Card2Type", Settings::GetMemoryCardTypeName(Settings::DEFAULT_MEMORY_CARD_2_TYPE)); si.SetStringValue("MemoryCards", "Card2Path", "memcards/shared_card_2.mcd"); - si.SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(LOGLEVEL_INFO)); + si.SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Settings::DEFAULT_LOG_LEVEL)); si.SetStringValue("Logging", "LogFilter", ""); si.SetBoolValue("Logging", "LogToConsole", false); si.SetBoolValue("Logging", "LogToDebug", false); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 14002dce7..5dfce7501 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -72,7 +72,7 @@ bool Settings::HasAnyPerGameMemoryCards() const void Settings::Load(SettingsInterface& si) { region = - ParseConsoleRegionName(si.GetStringValue("Console", "Region", "NTSC-U").c_str()).value_or(ConsoleRegion::NTSC_U); + ParseConsoleRegionName(si.GetStringValue("Console", "Region", "NTSC-U").c_str()).value_or(DEFAULT_CONSOLE_REGION); emulation_speed = si.GetFloatValue("Main", "EmulationSpeed", 1.0f); speed_limiter_enabled = si.GetBoolValue("Main", "SpeedLimiterEnabled", true); @@ -82,8 +82,10 @@ void Settings::Load(SettingsInterface& si) save_state_on_exit = si.GetBoolValue("Main", "SaveStateOnExit", true); confim_power_off = si.GetBoolValue("Main", "ConfirmPowerOff", true); - cpu_execution_mode = ParseCPUExecutionMode(si.GetStringValue("CPU", "ExecutionMode", "Recompiler").c_str()) - .value_or(CPUExecutionMode::Interpreter); + cpu_execution_mode = + ParseCPUExecutionMode( + si.GetStringValue("CPU", "ExecutionMode", GetCPUExecutionModeName(DEFAULT_CPU_EXECUTION_MODE)).c_str()) + .value_or(DEFAULT_CPU_EXECUTION_MODE); gpu_renderer = ParseRendererName(si.GetStringValue("GPU", "Renderer", GetRendererName(DEFAULT_GPU_RENDERER)).c_str()) .value_or(DEFAULT_GPU_RENDERER); @@ -96,13 +98,14 @@ void Settings::Load(SettingsInterface& si) gpu_disable_interlacing = si.GetBoolValue("GPU", "DisableInterlacing", true); gpu_force_ntsc_timings = si.GetBoolValue("GPU", "ForceNTSCTimings", false); - display_crop_mode = ParseDisplayCropMode( - si.GetStringValue("Display", "CropMode", GetDisplayCropModeName(DisplayCropMode::None)).c_str()) - .value_or(DisplayCropMode::None); + display_crop_mode = + ParseDisplayCropMode( + si.GetStringValue("Display", "CropMode", GetDisplayCropModeName(DEFAULT_DISPLAY_CROP_MODE)).c_str()) + .value_or(DEFAULT_DISPLAY_CROP_MODE); display_aspect_ratio = ParseDisplayAspectRatio( - si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DisplayAspectRatio::R4_3)).c_str()) - .value_or(DisplayAspectRatio::R4_3); + si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DEFAULT_DISPLAY_ASPECT_RATIO)).c_str()) + .value_or(DEFAULT_DISPLAY_ASPECT_RATIO); display_linear_filtering = si.GetBoolValue("Display", "LinearFiltering", true); display_integer_scaling = si.GetBoolValue("Display", "IntegerScaling", false); display_show_osd_messages = si.GetBoolValue("Display", "ShowOSDMessages", true); @@ -117,7 +120,8 @@ void Settings::Load(SettingsInterface& si) cdrom_region_check = si.GetBoolValue("CDROM", "RegionCheck", true); audio_backend = - ParseAudioBackend(si.GetStringValue("Audio", "Backend", "Cubeb").c_str()).value_or(AudioBackend::Cubeb); + ParseAudioBackend(si.GetStringValue("Audio", "Backend", GetAudioBackendName(DEFAULT_AUDIO_BACKEND)).c_str()) + .value_or(DEFAULT_AUDIO_BACKEND); audio_output_volume = si.GetIntValue("Audio", "OutputVolume", 100); audio_buffer_size = si.GetIntValue("Audio", "BufferSize", HostInterface::DEFAULT_AUDIO_BUFFER_SIZE); audio_output_muted = si.GetBoolValue("Audio", "OutputMuted", false); @@ -133,27 +137,31 @@ void Settings::Load(SettingsInterface& si) bios_patch_tty_enable = si.GetBoolValue("BIOS", "PatchTTYEnable", false); bios_patch_fast_boot = si.GetBoolValue("BIOS", "PatchFastBoot", false); - controller_types[0] = ParseControllerTypeName(si.GetStringValue("Controller1", "Type", "DigitalController").c_str()) - .value_or(ControllerType::DigitalController); + controller_types[0] = + ParseControllerTypeName( + si.GetStringValue("Controller1", "Type", GetControllerTypeName(DEFAULT_CONTROLLER_1_TYPE)).c_str()) + .value_or(DEFAULT_CONTROLLER_1_TYPE); controller_types[1] = - ParseControllerTypeName(si.GetStringValue("Controller2", "Type", "None").c_str()).value_or(ControllerType::None); + ParseControllerTypeName( + si.GetStringValue("Controller2", "Type", GetControllerTypeName(DEFAULT_CONTROLLER_2_TYPE)).c_str()) + .value_or(DEFAULT_CONTROLLER_2_TYPE); // NOTE: The default value here if not present in the config is shared, but SetDefaultSettings() makes per-game. // This is so we don't break older builds which had the shared card by default. load_memory_cards_from_save_states = si.GetBoolValue("MemoryCards", "LoadFromSaveStates", false); memory_card_types[0] = ParseMemoryCardTypeName( - si.GetStringValue("MemoryCards", "Card1Type", GetMemoryCardTypeName(MemoryCardType::Shared)).c_str()) - .value_or(MemoryCardType::Shared); + si.GetStringValue("MemoryCards", "Card1Type", GetMemoryCardTypeName(DEFAULT_MEMORY_CARD_1_TYPE)).c_str()) + .value_or(DEFAULT_MEMORY_CARD_1_TYPE); memory_card_paths[0] = si.GetStringValue("MemoryCards", "Card1Path", "memcards/shared_card_1.mcd"); memory_card_types[1] = ParseMemoryCardTypeName( - si.GetStringValue("MemoryCards", "Card2Type", GetMemoryCardTypeName(MemoryCardType::None)).c_str()) - .value_or(MemoryCardType::None); + si.GetStringValue("MemoryCards", "Card2Type", GetMemoryCardTypeName(DEFAULT_MEMORY_CARD_2_TYPE)).c_str()) + .value_or(DEFAULT_MEMORY_CARD_2_TYPE); memory_card_paths[1] = si.GetStringValue("MemoryCards", "Card2Path", "memcards/shared_card_2.mcd"); - log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(LOGLEVEL_INFO)).c_str()) - .value_or(LOGLEVEL_INFO); + log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str()) + .value_or(DEFAULT_LOG_LEVEL); log_filter = si.GetStringValue("Logging", "LogFilter", ""); log_to_console = si.GetBoolValue("Logging", "LogToConsole", false); log_to_debug = si.GetBoolValue("Logging", "LogToDebug", false); diff --git a/src/core/settings.h b/src/core/settings.h index 8337581c4..f2c97bc0c 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -206,4 +206,14 @@ struct Settings #else static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareOpenGL; #endif + static constexpr ConsoleRegion DEFAULT_CONSOLE_REGION = ConsoleRegion::NTSC_U; + static constexpr CPUExecutionMode DEFAULT_CPU_EXECUTION_MODE = CPUExecutionMode::Recompiler; + static constexpr AudioBackend DEFAULT_AUDIO_BACKEND = AudioBackend::Cubeb; + static constexpr DisplayCropMode DEFAULT_DISPLAY_CROP_MODE = DisplayCropMode::Overscan; + static constexpr DisplayAspectRatio DEFAULT_DISPLAY_ASPECT_RATIO = DisplayAspectRatio::R4_3; + static constexpr ControllerType DEFAULT_CONTROLLER_1_TYPE = ControllerType::DigitalController; + static constexpr ControllerType DEFAULT_CONTROLLER_2_TYPE = ControllerType::None; + static constexpr MemoryCardType DEFAULT_MEMORY_CARD_1_TYPE = MemoryCardType::Shared; + static constexpr MemoryCardType DEFAULT_MEMORY_CARD_2_TYPE = MemoryCardType::None; + static constexpr LOGLEVEL DEFAULT_LOG_LEVEL = LOGLEVEL_INFO; }; diff --git a/src/duckstation-qt/advancedsettingswidget.cpp b/src/duckstation-qt/advancedsettingswidget.cpp index bcef3579e..1b934f471 100644 --- a/src/duckstation-qt/advancedsettingswidget.cpp +++ b/src/duckstation-qt/advancedsettingswidget.cpp @@ -10,7 +10,8 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(QtHostInterface* host_interface, m_ui.logLevel->addItem(tr(Settings::GetLogLevelDisplayName(static_cast(i)))); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.logLevel, QStringLiteral("Logging/LogLevel"), - &Settings::ParseLogLevelName, &Settings::GetLogLevelName); + &Settings::ParseLogLevelName, &Settings::GetLogLevelName, + Settings::DEFAULT_LOG_LEVEL); SettingWidgetBinder::BindWidgetToStringSetting(m_host_interface, m_ui.logFilter, QStringLiteral("Logging/LogFilter")); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.logToConsole, QStringLiteral("Logging/LogToConsole")); diff --git a/src/duckstation-qt/audiosettingswidget.cpp b/src/duckstation-qt/audiosettingswidget.cpp index 07b90d135..1b0e5409a 100644 --- a/src/duckstation-qt/audiosettingswidget.cpp +++ b/src/duckstation-qt/audiosettingswidget.cpp @@ -12,7 +12,8 @@ AudioSettingsWidget::AudioSettingsWidget(QtHostInterface* host_interface, QWidge m_ui.audioBackend->addItem(tr(Settings::GetAudioBackendDisplayName(static_cast(i)))); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.audioBackend, "Audio/Backend", - &Settings::ParseAudioBackend, &Settings::GetAudioBackendName); + &Settings::ParseAudioBackend, &Settings::GetAudioBackendName, + Settings::DEFAULT_AUDIO_BACKEND); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.syncToOutput, "Audio/Sync"); SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.bufferSize, "Audio/BufferSize"); SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.volume, "Audio/OutputVolume"); diff --git a/src/duckstation-qt/consolesettingswidget.cpp b/src/duckstation-qt/consolesettingswidget.cpp index e079c97ee..d5f8feea4 100644 --- a/src/duckstation-qt/consolesettingswidget.cpp +++ b/src/duckstation-qt/consolesettingswidget.cpp @@ -16,12 +16,14 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW m_ui.cpuExecutionMode->addItem(tr(Settings::GetCPUExecutionModeDisplayName(static_cast(i)))); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.region, "Console/Region", - &Settings::ParseConsoleRegionName, &Settings::GetConsoleRegionName); + &Settings::ParseConsoleRegionName, &Settings::GetConsoleRegionName, + Settings::DEFAULT_CONSOLE_REGION); SettingWidgetBinder::BindWidgetToStringSetting(m_host_interface, m_ui.biosPath, "BIOS/Path"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enableTTYOutput, "BIOS/PatchTTYEnable"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.fastBoot, "BIOS/PatchFastBoot"); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.cpuExecutionMode, "CPU/ExecutionMode", - &Settings::ParseCPUExecutionMode, &Settings::GetCPUExecutionModeName); + &Settings::ParseCPUExecutionMode, &Settings::GetCPUExecutionModeName, + Settings::DEFAULT_CPU_EXECUTION_MODE); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromReadThread, "CDROM/ReadThread"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromRegionCheck, "CDROM/RegionCheck"); diff --git a/src/duckstation-qt/gpusettingswidget.cpp b/src/duckstation-qt/gpusettingswidget.cpp index 7ceede2f1..dfa20df14 100644 --- a/src/duckstation-qt/gpusettingswidget.cpp +++ b/src/duckstation-qt/gpusettingswidget.cpp @@ -17,15 +17,16 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p setupAdditionalUi(); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.renderer, QStringLiteral("GPU/Renderer"), - &Settings::ParseRendererName, &Settings::GetRendererName); + &Settings::ParseRendererName, &Settings::GetRendererName, + Settings::DEFAULT_GPU_RENDERER); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.useDebugDevice, QStringLiteral("GPU/UseDebugDevice")); SettingWidgetBinder::BindWidgetToEnumSetting( m_host_interface, m_ui.displayAspectRatio, QStringLiteral("Display/AspectRatio"), - &Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName); + &Settings::ParseDisplayAspectRatio, &Settings::GetDisplayAspectRatioName, Settings::DEFAULT_DISPLAY_ASPECT_RATIO); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.displayCropMode, QStringLiteral("Display/CropMode"), &Settings::ParseDisplayCropMode, - &Settings::GetDisplayCropModeName); + &Settings::GetDisplayCropModeName, Settings::DEFAULT_DISPLAY_CROP_MODE); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.displayLinearFiltering, QStringLiteral("Display/LinearFiltering")); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.displayIntegerScaling, diff --git a/src/duckstation-qt/memorycardsettingswidget.cpp b/src/duckstation-qt/memorycardsettingswidget.cpp index 46fe92f5e..bfba3765c 100644 --- a/src/duckstation-qt/memorycardsettingswidget.cpp +++ b/src/duckstation-qt/memorycardsettingswidget.cpp @@ -62,9 +62,11 @@ void MemoryCardSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* u ui->memory_card_type->addItem( QString::fromUtf8(Settings::GetMemoryCardTypeDisplayName(static_cast(i)))); } - SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, ui->memory_card_type, - QStringLiteral("MemoryCards/Card%1Type").arg(index + 1), - &Settings::ParseMemoryCardTypeName, &Settings::GetMemoryCardTypeName); + + const MemoryCardType default_value = (index == 0) ? MemoryCardType::PerGameTitle : MemoryCardType::None; + SettingWidgetBinder::BindWidgetToEnumSetting( + m_host_interface, ui->memory_card_type, QStringLiteral("MemoryCards/Card%1Type").arg(index + 1), + &Settings::ParseMemoryCardTypeName, &Settings::GetMemoryCardTypeName, default_value); ui->layout->addWidget(new QLabel(tr("Memory Card Type:"), ui->container)); ui->layout->addWidget(ui->memory_card_type); diff --git a/src/duckstation-qt/settingwidgetbinder.h b/src/duckstation-qt/settingwidgetbinder.h index e381ee15d..2495402fc 100644 --- a/src/duckstation-qt/settingwidgetbinder.h +++ b/src/duckstation-qt/settingwidgetbinder.h @@ -156,11 +156,16 @@ struct SettingAccessor /// Binds a widget's value to a setting, updating it when the value changes. template -void BindWidgetToBoolSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name) +void BindWidgetToBoolSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name, + bool default_value = false) { using Accessor = SettingAccessor; - Accessor::setBoolValue(widget, hi->getSettingValue(setting_name).toBool()); + QVariant value = hi->getSettingValue(setting_name); + if (value.isValid()) + Accessor::setBoolValue(widget, value.toBool()); + else + Accessor::setBoolValue(widget, default_value); Accessor::connectValueChanged(widget, [hi, widget, setting_name]() { const bool new_value = Accessor::getBoolValue(widget); @@ -170,11 +175,15 @@ void BindWidgetToBoolSetting(QtHostInterface* hi, WidgetType* widget, const QStr } template -void BindWidgetToIntSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name) +void BindWidgetToIntSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name, int default_value = 0) { using Accessor = SettingAccessor; - Accessor::setIntValue(widget, hi->getSettingValue(setting_name).toInt()); + QVariant value = hi->getSettingValue(setting_name); + if (value.isValid()) + Accessor::setIntValue(widget, value.toInt()); + else + Accessor::setIntValue(widget, default_value); Accessor::connectValueChanged(widget, [hi, widget, setting_name]() { const int new_value = Accessor::getIntValue(widget); @@ -184,11 +193,16 @@ void BindWidgetToIntSetting(QtHostInterface* hi, WidgetType* widget, const QStri } template -void BindWidgetToNormalizedSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name, float range) +void BindWidgetToNormalizedSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name, float range, + float default_value = 0.0f) { using Accessor = SettingAccessor; - Accessor::setIntValue(widget, static_cast(hi->getSettingValue(setting_name).toFloat() * range)); + QVariant value = hi->getSettingValue(setting_name); + if (value.isValid()) + Accessor::setIntValue(widget, static_cast(value.toFloat() * range)); + else + Accessor::setIntValue(widget, static_cast(default_value * range)); Accessor::connectValueChanged(widget, [hi, widget, setting_name, range]() { const float new_value = (static_cast(Accessor::getIntValue(widget)) / range); @@ -198,11 +212,16 @@ void BindWidgetToNormalizedSetting(QtHostInterface* hi, WidgetType* widget, cons } template -void BindWidgetToStringSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name) +void BindWidgetToStringSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name, + const QString& default_value = QString()) { using Accessor = SettingAccessor; - Accessor::setStringValue(widget, hi->getSettingValue(setting_name).toString()); + QVariant value = hi->getSettingValue(setting_name); + if (value.isValid()) + Accessor::setStringValue(widget, value.toString()); + else + Accessor::setStringValue(widget, default_value); Accessor::connectValueChanged(widget, [hi, widget, setting_name]() { const QString new_value = Accessor::getStringValue(widget); @@ -214,7 +233,7 @@ void BindWidgetToStringSetting(QtHostInterface* hi, WidgetType* widget, const QS template void BindWidgetToEnumSetting(QtHostInterface* hi, WidgetType* widget, const QString& setting_name, std::optional (*from_string_function)(const char* str), - const char* (*to_string_function)(DataType value)) + const char* (*to_string_function)(DataType value), DataType default_value) { using Accessor = SettingAccessor; using UnderlyingType = std::underlying_type_t; @@ -224,6 +243,8 @@ void BindWidgetToEnumSetting(QtHostInterface* hi, WidgetType* widget, const QStr from_string_function(old_setting_string_value.toStdString().c_str()); if (old_setting_value.has_value()) Accessor::setIntValue(widget, static_cast(static_cast(old_setting_value.value()))); + else + Accessor::setIntValue(widget, static_cast(static_cast(default_value))); Accessor::connectValueChanged(widget, [hi, widget, setting_name, to_string_function]() { const DataType value = static_cast(static_cast(Accessor::getIntValue(widget)));