Add sensor buttons to JoyTabWidget

If a controller has sensors, add configuration buttons similar to a
control stick to the main view. The layout is based on a isometric 3D view
with the regular XY axes and a diagonal Z axis.

Add a JoySensor button for every direction to the JoySensor object
and connect them to the "flashing" events. Add dummy methods for required
JoySensor interfaces.

Make all the QT connections in JoyTabWidgets as for a JoyControlStick.
But I'm not sure for what checkSensorDisplay and checkSensorEmptyDisplay are
really used.

The new buttons have no function yet. Even though it is possible to map
buttons to the sensor directions, but no events will be generated yet.
This commit is contained in:
Max Maisel
2022-05-05 18:29:17 +02:00
parent 41120ef45e
commit 62cf09dfd2
19 changed files with 724 additions and 2 deletions

View File

@@ -193,7 +193,9 @@ set(antimicrox_SOURCES
src/joydpad.cpp
src/joygyroscopesensor.cpp
src/joysensor.cpp
src/joysensorbuttonpushbutton.cpp
src/joysensorfactory.cpp
src/joysensorpushbutton.cpp
src/joystick.cpp
src/keyboard/virtualkeyboardmousewidget.cpp
src/keyboard/virtualkeypushbutton.cpp
@@ -213,6 +215,7 @@ set(antimicrox_SOURCES
src/pt1filter.cpp
src/qtkeymapperbase.cpp
src/sdleventreader.cpp
src/sensorpushbuttongroup.cpp
src/setjoystick.cpp
src/simplekeygrabberbutton.cpp
src/statisticsestimator.cpp
@@ -314,8 +317,10 @@ set(antimicrox_HEADERS
src/joydpad.h
src/joygyroscopesensor.h
src/joysensor.h
src/joysensorbuttonpushbutton.h
src/joysensordirection.h
src/joysensorfactory.h
src/joysensorpushbutton.h
src/joysensortype.h
src/joystick.h
src/keyboard/virtualkeyboardmousewidget.h
@@ -336,6 +341,7 @@ set(antimicrox_HEADERS
src/pt1filter.h
src/qtkeymapperbase.h
src/sdleventreader.h
src/sensorpushbuttongroup.h
src/setjoystick.h
src/simplekeygrabberbutton.h
src/statisticsestimator.h

View File

@@ -30,11 +30,14 @@
#include "joyaxiswidget.h"
#include "joybuttontypes/joycontrolstickbutton.h"
#include "joybuttontypes/joydpadbutton.h"
#include "joybuttontypes/joysensorbutton.h"
#include "joybuttonwidget.h"
#include "joycontrolstick.h"
#include "joydpad.h"
#include "joysensor.h"
#include "joystick.h"
#include "quicksetdialog.h"
#include "sensorpushbuttongroup.h"
#include "setnamesdialog.h"
#include "stickpushbuttongroup.h"
#include "vdpad.h"
@@ -1766,6 +1769,18 @@ void JoyTabWidget::checkStickDisplay()
}
}
void JoyTabWidget::checkSensorDisplay()
{
JoySensorButton *button = qobject_cast<JoySensorButton *>(sender());
JoySensor *sensor = button->getSensor();
if ((sensor != nullptr) && sensor->hasSlotsAssigned())
{
SetJoystick *currentSet = m_joystick->getActiveSetJoystick();
removeSetButtons(currentSet);
fillSetButtons(currentSet);
}
}
void JoyTabWidget::checkDPadButtonDisplay()
{
JoyDPadButton *button = qobject_cast<JoyDPadButton *>(sender()); // static_cast
@@ -1815,6 +1830,18 @@ void JoyTabWidget::checkStickEmptyDisplay()
}
}
void JoyTabWidget::checkSensorEmptyDisplay()
{
SensorPushButtonGroup *group = qobject_cast<SensorPushButtonGroup *>(sender());
JoySensor *sensor = group->getSensor();
if ((sensor != nullptr) && !sensor->hasSlotsAssigned())
{
SetJoystick *currentSet = m_joystick->getActiveSetJoystick();
removeSetButtons(currentSet);
fillSetButtons(currentSet);
}
}
void JoyTabWidget::checkDPadButtonEmptyDisplay()
{
DPadPushButtonGroup *group = qobject_cast<DPadPushButtonGroup *>(sender()); // static_cast
@@ -1979,6 +2006,75 @@ void JoyTabWidget::fillSetButtons(SetJoystick *set)
column = 0;
QGridLayout *sensorGrid = nullptr;
QGroupBox *sensorGroup = nullptr;
int sensorGridColumn = 0;
int sensorGridRow = 0;
for (size_t i = 0; i < SENSOR_COUNT; ++i)
{
JoySensorType type = static_cast<JoySensorType>(i);
if (!m_joystick->hasSensor(type))
continue;
JoySensor *sensor = currentSet->getSensor(type);
sensor->establishPropertyUpdatedConnection();
QHash<JoySensorDirection, JoySensorButton *> *sensorButtons = sensor->getButtons();
if (!hideEmptyButtons || sensor->hasSlotsAssigned())
{
if (sensorGroup == nullptr)
sensorGroup = new QGroupBox(tr("Sensors"), this);
if (sensorGrid == nullptr)
{
sensorGrid = new QGridLayout();
sensorGridColumn = 0;
sensorGridRow = 0;
}
QWidget *groupContainer = new QWidget(sensorGroup);
SensorPushButtonGroup *sensorButtonGroup =
new SensorPushButtonGroup(sensor, isKeypadUnlocked(), displayingNames, groupContainer);
if (hideEmptyButtons)
{
connect(sensorButtonGroup, &SensorPushButtonGroup::buttonSlotChanged, this,
&JoyTabWidget::checkSensorEmptyDisplay);
}
connect(namesPushButton, &QPushButton::clicked, sensorButtonGroup, &SensorPushButtonGroup::toggleNameDisplay);
if (sensorGridColumn > 1)
{
sensorGridColumn = 0;
sensorGridRow++;
}
groupContainer->setLayout(sensorButtonGroup);
sensorGrid->addWidget(groupContainer, sensorGridRow, sensorGridColumn);
sensorGridColumn++;
} else
{
for (auto iter = sensorButtons->cbegin(); iter != sensorButtons->cend(); ++iter)
{
JoySensorButton *button = iter.value();
button->establishPropertyUpdatedConnections();
connect(button, &JoySensorButton::slotsChanged, this, &JoyTabWidget::checkSensorDisplay);
}
}
}
if (sensorGroup != nullptr)
{
QSpacerItem *tempspacer = new QSpacerItem(10, 4, QSizePolicy::Minimum, QSizePolicy::Fixed);
QVBoxLayout *tempvbox = new QVBoxLayout;
tempvbox->addLayout(sensorGrid);
tempvbox->addItem(tempspacer);
sensorGroup->setLayout(tempvbox);
current_layout->addWidget(sensorGroup, row, column, 1, 2, Qt::AlignTop);
row++;
}
QGridLayout *hatGrid = nullptr;
QGroupBox *hatGroup = nullptr;
int hatGridColumn = 0;

View File

@@ -130,11 +130,13 @@ class JoyTabWidget : public QWidget
void checkForUnsavedProfile(int newindex = -1);
void checkStickDisplay();
void checkSensorDisplay();
void checkDPadButtonDisplay();
void checkAxisButtonDisplay();
void checkButtonDisplay();
void checkStickEmptyDisplay();
void checkSensorEmptyDisplay();
void checkDPadButtonEmptyDisplay();
void checkAxisButtonEmptyDisplay();
void checkButtonEmptyDisplay();

View File

@@ -36,6 +36,7 @@
#include "joycontrolstickbuttonpushbutton.h"
#include "joycontrolstickpushbutton.h"
#include "joydpadbuttonwidget.h"
#include "joysensorpushbutton.h"
#include "joystick.h"
#include "joystickstatuswindow.h"
#include "joytabwidget.h"
@@ -846,6 +847,13 @@ void MainWindow::enableFlashActions()
stickWidget->tryFlash();
}
QList<JoySensorPushButton *> sensors = ui->tabWidget->widget(i)->findChildren<JoySensorPushButton *>();
for (const auto &sensorWidget : sensors)
{
sensorWidget->enableFlashes();
sensorWidget->tryFlash();
}
QList<JoyDPadButtonWidget *> list4 = ui->tabWidget->widget(i)->findChildren<JoyDPadButtonWidget *>();
QListIterator<JoyDPadButtonWidget *> iter4(list4);
while (iter4.hasNext())

View File

@@ -568,6 +568,12 @@ int InputDevice::getNumberHats() { return getActiveSetJoystick()->getNumberHats(
int InputDevice::getNumberSticks() { return getActiveSetJoystick()->getNumberSticks(); }
/**
* @brief Checks if this input device has a sensor of given type
* @returns True if sensor is present, false otherwise
*/
bool InputDevice::hasSensor(JoySensorType type) { return getActiveSetJoystick()->hasSensor(type); }
int InputDevice::getNumberVDPads() { return getActiveSetJoystick()->getNumberVDPads(); }
SetJoystick *InputDevice::getSetJoystick(int index) { return getJoystick_sets().value(index); }
@@ -1226,8 +1232,8 @@ QString InputDevice::getDescription()
QObject::tr("# of Axes: %1").arg(getNumberRawAxes()) + "\n " +
QObject::tr("# of Buttons: %1").arg(getNumberRawButtons()) + "\n " +
QObject::tr("# of Hats: %1").arg(getNumberHats()) + "\n " +
QObject::tr("Accelerometer: %1").arg(hasRawSensor(ACCELEROMETER)) + "\n " +
QObject::tr("Gyroscope: %1").arg(hasRawSensor(GYROSCOPE)) + "\n";
QObject::tr("Accelerometer: %1").arg(hasSensor(ACCELEROMETER)) + "\n " +
QObject::tr("Gyroscope: %1").arg(hasSensor(GYROSCOPE)) + "\n";
return full_desc;
}

View File

@@ -45,6 +45,7 @@ class InputDevice : public QObject
virtual int getNumberAxes();
virtual int getNumberHats();
virtual int getNumberSticks();
virtual bool hasSensor(JoySensorType type);
virtual int getNumberVDPads();
int getJoyNumber();

View File

@@ -16,10 +16,12 @@
*/
#include "joyaccelerometersensor.h"
#include "joybuttontypes/joyaccelerometerbutton.h"
JoyAccelerometerSensor::JoyAccelerometerSensor(double rate, int originset, SetJoystick *parent_set, QObject *parent)
: JoySensor(ACCELEROMETER, originset, parent_set, parent)
{
populateButtons();
}
JoyAccelerometerSensor::~JoyAccelerometerSensor() {}
@@ -47,3 +49,25 @@ float JoyAccelerometerSensor::getZCoordinate() const { return m_current_value[2]
* @returns Translated sensor type name
*/
QString JoyAccelerometerSensor::sensorTypeName() const { return tr("Accelerometer"); }
/**
* @brief Initializes the JoySensorButton objects for this sensor.
*/
void JoyAccelerometerSensor::populateButtons()
{
JoySensorButton *button = nullptr;
button = new JoyAccelerometerButton(this, SENSOR_LEFT, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_LEFT, button);
button = new JoyAccelerometerButton(this, SENSOR_RIGHT, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_RIGHT, button);
button = new JoyAccelerometerButton(this, SENSOR_UP, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_UP, button);
button = new JoyAccelerometerButton(this, SENSOR_DOWN, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_DOWN, button);
button = new JoyAccelerometerButton(this, SENSOR_BWD, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_BWD, button);
}

View File

@@ -34,4 +34,7 @@ class JoyAccelerometerSensor : public JoySensor
virtual float getYCoordinate() const override;
virtual float getZCoordinate() const override;
virtual QString sensorTypeName() const override;
protected:
virtual void populateButtons() override;
};

View File

@@ -2463,6 +2463,10 @@ void JoyButton::setChangeSetCondition(SetChangeCondition condition, bool passive
JoyButton::SetChangeCondition JoyButton::getChangeSetCondition() { return setSelectionCondition; }
/**
* @brief Checks if this button is currently active
* @returns True if the button is pressed, false otherwise
*/
bool JoyButton::getButtonState() { return isButtonPressed; }
int JoyButton::getOriginSet() { return m_originset; }

View File

@@ -16,10 +16,12 @@
*/
#include "joygyroscopesensor.h"
#include "joybuttontypes/joygyroscopebutton.h"
JoyGyroscopeSensor::JoyGyroscopeSensor(int originset, SetJoystick *parent_set, QObject *parent)
: JoySensor(GYROSCOPE, originset, parent_set, parent)
{
populateButtons();
}
JoyGyroscopeSensor::~JoyGyroscopeSensor() {}
@@ -47,3 +49,28 @@ float JoyGyroscopeSensor::getZCoordinate() const { return radToDeg(m_current_val
* @returns Translated sensor type name
*/
QString JoyGyroscopeSensor::sensorTypeName() const { return tr("Gyroscope"); }
/**
* @brief Initializes the JoySensorButton objects for this sensor.
*/
void JoyGyroscopeSensor::populateButtons()
{
JoySensorButton *button = nullptr;
button = new JoyGyroscopeButton(this, SENSOR_LEFT, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_LEFT, button);
button = new JoyGyroscopeButton(this, SENSOR_RIGHT, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_RIGHT, button);
button = new JoyGyroscopeButton(this, SENSOR_UP, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_UP, button);
button = new JoyGyroscopeButton(this, SENSOR_DOWN, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_DOWN, button);
button = new JoyGyroscopeButton(this, SENSOR_FWD, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_FWD, button);
button = new JoyGyroscopeButton(this, SENSOR_BWD, m_originset, getParentSet(), this);
m_buttons.insert(SENSOR_BWD, button);
}

View File

@@ -34,4 +34,7 @@ class JoyGyroscopeSensor : public JoySensor
virtual float getYCoordinate() const override;
virtual float getZCoordinate() const override;
virtual QString sensorTypeName() const override;
protected:
virtual void populateButtons();
};

View File

@@ -18,6 +18,9 @@
#define _USE_MATH_DEFINES
#include "joysensor.h"
#include "inputdevice.h"
#include "joybuttontypes/joysensorbutton.h"
#include "xml/joybuttonxml.h"
#include <cmath>
@@ -87,6 +90,23 @@ void JoySensor::clearPendingEvent()
m_pending_ignore_sets = false;
}
/**
* @brief Check if any direction is mapped to a keyboard or mouse event
* @returns True if a mapping exists, false otherwise
*/
bool JoySensor::hasSlotsAssigned() const
{
for (const auto &button : m_buttons)
{
if (button != nullptr)
{
if (button->getAssignedSlots()->count() > 0)
return true;
}
}
return false;
}
/**
* @brief Get the name of this sensor
* @returns Sensor name
@@ -111,11 +131,21 @@ QString JoySensor::getPartialName(bool forceFullFormat, bool displayNames) const
return label;
}
/**
* @brief Returns the sensor name
*/
QString JoySensor::getSensorName() const { return m_sensor_name; }
/**
* @brief Returns the sensor type
*/
JoySensorType JoySensor::getType() const { return m_type; }
/**
* @brief Returns the current sensor direction
*/
JoySensorDirection JoySensor::getCurrentDirection() const { return m_current_direction; }
bool JoySensor::inDeadZone(float *values) const { return false; }
double JoySensor::calculateDirectionalDistance(JoySensorDirection direction) const { return 0; }
@@ -130,6 +160,12 @@ double JoySensor::radToDeg(double value) { return value * 180 / M_PI; }
*/
double JoySensor::degToRad(double value) { return value * M_PI / 180; }
/**
* @brief Returns a QHash which maps the SensorDirection to
* the corresponding JoySensorButton.
*/
QHash<JoySensorDirection, JoySensorButton *> *JoySensor::getButtons() { return &m_buttons; }
bool JoySensor::isDefault() const { return false; }
/**
@@ -144,3 +180,14 @@ void JoySensor::setSensorName(QString tempName)
emit sensorNameChanged();
}
}
void JoySensor::establishPropertyUpdatedConnection()
{
connect(this, &JoySensor::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited);
}
/**
* @brief Get pointer to the set that a sensor belongs to.
* @return Pointer to the set that a sensor belongs to.
*/
SetJoystick *JoySensor::getParentSet() const { return m_parent_set; }

View File

@@ -17,12 +17,14 @@
#pragma once
#include <QHash>
#include <QObject>
#include "joysensordirection.h"
#include "joysensortype.h"
class SetJoystick;
class JoySensorButton;
/**
* @brief Represents one sensor in a SetJoystick and its connections to
@@ -44,9 +46,13 @@ class JoySensor : public QObject
bool hasPendingEvent() const;
void clearPendingEvent();
bool hasSlotsAssigned() const;
QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const;
QString getSensorName() const;
JoySensorType getType() const;
JoySensorDirection getCurrentDirection() const;
virtual float getXCoordinate() const = 0;
virtual float getYCoordinate() const = 0;
virtual float getZCoordinate() const = 0;
@@ -58,16 +64,26 @@ class JoySensor : public QObject
static double radToDeg(double value);
static double degToRad(double value);
QHash<JoySensorDirection, JoySensorButton *> *getButtons();
bool isDefault() const;
SetJoystick *getParentSet() const;
signals:
void moved(float xaxis, float yaxis, float zaxis);
void active(float xaxis, float yaxis, float zaxis);
void released(float xaxis, float yaxis, float zaxis);
void sensorNameChanged();
void propertyUpdated();
public slots:
void setSensorName(QString tempName);
void establishPropertyUpdatedConnection();
protected:
virtual void populateButtons() = 0;
JoySensorType m_type;
float m_current_value[3];
@@ -78,5 +94,7 @@ class JoySensor : public QObject
QString m_sensor_name;
JoySensorDirection m_current_direction;
SetJoystick *m_parent_set;
QHash<JoySensorDirection, JoySensorButton *> m_buttons;
};

View File

@@ -0,0 +1,108 @@
/* antimicrox Gamepad to KB+M event mapper
* Copyright (C) 2022 Max Maisel <max.maisel@posteo.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "joysensorbuttonpushbutton.h"
#include "joybuttoncontextmenu.h"
#include "joybuttontypes/joysensorbutton.h"
#include "joysensor.h"
#include <QDebug>
#include <QMenu>
#include <QWidget>
JoySensorButtonPushButton::JoySensorButtonPushButton(JoySensorButton *button, bool displayNames, QWidget *parent)
: FlashButtonWidget(displayNames, parent)
, m_button(button)
{
refreshLabel();
enableFlashes();
tryFlash();
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &JoySensorButtonPushButton::customContextMenuRequested, this, &JoySensorButtonPushButton::showContextMenu);
connect(m_button, &JoySensorButton::propertyUpdated, this, &JoySensorButtonPushButton::refreshLabel);
connect(m_button, &JoySensorButton::activeZoneChanged, this, &JoySensorButtonPushButton::refreshLabel);
}
/**
* @brief Get the JoySensorButton for this mapping
*/
JoySensorButton *JoySensorButtonPushButton::getButton() { return m_button; }
/**
* @brief Disables highlight when the sensor axis is moved
*/
void JoySensorButtonPushButton::disableFlashes()
{
if (m_button != nullptr)
{
disconnect(m_button, &JoySensorButton::clicked, this, &JoySensorButtonPushButton::flash);
disconnect(m_button, &JoySensorButton::released, this, &JoySensorButtonPushButton::unflash);
}
unflash();
}
/**
* @brief Enables highlight when the sensor axis is moved
*/
void JoySensorButtonPushButton::enableFlashes()
{
if (m_button != nullptr)
{
connect(m_button, &JoySensorButton::clicked, this, &JoySensorButtonPushButton::flash, Qt::QueuedConnection);
connect(m_button, &JoySensorButton::released, this, &JoySensorButtonPushButton::unflash, Qt::QueuedConnection);
}
}
/**
* @brief Generate the string that will be displayed on the button
* @return Display string
*/
QString JoySensorButtonPushButton::generateLabel()
{
QString temp = QString();
if (m_button != nullptr)
{
if (!m_button->getActionName().isEmpty() && ifDisplayNames())
{
qDebug() << "Action name was not empty";
temp = m_button->getActionName().replace("&", "&&");
} else
{
qDebug() << "Action name was empty";
temp = m_button->getCalculatedActiveZoneSummary().replace("&", "&&");
}
}
qDebug() << "Here is name of action for pushed sensor button: " << temp;
return temp;
}
void JoySensorButtonPushButton::showContextMenu(const QPoint &point) {}
/**
* @brief Highlights the button when mapped button is active
*/
void JoySensorButtonPushButton::tryFlash()
{
if (m_button != nullptr && m_button->getButtonState())
flash();
}

View File

@@ -0,0 +1,50 @@
/* antimicrox Gamepad to KB+M event mapper
* Copyright (C) 2022 Max Maisel <max.maisel@posteo.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "flashbuttonwidget.h"
class JoySensorButton;
class QWidget;
/**
* @brief A direction button in the SensorPushButtonGroup
*/
class JoySensorButtonPushButton : public FlashButtonWidget
{
Q_OBJECT
Q_PROPERTY(bool isflashing READ isButtonFlashing)
public:
explicit JoySensorButtonPushButton(JoySensorButton *button, bool displayNames, QWidget *parent = nullptr);
JoySensorButton *getButton();
void tryFlash();
protected:
virtual QString generateLabel() override;
public slots:
void disableFlashes() override;
void enableFlashes() override;
private slots:
void showContextMenu(const QPoint &point);
private:
JoySensorButton *m_button;
};

View File

@@ -0,0 +1,90 @@
/* antimicrox Gamepad to KB+M event mapper
* Copyright (C) 2022 Max Maisel <max.maisel@posteo.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "joysensorpushbutton.h"
#include "joysensor.h"
#include <QDebug>
JoySensorPushButton::JoySensorPushButton(JoySensor *sensor, bool displayNames, QWidget *parent)
: FlashButtonWidget(displayNames, parent)
, m_sensor(sensor)
{
refreshLabel();
tryFlash();
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &JoySensorPushButton::customContextMenuRequested, this, &JoySensorPushButton::showContextMenu);
connect(m_sensor, &JoySensor::active, this, &JoySensorPushButton::flash, Qt::QueuedConnection);
connect(m_sensor, &JoySensor::released, this, &JoySensorPushButton::unflash, Qt::QueuedConnection);
connect(m_sensor, &JoySensor::sensorNameChanged, this, &JoySensorPushButton::refreshLabel);
}
/**
* @brief Get the underlying JoySensor object.
*/
JoySensor *JoySensorPushButton::getSensor() const { return m_sensor; }
/**
* @brief Generate the string that will be displayed on the button
* @return Display string
*/
QString JoySensorPushButton::generateLabel()
{
QString temp = QString();
if (!m_sensor->getSensorName().isEmpty() && ifDisplayNames())
temp.append(m_sensor->getPartialName(false, true));
else
temp.append(m_sensor->getPartialName(false));
qDebug() << "Name of joy sensor push button: " << temp;
return temp;
}
/**
* @brief Disables highlight when the sensor axis is moved
*/
void JoySensorPushButton::disableFlashes()
{
disconnect(m_sensor, &JoySensor::active, this, &JoySensorPushButton::flash);
disconnect(m_sensor, &JoySensor::released, this, &JoySensorPushButton::unflash);
unflash();
}
/**
* @brief Enables highlight when the sensor axis is moved
*/
void JoySensorPushButton::enableFlashes()
{
connect(m_sensor, &JoySensor::active, this, &JoySensorPushButton::flash, Qt::QueuedConnection);
connect(m_sensor, &JoySensor::released, this, &JoySensorPushButton::unflash, Qt::QueuedConnection);
}
void JoySensorPushButton::showContextMenu(const QPoint &point) {}
/**
* @brief Highlights the button when sensor is not centered
*/
void JoySensorPushButton::tryFlash()
{
if (m_sensor->getCurrentDirection() != JoySensorDirection::SENSOR_CENTERED)
flash();
}

49
src/joysensorpushbutton.h Normal file
View File

@@ -0,0 +1,49 @@
/* antimicrox Gamepad to KB+M event mapper
* Copyright (C) 2022 Max Maisel <max.maisel@posteo.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "flashbuttonwidget.h"
class JoySensor;
class QWidget;
/**
* @brief The central button in a SensorPushButtonGroup
*/
class JoySensorPushButton : public FlashButtonWidget
{
Q_OBJECT
public:
explicit JoySensorPushButton(JoySensor *sensor, bool displayNames, QWidget *parent = nullptr);
JoySensor *getSensor() const;
void tryFlash();
protected:
virtual QString generateLabel() override;
public slots:
void disableFlashes() override;
void enableFlashes() override;
private slots:
void showContextMenu(const QPoint &point);
private:
JoySensor *m_sensor;
};

View File

@@ -0,0 +1,110 @@
/* antimicrox Gamepad to KB+M event mapper
* Copyright (C) 2022 Max Maisel <max.maisel@posteo.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sensorpushbuttongroup.h"
#include "buttoneditdialog.h"
#include "inputdevice.h"
#include "joybuttontypes/joysensorbutton.h"
#include "joysensor.h"
#include "joysensorbuttonpushbutton.h"
#include "joysensorpushbutton.h"
#include <QDebug>
#include <QHash>
#include <QWidget>
SensorPushButtonGroup::SensorPushButtonGroup(JoySensor *sensor, bool keypadUnlocked, bool displayNames, QWidget *parent)
: QGridLayout(parent)
, m_sensor(sensor)
, m_display_names(displayNames)
, m_keypad_unlocked(keypadUnlocked)
{
m_left_button = generateBtnToGrid(SENSOR_LEFT, 1, 0);
m_right_button = generateBtnToGrid(SENSOR_RIGHT, 1, 2);
m_up_button = generateBtnToGrid(SENSOR_UP, 0, 1);
m_down_button = generateBtnToGrid(SENSOR_DOWN, 2, 1);
m_bwd_button = generateBtnToGrid(SENSOR_BWD, 0, 2);
if (m_sensor->getType() == GYROSCOPE)
m_fwd_button = generateBtnToGrid(SENSOR_FWD, 2, 0);
else
m_fwd_button = nullptr;
m_sensor_widget = new JoySensorPushButton(m_sensor, m_display_names, parentWidget());
m_sensor_widget->setIcon(
QIcon::fromTheme(QString::fromUtf8("games_config_options"), QIcon(":/images/actions/games_config_options.png")));
connect(m_sensor_widget, &JoySensorPushButton::clicked, this, &SensorPushButtonGroup::showSensorDialog);
addWidget(m_sensor_widget, 1, 1);
}
/**
* @brief Generates a new push button at the given grid coordinates
* @returns Newly created push button
*/
JoySensorButtonPushButton *SensorPushButtonGroup::generateBtnToGrid(JoySensorDirection sensorDir, int gridRow, int gridCol)
{
JoySensorButton *button = m_sensor->getButtons()->value(sensorDir);
JoySensorButtonPushButton *pushbutton = new JoySensorButtonPushButton(button, m_display_names, parentWidget());
connect(pushbutton, &JoySensorButtonPushButton::clicked, this,
[this, pushbutton] { openSensorButtonDialog(pushbutton); });
button->establishPropertyUpdatedConnections();
connect(button, &JoySensorButton::slotsChanged, this, &SensorPushButtonGroup::propagateSlotsChanged);
addWidget(pushbutton, gridRow, gridCol);
return pushbutton;
}
void SensorPushButtonGroup::propagateSlotsChanged() { emit buttonSlotChanged(); }
/**
* @brief Get the underlying JoySensor object.
*/
JoySensor *SensorPushButtonGroup::getSensor() const { return m_sensor; }
/**
* @brief Shows the button mapping dialog for the given direction button
*/
void SensorPushButtonGroup::openSensorButtonDialog(JoySensorButtonPushButton *pushbutton)
{
ButtonEditDialog *dialog = new ButtonEditDialog(pushbutton->getButton(), m_sensor->getParentSet()->getInputDevice(),
m_keypad_unlocked, parentWidget());
dialog->show();
}
void SensorPushButtonGroup::showSensorDialog() {}
void SensorPushButtonGroup::toggleNameDisplay()
{
m_display_names = !m_display_names;
m_up_button->toggleNameDisplay();
m_down_button->toggleNameDisplay();
m_left_button->toggleNameDisplay();
m_right_button->toggleNameDisplay();
m_bwd_button->toggleNameDisplay();
if (m_fwd_button != nullptr)
m_fwd_button->toggleNameDisplay();
m_sensor_widget->toggleNameDisplay();
}
bool SensorPushButtonGroup::ifDisplayNames() const { return m_display_names; }

View File

@@ -0,0 +1,70 @@
/* antimicrox Gamepad to KB+M event mapper
* Copyright (C) 2022 Max Maisel <max.maisel@posteo.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "joysensordirection.h"
#include <QGridLayout>
class JoySensor;
class QWidget;
class JoySensorButtonPushButton;
class JoySensorPushButton;
/**
* @brief The sensor button mapping widget in the main window.
* The layout is based on a isometric 3D view with the regular
* XY axes and a diagonal Z axis.
*/
class SensorPushButtonGroup : public QGridLayout
{
Q_OBJECT
public:
explicit SensorPushButtonGroup(JoySensor *sensor, bool keypadUnlocked, bool displayNames = false,
QWidget *parent = nullptr);
JoySensor *getSensor() const;
bool ifDisplayNames() const;
signals:
void buttonSlotChanged();
public slots:
void toggleNameDisplay();
private slots:
void propagateSlotsChanged();
void openSensorButtonDialog(JoySensorButtonPushButton *pushbutton);
void showSensorDialog();
private:
JoySensor *m_sensor;
bool m_display_names;
bool m_keypad_unlocked;
JoySensorButtonPushButton *m_up_button;
JoySensorButtonPushButton *m_down_button;
JoySensorButtonPushButton *m_left_button;
JoySensorButtonPushButton *m_right_button;
JoySensorButtonPushButton *m_fwd_button;
JoySensorButtonPushButton *m_bwd_button;
JoySensorPushButton *m_sensor_widget;
JoySensorButtonPushButton *generateBtnToGrid(JoySensorDirection sensorDir, int gridRow, int gridCol);
};