mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
Qt: Thread-safe QSettings access and updating
This commit is contained in:
parent
9562cbea56
commit
c5282b99e1
|
@ -6,12 +6,14 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
|
|||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.region, &Settings::region);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.biosPath, &Settings::bios_path);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.enableTTYOutput, &Settings::bios_patch_tty_enable);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.fastBoot, &Settings::bios_patch_fast_boot);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.enableSpeedLimiter, &Settings::speed_limiter_enabled);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.pauseOnStart, &Settings::start_paused);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.region, "Console/Region",
|
||||
&Settings::ParseConsoleRegionName, &Settings::GetConsoleRegionName);
|
||||
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::BindWidgetToBoolSetting(m_host_interface, m_ui.enableSpeedLimiter,
|
||||
"General/SpeedLimiterEnabled");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.pauseOnStart, "General/StartPaused");
|
||||
}
|
||||
|
||||
ConsoleSettingsWidget::~ConsoleSettingsWidget() = default;
|
||||
|
|
|
@ -138,13 +138,11 @@ public:
|
|||
|
||||
void loadFromSettings()
|
||||
{
|
||||
const QSettings& qsettings = m_host_interface->getQSettings();
|
||||
|
||||
QStringList path_list = qsettings.value(QStringLiteral("GameList/Paths")).toStringList();
|
||||
QStringList path_list = m_host_interface->getSettingValue(QStringLiteral("GameList/Paths")).toStringList();
|
||||
for (QString& entry : path_list)
|
||||
m_entries.push_back({std::move(entry), false});
|
||||
|
||||
path_list = qsettings.value(QStringLiteral("GameList/RecursivePaths")).toStringList();
|
||||
path_list = m_host_interface->getSettingValue(QStringLiteral("GameList/RecursivePaths")).toStringList();
|
||||
for (QString& entry : path_list)
|
||||
m_entries.push_back({std::move(entry), true});
|
||||
}
|
||||
|
@ -162,17 +160,15 @@ public:
|
|||
paths.push_back(entry.path);
|
||||
}
|
||||
|
||||
QSettings& qsettings = m_host_interface->getQSettings();
|
||||
|
||||
if (paths.empty())
|
||||
qsettings.remove(QStringLiteral("GameList/Paths"));
|
||||
m_host_interface->removeSettingValue(QStringLiteral("GameList/Paths"));
|
||||
else
|
||||
qsettings.setValue(QStringLiteral("GameList/Paths"), paths);
|
||||
m_host_interface->putSettingValue(QStringLiteral("GameList/Paths"), paths);
|
||||
|
||||
if (recursive_paths.empty())
|
||||
qsettings.remove(QStringLiteral("GameList/RecursivePaths"));
|
||||
m_host_interface->removeSettingValue(QStringLiteral("GameList/RecursivePaths"));
|
||||
else
|
||||
qsettings.setValue(QStringLiteral("GameList/RecursivePaths"), recursive_paths);
|
||||
m_host_interface->putSettingValue(QStringLiteral("GameList/RecursivePaths"), recursive_paths);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -191,10 +187,8 @@ GameListSettingsWidget::GameListSettingsWidget(QtHostInterface* host_interface,
|
|||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
QSettings& qsettings = host_interface->getQSettings();
|
||||
|
||||
m_search_directories_model = new GameListSearchDirectoriesModel(host_interface);
|
||||
m_ui.redumpDatabasePath->setText(qsettings.value("GameList/RedumpDatabasePath").toString());
|
||||
m_ui.redumpDatabasePath->setText(host_interface->getSettingValue("GameList/RedumpDatabasePath").toString());
|
||||
m_ui.searchDirectoryList->setModel(m_search_directories_model);
|
||||
m_ui.searchDirectoryList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_ui.searchDirectoryList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
@ -280,7 +274,7 @@ void GameListSettingsWidget::onBrowseRedumpPathButtonPressed()
|
|||
return;
|
||||
|
||||
m_ui.redumpDatabasePath->setText(filename);
|
||||
m_host_interface->getQSettings().setValue("GameList/RedumpDatabasePath", filename);
|
||||
m_host_interface->putSettingValue(QStringLiteral("GameList/RedumpDatabasePath"), filename);
|
||||
m_host_interface->refreshGameList(true, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,17 +9,16 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p
|
|||
m_ui.setupUi(this);
|
||||
setupAdditionalUi();
|
||||
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.renderer, &Settings::gpu_renderer);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.fullscreen, &Settings::display_fullscreen);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.displayLinearFiltering,
|
||||
&Settings::display_linear_filtering);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.vsync, &Settings::video_sync_enabled);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.resolutionScale, &Settings::gpu_resolution_scale);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.trueColor, &Settings::gpu_true_color);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.linearTextureFiltering,
|
||||
&Settings::gpu_texture_filtering);
|
||||
SettingWidgetBinder::BindWidgetToSetting(m_host_interface, m_ui.forceProgressiveScan,
|
||||
&Settings::gpu_force_progressive_scan);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.renderer, "GPU/Renderer",
|
||||
&Settings::ParseRendererName, &Settings::GetRendererName);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.fullscreen, "Display/Fullscreen");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.displayLinearFiltering,
|
||||
"Display/LinearFiltering");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.vsync, "Display/VSync");
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.resolutionScale, "GPU/ResolutionScale");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.trueColor, "GPU/TrueColor");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.linearTextureFiltering, "GPU/TextureFiltering");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.forceProgressiveScan, "GPU/ForceProgressiveScan");
|
||||
}
|
||||
|
||||
GPUSettingsWidget::~GPUSettingsWidget() = default;
|
||||
|
|
|
@ -9,7 +9,7 @@ InputButtonBindingWidget::InputButtonBindingWidget(QtHostInterface* host_interfa
|
|||
QWidget* parent)
|
||||
: QPushButton(parent), m_host_interface(host_interface), m_setting_name(std::move(setting_name))
|
||||
{
|
||||
m_current_binding_value = m_host_interface->getQSettings().value(m_setting_name).toString();
|
||||
m_current_binding_value = m_host_interface->getSettingValue(m_setting_name).toString();
|
||||
setText(m_current_binding_value);
|
||||
|
||||
connect(this, &QPushButton::pressed, this, &InputButtonBindingWidget::onPressed);
|
||||
|
@ -54,7 +54,7 @@ void InputButtonBindingWidget::setNewBinding()
|
|||
if (m_new_binding_value.isEmpty())
|
||||
return;
|
||||
|
||||
m_host_interface->getQSettings().setValue(m_setting_name, m_new_binding_value);
|
||||
m_host_interface->putSettingValue(m_setting_name, m_new_binding_value);
|
||||
m_host_interface->updateInputMap();
|
||||
|
||||
m_current_binding_value = std::move(m_new_binding_value);
|
||||
|
|
|
@ -216,9 +216,8 @@ void MainWindow::setupAdditionalUi()
|
|||
action->setCheckable(true);
|
||||
action->setChecked(m_host_interface->GetCoreSettings().gpu_renderer == renderer);
|
||||
connect(action, &QAction::triggered, [this, action, renderer]() {
|
||||
m_host_interface->getQSettings().setValue(QStringLiteral("GPU/Renderer"),
|
||||
QString(Settings::GetRendererName(renderer)));
|
||||
m_host_interface->GetCoreSettings().gpu_renderer = renderer;
|
||||
m_host_interface->putSettingValue(QStringLiteral("GPU/Renderer"), QString(Settings::GetRendererName(renderer)));
|
||||
m_host_interface->applySettings();
|
||||
action->setChecked(true);
|
||||
switchRenderer();
|
||||
});
|
||||
|
|
|
@ -30,13 +30,12 @@ void PortSettingsWidget::createUi()
|
|||
|
||||
void PortSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* ui)
|
||||
{
|
||||
const Settings& settings = m_host_interface->GetCoreSettings();
|
||||
|
||||
ui->widget = new QWidget(m_tab_widget);
|
||||
ui->layout = new QVBoxLayout(ui->widget);
|
||||
|
||||
QHBoxLayout* memory_card_layout = new QHBoxLayout();
|
||||
ui->memory_card_path = new QLineEdit(QString::fromStdString(settings.memory_card_paths[index]), ui->widget);
|
||||
ui->memory_card_path = new QLineEdit(
|
||||
m_host_interface->getSettingValue(QStringLiteral("MemoryCards/Card%1Path").arg(index + 1)).toString(), ui->widget);
|
||||
memory_card_layout->addWidget(ui->memory_card_path);
|
||||
ui->memory_card_path_browse = new QPushButton(tr("Browse..."), ui->widget);
|
||||
memory_card_layout->addWidget(ui->memory_card_path_browse);
|
||||
|
@ -49,13 +48,19 @@ void PortSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* ui)
|
|||
ui->controller_type->addItem(
|
||||
QString::fromLocal8Bit(Settings::GetControllerTypeDisplayName(static_cast<ControllerType>(i))));
|
||||
}
|
||||
ui->controller_type->setCurrentIndex(static_cast<int>(settings.controller_types[index]));
|
||||
ControllerType ctype = Settings::ParseControllerTypeName(
|
||||
m_host_interface->getSettingValue(QStringLiteral("Controller%1/Type").arg(index + 1))
|
||||
.toString()
|
||||
.toStdString()
|
||||
.c_str())
|
||||
.value_or(ControllerType::None);
|
||||
ui->controller_type->setCurrentIndex(static_cast<int>(ctype));
|
||||
connect(ui->controller_type, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
[this, index]() { onControllerTypeChanged(index); });
|
||||
ui->layout->addWidget(new QLabel(tr("Controller Type:"), ui->widget));
|
||||
ui->layout->addWidget(ui->controller_type);
|
||||
|
||||
createPortBindingSettingsUi(index, ui);
|
||||
createPortBindingSettingsUi(index, ui, ctype);
|
||||
|
||||
ui->layout->addStretch(1);
|
||||
|
||||
|
@ -64,12 +69,11 @@ void PortSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* ui)
|
|||
m_tab_widget->addTab(ui->widget, tr("Port %1").arg(index + 1));
|
||||
}
|
||||
|
||||
void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* ui)
|
||||
void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* ui, ControllerType ctype)
|
||||
{
|
||||
QWidget* container = new QWidget(ui->widget);
|
||||
QGridLayout* layout = new QGridLayout(container);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
const ControllerType ctype = m_host_interface->GetCoreSettings().controller_types[index];
|
||||
const auto buttons = Controller::GetButtonNames(ctype);
|
||||
|
||||
if (!buttons.empty())
|
||||
|
@ -124,9 +128,9 @@ void PortSettingsWidget::onControllerTypeChanged(int index)
|
|||
if (type_index < 0 || type_index >= static_cast<int>(ControllerType::Count))
|
||||
return;
|
||||
|
||||
m_host_interface->GetCoreSettings().controller_types[index] = static_cast<ControllerType>(type_index);
|
||||
m_host_interface->getQSettings().setValue(
|
||||
m_host_interface->putSettingValue(
|
||||
QStringLiteral("Controller%1/Type").arg(index + 1),
|
||||
QString::fromStdString(Settings::GetControllerTypeName(static_cast<ControllerType>(type_index))));
|
||||
createPortBindingSettingsUi(index, &m_port_ui[index]);
|
||||
m_host_interface->applySettings();
|
||||
createPortBindingSettingsUi(index, &m_port_ui[index], static_cast<ControllerType>(type_index));
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ private:
|
|||
|
||||
void createUi();
|
||||
void createPortSettingsUi(int index, PortSettingsUI* ui);
|
||||
void createPortBindingSettingsUi(int index, PortSettingsUI* ui);
|
||||
void createPortBindingSettingsUi(int index, PortSettingsUI* ui, ControllerType ctype);
|
||||
void onControllerTypeChanged(int index);
|
||||
|
||||
std::array<PortSettingsUI, 2> m_port_ui = {};
|
||||
|
|
|
@ -48,6 +48,8 @@ void QtHostInterface::ReportMessage(const char* message)
|
|||
|
||||
void QtHostInterface::setDefaultSettings()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_qsettings_mutex);
|
||||
|
||||
m_settings.SetDefaults();
|
||||
|
||||
// default input settings for Qt
|
||||
|
@ -67,20 +69,57 @@ void QtHostInterface::setDefaultSettings()
|
|||
m_qsettings.setValue(QStringLiteral("Controller1/ButtonR1"), QStringLiteral("Keyboard/E"));
|
||||
m_qsettings.setValue(QStringLiteral("Controller1/ButtonR2"), QStringLiteral("Keyboard/3"));
|
||||
|
||||
updateQSettings();
|
||||
updateQSettingsFromCoreSettings();
|
||||
}
|
||||
|
||||
void QtHostInterface::updateQSettings()
|
||||
QVariant QtHostInterface::getSettingValue(const QString& name)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_qsettings_mutex);
|
||||
return m_qsettings.value(name);
|
||||
}
|
||||
|
||||
void QtHostInterface::putSettingValue(const QString& name, const QVariant& value)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_qsettings_mutex);
|
||||
m_qsettings.setValue(name, value);
|
||||
}
|
||||
|
||||
void QtHostInterface::removeSettingValue(const QString& name)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_qsettings_mutex);
|
||||
m_qsettings.remove(name);
|
||||
}
|
||||
|
||||
void QtHostInterface::updateQSettingsFromCoreSettings()
|
||||
{
|
||||
QtSettingsInterface si(m_qsettings);
|
||||
m_settings.Save(si);
|
||||
// m_qsettings.sync();
|
||||
}
|
||||
|
||||
void QtHostInterface::applySettings()
|
||||
{
|
||||
QtSettingsInterface si(m_qsettings);
|
||||
m_settings.Load(si);
|
||||
if (!isOnWorkerThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "applySettings", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Should we move this to the base class?
|
||||
const bool old_vsync_enabled = m_settings.video_sync_enabled;
|
||||
const bool old_audio_sync_enabled = m_settings.audio_sync_enabled;
|
||||
const bool old_speed_limiter_enabled = m_settings.speed_limiter_enabled;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_qsettings_mutex);
|
||||
QtSettingsInterface si(m_qsettings);
|
||||
m_settings.Load(si);
|
||||
}
|
||||
|
||||
if (m_settings.video_sync_enabled != old_vsync_enabled || m_settings.audio_sync_enabled != old_audio_sync_enabled ||
|
||||
m_settings.speed_limiter_enabled != old_speed_limiter_enabled)
|
||||
{
|
||||
UpdateSpeedLimiterState();
|
||||
}
|
||||
}
|
||||
|
||||
void QtHostInterface::checkSettings()
|
||||
|
@ -105,7 +144,9 @@ void QtHostInterface::checkSettings()
|
|||
setDefaultSettings();
|
||||
}
|
||||
|
||||
applySettings();
|
||||
// initial setting init - we don't do this locked since the thread hasn't been created yet
|
||||
QtSettingsInterface si(m_qsettings);
|
||||
m_settings.Load(si);
|
||||
}
|
||||
|
||||
void QtHostInterface::createGameList()
|
||||
|
@ -446,6 +487,7 @@ void QtHostInterface::doBootSystem(QString initial_filename, QString initial_sav
|
|||
|
||||
wakeThread();
|
||||
m_audio_stream->PauseOutput(false);
|
||||
UpdateSpeedLimiterState();
|
||||
emit emulationStarted();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -30,11 +31,12 @@ public:
|
|||
void ReportError(const char* message) override;
|
||||
void ReportMessage(const char* message) override;
|
||||
|
||||
const QSettings& getQSettings() const { return m_qsettings; }
|
||||
QSettings& getQSettings() { return m_qsettings; }
|
||||
void setDefaultSettings();
|
||||
void updateQSettings();
|
||||
void applySettings();
|
||||
|
||||
/// Thread-safe QSettings access.
|
||||
QVariant getSettingValue(const QString& name);
|
||||
void putSettingValue(const QString& name, const QVariant& value);
|
||||
void removeSettingValue(const QString& name);
|
||||
|
||||
const Settings& GetCoreSettings() const { return m_settings; }
|
||||
Settings& GetCoreSettings() { return m_settings; }
|
||||
|
@ -74,6 +76,7 @@ Q_SIGNALS:
|
|||
void performanceCountersUpdated(float speed, float fps, float vps, float avg_frame_time, float worst_frame_time);
|
||||
|
||||
public Q_SLOTS:
|
||||
void applySettings();
|
||||
void powerOffSystem();
|
||||
void resetSystem();
|
||||
void pauseSystem(bool paused);
|
||||
|
@ -113,6 +116,8 @@ private:
|
|||
};
|
||||
|
||||
void checkSettings();
|
||||
void updateQSettingsFromCoreSettings();
|
||||
|
||||
void createGameList();
|
||||
void updateControllerInputMap();
|
||||
void updateHotkeyInputMap();
|
||||
|
@ -124,6 +129,7 @@ private:
|
|||
void wakeThread();
|
||||
|
||||
QSettings m_qsettings;
|
||||
std::mutex m_qsettings_mutex;
|
||||
|
||||
std::unique_ptr<GameList> m_game_list;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "core/settings.h"
|
||||
|
@ -63,7 +64,7 @@ struct SettingAccessor<QComboBox>
|
|||
template<typename F>
|
||||
static void connectValueChanged(QComboBox* widget, F func)
|
||||
{
|
||||
widget->connect(widget, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), func);
|
||||
widget->connect(widget, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), func);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -90,64 +91,68 @@ struct SettingAccessor<QCheckBox>
|
|||
};
|
||||
|
||||
/// Binds a widget's value to a setting, updating it when the value changes.
|
||||
// template<typename WidgetType, typename DataType, typename = void>
|
||||
// void BindWidgetToSetting(QtHostInterface* hi, WidgetType* widget, DataType Settings::*settings_ptr);
|
||||
|
||||
template<typename WidgetType>
|
||||
void BindWidgetToSetting(QtHostInterface* hi, WidgetType* widget, bool Settings::*settings_ptr)
|
||||
void BindWidgetToBoolSetting(QtHostInterface* hi, WidgetType* widget, const char* setting_name)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
Accessor::setBoolValue(widget, hi->GetCoreSettings().*settings_ptr);
|
||||
Accessor::setBoolValue(widget, hi->getSettingValue(setting_name).toBool());
|
||||
|
||||
Accessor::connectValueChanged(widget, [hi, widget, settings_ptr]() {
|
||||
(hi->GetCoreSettings().*settings_ptr) = Accessor::getBoolValue(widget);
|
||||
hi->updateQSettings();
|
||||
Accessor::connectValueChanged(widget, [hi, widget, setting_name]() {
|
||||
const bool new_value = Accessor::getBoolValue(widget);
|
||||
hi->putSettingValue(setting_name, new_value);
|
||||
hi->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template<typename WidgetType>
|
||||
void BindWidgetToSetting(QtHostInterface* hi, WidgetType* widget, std::string Settings::*settings_ptr)
|
||||
void BindWidgetToIntSetting(QtHostInterface* hi, WidgetType* widget, const char* setting_name)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
Accessor::setStringValue(widget, QString::fromStdString(hi->GetCoreSettings().*settings_ptr));
|
||||
Accessor::setIntValue(widget, hi->getSettingValue(setting_name).toInt());
|
||||
|
||||
Accessor::connectValueChanged(widget, [hi, widget, settings_ptr]() {
|
||||
const QString value = Accessor::getStringValue(widget);
|
||||
(hi->GetCoreSettings().*settings_ptr) = value.toStdString();
|
||||
hi->updateQSettings();
|
||||
Accessor::connectValueChanged(widget, [hi, widget, setting_name]() {
|
||||
const int new_value = Accessor::getIntValue(widget);
|
||||
hi->putSettingValue(setting_name, new_value);
|
||||
hi->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template<typename WidgetType>
|
||||
void BindWidgetToStringSetting(QtHostInterface* hi, WidgetType* widget, const char* setting_name)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
Accessor::setStringValue(widget, hi->getSettingValue(setting_name).toString());
|
||||
|
||||
Accessor::connectValueChanged(widget, [hi, widget, setting_name]() {
|
||||
const QString new_value = Accessor::getStringValue(widget);
|
||||
hi->putSettingValue(setting_name, new_value);
|
||||
hi->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template<typename WidgetType, typename DataType>
|
||||
void BindWidgetToSetting(QtHostInterface* hi, WidgetType* widget, DataType Settings::*settings_ptr,
|
||||
std::enable_if_t<std::is_enum_v<DataType>, int>* v = nullptr)
|
||||
void BindWidgetToEnumSetting(QtHostInterface* hi, WidgetType* widget, const char* setting_name,
|
||||
std::optional<DataType> (*from_string_function)(const char* str),
|
||||
const char* (*to_string_function)(DataType value))
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
using UnderlyingType = std::underlying_type_t<DataType>;
|
||||
|
||||
Accessor::setIntValue(widget, static_cast<int>(static_cast<UnderlyingType>(hi->GetCoreSettings().*settings_ptr)));
|
||||
const QString old_setting_string_value = hi->getSettingValue(setting_name).toString();
|
||||
const std::optional<DataType> old_setting_value =
|
||||
from_string_function(old_setting_string_value.toStdString().c_str());
|
||||
if (old_setting_value.has_value())
|
||||
Accessor::setIntValue(widget, static_cast<int>(static_cast<UnderlyingType>(old_setting_value.value())));
|
||||
|
||||
Accessor::connectValueChanged(widget, [hi, widget, settings_ptr](int) {
|
||||
const int value = Accessor::getIntValue(widget);
|
||||
(hi->GetCoreSettings().*settings_ptr) = static_cast<DataType>(static_cast<UnderlyingType>(value));
|
||||
hi->updateQSettings();
|
||||
});
|
||||
}
|
||||
|
||||
template<typename WidgetType, typename DataType>
|
||||
void BindWidgetToSetting(QtHostInterface* hi, WidgetType* widget, DataType Settings::*settings_ptr,
|
||||
std::enable_if_t<std::is_integral_v<DataType>, int>* v = nullptr)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
Accessor::setIntValue(widget, static_cast<int>(hi->GetCoreSettings().*settings_ptr));
|
||||
|
||||
Accessor::connectValueChanged(widget, [hi, widget, settings_ptr](int) {
|
||||
const int value = Accessor::getIntValue(widget);
|
||||
(hi->GetCoreSettings().*settings_ptr) = static_cast<DataType>(value);
|
||||
hi->updateQSettings();
|
||||
Accessor::connectValueChanged(widget, [hi, widget, setting_name, to_string_function]() {
|
||||
const DataType value = static_cast<DataType>(static_cast<UnderlyingType>(Accessor::getIntValue(widget)));
|
||||
const char* string_value = to_string_function(value);
|
||||
hi->putSettingValue(setting_name, QString::fromLocal8Bit(string_value));
|
||||
hi->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue