From 1eeb1012aa6472d6bb18ad4a62d6b60809adc2a8 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 14 Apr 2020 16:35:04 +1000 Subject: [PATCH] Qt: Add buttons for binding controller rumble --- src/duckstation-qt/inputbindingwidgets.cpp | 63 +++++++++++++++++++++- src/duckstation-qt/inputbindingwidgets.h | 18 +++++++ src/duckstation-qt/portsettingswidget.cpp | 24 ++++++++- 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/duckstation-qt/inputbindingwidgets.cpp b/src/duckstation-qt/inputbindingwidgets.cpp index aa31401ae..54d64e66a 100644 --- a/src/duckstation-qt/inputbindingwidgets.cpp +++ b/src/duckstation-qt/inputbindingwidgets.cpp @@ -4,8 +4,8 @@ #include "qthostinterface.h" #include "qtutils.h" #include -#include #include +#include #include InputBindingWidget::InputBindingWidget(QtHostInterface* host_interface, QString setting_name, QWidget* parent) @@ -13,6 +13,8 @@ InputBindingWidget::InputBindingWidget(QtHostInterface* host_interface, QString { m_current_binding_value = m_host_interface->getSettingValue(m_setting_name).toString(); setText(m_current_binding_value); + setMinimumWidth(150); + setMaximumWidth(150); connect(this, &QPushButton::pressed, this, &InputBindingWidget::onPressed); } @@ -290,3 +292,62 @@ void InputAxisBindingWidget::stopListeningForInput() unhookControllerInput(); InputBindingWidget::stopListeningForInput(); } + +InputRumbleBindingWidget::InputRumbleBindingWidget(QtHostInterface* host_interface, QString setting_name, + QWidget* parent) + : InputBindingWidget(host_interface, setting_name, parent) +{ +} + +InputRumbleBindingWidget::~InputRumbleBindingWidget() +{ + if (isListeningForInput()) + InputRumbleBindingWidget::stopListeningForInput(); +} + +void InputRumbleBindingWidget::hookControllerInput() +{ + ControllerInterface* controller_interface = m_host_interface->getControllerInterface(); + if (!controller_interface) + return; + + m_host_interface->enableBackgroundControllerPolling(); + controller_interface->SetHook([this](const ControllerInterface::Hook& ei) { + if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f) + { + QMetaObject::invokeMethod(this, "bindToControllerRumble", Q_ARG(int, ei.controller_index)); + return ControllerInterface::Hook::CallbackResult::StopMonitoring; + } + + return ControllerInterface::Hook::CallbackResult::ContinueMonitoring; + }); +} + +void InputRumbleBindingWidget::unhookControllerInput() +{ + ControllerInterface* controller_interface = m_host_interface->getControllerInterface(); + if (!controller_interface) + return; + + controller_interface->ClearHook(); + m_host_interface->disableBackgroundControllerPolling(); +} + +void InputRumbleBindingWidget::bindToControllerRumble(int controller_index) +{ + m_new_binding_value = QStringLiteral("Controller%1").arg(controller_index); + setNewBinding(); + stopListeningForInput(); +} + +void InputRumbleBindingWidget::startListeningForInput(u32 timeout_in_seconds) +{ + InputBindingWidget::startListeningForInput(timeout_in_seconds); + hookControllerInput(); +} + +void InputRumbleBindingWidget::stopListeningForInput() +{ + unhookControllerInput(); + InputBindingWidget::stopListeningForInput(); +} diff --git a/src/duckstation-qt/inputbindingwidgets.h b/src/duckstation-qt/inputbindingwidgets.h index 9492cf7c0..c9c0668f4 100644 --- a/src/duckstation-qt/inputbindingwidgets.h +++ b/src/duckstation-qt/inputbindingwidgets.h @@ -91,3 +91,21 @@ protected: void hookControllerInput(); void unhookControllerInput(); }; + +class InputRumbleBindingWidget : public InputBindingWidget +{ + Q_OBJECT + +public: + InputRumbleBindingWidget(QtHostInterface* host_interface, QString setting_name, QWidget* parent); + ~InputRumbleBindingWidget(); + +private Q_SLOTS: + void bindToControllerRumble(int controller_index); + +protected: + void startListeningForInput(u32 timeout_in_seconds) override; + void stopListeningForInput() override; + void hookControllerInput(); + void unhookControllerInput(); +}; \ No newline at end of file diff --git a/src/duckstation-qt/portsettingswidget.cpp b/src/duckstation-qt/portsettingswidget.cpp index 4bfa88737..e3871845b 100644 --- a/src/duckstation-qt/portsettingswidget.cpp +++ b/src/duckstation-qt/portsettingswidget.cpp @@ -171,6 +171,28 @@ void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* start_row += num_rows; } + + const u32 num_motors = Controller::GetVibrationMotorCount(ctype); + if (num_motors > 0) + { + layout->addWidget(QtUtils::CreateHorizontalLine(ui->widget), start_row++, 0, 1, 4); + + const QString setting_name = QStringLiteral("Controller%1/Rumble").arg(index + 1); + QLabel* label = new QLabel(tr("Rumble"), container); + InputRumbleBindingWidget* button = new InputRumbleBindingWidget(m_host_interface, setting_name, container); + + layout->addWidget(label, start_row, 0); + layout->addWidget(button, start_row, 1); + + if (!first_button) + first_button = button; + if (last_button) + last_button->setNextWidget(button); + last_button = button; + + start_row++; + } + layout->addWidget(QtUtils::CreateHorizontalLine(ui->widget), start_row++, 0, 1, 4); if (first_button) @@ -212,7 +234,7 @@ void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* hbox->addWidget(clear_all_button); hbox->addWidget(rebind_all_button); - layout->addLayout(hbox, start_row++, 0, 1, 4, Qt::AlignRight); + layout->addLayout(hbox, start_row, 2, 1, 2, Qt::AlignRight); } if (ui->button_binding_container)