JoystickWidget.cc 9.04 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"
pixhawk's avatar
pixhawk committed
6
#include <QDebug>
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(int,int)), this, SLOT(setHat(int,int)));
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 34 35 36 37 38
    // If the selected joystick is changed, update the joystick and the UI.
    connect(m_ui->joystickNameComboBox, SIGNAL(currentIndexChanged(int)), this->joystick, SLOT(setActiveJoystick(int)));
    connect(m_ui->joystickNameComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(createUIForJoystick()));

    // Initialize the UI to the current JoystickInput state. Also make sure to listen for future changes
    // so that the UI can be updated.
39
    connect(m_ui->enableCheckBox, SIGNAL(toggled(bool)), m_ui->joystickFrame, SLOT(setEnabled(bool)));
40 41
    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)));
42

43 44 45 46
    // 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)));

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

52 53 54 55 56 57 58 59 60 61 62 63
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());
64 65 66 67 68
        // And if joystick support is enabled, show the UI.
        if (m_ui->enableCheckBox->isChecked())
        {
            m_ui->joystickFrame->setEnabled(true);
        }
69
    }
70
    // But if there're no joysticks, just disable everything.
71 72
    else
    {
73
        m_ui->enableCheckBox->setEnabled(false);
74
        m_ui->joystickNameComboBox->addItem(tr("No joysticks found. Connect and restart QGC to add one."));
75
        m_ui->joystickNameComboBox->setEnabled(false);
76 77 78
    }

    // Add any missing buttons
79
    createUIForJoystick();
80 81
}

82 83 84 85 86 87 88 89 90 91 92 93
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
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
JoystickWidget::~JoystickWidget()
{
    delete m_ui;
}

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

110 111 112 113 114 115 116 117 118 119 120 121 122 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
void JoystickWidget::updateUI()
{
    for (int i = 0; i < buttons.size(); i++)
    {
        JoystickButton* button = buttons[i];
        int action = joystick->getActionForButton(i);
        button->setAction(action + 1);
        qDebug() << "JoystickWidget: Updating button " << i << " to action " << action + 1;
    }
    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];
        float value = joystick->getCurrentValueForAxis(i);
        axis->setValue(value);
        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);
        qDebug() << "JoystickWidget: Updating axis " << i << " to value:" << value << ", mapping:" << mapping << ", inverted:" << inverted << ", limited:" << limited;
    }
}

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

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

188
    // Do the same for the axes supported by this joystick.
189 190 191 192
    int rollAxis = joystick->getMappingRollAxis();
    int pitchAxis = joystick->getMappingPitchAxis();
    int yawAxis = joystick->getMappingYawAxis();
    int throttleAxis = joystick->getMappingThrottleAxis();
193 194 195 196 197 198 199
    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));
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
            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));
218 219
            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)));
220
            connect(axis, SIGNAL(rangeChanged(int,bool)), this->joystick, SLOT(setAxisRangeLimit(int,bool)));
221
            connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), axis, SLOT(setActiveUAS(UASInterface*)));
222
            m_ui->axesLayout->addWidget(axis);
223 224 225 226
            axes.append(axis);
        }
    }
    else
227
    {
228
        m_ui->buttonBox->hide();
229
    }
pixhawk's avatar
pixhawk committed
230
}
pixhawk's avatar
pixhawk committed
231

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

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

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

void JoystickWidget::joystickButtonReleased(int key)
pixhawk's avatar
pixhawk committed
252
{
253
    buttons.at(key)->setStyleSheet("");
254
}