Qt: Implement "Iterative Input"

This commit is contained in:
spycrab 2018-04-01 16:25:34 +02:00
parent 9be505fde2
commit e0ba2a4aeb
7 changed files with 64 additions and 12 deletions

View File

@ -22,12 +22,6 @@ void GCPadEmu::CreateMainLayout()
{ {
m_main_layout = new QHBoxLayout(); 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( m_main_layout->addWidget(
CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons))); CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons)));
m_main_layout->addWidget( m_main_layout->addWidget(
@ -35,8 +29,15 @@ void GCPadEmu::CreateMainLayout()
m_main_layout->addWidget( m_main_layout->addWidget(
CreateGroupBox(tr("C Stick"), Pad::GetGroup(GetPort(), PadGroup::CStick))); CreateGroupBox(tr("C Stick"), Pad::GetGroup(GetPort(), PadGroup::CStick)));
m_main_layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad))); m_main_layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)));
auto* hbox_layout = new QVBoxLayout();
m_main_layout->addItem(hbox_layout); 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); setLayout(m_main_layout);
} }

View File

@ -28,6 +28,11 @@ static QString EscapeAmpersand(QString&& string)
return string.replace(QStringLiteral("&"), QStringLiteral("&&")); return string.replace(QStringLiteral("&"), QStringLiteral("&&"));
} }
bool MappingButton::IsInput() const
{
return m_reference->IsInput();
}
MappingButton::MappingButton(MappingWidget* widget, ControlReference* ref, bool indicator) MappingButton::MappingButton(MappingWidget* widget, ControlReference* ref, bool indicator)
: ElidedButton(EscapeAmpersand(QString::fromStdString(ref->GetExpression()))), m_parent(widget), : ElidedButton(EscapeAmpersand(QString::fromStdString(ref->GetExpression()))), m_parent(widget),
m_reference(ref) m_reference(ref)
@ -71,10 +76,10 @@ MappingButton::MappingButton(MappingWidget* widget, ControlReference* ref, bool
void MappingButton::Connect() 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()) if (m_parent->GetDevice() == nullptr || !m_reference->IsInput())
return; return;
@ -84,7 +89,7 @@ void MappingButton::OnButtonPressed()
grabMouse(); grabMouse();
// Make sure that we don't block event handling // Make sure that we don't block event handling
std::thread([this] { std::thread thread([this] {
const auto dev = m_parent->GetDevice(); const auto dev = m_parent->GetDevice();
setText(QStringLiteral("...")); setText(QStringLiteral("..."));
@ -104,12 +109,17 @@ void MappingButton::OnButtonPressed()
m_reference->SetExpression(expr.toStdString()); m_reference->SetExpression(expr.toStdString());
m_parent->SaveSettings(); m_parent->SaveSettings();
Update(); Update();
if (m_parent->IsIterativeInput())
m_parent->NextButton(this);
} }
else else
{ {
OnButtonTimeout(); OnButtonTimeout();
} }
}).detach(); });
thread.detach();
} }
void MappingButton::OnButtonTimeout() void MappingButton::OnButtonTimeout()

View File

@ -21,6 +21,8 @@ public:
void Clear(); void Clear();
void Update(); void Update();
void Detect();
bool IsInput() const;
signals: signals:
void AdvancedPressed(); void AdvancedPressed();
@ -28,7 +30,6 @@ signals:
private: private:
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
void OnButtonPressed();
void OnButtonTimeout(); void OnButtonTimeout();
void Connect(); void Connect();

View File

@ -31,6 +31,29 @@ MappingWindow* MappingWidget::GetParent() const
return m_parent; 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<ciface::Core::Device> MappingWidget::GetDevice() const std::shared_ptr<ciface::Core::Device> MappingWidget::GetDevice() const
{ {
return m_parent->GetDevice(); return m_parent->GetDevice();

View File

@ -45,6 +45,9 @@ public:
MappingWindow* GetParent() const; MappingWindow* GetParent() const;
bool IsIterativeInput() const;
void NextButton(MappingButton* button);
virtual void LoadSettings() = 0; virtual void LoadSettings() = 0;
virtual void SaveSettings() = 0; virtual void SaveSettings() = 0;
virtual InputConfig* GetConfig() = 0; virtual InputConfig* GetConfig() = 0;

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <QCheckBox>
#include <QComboBox> #include <QComboBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QGroupBox> #include <QGroupBox>
@ -108,14 +109,19 @@ void MappingWindow::CreateMainLayout()
{ {
m_main_layout = new QVBoxLayout(); m_main_layout = new QVBoxLayout();
m_config_layout = new QHBoxLayout(); m_config_layout = new QHBoxLayout();
m_iterative_input = new QCheckBox(tr("Iterative Input"));
m_tab_widget = new QTabWidget(); m_tab_widget = new QTabWidget();
m_button_box = new QDialogButtonBox(QDialogButtonBox::Close); 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_devices_box);
m_config_layout->addWidget(m_reset_box); m_config_layout->addWidget(m_reset_box);
m_config_layout->addWidget(m_profiles_box); m_config_layout->addWidget(m_profiles_box);
m_main_layout->addItem(m_config_layout); 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_tab_widget);
m_main_layout->addWidget(m_button_box); m_main_layout->addWidget(m_button_box);
@ -337,3 +343,8 @@ void MappingWindow::OnDefaultFieldsPressed()
m_controller->UpdateReferences(g_controller_interface); m_controller->UpdateReferences(g_controller_interface);
emit Update(); emit Update();
} }
bool MappingWindow::IsIterativeInput() const
{
return m_iterative_input->isChecked();
}

View File

@ -16,6 +16,7 @@ class EmulatedController;
} }
class InputConfig; class InputConfig;
class QCheckBox;
class QComboBox; class QComboBox;
class QDialogButtonBox; class QDialogButtonBox;
class QEvent; class QEvent;
@ -50,8 +51,9 @@ public:
int GetPort() const; int GetPort() const;
std::shared_ptr<ciface::Core::Device> GetDevice() const; std::shared_ptr<ciface::Core::Device> GetDevice() const;
ControllerEmu::EmulatedController* GetController() const; ControllerEmu::EmulatedController* GetController() const;
bool IsIterativeInput() const;
signals: signals:
void Update(); void Update();
void ClearFields(); void ClearFields();
@ -77,6 +79,7 @@ private:
ControllerEmu::EmulatedController* m_controller = nullptr; ControllerEmu::EmulatedController* m_controller = nullptr;
// Main // Main
QCheckBox* m_iterative_input;
QVBoxLayout* m_main_layout; QVBoxLayout* m_main_layout;
QHBoxLayout* m_config_layout; QHBoxLayout* m_config_layout;
QDialogButtonBox* m_button_box; QDialogButtonBox* m_button_box;