diff --git a/companion/src/boards.h b/companion/src/boards.h index ab8ede1f2d..96420498b1 100644 --- a/companion/src/boards.h +++ b/companion/src/boards.h @@ -66,6 +66,42 @@ namespace Board { SWITCH_3POS }; + enum TrimAxes { + TRIM_AXIS_LH = 0, + TRIM_AXIS_LV, + TRIM_AXIS_RV, + TRIM_AXIS_RH, + TRIM_AXIS_T5, + TRIM_AXIS_T6, + }; + + enum TrimSwitchIndex + { + TRIM_SW_LH_DEC, + TRIM_SW_LH_INC, + TRIM_SW_LV_DEC, + TRIM_SW_LV_INC, + TRIM_SW_RV_DEC, + TRIM_SW_RV_INC, + TRIM_SW_RH_DEC, + TRIM_SW_RH_INC, + TRIM_SW_T5_DEC, + TRIM_SW_T5_INC, + TRIM_SW_T6_DEC, + TRIM_SW_T6_INC, + TRIM_SW_ENUM_END + }; + + enum Capability { + Pots, + Sliders, + MouseAnalogs, + Switches, + FactoryInstalledSwitches, + NumTrims, + NumTrimSwitches + }; + struct SwitchInfo { SwitchType config; @@ -82,15 +118,6 @@ namespace Board { unsigned int position; }; - enum Capability { - Pots, - Sliders, - MouseAnalogs, - Switches, - FactoryInstalledSwitches, - NumTrims, - NumTrimSwitches - }; } // TODO remove all those constants diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index 4a97f106ce..cbd77a2d81 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -17,6 +17,14 @@ images/simulator/icons/svg/console.svg images/simulator/icons/svg/eraser.svg images/simulator/icons/svg/eraser-active.svg + images/simulator/icons/svg/fixed_x.svg + images/simulator/icons/svg/fixed_x-on.svg + images/simulator/icons/svg/fixed_y.svg + images/simulator/icons/svg/fixed_y-on.svg + images/simulator/icons/svg/hold_x.svg + images/simulator/icons/svg/hold_x-on.svg + images/simulator/icons/svg/hold_y.svg + images/simulator/icons/svg/hold_y-on.svg images/simulator/icons/svg/info.svg images/simulator/icons/svg/info-active.svg images/simulator/icons/svg/joystick_settings.svg diff --git a/companion/src/images/simulator/icons/svg/fixed_x-on.svg b/companion/src/images/simulator/icons/svg/fixed_x-on.svg new file mode 100644 index 0000000000..3a9a7022b7 --- /dev/null +++ b/companion/src/images/simulator/icons/svg/fixed_x-on.svg @@ -0,0 +1,18 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/fixed_x.svg b/companion/src/images/simulator/icons/svg/fixed_x.svg new file mode 100644 index 0000000000..767a9a43ae --- /dev/null +++ b/companion/src/images/simulator/icons/svg/fixed_x.svg @@ -0,0 +1,18 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/fixed_y-on.svg b/companion/src/images/simulator/icons/svg/fixed_y-on.svg new file mode 100644 index 0000000000..319b784efd --- /dev/null +++ b/companion/src/images/simulator/icons/svg/fixed_y-on.svg @@ -0,0 +1,18 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/fixed_y.svg b/companion/src/images/simulator/icons/svg/fixed_y.svg new file mode 100644 index 0000000000..e6b15140a4 --- /dev/null +++ b/companion/src/images/simulator/icons/svg/fixed_y.svg @@ -0,0 +1,18 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/hold_x-on.svg b/companion/src/images/simulator/icons/svg/hold_x-on.svg new file mode 100644 index 0000000000..81808417a7 --- /dev/null +++ b/companion/src/images/simulator/icons/svg/hold_x-on.svg @@ -0,0 +1,19 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/hold_x.svg b/companion/src/images/simulator/icons/svg/hold_x.svg new file mode 100644 index 0000000000..c65cf55147 --- /dev/null +++ b/companion/src/images/simulator/icons/svg/hold_x.svg @@ -0,0 +1,19 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/hold_y-on.svg b/companion/src/images/simulator/icons/svg/hold_y-on.svg new file mode 100644 index 0000000000..4058d326c6 --- /dev/null +++ b/companion/src/images/simulator/icons/svg/hold_y-on.svg @@ -0,0 +1,19 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/companion/src/images/simulator/icons/svg/hold_y.svg b/companion/src/images/simulator/icons/svg/hold_y.svg new file mode 100644 index 0000000000..e620307b13 --- /dev/null +++ b/companion/src/images/simulator/icons/svg/hold_y.svg @@ -0,0 +1,19 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/companion/src/modeledit/node.h b/companion/src/modeledit/node.h index b58437c011..b952a43e56 100644 --- a/companion/src/modeledit/node.h +++ b/companion/src/modeledit/node.h @@ -48,22 +48,25 @@ class Node : public QGraphicsObject void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void setBallSize(int size); void stepToCenter(qreal step=10); - int getBallSize() {return ballSize;} + int getBallSize() { return ballSize; } qreal getX(); qreal getY(); void setX(qreal newX); void setY(qreal newX); - void setCenteringX(bool val) {centerX = val;} - void setCenteringY(bool val) {centerY = val;} - void setFixedX(bool val) {fixedX = val;} - void setFixedY(bool val) {fixedY = val;} - bool getFixedX() {return fixedX;} - bool getFixedY() {return fixedY;} - void setMinX(int val) {minX = val;}; - void setMaxX(int val) {maxX = val;}; + void setCenteringX(bool val) { centerX = val; } + void setCenteringY(bool val) { centerY = val; } + void setFixedX(bool val) { fixedX = val; } + void setFixedY(bool val) { fixedY = val; } + bool getFixedX() { return fixedX; } + bool getFixedY() { return fixedY; } + void setMinX(int val) { minX = val; } + void setMaxX(int val) { maxX = val; } + void setPressed(bool pressed) { bPressed = pressed; } + bool isPressed() const { return bPressed; } + void setColor(const QColor & color); - + signals: void moved(int x, int y); void focus(); @@ -73,7 +76,7 @@ class Node : public QGraphicsObject QVariant itemChange(GraphicsItemChange change, const QVariant &value); void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - + private: bool bPressed; bool centerX; diff --git a/companion/src/radiodata.h b/companion/src/radiodata.h index e5b8b8bc2f..3c6b0af006 100644 --- a/companion/src/radiodata.h +++ b/companion/src/radiodata.h @@ -69,20 +69,6 @@ enum FailsafeModes { FAILSAFE_LAST = FAILSAFE_RECEIVER }; -#define TRIM_LH_L 0 -#define TRIM_LH_R 1 -#define TRIM_LV_DN 2 -#define TRIM_LV_UP 3 -#define TRIM_RV_DN 4 -#define TRIM_RV_UP 5 -#define TRIM_RH_L 6 -#define TRIM_RH_R 7 -#define TRIM_T5_DN 8 -#define TRIM_T5_UP 9 -#define TRIM_T6_DN 10 -#define TRIM_T6_UP 11 -#define TRIM_NONE 12 - #define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*" @@ -1010,9 +996,9 @@ class ModelData { ModelData(); ModelData(const ModelData & src); ModelData & operator = (const ModelData & src); - + void convert(Board::Type before, Board::Type after); - + ExpoData * insertInput(const int idx); void removeInput(const int idx); @@ -1248,7 +1234,7 @@ class RadioData { GeneralSettings generalSettings; std::vector categories; std::vector models; - + void convert(Board::Type before, Board::Type after); void setCurrentModel(unsigned int index); diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index ed9709e9b3..d29ed78a98 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -51,6 +51,7 @@ set(simulation_HDRS widgets/radiofaderwidget.h widgets/radioknobwidget.h widgets/radioswitchwidget.h + widgets/radiotrimwidget.h widgets/sliderwidget.h widgets/virtualjoystickwidget.h ) diff --git a/companion/src/simulation/simulatorinterface.h b/companion/src/simulation/simulatorinterface.h index faec701915..7939f37158 100644 --- a/companion/src/simulation/simulatorinterface.h +++ b/companion/src/simulation/simulatorinterface.h @@ -57,7 +57,7 @@ class TxOutputs struct Trims { - int values[CPN_MAX_STICKS]; /* lh lv rv rh */ + int values[CPN_MAX_STICKS + CPN_MAX_AUX_TRIMS]; /* lh lv rv rh t5 t6 */ bool extended; }; diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index 0becb63e9b..61e4d7bf9e 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -55,7 +55,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface *simulator flags(flags), lastPhase(-1), buttonPressed(0), - trimPressed(TRIM_NONE), + trimPressed(255), startupFromFile(false), deleteTempRadioData(false), saveTempRadioData(false), @@ -113,13 +113,13 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface *simulator vJoyRight = new VirtualJoystickWidget(this, 'R'); ui->rightStickLayout->addWidget(vJoyRight); - connect(vJoyLeft, SIGNAL(trimButtonPressed(int)), this, SLOT(onTrimPressed(int))); - connect(vJoyLeft, SIGNAL(trimButtonReleased()), this, SLOT(onTrimReleased())); - connect(vJoyLeft, SIGNAL(trimSliderMoved(int,int)), this, SLOT(onTrimSliderMoved(int,int))); + connect(vJoyLeft, &VirtualJoystickWidget::trimButtonPressed, this, &SimulatorWidget::onTrimPressed); + connect(vJoyLeft, &VirtualJoystickWidget::trimButtonReleased, this, &SimulatorWidget::onTrimReleased); + connect(vJoyLeft, &VirtualJoystickWidget::trimSliderMoved, this, &SimulatorWidget::onTrimSliderMoved); - connect(vJoyRight, SIGNAL(trimButtonPressed(int)), this, SLOT(onTrimPressed(int))); - connect(vJoyRight, SIGNAL(trimButtonReleased()), this, SLOT(onTrimReleased())); - connect(vJoyRight, SIGNAL(trimSliderMoved(int,int)), this, SLOT(onTrimSliderMoved(int,int))); + connect(vJoyRight, &VirtualJoystickWidget::trimButtonPressed, this, &SimulatorWidget::onTrimPressed); + connect(vJoyRight, &VirtualJoystickWidget::trimButtonReleased, this, &SimulatorWidget::onTrimReleased); + connect(vJoyRight, &VirtualJoystickWidget::trimSliderMoved, this, &SimulatorWidget::onTrimSliderMoved); timer->setInterval(10); connect(timer, SIGNAL(timeout()), this, SLOT(onTimerEvent())); @@ -739,19 +739,19 @@ void SimulatorWidget::getValues() // Read stick trim values from firmware simulator and set joystick widgets as needed. void SimulatorWidget::setTrims() { - typedef VirtualJoystickWidget VJW; + using namespace Board; static Trims lastTrims; Trims trims; simulator->getTrims(trims); - if (trims.values[VJW::TRIM_AXIS_L_X] != lastTrims.values[VJW::TRIM_AXIS_L_X]) - vJoyLeft->setTrimValue(VJW::TRIM_AXIS_L_X, trims.values[VJW::TRIM_AXIS_L_X]); - if (trims.values[VJW::TRIM_AXIS_L_Y] != lastTrims.values[VJW::TRIM_AXIS_L_Y]) - vJoyLeft->setTrimValue(VJW::TRIM_AXIS_L_Y, trims.values[VJW::TRIM_AXIS_L_Y]); - if (trims.values[VJW::TRIM_AXIS_R_Y] != lastTrims.values[VJW::TRIM_AXIS_R_Y]) - vJoyRight->setTrimValue(VJW::TRIM_AXIS_R_Y, trims.values[VJW::TRIM_AXIS_R_Y]); - if (trims.values[VJW::TRIM_AXIS_R_X] != lastTrims.values[VJW::TRIM_AXIS_R_X]) - vJoyRight->setTrimValue(VJW::TRIM_AXIS_R_X, trims.values[VJW::TRIM_AXIS_R_X]); + if (trims.values[TRIM_AXIS_LH] != lastTrims.values[TRIM_AXIS_LH]) + vJoyLeft->setTrimValue(TRIM_AXIS_LH, trims.values[TRIM_AXIS_LH]); + if (trims.values[TRIM_AXIS_LV] != lastTrims.values[TRIM_AXIS_LV]) + vJoyLeft->setTrimValue(TRIM_AXIS_LV, trims.values[TRIM_AXIS_LV]); + if (trims.values[TRIM_AXIS_RV] != lastTrims.values[TRIM_AXIS_RV]) + vJoyRight->setTrimValue(TRIM_AXIS_RV, trims.values[TRIM_AXIS_RV]); + if (trims.values[TRIM_AXIS_RH] != lastTrims.values[TRIM_AXIS_RH]) + vJoyRight->setTrimValue(TRIM_AXIS_RH, trims.values[TRIM_AXIS_RH]); if (trims.extended != lastTrims.extended) { int trimMin = -125, trimMax = +125; @@ -759,10 +759,10 @@ void SimulatorWidget::setTrims() trimMin = -500; trimMax = +500; } - vJoyLeft->setTrimRange(VJW::TRIM_AXIS_L_X, trimMin, trimMax); - vJoyLeft->setTrimRange(VJW::TRIM_AXIS_L_Y, trimMin, trimMax); - vJoyRight->setTrimRange(VJW::TRIM_AXIS_R_Y, trimMin, trimMax); - vJoyRight->setTrimRange(VJW::TRIM_AXIS_R_X, trimMin, trimMax); + vJoyLeft->setTrimRange(TRIM_AXIS_LH, trimMin, trimMax); + vJoyLeft->setTrimRange(TRIM_AXIS_LV, trimMin, trimMax); + vJoyRight->setTrimRange(TRIM_AXIS_RV, trimMin, trimMax); + vJoyRight->setTrimRange(TRIM_AXIS_RH, trimMin, trimMax); } lastTrims = trims; } @@ -771,17 +771,6 @@ void SimulatorWidget::setTrims() * Event handlers/private slots */ -//void SimulatorDialog::showEvent(QShowEvent *) -//{ -// if (firstShow && isVisible()) { -// firstShow = false; -// } -//} - -//void SimulatorDialog::closeEvent(QCloseEvent *) -//{ -//} - void SimulatorWidget::mousePressEvent(QMouseEvent *event) { if (radioUiWidget) @@ -819,19 +808,19 @@ void SimulatorWidget::onTimerEvent() } } -void SimulatorWidget::onTrimPressed(int which) +void SimulatorWidget::onTrimPressed(int index) { - trimPressed = which; + trimPressed = index; } -void SimulatorWidget::onTrimReleased() +void SimulatorWidget::onTrimReleased(int) { - trimPressed = TRIM_NONE; + trimPressed = 255; } -void SimulatorWidget::onTrimSliderMoved(int which, int value) +void SimulatorWidget::onTrimSliderMoved(int index, int value) { - simulator->setTrim(which, value); + simulator->setTrim(index, value); } void SimulatorWidget::centerSticks() diff --git a/companion/src/simulation/simulatorwidget.h b/companion/src/simulation/simulatorwidget.h index 7272002527..e7398039af 100644 --- a/companion/src/simulation/simulatorwidget.h +++ b/companion/src/simulation/simulatorwidget.h @@ -140,16 +140,14 @@ class SimulatorWidget : public QWidget #endif private slots: - //virtual void showEvent(QShowEvent *); - //virtual void closeEvent(QCloseEvent *); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void wheelEvent(QWheelEvent *event); void onTimerEvent(); - void onTrimPressed(int which); - void onTrimReleased(); - void onTrimSliderMoved(int which, int value); + void onTrimPressed(int index); + void onTrimReleased(int); + void onTrimSliderMoved(int index, int value); void centerSticks(); void onjoystickAxisValueChanged(int axis, int value); diff --git a/companion/src/simulation/widgets/radiotrimwidget.h b/companion/src/simulation/widgets/radiotrimwidget.h new file mode 100644 index 0000000000..a6f46bc898 --- /dev/null +++ b/companion/src/simulation/widgets/radiotrimwidget.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#ifndef _RADIOTRIMWIDGET_H_ +#define _RADIOTRIMWIDGET_H_ + +#include "radiowidget.h" +#include "sliderwidget.h" + +#include + +class RadioTrimWidget : public RadioWidget +{ + Q_OBJECT + + public: + + explicit RadioTrimWidget(Qt::Orientation orientation = Qt::Vertical, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) : + RadioWidget(parent, f), + m_slider(NULL) + { + init(orientation); + } + explicit RadioTrimWidget(const QString & labelText, Qt::Orientation orientation = Qt::Vertical, int value = 0, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) : + RadioWidget(labelText, value, parent, f), + m_slider(NULL) + { + init(orientation); + } + + void setIndices(int sliderIdx = -1, int decrBtnIdx = -1, int incrBtnIdx = -1) + { + setIndex(sliderIdx); + m_btnDecIndex = decrBtnIdx; + m_btnIncIndex = incrBtnIdx; + } + + void setTrimRange(int min, int max) + { + if (m_slider) + m_slider->setRange(min, max); + } + + signals: + + void trimButtonPressed(int index); + void trimButtonReleased(int index); + void trimSliderMoved(int index, int value); + + protected slots: + + void init(Qt::Orientation orientation) + { + m_type = RADIO_WIDGET_TRIM; + m_slider = new SliderWidget(this); + m_slider->setOrientation(orientation); + + setTrimRange(-125, 125); + setIndices(); + + QSize btnIcnSz(12, 12); + QWidget * trimWidget = new QWidget(this); + QBoxLayout * trimLayout = new QVBoxLayout(trimWidget); + trimLayout->setSpacing(5); + trimLayout->setContentsMargins(8, 8, 8, 8); + QToolButton * trimBtnInc = new QToolButton(trimWidget); + trimBtnInc->setIconSize(btnIcnSz); + QToolButton * trimBtnDec = new QToolButton(trimWidget); + trimBtnDec->setIconSize(btnIcnSz); + + Qt::Alignment algn; + if (orientation == Qt::Horizontal) { + trimWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + trimLayout->setDirection(QBoxLayout::RightToLeft); + trimBtnInc->setArrowType(Qt::RightArrow); + trimBtnDec->setArrowType(Qt::LeftArrow); + algn = Qt::AlignVCenter; + } + else { + trimWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + trimLayout->setDirection(QBoxLayout::TopToBottom); + trimBtnInc->setArrowType(Qt::UpArrow); + trimBtnDec->setArrowType(Qt::DownArrow); + algn = Qt::AlignHCenter; + } + + trimLayout->addWidget(trimBtnInc, 0, algn); + trimLayout->addWidget(m_slider, 1, algn); + trimLayout->addWidget(trimBtnDec, 0, algn); + + setWidget(trimWidget, algn); + + connect(m_slider, &SliderWidget::valueChanged, this, &RadioWidget::setValue); + connect(this, &RadioWidget::valueChanged, this, &RadioTrimWidget::onValueChanged); + + connect(trimBtnInc, &QToolButton::pressed, [this]() { emit trimButtonPressed(m_btnIncIndex); }); + connect(trimBtnInc, &QToolButton::released, [this]() { emit trimButtonReleased(m_btnIncIndex); }); + connect(trimBtnDec, &QToolButton::pressed, [this]() { emit trimButtonPressed(m_btnDecIndex); }); + connect(trimBtnDec, &QToolButton::released, [this]() { emit trimButtonReleased(m_btnDecIndex); }); + } + + void onValueChanged(int value) + { + m_slider->blockSignals(true); + m_slider->setValue(value); + m_slider->blockSignals(false); + emit trimSliderMoved(m_index, m_value); + } + + protected: + SliderWidget * m_slider; + int m_btnDecIndex; + int m_btnIncIndex; +}; + + +#endif // _RADIOTRIMWIDGET_H_ diff --git a/companion/src/simulation/widgets/radiowidget.cpp b/companion/src/simulation/widgets/radiowidget.cpp index f875222346..2e6d213dd0 100644 --- a/companion/src/simulation/widgets/radiowidget.cpp +++ b/companion/src/simulation/widgets/radiowidget.cpp @@ -58,7 +58,7 @@ void RadioWidget::setValue(int value) { if (value != m_value) { m_value = value; - emit valueChanged(m_value); + emit valueChanged(value); } } @@ -166,7 +166,7 @@ void RadioWidget::addLabel() } } -void RadioWidget::setWidget(QWidget * widget) +void RadioWidget::setWidget(QWidget * widget, Qt::Alignment align) { if (m_controlWidget) { m_gridLayout->removeWidget(m_controlWidget); @@ -174,7 +174,7 @@ void RadioWidget::setWidget(QWidget * widget) } m_controlWidget = widget; if (widget) { - m_gridLayout->addWidget(widget, 0, 0, 1, 1, Qt::AlignHCenter); + m_gridLayout->addWidget(widget, 0, 0, 1, 1, align); m_gridLayout->setRowStretch(0, 1); } } diff --git a/companion/src/simulation/widgets/radiowidget.h b/companion/src/simulation/widgets/radiowidget.h index ad1b5bac74..aa9bb81ab4 100644 --- a/companion/src/simulation/widgets/radiowidget.h +++ b/companion/src/simulation/widgets/radiowidget.h @@ -41,6 +41,7 @@ class RadioWidget : public QWidget RADIO_WIDGET_SWITCH, RADIO_WIDGET_KNOB, RADIO_WIDGET_FADER, + RADIO_WIDGET_TRIM, RADIO_WIDGET_STICK // actually one axis of a stick }; @@ -76,7 +77,6 @@ class RadioWidget : public QWidget void setStateData(const QByteArray & data); void changeVisibility(bool visible); - virtual int getValue() const; int getIndex() const; int getType() const; @@ -87,7 +87,7 @@ class RadioWidget : public QWidget void init(); void addLabel(); - void setWidget(QWidget * widget = NULL); + void setWidget(QWidget * widget = NULL, Qt::Alignment align = Qt::AlignHCenter); int m_value; int m_index; @@ -105,7 +105,7 @@ class RadioWidget : public QWidget signals: - void valueChanged(int m_value); + void valueChanged(int value); void flagsChanged(quint16 flags); }; diff --git a/companion/src/simulation/widgets/sliderwidget.h b/companion/src/simulation/widgets/sliderwidget.h index aa5140b82f..f99ce570e9 100644 --- a/companion/src/simulation/widgets/sliderwidget.h +++ b/companion/src/simulation/widgets/sliderwidget.h @@ -42,6 +42,7 @@ class SliderWidget : public QSlider { if (event->button() == Qt::RightButton && event->type() == QEvent::MouseButtonDblClick) { setValue(0); + emit sliderMoved(0); event->accept(); } QSlider::mousePressEvent(event); diff --git a/companion/src/simulation/widgets/virtualjoystickwidget.cpp b/companion/src/simulation/widgets/virtualjoystickwidget.cpp index 9242b01c44..dd250dcad0 100644 --- a/companion/src/simulation/widgets/virtualjoystickwidget.cpp +++ b/companion/src/simulation/widgets/virtualjoystickwidget.cpp @@ -18,27 +18,32 @@ * GNU General Public License for more details. */ -#define GBALL_SIZE 20 -#define RESX 1024 +#define GBALL_SIZE 25 +#define GBALL_SIZE_MN 20 +#define GBALL_SIZE_MX 35 #include "virtualjoystickwidget.h" + +#include "boards.h" #include "constants.h" -#include "sliderwidget.h" #include "modeledit/node.h" #include "helpers.h" +#include "radiotrimwidget.h" +#include "simulator.h" VirtualJoystickWidget::VirtualJoystickWidget(QWidget *parent, QChar side, bool showTrims, bool showBtns, bool showValues, QSize size) : QWidget(parent), stickSide(side), prefSize(size), - hTrimSlider(NULL), - vTrimSlider(NULL), + hTrimWidget(NULL), + vTrimWidget(NULL), btnHoldX(NULL), btnHoldY(NULL), btnFixX(NULL), btnFixY(NULL), nodeLabelX(NULL), - nodeLabelY(NULL) + nodeLabelY(NULL), + m_stickPressed(false) { ar = (float)size.width() / size.height(); extraSize = QSize(0, 0); @@ -54,12 +59,11 @@ VirtualJoystickWidget::VirtualJoystickWidget(QWidget *parent, QChar side, bool s gv = new QGraphicsView(this); gv->setSizePolicy(sizePolicy); gv->setMinimumSize(size); -// gv->setMaximumSize(size + size * 3); -// gv->setFixedSize(prefSize); gv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); gv->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + gv->setRenderHints(QPainter::Antialiasing); - scene = new QGraphicsScene(gv); + scene = new CustomGraphicsScene(gv); scene->setItemIndexMethod(QGraphicsScene::NoIndex); gv->setScene(scene); @@ -83,14 +87,12 @@ VirtualJoystickWidget::VirtualJoystickWidget(QWidget *parent, QChar side, bool s } if (showTrims) { - QWidget * hTrimWidget = createTrimWidget('H'); - QWidget * vTrimWidget = createTrimWidget('V'); + hTrimWidget = createTrimWidget('H'); + vTrimWidget = createTrimWidget('V'); layout->addWidget(vTrimWidget, 1, colvt, 1, 1); layout->addWidget(hTrimWidget, 2, 2, 1, 1); - hTrimSlider = hTrimWidget->findChild(); - vTrimSlider = vTrimWidget->findChild(); extraSize += QSize(vTrimWidget->sizeHint().width(), hTrimWidget->sizeHint().height()); } else { @@ -131,10 +133,12 @@ VirtualJoystickWidget::VirtualJoystickWidget(QWidget *parent, QChar side, bool s layout->addItem(new QSpacerItem(0, 0), 1, 0, 2, 1); // r1-2 c0: left h spacer layout->addWidget(gv, 1, 2, 1, 1); // r1 c2: stick widget layout->addItem(new QSpacerItem(0, 0), 1, 4, 2, 1); // r1-2 c4: right h spacer - layout->addItem(new QSpacerItem(0, 0), 3, 0, 1, 5); // r3 c0-4: bot v spacer + layout->addItem(new QSpacerItem(0, 0), 3, 0, 1, 5); // r4 c0-4: bot v spacer - connect(node, SIGNAL(xChanged()), this, SLOT(updateNodeValueLabels())); - connect(node, SIGNAL(yChanged()), this, SLOT(updateNodeValueLabels())); + connect(node, &Node::xChanged, this, &VirtualJoystickWidget::updateNodeValueLabels); + connect(node, &Node::yChanged, this, &VirtualJoystickWidget::updateNodeValueLabels); + + connect(scene, &CustomGraphicsScene::mouseEvent, this, &VirtualJoystickWidget::onGsMouseEvent); setSize(prefSize, frameSize()); } @@ -176,25 +180,25 @@ QPointF VirtualJoystickWidget::getStickPos() void VirtualJoystickWidget::setTrimValue(int which, int value) { - SliderWidget * slider = getTrimSlider(which); - if (slider) { - slider->setValue(value); + RadioTrimWidget * trim = getTrimWidget(which); + if (trim) { + trim->setValue(value); } } void VirtualJoystickWidget::setTrimRange(int which, int min, int max) { - SliderWidget * slider = getTrimSlider(which); - if (slider) { - slider->setRange(min, max); + RadioTrimWidget * trim = getTrimWidget(which); + if (trim) { + trim->setTrimRange(min, max); } } int VirtualJoystickWidget::getTrimValue(int which) { - SliderWidget * slider = getTrimSlider(which); - if (slider) { - return slider->value(); + RadioTrimWidget * trim = getTrimWidget(which); + if (trim) { + return trim->getValue(); } return 0; } @@ -269,13 +273,15 @@ void VirtualJoystickWidget::setSize(const QSize & size, const QSize &) layout->setColumnStretch(2, newGvSz); layout->setRowStretch(1, newGvSz); - //prefSize = QSize(newGvSz + extraSize.width(), newGvSz + extraSize.height()); gv->resize(newGvSz, newGvSz); gv->updateGeometry(); + int ballSize = (newGvSz * GBALL_SIZE * 0.005f); + ballSize = qMin(GBALL_SIZE_MX, qMax(ballSize, GBALL_SIZE_MN)); + QRectF qr = (QRectF)gv->contentsRect(); - qreal w = qr.width() - GBALL_SIZE; - qreal h = qr.height() - GBALL_SIZE; + qreal w = qr.width() - ballSize; + qreal h = qr.height() - ballSize; qreal cx = qr.width() / 2; qreal cy = qr.height() / 2; qreal nodeX = node->getX(); @@ -283,120 +289,64 @@ void VirtualJoystickWidget::setSize(const QSize & size, const QSize &) scene->setSceneRect(-cx,-cy,w,h); + node->setBallSize(ballSize); node->setX(nodeX); node->setY(nodeY); //qDebug() << thisAspectRatio << size << newGvSz << spacerSz << extraSize << gv->geometry() << gv->contentsRect() << gv->frameRect() << getStickPos(); } -QWidget *VirtualJoystickWidget::createTrimWidget(QChar type) +RadioTrimWidget * VirtualJoystickWidget::createTrimWidget(QChar type) { - QSizePolicy sp; - QString btnAlabel, btnBlabel; + RadioTrimWidget * trimWidget = new RadioTrimWidget(type == 'H' ? Qt::Horizontal : Qt::Vertical); + trimWidget->setIndices(getTrimSliderType(type), getTrimButtonType(type, 0), getTrimButtonType(type, 1)); - QString btnAname = QString("%1TrimBtnA_%2").arg(type.toLower()).arg(stickSide); - QString btnBname = QString("%1TrimBtnB_%2").arg(type.toLower()).arg(stickSide); - QString sliderName = QString("%1TrimAdj_%2").arg(type.toLower()).arg(stickSide); - - QWidget * trimWidget = new QWidget(this); - QBoxLayout * trimLayout = new QVBoxLayout(trimWidget); - SliderWidget * trimSlider = new SliderWidget(trimWidget); - QPushButton * trimBtnA = new QPushButton(trimWidget); - QPushButton * trimBtnB = new QPushButton(trimWidget); - - if (type == 'H') { - sp = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - trimLayout->setDirection(QBoxLayout::LeftToRight); - trimSlider->setFixedHeight(23); - trimSlider->setOrientation(Qt::Horizontal); - trimBtnA->setText(ARROW_LEFT); - trimBtnB->setText(ARROW_RIGHT); - } - else { - sp = QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - trimLayout->setDirection(QBoxLayout::TopToBottom); - trimSlider->setFixedWidth(23); - trimSlider->setOrientation(Qt::Vertical); - trimBtnA->setText(ARROW_UP); - trimBtnB->setText(ARROW_DOWN); - } - - trimWidget->setSizePolicy(sp); - - trimSlider->setObjectName(sliderName); - trimSlider->setProperty("trimType", getTrimSliderType(type)); - trimSlider->setSizePolicy(sp); - trimSlider->setMinimum(-125); - trimSlider->setMaximum(125); - - trimBtnA->setObjectName(btnAname); - trimBtnA->setProperty("btnType", getTrimButtonType(type, 0)); - trimBtnA->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - trimBtnA->setMaximumSize(QSize(23, 23)); - trimBtnA->setAutoDefault(false); - - trimBtnB->setObjectName(btnBname); - trimBtnB->setProperty("btnType", getTrimButtonType(type, 1)); - trimBtnB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - trimBtnB->setMaximumSize(QSize(23, 23)); - trimBtnB->setAutoDefault(false); - - trimLayout->setSpacing(6); - trimLayout->setContentsMargins(8, 9, 8, 9); - trimLayout->addWidget(trimBtnA); - trimLayout->addWidget(trimSlider); - trimLayout->addWidget(trimBtnB); - - connect(trimBtnA, SIGNAL(pressed()), SLOT(onTrimPressed())); - connect(trimBtnB, SIGNAL(pressed()), SLOT(onTrimPressed())); - connect(trimBtnA, SIGNAL(released()), SIGNAL(trimButtonReleased())); - connect(trimBtnB, SIGNAL(released()), SIGNAL(trimButtonReleased())); - connect(trimSlider, SIGNAL(valueChanged(int)), SLOT(onSliderChange(int))); + connect(trimWidget, &RadioTrimWidget::trimButtonPressed, this, &VirtualJoystickWidget::trimButtonPressed); + connect(trimWidget, &RadioTrimWidget::trimButtonReleased, this, &VirtualJoystickWidget::trimButtonReleased); + connect(trimWidget, &RadioTrimWidget::trimSliderMoved, this, &VirtualJoystickWidget::trimSliderMoved); return trimWidget; } -QPushButton * VirtualJoystickWidget::createButtonWidget(int type) +QToolButton * VirtualJoystickWidget::createButtonWidget(int type) { - QString btnRole, btnLabel; + QString btnLabel, tooltip; + QIcon icon; switch (type) { case HOLD_Y: - btnLabel = tr("Hold Y"); + btnLabel = tr("Hld Y"); + tooltip = tr("Hold Vertical stick position."); + icon = Simulator::SimulatorIcon("hold_y"); break; case FIX_Y: btnLabel = tr("Fix Y"); + tooltip = tr("Prevent Vertical movement of stick."); + icon = Simulator::SimulatorIcon("fixed_y"); break; case FIX_X: btnLabel = tr("Fix X"); + tooltip = tr("Prevent Horizontal movement of stick."); + icon = Simulator::SimulatorIcon("fixed_x"); break; case HOLD_X: - default: - btnLabel = tr("Hold X"); + btnLabel = tr("Hld X"); + tooltip = tr("Hold Horizontal stick position."); + icon = Simulator::SimulatorIcon("hold_x"); break; + default: + return NULL; } - QPushButton * btn = new QPushButton(this); - btn->setObjectName(QString("%1_%2").arg(btnLabel.replace(" ", "_")).arg(stickSide)); + QToolButton * btn = new QToolButton(this); btn->setProperty("btnType", type); + btn->setIcon(icon); + btn->setIconSize(QSize(20, 20)); + btn->setToolButtonStyle(Qt::ToolButtonIconOnly); btn->setText(btnLabel); - QFont font; - font.setPointSize(8); - btn->setFont(font); - btn->setStyleSheet(QLatin1String( \ - "QPushButton {" - " background-color: #EEEEEE;" - " border-style: outset;" - " border-width: 1px;" - " border-radius: 4px;" - " border-color: black;" - " padding: 2px;" - "}" - "QPushButton:checked {\n" - " background-color: #4CC417;\n" - " border-style: inset;\n" - "}" )); + btn->setToolTip(tooltip); btn->setCheckable(true); + btn->setAutoRaise(true); - connect(btn, SIGNAL(toggled(bool)), SLOT(onButtonChange(bool))); + connect(btn, &QToolButton::toggled, this, &VirtualJoystickWidget::onButtonChange); return btn; } @@ -423,76 +373,63 @@ QLayout *VirtualJoystickWidget::createNodeValueLayout(QChar type, QLabel *& valL int VirtualJoystickWidget::getTrimSliderType(QChar type) { + using namespace Board; + if (stickSide == 'L') { if (type == 'H') - return TRIM_AXIS_L_X; + return TRIM_AXIS_LH; else - return TRIM_AXIS_L_Y; + return TRIM_AXIS_LV; } else { if (type == 'H') - return TRIM_AXIS_R_X; + return TRIM_AXIS_RH; else - return TRIM_AXIS_R_Y; + return TRIM_AXIS_RV; } } int VirtualJoystickWidget::getTrimButtonType(QChar type, int pos) { + using namespace Board; + if (stickSide == 'L') { if (type == 'H') { if (pos == 0) - return TRIM_LH_L; + return TRIM_SW_LH_DEC; else - return TRIM_LH_R; + return TRIM_SW_LH_INC; } else { if (pos == 0) - return TRIM_LV_UP; + return TRIM_SW_LV_DEC; else - return TRIM_LV_DN; + return TRIM_SW_LV_INC; } } // right side else { if (type == 'H') { if (pos == 0) - return TRIM_RH_L; + return TRIM_SW_RH_DEC; else - return TRIM_RH_R; + return TRIM_SW_RH_INC; } else { if (pos == 0) - return TRIM_RV_UP; + return TRIM_SW_RV_DEC; else - return TRIM_RV_DN; + return TRIM_SW_RV_INC; } } } -SliderWidget *VirtualJoystickWidget::getTrimSlider(int which) +RadioTrimWidget * VirtualJoystickWidget::getTrimWidget(int which) { - if (which == TRIM_AXIS_L_X || which == TRIM_AXIS_R_X) - return hTrimSlider; + if (which == Board::TRIM_AXIS_LH || which == Board::TRIM_AXIS_RH) + return hTrimWidget; else - return vTrimSlider; -} - -void VirtualJoystickWidget::onTrimPressed() -{ - if (!sender() || !sender()->property("btnType").isValid()) - return; - - emit trimButtonPressed(sender()->property("btnType").toInt()); -} - -void VirtualJoystickWidget::onSliderChange(int value) -{ - if (!sender() || !sender()->property("trimType").isValid()) - return; - - emit trimSliderMoved(sender()->property("trimType").toInt(), value); - updateNodeValueLabels(); + return vTrimWidget; } void VirtualJoystickWidget::onButtonChange(bool checked) @@ -523,3 +460,57 @@ void VirtualJoystickWidget::updateNodeValueLabels() if (nodeLabelY) nodeLabelY->setText(QString("%1").arg((qreal)node->getY() * -100 + getTrimValue(1) / 5, 2, 'f', 0)); } + +void VirtualJoystickWidget::onGsMouseEvent(QGraphicsSceneMouseEvent * event) +{ + if (!node) + return; + + //qDebug() << event->type() << event->scenePos() << event->buttons() << event->isAccepted() << m_stickPressed; + if (event->type() == QEvent::GraphicsSceneMouseRelease && m_stickPressed) { + node->setPressed(false); + m_stickPressed = false; + return; + } + + if (!(event->buttons() & Qt::LeftButton)) + return; + + if (event->type() == QEvent::GraphicsSceneMousePress) { + node->setPressed(true); + m_stickPressed = true; + } + else if (!m_stickPressed || event->type() != QEvent::GraphicsSceneMouseMove) { + return; + } + node->setPos(event->scenePos()); +} + + +/* + * CustomGraphicsScene +*/ + +void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * event) +{ + QGraphicsScene::mousePressEvent(event); + if (!event->isAccepted()) { + event->accept(); + emit mouseEvent(event); + } +} + +void CustomGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) +{ + QGraphicsScene::mouseReleaseEvent(event); + emit mouseEvent(event); +} + +void CustomGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * event) +{ + QGraphicsScene::mouseMoveEvent(event); + if (!event->isAccepted() && (event->buttons() & Qt::LeftButton)) { + event->accept(); + emit mouseEvent(event); + } +} diff --git a/companion/src/simulation/widgets/virtualjoystickwidget.h b/companion/src/simulation/widgets/virtualjoystickwidget.h index 478f6398e2..69faeddc17 100644 --- a/companion/src/simulation/widgets/virtualjoystickwidget.h +++ b/companion/src/simulation/widgets/virtualjoystickwidget.h @@ -27,24 +27,18 @@ #include #include #include -#include +#include #include +class CustomGraphicsScene; class Node; -class SliderWidget; +class RadioTrimWidget; class VirtualJoystickWidget : public QWidget { Q_OBJECT public: - enum TrimAxes { - TRIM_AXIS_L_X = 0, - TRIM_AXIS_L_Y, - TRIM_AXIS_R_Y, - TRIM_AXIS_R_X, - }; - enum ConstraintTypes { HOLD_X = 0, HOLD_Y, @@ -73,38 +67,60 @@ class VirtualJoystickWidget : public QWidget virtual void resizeEvent(QResizeEvent *event); signals: - void trimButtonPressed(int which); - void trimButtonReleased(); - void trimSliderMoved(int which, int value); + void trimButtonPressed(int index); + void trimButtonReleased(int index); + void trimSliderMoved(int index, int value); protected slots: - void onTrimPressed(); - void onSliderChange(int value); void onButtonChange(bool checked); void updateNodeValueLabels(); + void onGsMouseEvent(QGraphicsSceneMouseEvent * event); protected: void setSize(const QSize & size, const QSize &); - QWidget * createTrimWidget(QChar type); - QPushButton * createButtonWidget(int type); + RadioTrimWidget * createTrimWidget(QChar type); + QToolButton * createButtonWidget(int type); QLayout * createNodeValueLayout(QChar type, QLabel *& valLabel); int getTrimSliderType(QChar type); int getTrimButtonType(QChar type, int pos); - SliderWidget * getTrimSlider(int which); + RadioTrimWidget * getTrimWidget(int which); QChar stickSide; QSize prefSize; QGridLayout * layout; QGraphicsView * gv; - QGraphicsScene * scene; + CustomGraphicsScene * scene; Node * node; - SliderWidget * hTrimSlider, * vTrimSlider; - QPushButton * btnHoldX, * btnHoldY; - QPushButton * btnFixX, * btnFixY; + RadioTrimWidget * hTrimWidget; + RadioTrimWidget * vTrimWidget; + QToolButton * btnHoldX, * btnHoldY; + QToolButton * btnFixX, * btnFixY; QLabel * nodeLabelX, * nodeLabelY; QSize extraSize; float ar; // aspect ratio + bool m_stickPressed; +}; + +/* + * Custom GraphicsScene for mouse handling +*/ +class CustomGraphicsScene : public QGraphicsScene +{ + Q_OBJECT + + public: + CustomGraphicsScene(QObject *parent = Q_NULLPTR) : + QGraphicsScene(parent) + {} + + signals: + void mouseEvent(QGraphicsSceneMouseEvent * event); + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent * event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); }; #endif // VIRTUALJOYSTICKWIDGET_H diff --git a/radio/src/targets/simu/opentxsimulator.cpp b/radio/src/targets/simu/opentxsimulator.cpp index b0d1973def..2fd639e4dc 100644 --- a/radio/src/targets/simu/opentxsimulator.cpp +++ b/radio/src/targets/simu/opentxsimulator.cpp @@ -134,7 +134,7 @@ void OpenTxSimulator::getTrims(Trims & trims) { uint8_t phase = getFlightMode(); trims.extended = hasExtendedTrims(); - for (uint8_t idx=0; idx<4; idx++) { + for (uint8_t idx=0; idx < CPN_MAX_STICKS + CPN_MAX_AUX_TRIMS; idx++) { trims.values[idx] = getTrimValue(getTrimFlightMode(phase, idx), idx); }