diff --git a/Source/Core/DolphinQt2/Config/Mapping/GCPadEmu.cpp b/Source/Core/DolphinQt2/Config/Mapping/GCPadEmu.cpp index 3e16caa95f..35df8cb130 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/GCPadEmu.cpp +++ b/Source/Core/DolphinQt2/Config/Mapping/GCPadEmu.cpp @@ -22,12 +22,6 @@ void GCPadEmu::CreateMainLayout() { m_main_layout = new QHBoxLayout(); - auto* hbox_layout = new QVBoxLayout(); - - hbox_layout->addWidget( - CreateGroupBox(tr("Triggers"), Pad::GetGroup(GetPort(), PadGroup::Triggers))); - hbox_layout->addWidget(CreateGroupBox(tr("Rumble"), Pad::GetGroup(GetPort(), PadGroup::Rumble))); - m_main_layout->addWidget( CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons))); m_main_layout->addWidget( @@ -35,8 +29,15 @@ void GCPadEmu::CreateMainLayout() m_main_layout->addWidget( CreateGroupBox(tr("C Stick"), Pad::GetGroup(GetPort(), PadGroup::CStick))); m_main_layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad))); + + auto* hbox_layout = new QVBoxLayout(); + m_main_layout->addItem(hbox_layout); + hbox_layout->addWidget( + CreateGroupBox(tr("Triggers"), Pad::GetGroup(GetPort(), PadGroup::Triggers))); + hbox_layout->addWidget(CreateGroupBox(tr("Rumble"), Pad::GetGroup(GetPort(), PadGroup::Rumble))); + setLayout(m_main_layout); } diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingButton.cpp b/Source/Core/DolphinQt2/Config/Mapping/MappingButton.cpp index 934cbde7e8..4598099c89 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/MappingButton.cpp +++ b/Source/Core/DolphinQt2/Config/Mapping/MappingButton.cpp @@ -28,6 +28,11 @@ static QString EscapeAmpersand(QString&& string) return string.replace(QStringLiteral("&"), QStringLiteral("&&")); } +bool MappingButton::IsInput() const +{ + return m_reference->IsInput(); +} + MappingButton::MappingButton(MappingWidget* widget, ControlReference* ref, bool indicator) : ElidedButton(EscapeAmpersand(QString::fromStdString(ref->GetExpression()))), m_parent(widget), m_reference(ref) @@ -71,10 +76,10 @@ MappingButton::MappingButton(MappingWidget* widget, ControlReference* ref, bool void MappingButton::Connect() { - connect(this, &MappingButton::clicked, this, &MappingButton::OnButtonPressed); + connect(this, &MappingButton::pressed, this, &MappingButton::Detect); } -void MappingButton::OnButtonPressed() +void MappingButton::Detect() { if (m_parent->GetDevice() == nullptr || !m_reference->IsInput()) return; @@ -84,7 +89,7 @@ void MappingButton::OnButtonPressed() grabMouse(); // Make sure that we don't block event handling - std::thread([this] { + std::thread thread([this] { const auto dev = m_parent->GetDevice(); setText(QStringLiteral("...")); @@ -104,12 +109,17 @@ void MappingButton::OnButtonPressed() m_reference->SetExpression(expr.toStdString()); m_parent->SaveSettings(); Update(); + + if (m_parent->IsIterativeInput()) + m_parent->NextButton(this); } else { OnButtonTimeout(); } - }).detach(); + }); + + thread.detach(); } void MappingButton::OnButtonTimeout() diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingButton.h b/Source/Core/DolphinQt2/Config/Mapping/MappingButton.h index 10ee152381..a1eb6b9535 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/MappingButton.h +++ b/Source/Core/DolphinQt2/Config/Mapping/MappingButton.h @@ -21,6 +21,8 @@ public: void Clear(); void Update(); + void Detect(); + bool IsInput() const; signals: void AdvancedPressed(); @@ -28,7 +30,6 @@ signals: private: void mouseReleaseEvent(QMouseEvent* event) override; - void OnButtonPressed(); void OnButtonTimeout(); void Connect(); diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.cpp index efe64ac2ce..01913ca8c7 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.cpp +++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.cpp @@ -31,6 +31,29 @@ MappingWindow* MappingWidget::GetParent() const return m_parent; } +bool MappingWidget::IsIterativeInput() const +{ + return m_parent->IsIterativeInput(); +} + +void MappingWidget::NextButton(MappingButton* button) +{ + auto iterator = std::find(m_buttons.begin(), m_buttons.end(), button); + + if (iterator == m_buttons.end()) + return; + + if (++iterator == m_buttons.end()) + return; + + MappingButton* next = *iterator; + + if (next->IsInput() && next->isVisible()) + next->Detect(); + else + NextButton(next); +} + std::shared_ptr MappingWidget::GetDevice() const { return m_parent->GetDevice(); diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.h b/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.h index 2c24c1a814..5f6caff381 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.h +++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWidget.h @@ -45,6 +45,9 @@ public: MappingWindow* GetParent() const; + bool IsIterativeInput() const; + void NextButton(MappingButton* button); + virtual void LoadSettings() = 0; virtual void SaveSettings() = 0; virtual InputConfig* GetConfig() = 0; diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp index def3b25a28..34f10b64e3 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include #include @@ -108,14 +109,19 @@ void MappingWindow::CreateMainLayout() { m_main_layout = new QVBoxLayout(); m_config_layout = new QHBoxLayout(); + m_iterative_input = new QCheckBox(tr("Iterative Input")); m_tab_widget = new QTabWidget(); m_button_box = new QDialogButtonBox(QDialogButtonBox::Close); + m_iterative_input->setToolTip(tr("Automatically progress one button after another during " + "configuration. Useful for first-time setup.")); + m_config_layout->addWidget(m_devices_box); m_config_layout->addWidget(m_reset_box); m_config_layout->addWidget(m_profiles_box); m_main_layout->addItem(m_config_layout); + m_main_layout->addWidget(m_iterative_input); m_main_layout->addWidget(m_tab_widget); m_main_layout->addWidget(m_button_box); @@ -337,3 +343,8 @@ void MappingWindow::OnDefaultFieldsPressed() m_controller->UpdateReferences(g_controller_interface); emit Update(); } + +bool MappingWindow::IsIterativeInput() const +{ + return m_iterative_input->isChecked(); +} diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h index e16d120c1a..b3849de1ca 100644 --- a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h +++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h @@ -16,6 +16,7 @@ class EmulatedController; } class InputConfig; +class QCheckBox; class QComboBox; class QDialogButtonBox; class QEvent; @@ -50,8 +51,9 @@ public: int GetPort() const; std::shared_ptr GetDevice() const; - ControllerEmu::EmulatedController* GetController() const; + bool IsIterativeInput() const; + signals: void Update(); void ClearFields(); @@ -77,6 +79,7 @@ private: ControllerEmu::EmulatedController* m_controller = nullptr; // Main + QCheckBox* m_iterative_input; QVBoxLayout* m_main_layout; QHBoxLayout* m_config_layout; QDialogButtonBox* m_button_box;