controllersettingwidgetbinder.h (6591B)
1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "qthost.h" 7 #include "settingwidgetbinder.h" 8 9 #include "core/host.h" 10 11 #include <QtCore/QtCore> 12 #include <QtGui/QAction> 13 #include <QtWidgets/QCheckBox> 14 #include <QtWidgets/QComboBox> 15 #include <QtWidgets/QDoubleSpinBox> 16 #include <QtWidgets/QLineEdit> 17 #include <QtWidgets/QSlider> 18 #include <QtWidgets/QSpinBox> 19 #include <optional> 20 #include <type_traits> 21 22 /// This nastyness is required because input profiles aren't overlaid settings like the rest of them, it's 23 /// input profile *or* global, not both. 24 namespace ControllerSettingWidgetBinder { 25 /// Interface specific method of BindWidgetToBoolSetting(). 26 template<typename WidgetType> 27 static void BindWidgetToInputProfileBool(SettingsInterface* sif, WidgetType* widget, std::string section, 28 std::string key, bool default_value) 29 { 30 using Accessor = SettingWidgetBinder::SettingAccessor<WidgetType>; 31 32 if (sif) 33 { 34 const bool value = sif->GetBoolValue(section.c_str(), key.c_str(), default_value); 35 Accessor::setBoolValue(widget, value); 36 37 Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key)]() { 38 const bool new_value = Accessor::getBoolValue(widget); 39 sif->SetBoolValue(section.c_str(), key.c_str(), new_value); 40 QtHost::SaveGameSettings(sif, false); 41 g_emu_thread->reloadGameSettings(); 42 }); 43 } 44 else 45 { 46 const bool value = Host::GetBaseBoolSettingValue(section.c_str(), key.c_str(), default_value); 47 Accessor::setBoolValue(widget, value); 48 49 Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() { 50 const bool new_value = Accessor::getBoolValue(widget); 51 Host::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value); 52 Host::CommitBaseSettingChanges(); 53 g_emu_thread->applySettings(); 54 }); 55 } 56 } 57 58 /// Interface specific method of BindWidgetToFloatSetting(). 59 template<typename WidgetType> 60 static void BindWidgetToInputProfileFloat(SettingsInterface* sif, WidgetType* widget, std::string section, 61 std::string key, float default_value) 62 { 63 using Accessor = SettingWidgetBinder::SettingAccessor<WidgetType>; 64 65 if (sif) 66 { 67 const float value = sif->GetFloatValue(section.c_str(), key.c_str(), default_value); 68 Accessor::setFloatValue(widget, value); 69 70 Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key)]() { 71 const float new_value = Accessor::getFloatValue(widget); 72 sif->SetFloatValue(section.c_str(), key.c_str(), new_value); 73 QtHost::SaveGameSettings(sif, false); 74 g_emu_thread->reloadGameSettings(); 75 }); 76 } 77 else 78 { 79 const float value = Host::GetBaseFloatSettingValue(section.c_str(), key.c_str(), default_value); 80 Accessor::setFloatValue(widget, value); 81 82 Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() { 83 const float new_value = Accessor::getFloatValue(widget); 84 Host::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value); 85 Host::CommitBaseSettingChanges(); 86 g_emu_thread->applySettings(); 87 }); 88 } 89 } 90 91 /// Interface specific method of BindWidgetToNormalizedSetting(). 92 template<typename WidgetType> 93 static void BindWidgetToInputProfileNormalized(SettingsInterface* sif, WidgetType* widget, std::string section, 94 std::string key, float range, float default_value) 95 { 96 using Accessor = SettingWidgetBinder::SettingAccessor<WidgetType>; 97 98 if (sif) 99 { 100 const float value = sif->GetFloatValue(section.c_str(), key.c_str(), default_value); 101 Accessor::setIntValue(widget, static_cast<int>(value * range)); 102 103 Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), range]() { 104 const int new_value = Accessor::getIntValue(widget); 105 sif->SetFloatValue(section.c_str(), key.c_str(), static_cast<float>(new_value) / range); 106 QtHost::SaveGameSettings(sif, false); 107 g_emu_thread->reloadGameSettings(); 108 }); 109 } 110 else 111 { 112 const float value = Host::GetBaseFloatSettingValue(section.c_str(), key.c_str(), default_value); 113 Accessor::setIntValue(widget, static_cast<int>(value * range)); 114 115 Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key), range]() { 116 const float new_value = (static_cast<float>(Accessor::getIntValue(widget)) / range); 117 Host::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value); 118 Host::CommitBaseSettingChanges(); 119 g_emu_thread->applySettings(); 120 }); 121 } 122 } 123 124 /// Interface specific method of BindWidgetToStringSetting(). 125 template<typename WidgetType> 126 static void BindWidgetToInputProfileString(SettingsInterface* sif, WidgetType* widget, std::string section, 127 std::string key, std::string default_value = std::string()) 128 { 129 using Accessor = SettingWidgetBinder::SettingAccessor<WidgetType>; 130 131 if (sif) 132 { 133 const QString value( 134 QString::fromStdString(sif->GetStringValue(section.c_str(), key.c_str(), default_value.c_str()))); 135 136 Accessor::setStringValue(widget, value); 137 138 Accessor::connectValueChanged(widget, [widget, sif, section = std::move(section), key = std::move(key)]() { 139 const QString new_value = Accessor::getStringValue(widget); 140 if (!new_value.isEmpty()) 141 sif->SetStringValue(section.c_str(), key.c_str(), new_value.toUtf8().constData()); 142 else 143 sif->DeleteValue(section.c_str(), key.c_str()); 144 145 QtHost::SaveGameSettings(sif, false); 146 g_emu_thread->reloadGameSettings(); 147 }); 148 } 149 else 150 { 151 const QString value( 152 QString::fromStdString(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()))); 153 154 Accessor::setStringValue(widget, value); 155 156 Accessor::connectValueChanged(widget, [widget, section = std::move(section), key = std::move(key)]() { 157 const QString new_value = Accessor::getStringValue(widget); 158 if (!new_value.isEmpty()) 159 Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData()); 160 else 161 Host::DeleteBaseSettingValue(section.c_str(), key.c_str()); 162 Host::CommitBaseSettingChanges(); 163 g_emu_thread->applySettings(); 164 }); 165 } 166 } 167 } // namespace ControllerSettingWidgetBinder