Rotator Controller: Add additional gamepad calibration and functionality

pull/1761/head
Jon Beniston 2023-08-05 12:33:01 +01:00
rodzic 83834674c0
commit 2d7c572040
22 zmienionych plików z 1063 dodań i 204 usunięć

Wyświetl plik

@ -45,6 +45,7 @@ if(NOT SERVER_MODE)
gs232controllergui.h
dfmstatusdialog.h
inputcontroller.h
inputcontrollersettings.h
)
set(TARGET_NAME featuregs232controller)

Wyświetl plik

@ -19,17 +19,32 @@
#include <QGamepad>
#include "gamepadconfigurationdialog.h"
#include "inputcontrollersettings.h"
GamepadConfigurationDialog::GamepadConfigurationDialog(QGamepad *gamepad, QWidget* parent) :
GamepadConfigurationDialog::GamepadConfigurationDialog(QGamepad *gamepad, InputControllerSettings *settings, bool supportsConfiguraiton, QWidget* parent) :
QDialog(parent),
ui(new Ui::GamepadConfigurationDialog),
m_gamepad(gamepad)
m_gamepad(gamepad),
m_settings(settings)
{
ui->setupUi(this);
connect(m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadConfigurationDialog::axisRightXChanged);
connect(m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadConfigurationDialog::axisRightYChanged);
connect(m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadConfigurationDialog::axisLeftXChanged);
connect(m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadConfigurationDialog::axisLeftYChanged);
ui->deadzone0->setValue(settings->m_deadzone[0]);
ui->deadzone1->setValue(settings->m_deadzone[1]);
ui->deadzone2->setValue(settings->m_deadzone[2]);
ui->deadzone3->setValue(settings->m_deadzone[3]);
ui->lowSensitivity->blockSignals(true);
ui->lowSensitivity->setRange(0.01, 100);
ui->lowSensitivity->blockSignals(false);
ui->lowSensitivity->setValue((double)settings->m_lowSensitivity);
ui->highSensitivity->blockSignals(true);
ui->highSensitivity->setRange(0.01, 100);
ui->highSensitivity->blockSignals(false);
ui->highSensitivity->setValue((double)settings->m_highSensitivity);
ui->configurationGroup->setEnabled(supportsConfiguraiton);
}
GamepadConfigurationDialog::~GamepadConfigurationDialog()
@ -42,6 +57,11 @@ void GamepadConfigurationDialog::accept()
QDialog::accept();
}
void GamepadConfigurationDialog::on_configReset_clicked()
{
QGamepadManager::instance()->resetConfiguration(m_gamepad->deviceId());
}
void GamepadConfigurationDialog::on_config0_clicked()
{
ui->config0->setText("Configuring");
@ -121,3 +141,52 @@ void GamepadConfigurationDialog::axisLeftYChanged(double value)
ui->config2->setEnabled(true);
ui->config3->setEnabled(true);
}
// Convert double to string and remove trailing zeros
static QString toSimpleFloat(double v, int prec)
{
QString s = QString::number(v, 'f', prec);
while (s.back() == '0') {
s.chop(1);
}
if (s.back() == '.') {
s.chop(1);
}
return s;
}
void GamepadConfigurationDialog::on_lowSensitivity_logValueChanged(double value)
{
m_settings->m_lowSensitivity = value;
ui->lowSensitivityText->setText(QString("%1%").arg(toSimpleFloat(m_settings->m_lowSensitivity, 4)));
}
void GamepadConfigurationDialog::on_highSensitivity_logValueChanged(double value)
{
m_settings->m_highSensitivity = value;
ui->highSensitivityText->setText(QString("%1%").arg(toSimpleFloat(m_settings->m_highSensitivity, 4)));
}
void GamepadConfigurationDialog::on_deadzone0_valueChanged(int value)
{
m_settings->m_deadzone[0] = value;
ui->deadzone0Text->setText(QString("%1%").arg(m_settings->m_deadzone[0]));
}
void GamepadConfigurationDialog::on_deadzone1_valueChanged(int value)
{
m_settings->m_deadzone[1] = value;
ui->deadzone1Text->setText(QString("%1%").arg(m_settings->m_deadzone[1]));
}
void GamepadConfigurationDialog::on_deadzone2_valueChanged(int value)
{
m_settings->m_deadzone[2] = value;
ui->deadzone2Text->setText(QString("%1%").arg(m_settings->m_deadzone[2]));
}
void GamepadConfigurationDialog::on_deadzone3_valueChanged(int value)
{
m_settings->m_deadzone[3] = value;
ui->deadzone3Text->setText(QString("%1%").arg(m_settings->m_deadzone[3]));
}

Wyświetl plik

@ -21,16 +21,18 @@
#include "ui_gamepadconfigurationdialog.h"
class QGamepad;
struct InputControllerSettings;
class GamepadConfigurationDialog : public QDialog {
Q_OBJECT
public:
explicit GamepadConfigurationDialog(QGamepad *gamepad, QWidget* parent = 0);
explicit GamepadConfigurationDialog(QGamepad *gamepad, InputControllerSettings *settings, bool supportsConfiguraiton, QWidget* parent = 0);
~GamepadConfigurationDialog();
private slots:
void accept();
void on_configReset_clicked();
void on_config0_clicked();
void on_config1_clicked();
void on_config2_clicked();
@ -39,10 +41,17 @@ private slots:
void axisRightYChanged(double value);
void axisLeftXChanged(double value);
void axisLeftYChanged(double value);
void on_lowSensitivity_logValueChanged(double value);
void on_highSensitivity_logValueChanged(double value);
void on_deadzone0_valueChanged(int value);
void on_deadzone1_valueChanged(int value);
void on_deadzone2_valueChanged(int value);
void on_deadzone3_valueChanged(int value);
private:
Ui::GamepadConfigurationDialog* ui;
QGamepad *m_gamepad;
InputControllerSettings *m_settings;
};
#endif // INCLUDE_GAMEPADCONFIGURATIONDIALOG_H

Wyświetl plik

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>380</width>
<height>309</height>
<width>383</width>
<height>568</height>
</rect>
</property>
<property name="font">
@ -21,10 +21,37 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="configurationGroup">
<property name="title">
<string>Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2">
<widget class="QLabel" name="value0">
<item row="8" column="1">
<widget class="QPushButton" name="configReset">
<property name="toolTip">
<string>Reset configuration</string>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="value3">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="config3Label">
<property name="text">
<string>Elevation Offset Axis</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="value2">
<property name="text">
<string>0</string>
</property>
@ -37,48 +64,6 @@
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="value1">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="config1">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="config3Label">
<property name="text">
<string>Elevation Offset Axis</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="value3">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="config2">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="config2Label">
<property name="text">
<string>Azimuth Offset Axis</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="config1Label">
<property name="text">
@ -86,40 +71,6 @@
</property>
</widget>
</item>
<item row="7" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="config0Label">
<property name="text">
<string>Target Aziumth/X Axis</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="value2">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="config0">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="instructions">
<property name="minimumSize">
@ -136,9 +87,264 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="config0">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="config0Label">
<property name="text">
<string>Target Aziumth/X Axis</string>
</property>
</widget>
</item>
<item row="8" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="config1">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="value0">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="config2">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="value1">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="config2Label">
<property name="text">
<string>Azimuth Offset Axis</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="deadzonesGroup">
<property name="title">
<string>Deadzones</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="deadzone0Label">
<property name="text">
<string>Target Azimuth/X Axis</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="deadzone0">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="deadzone0Text">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="deadzone1Label">
<property name="text">
<string>Target Elevation/Y Axis</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="deadzone1">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="deadzone1Text">
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="deadzone2Label">
<property name="text">
<string>Azimuth Offset Axis</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="deadzone2">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="deadzone2Text">
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="deadzone3Label">
<property name="text">
<string>Elevation Offset Axis</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="deadzone3">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="deadzone3Text">
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="responseGroup">
<property name="title">
<string>Sensitivity</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="LogLabelSlider" name="lowSensitivity"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="highSensitivityText">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lowSensitivityLabel">
<property name="minimumSize">
<size>
<width>65</width>
<height>0</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Low</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lowSensitivityText">
<property name="minimumSize">
<size>
<width>65</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="highSensitivityLabel">
<property name="text">
<string>High</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LogLabelSlider" name="highSensitivity"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
@ -151,6 +357,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LogLabelSlider</class>
<extends>QSlider</extends>
<header>gui/loglabelslider.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>config0</tabstop>
<tabstop>config1</tabstop>
@ -166,8 +379,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
<x>257</x>
<y>519</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -182,8 +395,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
<x>325</x>
<y>519</y>
</hint>
<hint type="destinationlabel">
<x>286</x>

Wyświetl plik

@ -26,12 +26,25 @@ GamepadInputController::GamepadInputController(int deviceId) :
m_rightX(0.0),
m_rightY(0.0),
m_leftX(0.0),
m_leftY(0.0)
m_leftY(0.0),
m_configurationDialog(nullptr)
{
connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
connect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
connect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
connect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
connect(&m_gamepad, &QGamepad::buttonAChanged, this, &GamepadInputController::buttonAChanged);
connect(&m_gamepad, &QGamepad::buttonBChanged, this, &GamepadInputController::buttonBChanged);
connect(&m_gamepad, &QGamepad::buttonXChanged, this, &GamepadInputController::buttonXChanged);
connect(&m_gamepad, &QGamepad::buttonYChanged, this, &GamepadInputController::buttonYChanged);
connect(&m_gamepad, &QGamepad::buttonUpChanged, this, &GamepadInputController::buttonUpChanged);
connect(&m_gamepad, &QGamepad::buttonDownChanged, this, &GamepadInputController::buttonDownChanged);
connect(&m_gamepad, &QGamepad::buttonLeftChanged, this, &GamepadInputController::buttonLeftChanged);
connect(&m_gamepad, &QGamepad::buttonRightChanged, this, &GamepadInputController::buttonRightChanged);
connect(&m_gamepad, &QGamepad::buttonR1Changed, this, &GamepadInputController::buttonR1Changed);
connect(&m_gamepad, &QGamepad::buttonL1Changed, this, &GamepadInputController::buttonL1Changed);
connect(&m_gamepad, &QGamepad::buttonR3Changed, this, &GamepadInputController::buttonR3Changed);
connect(&m_gamepad, &QGamepad::buttonL3Changed, this, &GamepadInputController::buttonL3Changed);
}
double GamepadInputController::getAxisValue(int axis)
@ -65,20 +78,27 @@ bool GamepadInputController::supportsConfiguration() const
#endif
}
void GamepadInputController::configure()
void GamepadInputController::configure(InputControllerSettings *settings)
{
disconnect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
disconnect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
disconnect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
disconnect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
if (!m_configurationDialog)
{
m_configurationDialog = new GamepadConfigurationDialog(&m_gamepad, settings, supportsConfiguration());
connect(m_configurationDialog, &QDialog::finished, this, &GamepadInputController::configurationDialogClosed);
m_configurationDialog->setAttribute(Qt::WA_DeleteOnClose, true);
m_configurationDialog->setModal(false);
m_configurationDialog->show();
}
else
{
m_configurationDialog->raise();
m_configurationDialog->activateWindow();
}
}
GamepadConfigurationDialog dialog(&m_gamepad);
dialog.exec();
connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
connect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
connect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
connect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
void GamepadInputController::configurationDialogClosed()
{
m_configurationDialog = false;
emit configurationComplete();
}
void GamepadInputController::axisRightXChanged(double value)
@ -101,6 +121,66 @@ void GamepadInputController::axisLeftYChanged(double value)
m_leftY = value;
}
void GamepadInputController::buttonAChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_BOTTOM, !value);
}
void GamepadInputController::buttonBChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_RIGHT, !value);
}
void GamepadInputController::buttonXChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_LEFT, !value);
}
void GamepadInputController::buttonYChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_TOP, !value);
}
void GamepadInputController::buttonUpChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_UP, !value);
}
void GamepadInputController::buttonDownChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_DOWN, !value);
}
void GamepadInputController::buttonLeftChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_LEFT, !value);
}
void GamepadInputController::buttonRightChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_RIGHT, !value);
}
void GamepadInputController::buttonL1Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_L1, !value);
}
void GamepadInputController::buttonR1Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_R1, !value);
}
void GamepadInputController::buttonL3Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_L3, !value);
}
void GamepadInputController::buttonR3Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_R3, !value);
}
QStringList GamepadInputController::getAllControllers()
{
QStringList names;

Wyświetl plik

@ -22,6 +22,8 @@
#include <QGamepad>
class GamepadConfigurationDialog;
class GamepadInputController : public InputController {
public:
@ -30,17 +32,30 @@ public:
double getAxisValue(int axis) override;
int getNumberOfAxes() const override;
bool supportsConfiguration() const override;
void configure() override;
void configure(InputControllerSettings *settings) override;
static QStringList getAllControllers();
static GamepadInputController* open(const QString& name);
private slots:
void configurationDialogClosed();
void axisRightXChanged(double value);
void axisRightYChanged(double value);
void axisLeftXChanged(double value);
void axisLeftYChanged(double value);
void buttonAChanged(bool value);
void buttonBChanged(bool value);
void buttonXChanged(bool value);
void buttonYChanged(bool value);
void buttonUpChanged(bool value);
void buttonDownChanged(bool value);
void buttonLeftChanged(bool value);
void buttonRightChanged(bool value);
void buttonL1Changed(bool value);
void buttonR1Changed(bool value);
void buttonL3Changed(bool value);
void buttonR3Changed(bool value);
private:
@ -49,6 +64,8 @@ private:
double m_rightY;
double m_leftX;
double m_leftY;
GamepadConfigurationDialog *m_configurationDialog;
};
#endif // INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_

Wyświetl plik

@ -492,7 +492,7 @@ void GS232Controller::webapiFormatFeatureSettings(
response.getGs232ControllerSettings()->setPrecision(settings.m_precision);
response.getGs232ControllerSettings()->setCoordinates((int)settings.m_coordinates);
response.getGs232ControllerSettings()->setInputController(new QString(settings.m_inputController));
response.getGs232ControllerSettings()->setInputSensitivity(settings.m_inputSensitivity);
response.getGs232ControllerSettings()->setInputSensitivity(settings.m_inputControllerSettings.m_lowSensitivity);
if (response.getGs232ControllerSettings()->getTitle()) {
*response.getGs232ControllerSettings()->getTitle() = settings.m_title;
@ -591,7 +591,7 @@ void GS232Controller::webapiUpdateFeatureSettings(
settings.m_inputController = *response.getGs232ControllerSettings()->getInputController();
}
if (featureSettingsKeys.contains("inputSensitivity")) {
settings.m_inputSensitivity = response.getGs232ControllerSettings()->getInputSensitivity();
settings.m_inputControllerSettings.m_lowSensitivity = response.getGs232ControllerSettings()->getInputSensitivity();
}
if (featureSettingsKeys.contains("title")) {
settings.m_title = *response.getGs232ControllerSettings()->getTitle();
@ -688,7 +688,7 @@ void GS232Controller::webapiReverseSendSettings(const QList<QString>& featureSet
swgGS232ControllerSettings->setInputController(new QString(settings.m_inputController));
}
if (featureSettingsKeys.contains("inputSensitivity") || force) {
swgGS232ControllerSettings->setInputSensitivity(settings.m_inputSensitivity);
swgGS232ControllerSettings->setInputSensitivity(settings.m_inputControllerSettings.m_lowSensitivity);
}
if (featureSettingsKeys.contains("title") || force) {
swgGS232ControllerSettings->setTitle(new QString(settings.m_title));

Wyświetl plik

@ -252,7 +252,8 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
m_settings.setRollupState(&m_rollupState);
ui->inputConfigure->setVisible(false);
//ui->inputConfigure->setVisible(false);
ui->inputConfigure->setEnabled(false);
updateInputControllerList();
connect(InputControllerManager::instance(), &InputControllerManager::controllersChanged, this, &GS232ControllerGUI::updateInputControllerList);
connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController);
@ -293,6 +294,8 @@ void GS232ControllerGUI::updateInputController()
m_inputController = InputControllerManager::open(m_settings.m_inputController);
if (m_inputController)
{
connect(m_inputController, &InputController::buttonChanged, this, &GS232ControllerGUI::buttonChanged);
connect(m_inputController, &InputController::configurationComplete, this, &GS232ControllerGUI::inputConfigurationComplete);
m_inputTimer.start(20);
enabled = true;
}
@ -301,12 +304,32 @@ void GS232ControllerGUI::updateInputController()
{
m_inputTimer.stop();
}
ui->inputSensitivityLabel->setEnabled(enabled);
ui->inputSensitivity->setEnabled(enabled);
ui->inputSensitivityText->setEnabled(enabled);
ui->inputConfigure->setEnabled(enabled);
ui->inputConfigure->setVisible(enabled && m_inputController->supportsConfiguration());
}
void GS232ControllerGUI::buttonChanged(int button, bool released)
{
if (!released)
{
switch (button)
{
case INPUTCONTROLLER_BUTTON_RIGHT_TOP:
ui->startStop->doToggle(!ui->startStop->isChecked());
break;
case INPUTCONTROLLER_BUTTON_RIGHT_BOTTOM:
ui->track->click();
break;
case INPUTCONTROLLER_BUTTON_RIGHT_RIGHT:
ui->enableTargetControl->click();
break;
case INPUTCONTROLLER_BUTTON_RIGHT_LEFT:
ui->enableOffsetControl->click();
break;
case INPUTCONTROLLER_BUTTON_R1:
ui->highSensitivity->click();
break;
}
}
}
void GS232ControllerGUI::checkInputController()
@ -319,8 +342,11 @@ void GS232ControllerGUI::checkInputController()
if (!m_settings.m_track)
{
m_inputCoord1 += m_settings.m_inputSensitivity * m_inputController->getAxisValue(0);
m_inputCoord2 += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(1);
if (m_settings.m_targetControlEnabled)
{
m_inputCoord1 += m_extraSensitivity * m_inputController->getAxisCalibratedValue(0, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
m_inputCoord2 += m_extraSensitivity * -m_inputController->getAxisCalibratedValue(1, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
}
if (m_settings.m_coordinates == GS232ControllerSettings::AZ_EL)
{
@ -340,13 +366,19 @@ void GS232ControllerGUI::checkInputController()
if ((m_inputController->getNumberOfAxes() < 4) && m_settings.m_track)
{
m_inputAzOffset += m_settings.m_inputSensitivity * m_inputController->getAxisValue(0);
m_inputElOffset += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(1);
if (m_settings.m_offsetControlEnabled)
{
m_inputAzOffset += m_extraSensitivity * m_inputController->getAxisCalibratedValue(0, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
m_inputElOffset += m_extraSensitivity * -m_inputController->getAxisCalibratedValue(1, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
}
}
else if (m_inputController->getNumberOfAxes() >= 4)
{
m_inputAzOffset += m_settings.m_inputSensitivity * m_inputController->getAxisValue(2);
m_inputElOffset += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(3);
if (m_settings.m_offsetControlEnabled)
{
m_inputAzOffset += m_extraSensitivity * m_inputController->getAxisCalibratedValue(2, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
m_inputElOffset += m_extraSensitivity * -m_inputController->getAxisCalibratedValue(3, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
}
}
m_inputAzOffset = std::max(m_inputAzOffset, -360.0);
m_inputAzOffset = std::min(m_inputAzOffset, 360.0);
@ -374,25 +406,47 @@ void GS232ControllerGUI::on_inputController_currentIndexChanged(int index)
if (index >= 0)
{
m_settings.m_inputController = ui->inputController->currentText();
m_settingsKeys.append("inputController");
applySettings();
updateInputController();
}
}
void GS232ControllerGUI::on_inputSensitivty_valueChanged(int value)
{
m_settings.m_inputSensitivity = value / 1000.0;
ui->inputSensitivityText->setText(QString("%1%").arg(m_settings.m_inputSensitivity * 100.0));
applySettings();
}
void GS232ControllerGUI::on_inputConfigure_clicked()
{
if (m_inputController) {
m_inputController->configure();
m_inputController->configure(&m_settings.m_inputControllerSettings);
}
}
void GS232ControllerGUI::on_highSensitivity_clicked(bool checked)
{
m_settings.m_highSensitivity = checked;
ui->highSensitivity->setText(checked ? "H" : "L");
m_settingsKeys.append("highSensitivity");
applySettings();
}
void GS232ControllerGUI::on_enableTargetControl_clicked(bool checked)
{
m_settings.m_targetControlEnabled = checked;
m_settingsKeys.append("targetControlEnabled");
applySettings();
}
void GS232ControllerGUI::on_enableOffsetControl_clicked(bool checked)
{
m_settings.m_offsetControlEnabled = checked;
m_settingsKeys.append("offsetControlEnabled");
applySettings();
}
void GS232ControllerGUI::inputConfigurationComplete()
{
m_settingsKeys.append("inputControllerSettings");
applySettings();
}
GS232ControllerGUI::~GS232ControllerGUI()
{
m_dfmStatusDialog.close();
@ -440,8 +494,9 @@ void GS232ControllerGUI::displaySettings()
ui->elevationMax->setValue(m_settings.m_elevationMax);
ui->tolerance->setValue(m_settings.m_tolerance);
ui->inputController->setCurrentText(m_settings.m_inputController);
ui->inputSensitivity->setValue((int) (m_settings.m_inputSensitivity * 1000.0));
ui->inputSensitivityText->setText(QString("%1%").arg(m_settings.m_inputSensitivity * 100.0));
ui->highSensitivity->setChecked(m_settings.m_highSensitivity);
ui->enableTargetControl->setChecked(m_settings.m_targetControlEnabled);
ui->enableOffsetControl->setChecked(m_settings.m_offsetControlEnabled);
ui->dfmTrack->setChecked(m_settings.m_dfmTrackOn);
ui->dfmLubePumps->setChecked(m_settings.m_dfmLubePumpsOn);
ui->dfmBrakes->setChecked(m_settings.m_dfmBrakesOn);
@ -960,8 +1015,10 @@ void GS232ControllerGUI::makeUIConnections()
QObject::connect(ui->precision, qOverload<int>(&QSpinBox::valueChanged), this, &GS232ControllerGUI::on_precision_valueChanged);
QObject::connect(ui->coordinates, qOverload<int>(&QComboBox::currentIndexChanged), this, &GS232ControllerGUI::on_coordinates_currentIndexChanged);
QObject::connect(ui->inputController, qOverload<int>(&QComboBox::currentIndexChanged), this, &GS232ControllerGUI::on_inputController_currentIndexChanged);
QObject::connect(ui->inputSensitivity, qOverload<int>(&QSlider::valueChanged), this, &GS232ControllerGUI::on_inputSensitivty_valueChanged);
QObject::connect(ui->inputConfigure, &QToolButton::clicked, this, &GS232ControllerGUI::on_inputConfigure_clicked);
QObject::connect(ui->highSensitivity, &QToolButton::clicked, this, &GS232ControllerGUI::on_highSensitivity_clicked);
QObject::connect(ui->enableTargetControl, &QToolButton::clicked, this, &GS232ControllerGUI::on_enableTargetControl_clicked);
QObject::connect(ui->enableOffsetControl, &QToolButton::clicked, this, &GS232ControllerGUI::on_enableOffsetControl_clicked);
QObject::connect(ui->dfmTrack, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmTrack_clicked);
QObject::connect(ui->dfmLubePumps, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmLubePumps_clicked);
QObject::connect(ui->dfmBrakes, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmBrakes_clicked);

Wyświetl plik

@ -76,6 +76,7 @@ private:
double m_inputAzOffset;
double m_inputElOffset;
bool m_inputUpdate;
static const int m_extraSensitivity = 4.0f; // Otherwise 100% isn't quite fast enough
explicit GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
virtual ~GS232ControllerGUI();
@ -126,10 +127,14 @@ private slots:
void on_dfmShowStatus_clicked();
void updateStatus();
void on_inputController_currentIndexChanged(int index);
void on_inputSensitivty_valueChanged(int value);
void on_inputConfigure_clicked();
void on_highSensitivity_clicked(bool checked);
void on_enableTargetControl_clicked(bool checked);
void on_enableOffsetControl_clicked(bool checked);
void updateInputControllerList();
void checkInputController();
void buttonChanged(int button, bool released);
void inputConfigurationComplete();
};
#endif // INCLUDE_FEATURE_GS232CONTROLLERGUI_H_

Wyświetl plik

@ -382,16 +382,6 @@
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QLabel" name="inputSensitivityLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sensitivity</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="elevationMaxLabel">
<property name="text">
@ -667,64 +657,13 @@
</item>
<item row="8" column="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="inputSensitivity">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Input controller sensitivity</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>2000</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>25</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="inputSensitivityText">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="8" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="inputController">
<property name="toolTip">
<string>Gamepad / joystick to use</string>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QToolButton" name="inputConfigure">
<property name="toolTip">
<string>Configure input</string>
</property>
<property name="text">
<string>C</string>
<string>Config...</string>
</property>
</widget>
</item>
@ -762,6 +701,70 @@
</property>
</widget>
</item>
<item row="8" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="inputController">
<property name="toolTip">
<string>Gamepad / joystick to use</string>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QToolButton" name="highSensitivity">
<property name="toolTip">
<string>Input controller sensitvitiy (High / low)</string>
</property>
<property name="text">
<string>H</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="enableOffsetControl">
<property name="toolTip">
<string>Enable offset control</string>
</property>
<property name="text">
<string>O</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="enableTargetControl">
<property name="toolTip">
<string>Enable target control</string>
</property>
<property name="text">
<string>T</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
@ -800,6 +803,17 @@
<tabstop>elevationMin</tabstop>
<tabstop>elevationMax</tabstop>
<tabstop>tolerance</tabstop>
<tabstop>precision</tabstop>
<tabstop>coordinates</tabstop>
<tabstop>inputController</tabstop>
<tabstop>highSensitivity</tabstop>
<tabstop>enableTargetControl</tabstop>
<tabstop>inputConfigure</tabstop>
<tabstop>dfmTrack</tabstop>
<tabstop>dfmLubePumps</tabstop>
<tabstop>dfmBrakes</tabstop>
<tabstop>dfmDrives</tabstop>
<tabstop>dfmShowStatus</tabstop>
</tabstops>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>

Wyświetl plik

@ -30,7 +30,7 @@
const PluginDescriptor GS232ControllerPlugin::m_pluginDescriptor = {
GS232Controller::m_featureId,
QStringLiteral("Rotator Controller"),
QStringLiteral("7.15.2"),
QStringLiteral("7.15.3"),
QStringLiteral("(c) Jon Beniston, M7RCE"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

Wyświetl plik

@ -22,6 +22,7 @@
#include "settings/serializable.h"
#include "gs232controllersettings.h"
#include "inputcontrollersettings.h"
const QStringList GS232ControllerSettings::m_pipeTypes = {
QStringLiteral("ADSBDemod"),
@ -65,7 +66,14 @@ void GS232ControllerSettings::resetToDefaults()
m_precision = 0;
m_coordinates = AZ_EL;
m_inputController = "None";
m_inputSensitivity = 0.25;
m_targetControlEnabled = true;
m_offsetControlEnabled = true;
m_highSensitivity = true;
m_inputControllerSettings.m_lowSensitivity = 5.0f;
m_inputControllerSettings.m_highSensitivity = 50.0f;
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
m_inputControllerSettings.m_deadzone[i] = 10.0f;
}
m_dfmTrackOn = false;
m_dfmLubePumpsOn = false;
m_dfmBrakesOn = false;
@ -122,7 +130,15 @@ QByteArray GS232ControllerSettings::serialize() const
s.writeBool(33, m_dfmBrakesOn);
s.writeBool(34, m_dfmDrivesOn);
s.writeString(35, m_inputController);
s.writeFloat(36, m_inputSensitivity);
s.writeBool(37, m_targetControlEnabled);
s.writeBool(38, m_offsetControlEnabled);
s.writeBool(39, m_highSensitivity);
s.writeFloat(50, m_inputControllerSettings.m_lowSensitivity);
s.writeFloat(51, m_inputControllerSettings.m_highSensitivity);
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
s.writeFloat(60+i, m_inputControllerSettings.m_deadzone[i]);
}
return s.final();
}
@ -192,7 +208,15 @@ bool GS232ControllerSettings::deserialize(const QByteArray& data)
d.readBool(33, &m_dfmBrakesOn);
d.readBool(34, &m_dfmDrivesOn);
d.readString(35, &m_inputController, "None");
d.readFloat(36, &m_inputSensitivity, 0.25);
d.readBool(37, &m_targetControlEnabled, true);
d.readBool(38, &m_offsetControlEnabled, true);
d.readBool(39, &m_highSensitivity, true);
d.readFloat(50, &m_inputControllerSettings.m_lowSensitivity, 5.0f);
d.readFloat(51, &m_inputControllerSettings.m_highSensitivity, 50.0f);
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
d.readFloat(60+i, &m_inputControllerSettings.m_deadzone[i], 10.0f);
}
return true;
}
@ -280,8 +304,17 @@ void GS232ControllerSettings::applySettings(const QStringList& settingsKeys, con
if (settingsKeys.contains("inputController")) {
m_inputController = settings.m_inputController;
}
if (settingsKeys.contains("inputSensitivity")) {
m_inputSensitivity = settings.m_inputSensitivity;
if (settingsKeys.contains("inputControllerSettings")) {
m_inputControllerSettings = settings.m_inputControllerSettings;
}
if (settingsKeys.contains("targetControlEnabled")) {
m_targetControlEnabled = settings.m_targetControlEnabled;
}
if (settingsKeys.contains("offsetControlEnabled")) {
m_offsetControlEnabled = settings.m_offsetControlEnabled;
}
if (settingsKeys.contains("highSensitivity")) {
m_highSensitivity = settings.m_highSensitivity;
}
if (settingsKeys.contains("dfmTrackOn")) {
m_dfmTrackOn = settings.m_dfmTrackOn;
@ -385,8 +418,21 @@ QString GS232ControllerSettings::getDebugString(const QStringList& settingsKeys,
if (settingsKeys.contains("inputController") || force) {
ostr << " m_inputController: " << m_inputController.toStdString();
}
if (settingsKeys.contains("inputSensitivity") || force) {
ostr << " m_inputSensitivity: " << m_inputSensitivity;
if (settingsKeys.contains("inputControllerSettings") || force) {
ostr << " m_inputControllerSettings.m_lowSensitivity: " << m_inputControllerSettings.m_lowSensitivity;
ostr << " m_inputControllerSettings.m_highSensitivity: " << m_inputControllerSettings.m_highSensitivity;
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
ostr << " m_inputControllerSettings.m_deadzone: " << m_inputControllerSettings.m_deadzone[i];
}
}
if (settingsKeys.contains("targetControlEnabled") || force) {
ostr << " m_targetControlEnabled: " << m_targetControlEnabled;
}
if (settingsKeys.contains("offsetControlEnabled") || force) {
ostr << " m_offsetControlEnabled: " << m_offsetControlEnabled;
}
if (settingsKeys.contains("highSensitivity") || force) {
ostr << " m_highSensitivity: " << m_highSensitivity;
}
if (settingsKeys.contains("title") || force) {
ostr << " m_title: " << m_title.toStdString();

Wyświetl plik

@ -23,6 +23,7 @@
#include <QString>
#include "util/message.h"
#include "inputcontrollersettings.h"
class Serializable;
@ -63,7 +64,10 @@ struct GS232ControllerSettings
int m_precision;
enum Coordinates { AZ_EL, X_Y_85, X_Y_30 } m_coordinates;
QString m_inputController;
float m_inputSensitivity;
InputControllerSettings m_inputControllerSettings;
bool m_targetControlEnabled;
bool m_offsetControlEnabled;
bool m_highSensitivity;
bool m_dfmTrackOn;
bool m_dfmLubePumpsOn;

Wyświetl plik

@ -22,6 +22,23 @@
#include "inputcontroller.h"
double InputController::getAxisCalibratedValue(int axis, InputControllerSettings *settings, bool highSensitvity)
{
double value = getAxisValue(axis);
double absValue = abs(value);
double l = settings->m_deadzone[axis] / 100.0;
if (absValue < l) {
// Set to 0 if in deadzone
value = 0.0;
} else {
// Rescale to [0,1] if outside of deadzone
absValue = (absValue - l) / (1.0 - l);
// Negate if original value was negative
value = (value < 0.0) ? -absValue : absValue;
}
return value * (highSensitvity ? settings->m_highSensitivity : settings->m_lowSensitivity) / 100.0;
}
InputControllerManager* InputControllerManager::m_instance = nullptr;
QStringList InputControllerManager::getAllControllers()

Wyświetl plik

@ -20,6 +20,23 @@
#include <QObject>
#include "inputcontrollersettings.h"
#define INPUTCONTROLLER_BUTTON_RIGHT_TOP 0 // Y / triangle
#define INPUTCONTROLLER_BUTTON_RIGHT_BOTTOM 1 // A / X
#define INPUTCONTROLLER_BUTTON_RIGHT_LEFT 2 // X / Square
#define INPUTCONTROLLER_BUTTON_RIGHT_RIGHT 3 // B / Circle
#define INPUTCONTROLLER_BUTTON_LEFT_UP 4 // D-Pad
#define INPUTCONTROLLER_BUTTON_LEFT_DOWN 5
#define INPUTCONTROLLER_BUTTON_LEFT_LEFT 6
#define INPUTCONTROLLER_BUTTON_LEFT_RIGHT 7
#define INPUTCONTROLLER_BUTTON_R1 8 // On top of controller
#define INPUTCONTROLLER_BUTTON_L1 9
#define INPUTCONTROLLER_BUTTON_R3 10 // Sticks pushed
#define INPUTCONTROLLER_BUTTON_L3 11
class InputController : public QObject {
Q_OBJECT
public:
@ -28,9 +45,15 @@ public:
// axis 0-3. 0=Az/X, 1=El/Y, 2=Az Offset, 3=El Offset
// value returned should be current axis position in range [-1,1]
virtual double getAxisValue(int axis) = 0;
// Gets axis value applying deadzone and sensitivity
double getAxisCalibratedValue(int axis, InputControllerSettings *settings, bool highSensitivity);
virtual int getNumberOfAxes() const = 0;
virtual bool supportsConfiguration() const { return false; }
virtual void configure() {};
virtual void configure(InputControllerSettings *settings) {};
signals:
void buttonChanged(int button, bool released);
void configurationComplete();
};

Wyświetl plik

@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FEATURE_INPUTCONTROLLERSETTINGS_H_
#define INCLUDE_FEATURE_INPUTCONTROLLERSETTINGS_H_
#define INPUTCONTROLLER_MAX_AXES 4
struct InputControllerSettings {
float m_lowSensitivity;
float m_highSensitivity;
float m_deadzone[INPUTCONTROLLER_MAX_AXES];
};
#endif // INCLUDE_FEATURE_INPUTCONTROLLERSETTINGS_H_

Wyświetl plik

@ -115,14 +115,52 @@ When a gamepad with 2 sticks (4 axes) such as the XBox Wireless Controller is us
while the left stick is for controlling azimuth and elevation offset.
If a controller only has 2 axes, target coordinates will be controlled when not tracking (6) and offset will be controlled when tracking.
Buttons on a controller are assigned to the following functions:
| Button | XBox Controller | Function |
|---------|------------------|------------------------------------------|
| 0 | Y | Start/stop plugin |
| 1 | A | Enable/disabling tracking |
| 3 | B | Enable/disable target control |
| 2 | X | Enable/disable offset control |
| 8 | R1 | Switch between low and high sensitivity |
The [Qt Gamepad](https://doc.qt.io/qt-5/qtgamepad-index.html) library is used to implement gamepad support.
On Linux, using Qt Gamepad with the evdev backend, all joysticks & gamepads appear as though they have 4 axes (a limitation of Qt Gamepad).
If using a joystick which only has 2 axes, whether it corresponds to the left or right stick can be configured by pressing the 'C' button.
If using a joystick which only has 2 axes, whether it corresponds to the left or right stick can be configured by pressing the 'Config...' button.
On Linux, the [xone driver](https://github.com/medusalix/xone) has support for the Xbox Wireless Controller, that isn't supported by the older xpad driver that is included with Ubuntu.
<h3>23: Sensitivity</h3>
<h3>23: High or Low Sensitivity</h3>
Specifies the sensitivity on the input controls (22). The higher the value, the faster coordinates will change for a given control stick movement.
Specifies High (H) or Low (L) Sensitivity mode. This is how fast coordinates will change for a given control stick movement.
High Sensitivity is used for coarse target/offset adjustment, whereas Low sensitivity is used for fine target/offset adjustment.
The sensitivity in each mode can be set in the Input Configuration Dialog (22).
<h3>24: (T) Enable Target Control</h3>
When checked, the target coordinates can be set with the input controller. When unchecked, the axes controlling the target will be ignored.
<h3>25: (O) Enable Offset Control</h3>
When checked, the offset coordinates can be set with the input controller. When unchecked, the axes controlling the offset will be ignored.
<h3>26: Input Control Configuration</h3>
Pressing the Config... button will display the Input Configuration Dialog:
<h4>1: Configuration</h4>
The Configure buttons allow setting which axis is assigned to target or offset control. To assign an axis, press the corresponding Configure button, then move the controller axis.
<h4>2: Deadzones</h3>
Deadzones can be set individually for each for the 4 axes. A deadzone specifies the amount a controller axis can be moved without a response.
This can be used to prevent very small movements around the center position on a stick from adjusting the target, or eliminate target adjustments
when a stick is centered, but is reporting a non-zero position on the axis.
<h4>3: Sensitivity</h3>
Specifies the sensitivity of the input in Low and High Sensitivity mode (23). The higher the value, the faster coordinates will change for a given control stick movement.
<h2>Protocol Implementations</h2>

Wyświetl plik

@ -62,6 +62,8 @@ set(sdrgui_SOURCES
gui/indicator.cpp
gui/levelmeter.cpp
gui/loggingdialog.cpp
gui/logslider.cpp
gui/loglabelslider.cpp
gui/mypositiondialog.cpp
gui/pluginsdialog.cpp
gui/presetitem.cpp
@ -176,6 +178,8 @@ set(sdrgui_HEADERS
gui/indicator.h
gui/levelmeter.h
gui/loggingdialog.h
gui/logslider.h
gui/loglabelslider.h
gui/mypositiondialog.h
gui/physicalunit.h
gui/pluginsdialog.h

Wyświetl plik

@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 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 <QDebug>
#include "loglabelslider.h"
LogLabelSlider::LogLabelSlider(QWidget *parent) :
QWidget(parent)
{
m_vLayout = new QVBoxLayout(this);
m_hLayout = new QHBoxLayout();
m_slider = new LogSlider();
connect(m_slider, &LogSlider::logValueChanged, this, &LogLabelSlider::handleLogValueChanged);
m_vLayout->addLayout(m_hLayout);
m_vLayout->addWidget(m_slider);
}
void LogLabelSlider::setRange(double min, double max)
{
m_slider->setRange(min, max);
double start = floor(log10(min));
double stop = ceil(log10(max));
double steps = stop - start;
qDeleteAll(m_labels);
m_labels.clear();
double v = pow(10.0, start);
for (int i = 0; i <= steps; i++)
{
QString t = QString("%1").arg(v);
QLabel *label = new QLabel(t);
if (i == 0) {
label->setAlignment(Qt::AlignLeft);
} else if (i == steps) {
label->setAlignment(Qt::AlignRight);
} else {
label->setAlignment(Qt::AlignCenter);
}
m_labels.append(label);
m_hLayout->addWidget(label);
v *= 10.0;
}
}
void LogLabelSlider::handleLogValueChanged(double value)
{
emit logValueChanged(value);
}

Wyświetl plik

@ -0,0 +1,56 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRGUI_GUI_LOGLABELSLIDER_H
#define SDRGUI_GUI_LOGLABELSLIDER_H
#include <QSlider>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "logslider.h"
#include "export.h"
// Logarithmic Slider with labels above
class SDRGUI_API LogLabelSlider : public QWidget {
Q_OBJECT
public:
explicit LogLabelSlider(QWidget *parent = nullptr);
void setRange(double min, double max);
void setValue(double value) { m_slider->setValue(value); }
signals:
void logValueChanged(double value);
private slots:
void handleLogValueChanged(double value);
private:
QList<QLabel *> m_labels;
LogSlider *m_slider;
QVBoxLayout *m_vLayout;
QHBoxLayout *m_hLayout;
};
#endif // SDRGUI_GUI_LOGLABELSLIDER_H

Wyświetl plik

@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 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 <QFontMetrics>
#include <QPainter>
#include <QDebug>
#include "logslider.h"
LogSlider::LogSlider(QWidget *parent) :
QSlider(Qt::Horizontal, parent)
{
setRange(0, 1000);
connect(this, &QSlider::valueChanged, this, &LogSlider::handleValueChanged);
setPageStep(1);
setTickPosition(QSlider::TicksAbove);
setTickInterval(m_stepsPerPower);
}
void LogSlider::setRange(double min, double max)
{
m_start = floor(log10(min));
m_stop = ceil(log10(max));
m_steps = m_stop - m_start;
setMinimum(0);
setMaximum(m_steps * m_stepsPerPower);
}
void LogSlider::handleValueChanged(int value)
{
double v = pow(10.0, value/(double)m_stepsPerPower + m_start);
emit logValueChanged(v);
}
void LogSlider::setValue(double value)
{
int v = (int)((log10(value) - m_start) * 100);
QSlider::setValue(v);
}

Wyświetl plik

@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRGUI_GUI_LOGSLIDER_H
#define SDRGUI_GUI_LOGSLIDER_H
#include <QSlider>
#include "export.h"
// Logarithmic Slider (hozizontal only)
class SDRGUI_API LogSlider : public QSlider {
Q_OBJECT
public:
explicit LogSlider(QWidget *parent = nullptr);
void setRange(double min, double max);
void setValue(double value);
signals:
void logValueChanged(double value);
private slots:
void handleValueChanged(int value);
private:
double m_start;
double m_stop;
double m_steps;
static const int m_stepsPerPower = 100;
};
#endif // SDRGUI_GUI_LOGSLIDER_H