JoystickWidget.cc 9.27 KB
Newer Older
pixhawk's avatar
pixhawk committed
1
#include "JoystickWidget.h"
2
#include "MainWindow.h"
pixhawk's avatar
pixhawk committed
3
#include "ui_JoystickWidget.h"
4 5
#include "JoystickButton.h"
#include "JoystickAxis.h"
6

7
#include <QDesktopWidget>
pixhawk's avatar
pixhawk committed
8 9

JoystickWidget::JoystickWidget(JoystickInput* joystick, QWidget *parent) :
10
    QDialog(parent),
11
    joystick(joystick),
12
    m_ui(new Ui::JoystickWidget)
pixhawk's avatar
pixhawk committed
13 14
{
    m_ui->setupUi(this);
15 16 17 18 19 20

    // Center the window on the screen.
    QRect position = frameGeometry();
    position.moveCenter(QDesktopWidget().availableGeometry().center());
    move(position.topLeft());

21 22
    // Initialize the UI based on the current joystick
    initUI();
Lorenz Meier's avatar
Lorenz Meier committed
23

24
    // Watch for button, axis, and hat input events from the joystick.
25 26
    connect(this->joystick, SIGNAL(buttonPressed(int)), this, SLOT(joystickButtonPressed(int)));
    connect(this->joystick, SIGNAL(buttonReleased(int)), this, SLOT(joystickButtonReleased(int)));
27
    connect(this->joystick, SIGNAL(axisValueChanged(int,float)), this, SLOT(updateAxisValue(int,float)));
28
    connect(this->joystick, SIGNAL(hatDirectionChanged(qint8,qint8)), this, SLOT(setHat(qint8,qint8)));
pixhawk's avatar
pixhawk committed
29

30 31
    // Also watch for when new settings were loaded for the current joystick to do a mass UI refresh.
    connect(this->joystick, SIGNAL(joystickSettingsChanged()), this, SLOT(updateUI()));
32

33
    // If the selected joystick is changed, update the JoystickInput.
34
    connect(m_ui->joystickNameComboBox, SIGNAL(currentIndexChanged(int)), this->joystick, SLOT(setActiveJoystick(int)));
35 36
    // Also wait for the JoystickInput to switch, then update our UI.
    connect(this->joystick, SIGNAL(newJoystickSelected()), this, SLOT(createUIForJoystick()));
37 38 39

    // Initialize the UI to the current JoystickInput state. Also make sure to listen for future changes
    // so that the UI can be updated.
40
    connect(m_ui->enableCheckBox, SIGNAL(toggled(bool)), m_ui->joystickFrame, SLOT(setEnabled(bool)));
41 42
    m_ui->enableCheckBox->setChecked(this->joystick->enabled()); // Needs to be after connecting to the joystick frame and before watching for enabled events from JoystickInput.
    connect(m_ui->enableCheckBox, SIGNAL(toggled(bool)), this->joystick, SLOT(setEnabled(bool)));
43

44 45 46 47
    // Update the button label colors based on the current theme and watch for future theme changes.
    styleChanged(MainWindow::instance()->getStyle());
    connect(MainWindow::instance(), SIGNAL(styleChanged(MainWindow::QGC_MAINWINDOW_STYLE)), this, SLOT(styleChanged(MainWindow::QGC_MAINWINDOW_STYLE)));

48 49
    // Display the widget above all other windows.
    this->raise();
pixhawk's avatar
pixhawk committed
50 51 52
    this->show();
}

53 54 55 56 57 58 59 60 61 62 63 64
void JoystickWidget::initUI()
{
    // Add the joysticks to the top combobox. They're indexed by their item number.
    // And set the currently-selected combobox item to the current joystick.
    int joysticks = joystick->getNumJoysticks();
    if (joysticks)
    {
        for (int i = 0; i < joysticks; i++)
        {
            m_ui->joystickNameComboBox->addItem(joystick->getJoystickNameById(i));
        }
        m_ui->joystickNameComboBox->setCurrentIndex(joystick->getJoystickID());
65 66 67 68 69
        // And if joystick support is enabled, show the UI.
        if (m_ui->enableCheckBox->isChecked())
        {
            m_ui->joystickFrame->setEnabled(true);
        }
70 71 72

        // Create the initial UI.
        createUIForJoystick();
73
    }
74
    // But if there're no joysticks, disable everything and hide empty UI.
75 76
    else
    {
77
        m_ui->enableCheckBox->setEnabled(false);
78
        m_ui->joystickNameComboBox->addItem(tr("No joysticks found. Connect and restart QGC to add one."));
79
        m_ui->joystickNameComboBox->setEnabled(false);
80
        m_ui->joystickFrame->hide();
81 82 83
    }
}

84 85 86 87 88 89 90 91 92 93 94 95
void JoystickWidget::styleChanged(MainWindow::QGC_MAINWINDOW_STYLE newStyle)
{
    if (newStyle == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT)
    {
        buttonLabelColor = QColor(0x73, 0xD9, 0x5D);
    }
    else
    {
        buttonLabelColor = QColor(0x14, 0xC6, 0x14);
    }
}

pixhawk's avatar
pixhawk committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
JoystickWidget::~JoystickWidget()
{
    delete m_ui;
}

void JoystickWidget::changeEvent(QEvent *e)
{
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

112 113
void JoystickWidget::updateUI()
{
114
    // Update the actions for all of the buttons
115 116 117 118
    for (int i = 0; i < buttons.size(); i++)
    {
        JoystickButton* button = buttons[i];
        int action = joystick->getActionForButton(i);
119
        button->setAction(action);
120
    }
121 122

    // Update the axis mappings
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
    int rollAxis = joystick->getMappingRollAxis();
    int pitchAxis = joystick->getMappingPitchAxis();
    int yawAxis = joystick->getMappingYawAxis();
    int throttleAxis = joystick->getMappingThrottleAxis();
    for (int i = 0; i < axes.size(); i++)
    {
        JoystickAxis* axis = axes[i];
        JoystickInput::JOYSTICK_INPUT_MAPPING mapping = JoystickInput::JOYSTICK_INPUT_MAPPING_NONE;
        if (i == rollAxis)
        {
            mapping = JoystickInput::JOYSTICK_INPUT_MAPPING_ROLL;
        }
        else if (i == pitchAxis)
        {
            mapping = JoystickInput::JOYSTICK_INPUT_MAPPING_PITCH;
        }
        else if (i == yawAxis)
        {
            mapping = JoystickInput::JOYSTICK_INPUT_MAPPING_YAW;
        }
        else if (i == throttleAxis)
        {
            mapping = JoystickInput::JOYSTICK_INPUT_MAPPING_THROTTLE;
        }
        axis->setMapping(mapping);
        bool inverted = joystick->getInvertedForAxis(i);
        axis->setInverted(inverted);
        bool limited = joystick->getRangeLimitForAxis(i);
        axis->setRangeLimit(limited);
    }
}

void JoystickWidget::createUIForJoystick()
156
{
157 158
    // Delete all the old UI elements
    foreach (JoystickButton* b, buttons)
159
    {
160
        delete b;
161
    }
162 163 164 165 166 167
    buttons.clear();
    foreach (JoystickAxis* a, axes)
    {
        delete a;
    }
    axes.clear();
168

169 170
    // And add the necessary button displays for this joystick.
    int newButtons = joystick->getJoystickNumButtons();
171
    if (newButtons)
172
    {
173 174 175 176
        m_ui->buttonBox->show();
        for (int i = 0; i < newButtons; i++)
        {
            JoystickButton* button = new JoystickButton(i, m_ui->buttonBox);
177 178
            button->setAction(joystick->getActionForButton(i));
            connect(button, SIGNAL(actionChanged(int,int)), this->joystick, SLOT(setButtonAction(int,int)));
179
            connect(this->joystick, SIGNAL(activeUASSet(UASInterface*)), button, SLOT(setActiveUAS(UASInterface*)));
180
            m_ui->buttonLayout->addWidget(button);
181 182 183 184 185 186
            buttons.append(button);
        }
    }
    else
    {
        m_ui->buttonBox->hide();
187 188
    }

189
    // Do the same for the axes supported by this joystick.
190 191 192 193
    int rollAxis = joystick->getMappingRollAxis();
    int pitchAxis = joystick->getMappingPitchAxis();
    int yawAxis = joystick->getMappingYawAxis();
    int throttleAxis = joystick->getMappingThrottleAxis();
194 195 196 197 198 199 200
    int newAxes = joystick->getJoystickNumAxes();
    if (newAxes)
    {
        for (int i = 0; i < newAxes; i++)
        {
            JoystickAxis* axis = new JoystickAxis(i, m_ui->axesBox);
            axis->setValue(joystick->getCurrentValueForAxis(i));
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
            if (i == rollAxis)
            {
                axis->setMapping(JoystickInput::JOYSTICK_INPUT_MAPPING_ROLL);
            }
            else if (i == pitchAxis)
            {
                axis->setMapping(JoystickInput::JOYSTICK_INPUT_MAPPING_PITCH);
            }
            else if (i == yawAxis)
            {
                axis->setMapping(JoystickInput::JOYSTICK_INPUT_MAPPING_YAW);
            }
            else if (i == throttleAxis)
            {
                axis->setMapping(JoystickInput::JOYSTICK_INPUT_MAPPING_THROTTLE);
            }
            axis->setInverted(joystick->getInvertedForAxis(i));
            axis->setRangeLimit(joystick->getRangeLimitForAxis(i));
219 220
            connect(axis, SIGNAL(mappingChanged(int,JoystickInput::JOYSTICK_INPUT_MAPPING)), this->joystick, SLOT(setAxisMapping(int,JoystickInput::JOYSTICK_INPUT_MAPPING)));
            connect(axis, SIGNAL(inversionChanged(int,bool)), this->joystick, SLOT(setAxisInversion(int,bool)));
221
            connect(axis, SIGNAL(rangeChanged(int,bool)), this->joystick, SLOT(setAxisRangeLimit(int,bool)));
222
            connect(this->joystick, SIGNAL(activeUASSet(UASInterface*)), axis, SLOT(setActiveUAS(UASInterface*)));
223
            m_ui->axesLayout->addWidget(axis);
224 225 226 227
            axes.append(axis);
        }
    }
    else
228
    {
229
        m_ui->axesBox->hide();
230
    }
231 232

    connect(m_ui->calibrationButton, SIGNAL(clicked()), this, SLOT(cycleCalibrationButton()));
pixhawk's avatar
pixhawk committed
233
}
pixhawk's avatar
pixhawk committed
234

235
void JoystickWidget::updateAxisValue(int axis, float value)
pixhawk's avatar
pixhawk committed
236
{
237
    if (axis < axes.size())
238
    {
239
        axes.at(axis)->setValue(value);
240
    }
pixhawk's avatar
pixhawk committed
241
}
pixhawk's avatar
pixhawk committed
242

243
void JoystickWidget::setHat(qint8 x, qint8 y)
pixhawk's avatar
pixhawk committed
244
{
245
    m_ui->statusLabel->setText(tr("Hat position: x: %1, y: %2").arg(x).arg(y));
246 247
}

248 249 250
void JoystickWidget::joystickButtonPressed(int key)
{
    QString colorStyle = QString("QLabel { background-color: %1;}").arg(buttonLabelColor.name());
251
    buttons.at(key)->setStyleSheet(colorStyle);
252 253 254
}

void JoystickWidget::joystickButtonReleased(int key)
pixhawk's avatar
pixhawk committed
255
{
256
    buttons.at(key)->setStyleSheet("");
257
}
258 259 260 261 262 263 264 265 266 267 268

void JoystickWidget::cycleCalibrationButton()
{
    if (this->joystick->calibrating()) {
        this->joystick->setCalibrating(false);
        m_ui->calibrationButton->setText("Calibrate range");
    } else {
        this->joystick->setCalibrating(true);
        m_ui->calibrationButton->setText("End calibration");
    }
}