duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

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