Path: blob/master/src/duckstation-qt/controllerglobalsettingswidget.cpp
4802 views
// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin <[email protected]>1// SPDX-License-Identifier: CC-BY-NC-ND-4.023#include "controllerglobalsettingswidget.h"4#include "controllerbindingwidgets.h"5#include "controllersettingswindow.h"6#include "controllersettingwidgetbinder.h"7#include "qtutils.h"8#include "settingwidgetbinder.h"910#include "fmt/format.h"1112#include "util/ini_settings_interface.h"13#include "util/sdl_input_source.h"1415#include <QtWidgets/QDialogButtonBox>16#include <QtWidgets/QGridLayout>17#include <QtWidgets/QGroupBox>18#include <QtWidgets/QScrollArea>19#include <QtWidgets/QVBoxLayout>2021#include "moc_controllerglobalsettingswidget.cpp"2223ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent, ControllerSettingsWindow* dialog)24: QWidget(parent), m_dialog(dialog)25{26m_ui.setupUi(this);2728SettingsInterface* sif = dialog->getEditingSettingsInterface();2930ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLSource, "InputSources", "SDL", true);31ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLEnhancedMode, "InputSources",32"SDLControllerEnhancedMode", false);33ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableTouchPadAsPointer, "InputSources",34"SDLTouchpadAsPointer", false);35ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableSDLPS5PlayerLED, "InputSources",36"SDLPS5PlayerLED", false);37connect(m_ui.enableSDLSource, &QCheckBox::checkStateChanged, this,38&ControllerGlobalSettingsWidget::updateSDLOptionsEnabled);39connect(m_ui.ledSettings, &QToolButton::clicked, this, &ControllerGlobalSettingsWidget::ledSettingsClicked);40connect(m_ui.SDLHelpText, &QLabel::linkActivated, this, &ControllerGlobalSettingsWidget::sdlHelpTextLinkClicked);4142#ifdef _WIN3243ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableDInputSource, "InputSources", "DInput",44false);45ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableXInputSource, "InputSources", "XInput",46false);47ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableRawInput, "InputSources", "RawInput",48false);49#else50m_ui.mainLayout->removeWidget(m_ui.xinputGroup);51delete m_ui.xinputGroup;52m_ui.xinputGroup = nullptr;53m_ui.mainLayout->removeWidget(m_ui.dinputGroup);54delete m_ui.dinputGroup;55m_ui.dinputGroup = nullptr;56#endif5758ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, m_ui.enableMouseMapping, "UI", "EnableMouseMapping",59false);60ControllerSettingWidgetBinder::BindWidgetToInputProfileEnumSetting(61sif, m_ui.multitapMode, "ControllerPorts", "MultitapMode", &Settings::ParseMultitapModeName,62&Settings::GetMultitapModeName, &Settings::GetMultitapModeDisplayName, Settings::DEFAULT_MULTITAP_MODE,63MultitapMode::Count);64ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerXScale, "ControllerPorts",65"PointerXScale", 8.0f);66ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, m_ui.pointerYScale, "ControllerPorts",67"PointerYScale", 8.0f);6869if (dialog->isEditingProfile())70{71m_ui.useProfileHotkeyBindings->setChecked(72m_dialog->getBoolValue("ControllerPorts", "UseProfileHotkeyBindings", false));73connect(m_ui.useProfileHotkeyBindings, &QCheckBox::checkStateChanged, this, [this](int new_state) {74m_dialog->setBoolValue("ControllerPorts", "UseProfileHotkeyBindings", (new_state == Qt::Checked));75emit bindingSetupChanged();76});77}78else79{80// remove profile options from the UI.81m_ui.mainLayout->removeWidget(m_ui.profileSettings);82delete m_ui.profileSettings;83m_ui.profileSettings = nullptr;84}8586m_ui.deviceList->setModel(g_emu_thread->getInputDeviceListModel());8788connect(m_ui.multitapMode, &QComboBox::currentIndexChanged, this, [this]() { emit bindingSetupChanged(); });8990connect(m_ui.pointerXScale, &QSlider::valueChanged, this,91[this](int value) { m_ui.pointerXScaleLabel->setText(QStringLiteral("%1").arg(value)); });92connect(m_ui.pointerYScale, &QSlider::valueChanged, this,93[this](int value) { m_ui.pointerYScaleLabel->setText(QStringLiteral("%1").arg(value)); });94m_ui.pointerXScaleLabel->setText(QStringLiteral("%1").arg(m_ui.pointerXScale->value()));95m_ui.pointerYScaleLabel->setText(QStringLiteral("%1").arg(m_ui.pointerYScale->value()));9697updateSDLOptionsEnabled();98}99100ControllerGlobalSettingsWidget::~ControllerGlobalSettingsWidget() = default;101102void ControllerGlobalSettingsWidget::sdlHelpTextLinkClicked(const QString& link)103{104if (link == QStringLiteral("ADVANCED_SDL_OPTIONS"))105{106ControllerCustomSettingsDialog dialog(m_dialog, m_dialog->getEditingSettingsInterface(), "InputSources",107SDLInputSource::GetAdvancedSettingsInfo(), "SDLInputSource",108tr("Advanced SDL Options"));109dialog.exec();110}111}112113void ControllerGlobalSettingsWidget::updateSDLOptionsEnabled()114{115const bool enabled = m_ui.enableSDLSource->isChecked();116if (m_ui.enableSDLEnhancedMode)117m_ui.enableSDLEnhancedMode->setEnabled(enabled);118if (m_ui.enableTouchPadAsPointer)119m_ui.enableTouchPadAsPointer->setEnabled(enabled);120if (m_ui.enableSDLPS5PlayerLED)121m_ui.enableSDLPS5PlayerLED->setEnabled(enabled);122if (m_ui.ledSettings)123m_ui.ledSettings->setEnabled(enabled);124}125126void ControllerGlobalSettingsWidget::ledSettingsClicked()127{128static constexpr auto config_key = [](u32 player_id, bool active) {129return TinyString::from_format("Player{}{}LED", player_id, active ? "Active" : "");130};131132if (std::ranges::none_of(133g_emu_thread->getInputDeviceListModel()->getDeviceList(),134[](const InputDeviceListModel::Device& dev) { return (dev.key.source_type == InputSourceType::SDL); }))135{136QMessageBox::critical(this, tr("Error"), tr("No SDL devices are currently connected."));137return;138}139140QDialog dlg(this);141dlg.setWindowTitle(tr("Controller LED Settings"));142dlg.setFixedWidth(450);143dlg.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);144145QVBoxLayout* const main_layout = new QVBoxLayout(&dlg);146147QHBoxLayout* const heading_layout = new QHBoxLayout();148QLabel* const icon = new QLabel(&dlg);149icon->setPixmap(QIcon::fromTheme(QStringLiteral("lightbulb-line")).pixmap(32, 32));150QLabel* const heading = new QLabel(151tr("<strong>Controller LED Settings</strong><br>\nThe \"alternate\" color is used when analog mode is active."),152&dlg);153heading->setWordWrap(true);154heading_layout->addWidget(icon, 0, Qt::AlignTop | Qt::AlignLeft);155heading_layout->addWidget(heading, 1);156main_layout->addLayout(heading_layout);157158QScrollArea* const scroll_area = new QScrollArea(&dlg);159scroll_area->setWidgetResizable(true);160scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);161scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);162main_layout->addWidget(scroll_area, 1);163164QWidget* const scroll_area_widget = new QWidget(scroll_area);165scroll_area->setWidget(scroll_area_widget);166167QVBoxLayout* const scroll_area_layout = new QVBoxLayout(scroll_area_widget);168scroll_area_layout->setContentsMargins(10, 10, 10, 10);169170for (const InputDeviceListModel::Device& dev : g_emu_thread->getInputDeviceListModel()->getDeviceList())171{172if (dev.key.source_type != InputSourceType::SDL)173continue;174175QGroupBox* const gbox = new QGroupBox(QStringLiteral("%1: %2").arg(dev.identifier).arg(dev.display_name), &dlg);176QGridLayout* const gbox_layout = new QGridLayout(gbox);177for (u32 active = 0; active < 2; active++)178{179gbox_layout->addWidget(new QLabel(active ? tr("Alternate Mode:") : tr("Normal Mode:"), &dlg),180static_cast<int>(active), 0);181182ColorPickerButton* const button = new ColorPickerButton(gbox);183button->setColor(SDLInputSource::ParseRGBForPlayerId(184m_dialog->getStringValue("SDLExtra", config_key(dev.key.source_index, active != 0), ""), dev.key.source_index,185active != 0));186gbox_layout->addWidget(button, static_cast<int>(active), 1);187connect(button, &ColorPickerButton::colorChanged, this,188[this, player_id = dev.key.source_index, active](u32 new_rgb) {189m_dialog->setStringValue("SDLExtra", config_key(player_id, active),190TinyString::from_format("{:06X}", new_rgb));191});192}193194scroll_area_layout->addWidget(gbox);195}196197scroll_area_layout->addStretch(1);198199QDialogButtonBox* const bbox = new QDialogButtonBox(QDialogButtonBox::Close, &dlg);200connect(bbox, &QDialogButtonBox::rejected, &dlg, &QDialog::accept);201main_layout->addWidget(bbox);202203dlg.exec();204}205206207