[Simulator] Asynchronous SimulatorInterface & a few new features. (#4738)
* [Simulator] Create RadioKeyWidget class for UI buttons & refactor ButtonsWidget; Refactor SimulatedUIWidget (and subtypes) to use new RadioKeyWidgets/ButtonsWidget; Centralize help text for key mappings and get creative with some icons; Simplify some radio UI setups with rectangular buttons.
* [Simulator] Convert all simulator data I/O to signals/slots mechanism:
* SimulatorInterface/OpenTxSimulator:
- Now inherits from QObject to allow signal/slot interface;
- Allows data exchange on a per-item basis (eg. each I/O value is treated separately instead of sending whole arrays or structs of data);
- Checks for data changes and only emits signals when change is detected (GUI can now assume only new values are being sent);
- Manages its own 10ms timer (doesn't rely on GUI to do that);
- Sends "heartbeat" signals @ 1Hz for status monitoring;
* Simulator GUI:
- All data is exchanged between GUI elements as well as SimulatorInterface via signals/slots using standardized methods;
- Data is sent immediately, and only, when actually changed (eg. a control is moved) instead of in bulk at specific time intervals;
- Similarly, an asynchronous method is used for reading incoming data, w/out timers or loops;
- Improve VirtualJoystickWidget to be more encapsulated and configurable;
- Pause telemetry simulator if window is hidden;
* [Simulator] Move SimulatorInterface instance to separate thread, ensure safe asynchronous operations & proper timer interactions; Protect/remove some functions, & reorganize the order (cosmetics).
* [Simulator] Traces are now delivered to OpenTxSimulator and one or more QIODevice(s) can be added as recipient(s); Add SimulatorInterface::getCapability() for compile-time settings; Remove reversed POT1/SLIDER1 mixer exception (Taranis) requirement for SIMU; Fix plus/minus key delay on wheel event w/out encoder.
* [Simulator] Add current knob/slider/trim input value in tool-tips (KnobWidget and SliderWidget).
* [Simulator] Fix trims widget internal value not properly updating, and remove trim influence on virtual joystick X/Y value display (closes #4671).
* [SimulatorInterface] Add handling of transmitter input voltage, including a rough conversion of volts to ADC value for different boards, and default battery volts lookup function; Clear analogs array before starting.
* [Simulator] Add SimulatorInterface::init() method to separate pre-startup tasks; Report actual trim range, not just extended on/off; Change how radio widget states are restored; VirtualJoystickWidget: Connect trim changes directly from simulator, connect joystick events directly, report stick mode directly instead of setting values/constraints externally.
* [Simulator] Calculate default Tx V input based on configured range in radio settings (or warning V+2 for radios which don't support a range).
* [Simulator] Add functional aux. trims for Horus (closes #4699).
* [Companion] Remove problematic QMessageLogContext from AppDebugMessageHandler::messageOutput().
* [Simulator] Prevent trim change via slider if disabled for flight mode (closes #4600).
* [OpenTxSimulator] Fixes for Qt < 5.4.
* [OpenTxSimulator] Fix slot name.
This commit is contained in:
committed by
Bertrand Songis
parent
36bb951314
commit
57dc0159d6
@@ -22,47 +22,12 @@
|
||||
#define _BUTTONSWIDGET_H_
|
||||
|
||||
#include "radiouiaction.h"
|
||||
#include "radiokeywidget.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QtGui>
|
||||
#include <QStyleOption>
|
||||
|
||||
class Area : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Area(const QPolygon & polygon, const QString &image, RadioUiAction * action = NULL, QObject * parent = NULL):
|
||||
QObject(parent),
|
||||
polygon(polygon),
|
||||
imgFile(image),
|
||||
action(action)
|
||||
{
|
||||
if (action)
|
||||
connect(action, &RadioUiAction::toggled, this, &Area::onActionToggled);
|
||||
}
|
||||
|
||||
bool contains(int x, int y)
|
||||
{
|
||||
return polygon.containsPoint(QPoint(x, y), Qt::OddEvenFill);
|
||||
}
|
||||
|
||||
void onActionToggled(int, bool active)
|
||||
{
|
||||
if (active)
|
||||
emit imageChanged(imgFile);
|
||||
else
|
||||
emit imageChanged("");
|
||||
}
|
||||
|
||||
QPolygon polygon;
|
||||
QString imgFile;
|
||||
RadioUiAction * action;
|
||||
|
||||
signals:
|
||||
void imageChanged(const QString image);
|
||||
};
|
||||
|
||||
class ButtonsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -80,18 +45,17 @@ class ButtonsWidget : public QWidget
|
||||
QWidget::setStyleSheet(sheet);
|
||||
}
|
||||
|
||||
void addArea(int x1, int y1, int x2, int y2, const char * image, RadioUiAction * action = NULL)
|
||||
RadioKeyWidget * addArea(const QRect & rect, const char * image, RadioUiAction * action = NULL)
|
||||
{
|
||||
QPolygon polygon;
|
||||
polygon.setPoints(4, x1, y1, x1, y2, x2, y2, x2, y1);
|
||||
addArea(polygon, image, action);
|
||||
return addArea(QPolygon(rect), image, action);
|
||||
}
|
||||
|
||||
void addArea(const QPolygon & polygon, const char * image, RadioUiAction * action = NULL)
|
||||
RadioKeyWidget * addArea(const QPolygon & polygon, const char * image, RadioUiAction * action = NULL)
|
||||
{
|
||||
Area * area = new Area(polygon, image, action, this);
|
||||
areas.push_back(area);
|
||||
connect(area, &Area::imageChanged, this, &ButtonsWidget::setBitmap);
|
||||
RadioKeyWidget * btn = new RadioKeyWidget(polygon, image, action, this);
|
||||
m_buttons.append(btn);
|
||||
connect(btn, &RadioKeyWidget::imageChanged, this, &ButtonsWidget::setBitmap);
|
||||
return btn;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -113,16 +77,14 @@ class ButtonsWidget : public QWidget
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(Area * area, areas) {
|
||||
if (!area->action)
|
||||
continue;
|
||||
if (area->contains(event->x(), event->y())) {
|
||||
area->action->trigger(press);
|
||||
foreach(RadioKeyWidget * key, m_buttons) {
|
||||
if (key->contains(event->pos())) {
|
||||
key->toggle(press);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
else if (area->action->isActive()) {
|
||||
area->action->trigger(false);
|
||||
else if (key->getValue()) {
|
||||
key->toggle(false);
|
||||
}
|
||||
}
|
||||
event->ignore();
|
||||
@@ -145,7 +107,7 @@ class ButtonsWidget : public QWidget
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
QList<Area *> areas;
|
||||
QList<RadioKeyWidget *> m_buttons;
|
||||
QString defaultStyleSheet;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 RADIOKEYWIDGET_H
|
||||
#define RADIOKEYWIDGET_H
|
||||
|
||||
#include "radiouiaction.h"
|
||||
#include "radiowidget.h"
|
||||
|
||||
class RadioKeyWidget : public RadioWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit RadioKeyWidget(const QPolygon & polygon, const QString &image, RadioUiAction * action = NULL, QWidget * parent = NULL, Qt::WindowFlags f = Qt::WindowFlags()):
|
||||
RadioWidget(action, parent, f),
|
||||
polygon(polygon),
|
||||
imgFile(image)
|
||||
{
|
||||
m_type = RADIO_WIDGET_KEY;
|
||||
setValue(0);
|
||||
hide(); // we're a "virtual" button for now
|
||||
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
}
|
||||
|
||||
virtual void setAction(RadioUiAction * action)
|
||||
{
|
||||
if (m_action)
|
||||
disconnect(m_action, 0, this, 0);
|
||||
RadioWidget::setAction(action);
|
||||
if (m_action)
|
||||
connect(m_action, &RadioUiAction::toggled, this, &RadioKeyWidget::onActionToggled);
|
||||
}
|
||||
|
||||
virtual int getValue() const
|
||||
{
|
||||
return (m_action && m_action->isActive()) ? 1 : 0;
|
||||
}
|
||||
|
||||
void press() {
|
||||
if (m_action)
|
||||
m_action->trigger(true);
|
||||
}
|
||||
|
||||
void release() {
|
||||
if (m_action)
|
||||
m_action->trigger(false);
|
||||
}
|
||||
|
||||
void toggle(bool down)
|
||||
{
|
||||
if (down)
|
||||
press();
|
||||
else
|
||||
release();
|
||||
}
|
||||
|
||||
bool contains(const QPoint & point)
|
||||
{
|
||||
return polygon.containsPoint(point, Qt::OddEvenFill);
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
void imageChanged(const QString image);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onActionToggled(int index, bool active)
|
||||
{
|
||||
RadioWidget::onActionToggled(index, active);
|
||||
emit imageChanged(active ? imgFile : "");
|
||||
}
|
||||
|
||||
QPolygon polygon;
|
||||
QString imgFile;
|
||||
|
||||
};
|
||||
|
||||
#endif // RADIOKEYWIDGET_H
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <QDial>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include <QToolTip>
|
||||
#include <math.h>
|
||||
|
||||
class RadioKnobWidget : public RadioWidget
|
||||
@@ -65,7 +65,6 @@ class RadioKnobWidget : public RadioWidget
|
||||
|
||||
Board::PotType m_potType;
|
||||
|
||||
|
||||
class KnobWidget : public QDial
|
||||
{
|
||||
public:
|
||||
@@ -73,6 +72,8 @@ class RadioKnobWidget : public RadioWidget
|
||||
explicit KnobWidget(Board::PotType type, QWidget * parent = 0):
|
||||
QDial(parent)
|
||||
{
|
||||
m_toolTip = tr("<p>Value (input): <b>%1</b></p>");
|
||||
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
setFixedSize(QSize(42, 42));
|
||||
setNotchesVisible(true);
|
||||
@@ -88,7 +89,7 @@ class RadioKnobWidget : public RadioWidget
|
||||
}
|
||||
else {
|
||||
m_stepSize = 1;
|
||||
setToolTip(tr("Right-double-click to reset to center."));
|
||||
m_toolTip.append(tr("Right-double-click to reset to center."));
|
||||
setMinimum(-1024);
|
||||
setMaximum(1024);
|
||||
setPageStep(128);
|
||||
@@ -104,6 +105,19 @@ class RadioKnobWidget : public RadioWidget
|
||||
QDial::setValue(value);
|
||||
}
|
||||
|
||||
|
||||
bool event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
QHelpEvent * helpEvent = static_cast<QHelpEvent *>(event);
|
||||
if (helpEvent) {
|
||||
QToolTip::showText(helpEvent->globalPos(), m_toolTip.arg(this->value()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
if (m_stepSize == 1 && event->button() == Qt::RightButton && event->type() == QEvent::MouseButtonDblClick) {
|
||||
@@ -129,6 +143,7 @@ class RadioKnobWidget : public RadioWidget
|
||||
}
|
||||
|
||||
quint16 m_stepSize;
|
||||
QString m_toolTip;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -110,9 +110,8 @@ class RadioSwitchWidget : public RadioWidget
|
||||
void setToggleLocked(bool lock)
|
||||
{
|
||||
if (m_flags != (quint16)lock) {
|
||||
m_flags = lock;
|
||||
setFlags((quint16)lock);
|
||||
setValue((int)lock);
|
||||
emit flagsChanged(m_flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define _RADIOTRIMWIDGET_H_
|
||||
|
||||
#include "radiowidget.h"
|
||||
#include "boards.h"
|
||||
#include "sliderwidget.h"
|
||||
|
||||
#include <QToolButton>
|
||||
@@ -38,12 +39,6 @@ class RadioTrimWidget : public RadioWidget
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -58,11 +53,27 @@ class RadioTrimWidget : public RadioWidget
|
||||
m_slider->setRange(min, max);
|
||||
}
|
||||
|
||||
signals:
|
||||
void setTrimRangeQual(const int index, const int min, const int max)
|
||||
{
|
||||
if (index == m_index || index == Board::TRIM_AXIS_COUNT)
|
||||
setTrimRange(min, max);
|
||||
}
|
||||
|
||||
void trimButtonPressed(int index);
|
||||
void trimButtonReleased(int index);
|
||||
void trimSliderMoved(int index, int value);
|
||||
void setTrimValue(const int index, const int value)
|
||||
{
|
||||
if (index == m_index || index == Board::TRIM_AXIS_COUNT)
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
void setValue(const int & value)
|
||||
{
|
||||
if (sender() && qobject_cast<SliderWidget *>(sender())) {
|
||||
RadioWidget::setValue(value);
|
||||
}
|
||||
else if (m_slider) {
|
||||
m_slider->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected slots:
|
||||
|
||||
@@ -75,20 +86,20 @@ class RadioTrimWidget : public RadioWidget
|
||||
setTrimRange(-125, 125);
|
||||
setIndices();
|
||||
|
||||
QSize btnIcnSz(12, 12);
|
||||
const QSize btnSz(18, 18);
|
||||
QWidget * trimWidget = new QWidget(this);
|
||||
QBoxLayout * trimLayout = new QVBoxLayout(trimWidget);
|
||||
trimLayout->setSpacing(5);
|
||||
trimLayout->setContentsMargins(8, 8, 8, 8);
|
||||
trimLayout->setSpacing(4);
|
||||
QToolButton * trimBtnInc = new QToolButton(trimWidget);
|
||||
trimBtnInc->setIconSize(btnIcnSz);
|
||||
trimBtnInc->setMaximumSize(btnSz);
|
||||
QToolButton * trimBtnDec = new QToolButton(trimWidget);
|
||||
trimBtnDec->setIconSize(btnIcnSz);
|
||||
trimBtnDec->setMaximumSize(btnSz);
|
||||
|
||||
Qt::Alignment algn;
|
||||
if (orientation == Qt::Horizontal) {
|
||||
trimWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
trimLayout->setDirection(QBoxLayout::RightToLeft);
|
||||
trimLayout->setContentsMargins(0, 8, 0, 8);
|
||||
trimBtnInc->setArrowType(Qt::RightArrow);
|
||||
trimBtnDec->setArrowType(Qt::LeftArrow);
|
||||
algn = Qt::AlignVCenter;
|
||||
@@ -96,6 +107,7 @@ class RadioTrimWidget : public RadioWidget
|
||||
else {
|
||||
trimWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
trimLayout->setDirection(QBoxLayout::TopToBottom);
|
||||
trimLayout->setContentsMargins(8, 0, 8, 0);
|
||||
trimBtnInc->setArrowType(Qt::UpArrow);
|
||||
trimBtnDec->setArrowType(Qt::DownArrow);
|
||||
algn = Qt::AlignHCenter;
|
||||
@@ -107,21 +119,11 @@ class RadioTrimWidget : public RadioWidget
|
||||
|
||||
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);
|
||||
connect(m_slider, &SliderWidget::valueChanged, this, &RadioTrimWidget::setValue);
|
||||
connect(trimBtnInc, &QToolButton::pressed, [this]() { emit valueChange(m_type, m_btnIncIndex, RADIO_TRIM_BTN_ON); });
|
||||
connect(trimBtnInc, &QToolButton::released, [this]() { emit valueChange(m_type, m_btnIncIndex, RADIO_TRIM_BTN_OFF); });
|
||||
connect(trimBtnDec, &QToolButton::pressed, [this]() { emit valueChange(m_type, m_btnDecIndex, RADIO_TRIM_BTN_ON); });
|
||||
connect(trimBtnDec, &QToolButton::released, [this]() { emit valueChange(m_type, m_btnDecIndex, RADIO_TRIM_BTN_OFF); });
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -130,5 +132,4 @@ class RadioTrimWidget : public RadioWidget
|
||||
int m_btnIncIndex;
|
||||
};
|
||||
|
||||
|
||||
#endif // _RADIOTRIMWIDGET_H_
|
||||
|
||||
@@ -18,51 +18,66 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "radiouiaction.h"
|
||||
#include "radiowidget.h"
|
||||
|
||||
RadioWidget::RadioWidget(QWidget * parent, Qt::WindowFlags f) :
|
||||
QWidget(parent, f),
|
||||
m_gridLayout(NULL),
|
||||
m_controlWidget(NULL),
|
||||
m_nameLabel(NULL),
|
||||
m_action(NULL),
|
||||
m_value(0),
|
||||
m_flags(0),
|
||||
m_invertValue(false),
|
||||
m_valueReset(false),
|
||||
m_showLabel(false),
|
||||
m_labelText(""),
|
||||
m_type(RADIO_WIDGET_NONE)
|
||||
m_labelText("")
|
||||
{
|
||||
init();
|
||||
qRegisterMetaType<RadioWidgetState>();
|
||||
setIndex(-1);
|
||||
setType(RADIO_WIDGET_NONE);
|
||||
}
|
||||
|
||||
RadioWidget::RadioWidget(RadioUiAction * action, QWidget * parent, Qt::WindowFlags f) :
|
||||
RadioWidget(parent, f)
|
||||
{
|
||||
setAction(action);
|
||||
}
|
||||
|
||||
RadioWidget::RadioWidget(const QString & labelText, int value, QWidget * parent, Qt::WindowFlags f) :
|
||||
QWidget(parent, f),
|
||||
m_value(value),
|
||||
m_flags(0),
|
||||
m_invertValue(false),
|
||||
m_showLabel(true),
|
||||
m_labelText(labelText),
|
||||
m_type(RADIO_WIDGET_NONE)
|
||||
RadioWidget(parent, f)
|
||||
{
|
||||
init();
|
||||
setValue(value);
|
||||
setLabelText(labelText);
|
||||
}
|
||||
|
||||
void RadioWidget::setIndex(int index)
|
||||
void RadioWidget::setIndex(const int & index)
|
||||
{
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
void RadioWidget::setInvertValue(bool invertValue)
|
||||
void RadioWidget::setType(const RadioWidgetType & type)
|
||||
{
|
||||
m_invertValue = invertValue;
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
void RadioWidget::setValue(int value)
|
||||
void RadioWidget::setValue(const int & value)
|
||||
{
|
||||
if (value != m_value) {
|
||||
if (value != m_value || m_valueReset) {
|
||||
m_value = value;
|
||||
m_valueReset = false;
|
||||
emit valueChanged(value);
|
||||
emit valueChange(m_type, m_index, value);
|
||||
}
|
||||
}
|
||||
|
||||
void RadioWidget::setFlags(quint16 flags)
|
||||
void RadioWidget::setValueQual(const RadioWidget::RadioWidgetType & type, const int & index, const int & value)
|
||||
{
|
||||
if (type == m_type && index == m_index)
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
void RadioWidget::setFlags(const quint16 & flags)
|
||||
{
|
||||
if (flags != m_flags) {
|
||||
m_flags = flags;
|
||||
@@ -70,7 +85,7 @@ void RadioWidget::setFlags(quint16 flags)
|
||||
}
|
||||
}
|
||||
|
||||
void RadioWidget::setShowLabel(bool show)
|
||||
void RadioWidget::setShowLabel(const bool show)
|
||||
{
|
||||
if (show != m_showLabel) {
|
||||
m_showLabel = show;
|
||||
@@ -85,13 +100,12 @@ void RadioWidget::setLabelText(const QString & labelText, bool showLabel)
|
||||
addLabel();
|
||||
}
|
||||
|
||||
void RadioWidget::setStateData(const QByteArray & data)
|
||||
void RadioWidget::setStateData(const RadioWidgetState & state)
|
||||
{
|
||||
RadioWidgetState state;
|
||||
QDataStream stream(data);
|
||||
stream >> state;
|
||||
if (state.type != m_type || state.index != m_index)
|
||||
return;
|
||||
|
||||
//setIndex(state.index);
|
||||
m_valueReset = true;
|
||||
setValue(state.value);
|
||||
setFlags(state.flags);
|
||||
}
|
||||
@@ -109,9 +123,26 @@ void RadioWidget::changeVisibility(bool visible)
|
||||
}
|
||||
}
|
||||
|
||||
void RadioWidget::setAction(RadioUiAction * action)
|
||||
{
|
||||
if (m_action) {
|
||||
disconnect(m_action, 0, this, 0);
|
||||
delete m_action;
|
||||
m_action = NULL;
|
||||
}
|
||||
m_action = action;
|
||||
|
||||
if (m_action) {
|
||||
if (m_action->getIndex() > -1)
|
||||
setIndex(m_action->getIndex());
|
||||
connect(m_action, &RadioUiAction::toggled, this, &RadioWidget::onActionToggled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int RadioWidget::getValue() const
|
||||
{
|
||||
return m_value * (m_invertValue ? -1 : 1);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
int RadioWidget::getIndex() const
|
||||
@@ -134,25 +165,34 @@ QByteArray RadioWidget::getStateData() const
|
||||
|
||||
RadioWidget::RadioWidgetState RadioWidget::getState() const
|
||||
{
|
||||
return RadioWidgetState(quint8(m_type), qint8(m_index), qint16(m_value), quint16(m_flags));;
|
||||
return RadioWidgetState(quint8(m_type), qint8(m_index), qint16(m_value), quint16(m_flags));
|
||||
}
|
||||
|
||||
void RadioWidget::init()
|
||||
RadioUiAction * RadioWidget::getAction() const
|
||||
{
|
||||
setIndex(0);
|
||||
m_controlWidget = NULL;
|
||||
m_nameLabel = NULL;
|
||||
return m_action;
|
||||
}
|
||||
|
||||
m_gridLayout= new QGridLayout(this);
|
||||
void RadioWidget::onActionToggled(int index, bool active)
|
||||
{
|
||||
emit valueChange(m_type, index, getValue());
|
||||
}
|
||||
|
||||
|
||||
void RadioWidget::addLayout()
|
||||
{
|
||||
if (m_gridLayout)
|
||||
return;
|
||||
|
||||
m_gridLayout = new QGridLayout(this);
|
||||
m_gridLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_gridLayout->setVerticalSpacing(4);
|
||||
m_gridLayout->setHorizontalSpacing(0);
|
||||
|
||||
addLabel();
|
||||
}
|
||||
|
||||
void RadioWidget::addLabel()
|
||||
{
|
||||
addLayout();
|
||||
if (m_nameLabel) {
|
||||
m_gridLayout->removeWidget(m_nameLabel);
|
||||
m_nameLabel->deleteLater();
|
||||
@@ -168,6 +208,7 @@ void RadioWidget::addLabel()
|
||||
|
||||
void RadioWidget::setWidget(QWidget * widget, Qt::Alignment align)
|
||||
{
|
||||
addLayout();
|
||||
if (m_controlWidget) {
|
||||
m_gridLayout->removeWidget(m_controlWidget);
|
||||
m_controlWidget->deleteLater();
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#define RADIO_WIDGET_STATE_VERSION 1
|
||||
|
||||
class RadioUiAction;
|
||||
|
||||
class RadioWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -41,10 +43,14 @@ 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
|
||||
RADIO_WIDGET_TRIM, // trim axis, usually 2 buttons & slider
|
||||
RADIO_WIDGET_STICK, // actually one axis of a stick
|
||||
RADIO_WIDGET_KEY, // UI key/pushbutton
|
||||
RADIO_WIDGET_ENUM_COUNT
|
||||
};
|
||||
|
||||
enum RadioTrimWidgetButtonStates { RADIO_TRIM_BTN_ON = 1024, RADIO_TRIM_BTN_OFF = -1024 };
|
||||
|
||||
struct RadioWidgetState {
|
||||
public:
|
||||
RadioWidgetState(quint8 type = 0, qint8 index = 0, qint16 value = 0, quint16 flags = 0) :
|
||||
@@ -65,49 +71,58 @@ class RadioWidget : public QWidget
|
||||
quint8 _version = RADIO_WIDGET_STATE_VERSION; // structure definition version
|
||||
};
|
||||
|
||||
explicit RadioWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
||||
explicit RadioWidget(const QString &labelText, int value = 0, QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
||||
|
||||
void setIndex(int index);
|
||||
void setInvertValue(bool invertValue);
|
||||
void setValue(int value);
|
||||
void setFlags(quint16 flags);
|
||||
void setShowLabel(bool show);
|
||||
void setLabelText(const QString &labelText, bool showLabel = true);
|
||||
void setStateData(const QByteArray & data);
|
||||
void changeVisibility(bool visible);
|
||||
explicit RadioWidget(QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
||||
explicit RadioWidget(RadioUiAction * action = NULL, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
||||
explicit RadioWidget(const QString & labelText, int value = 0, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
||||
|
||||
virtual int getValue() const;
|
||||
int getIndex() const;
|
||||
int getType() const;
|
||||
QByteArray getStateData() const;
|
||||
RadioWidgetState getState() const;
|
||||
virtual int getIndex() const;
|
||||
virtual int getType() const;
|
||||
virtual QByteArray getStateData() const;
|
||||
virtual RadioWidgetState getState() const;
|
||||
virtual RadioUiAction * getAction() const;
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void setIndex(const int & index);
|
||||
virtual void setType(const RadioWidgetType & type);
|
||||
virtual void setValue(const int & value);
|
||||
virtual void setValueQual(const RadioWidgetType & type, const int & index, const int & value);
|
||||
virtual void setFlags(const quint16 & flags);
|
||||
virtual void setShowLabel(const bool show);
|
||||
virtual void setLabelText(const QString & labelText, bool showLabel = true);
|
||||
virtual void setStateData(const RadioWidgetState & state);
|
||||
virtual void changeVisibility(bool visible);
|
||||
virtual void setAction(RadioUiAction * action);
|
||||
|
||||
signals:
|
||||
|
||||
void valueChange(const RadioWidgetType type, const int index, int value);
|
||||
void valueChanged(const int value);
|
||||
void flagsChanged(const quint16 flags);
|
||||
|
||||
protected:
|
||||
|
||||
void init();
|
||||
void addLayout();
|
||||
void addLabel();
|
||||
void setWidget(QWidget * widget = NULL, Qt::Alignment align = Qt::AlignHCenter);
|
||||
|
||||
int m_value;
|
||||
int m_index;
|
||||
quint16 m_flags;
|
||||
bool m_invertValue;
|
||||
bool m_showLabel;
|
||||
QString m_labelText;
|
||||
RadioWidgetType m_type;
|
||||
|
||||
private:
|
||||
virtual void onActionToggled(int index, bool active);
|
||||
|
||||
QGridLayout * m_gridLayout;
|
||||
QWidget * m_controlWidget;
|
||||
QLabel * m_nameLabel;
|
||||
RadioUiAction * m_action;
|
||||
|
||||
signals:
|
||||
|
||||
void valueChanged(int value);
|
||||
void flagsChanged(quint16 flags);
|
||||
int m_value;
|
||||
int m_index;
|
||||
quint16 m_flags;
|
||||
bool m_valueReset;
|
||||
bool m_showLabel;
|
||||
QString m_labelText;
|
||||
RadioWidgetType m_type;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(RadioWidget::RadioWidgetState)
|
||||
|
||||
#endif // _RADIOWIDGET_H_
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <QtGui>
|
||||
#include <QSlider>
|
||||
#include <QToolTip>
|
||||
|
||||
class SliderWidget : public QSlider
|
||||
{
|
||||
@@ -33,20 +34,34 @@ class SliderWidget : public QSlider
|
||||
explicit SliderWidget(QWidget * parent = 0):
|
||||
QSlider(parent)
|
||||
{
|
||||
setToolTip(tr("Right-double-click to reset to center."));
|
||||
m_toolTip = tr("<p>Value (input): <b>%1</b></p>") % tr("Right-double-click to reset to center.");
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
void mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton && event->type() == QEvent::MouseButtonDblClick) {
|
||||
setValue(0);
|
||||
emit sliderMoved(0);
|
||||
event->accept();
|
||||
}
|
||||
QSlider::mousePressEvent(event);
|
||||
}
|
||||
bool event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
QHelpEvent * helpEvent = static_cast<QHelpEvent *>(event);
|
||||
if (helpEvent) {
|
||||
QToolTip::showText(helpEvent->globalPos(), m_toolTip.arg(this->value()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton && event->type() == QEvent::MouseButtonDblClick) {
|
||||
setValue(0);
|
||||
emit sliderMoved(0);
|
||||
event->accept();
|
||||
}
|
||||
QSlider::mousePressEvent(event);
|
||||
}
|
||||
|
||||
QString m_toolTip;
|
||||
};
|
||||
|
||||
#endif // _SLIDERWIDGET_H_
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#define GBALL_SIZE 25
|
||||
#define GBALL_SIZE_MN 20
|
||||
#define GBALL_SIZE_MX 35
|
||||
#define CENTER_INTERVAL 50 // ms
|
||||
|
||||
#include "virtualjoystickwidget.h"
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
#include "modeledit/node.h"
|
||||
#include "helpers.h"
|
||||
#include "radiotrimwidget.h"
|
||||
@@ -43,6 +43,7 @@ VirtualJoystickWidget::VirtualJoystickWidget(QWidget *parent, QChar side, bool s
|
||||
btnFixY(NULL),
|
||||
nodeLabelX(NULL),
|
||||
nodeLabelY(NULL),
|
||||
m_stickScale(1024),
|
||||
m_stickPressed(false)
|
||||
{
|
||||
ar = (float)size.width() / size.height();
|
||||
@@ -135,12 +136,18 @@ VirtualJoystickWidget::VirtualJoystickWidget(QWidget *parent, QChar side, bool s
|
||||
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); // r4 c0-4: bot v spacer
|
||||
|
||||
connect(node, &Node::xChanged, this, &VirtualJoystickWidget::updateNodeValueLabels);
|
||||
connect(node, &Node::yChanged, this, &VirtualJoystickWidget::updateNodeValueLabels);
|
||||
setStickIndices(getStickIndex('H'), getStickIndex('V'));
|
||||
|
||||
connect(node, &Node::xChanged, this, &VirtualJoystickWidget::onNodeXChanged);
|
||||
connect(node, &Node::yChanged, this, &VirtualJoystickWidget::onNodeYChanged);
|
||||
|
||||
connect(scene, &CustomGraphicsScene::mouseEvent, this, &VirtualJoystickWidget::onGsMouseEvent);
|
||||
|
||||
setSize(prefSize, frameSize());
|
||||
|
||||
centerStickTimer.setInterval(CENTER_INTERVAL);
|
||||
connect(¢erStickTimer, &QTimer::timeout, this, &VirtualJoystickWidget::centerStick);
|
||||
centerStickTimer.start();
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setStickX(qreal x)
|
||||
@@ -158,6 +165,31 @@ void VirtualJoystickWidget::setStickPos(QPointF xy)
|
||||
node->setPos(xy);
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setStickAxisValue(int index, int value)
|
||||
{
|
||||
using namespace Board;
|
||||
qreal rvalue = value / 1024.0f;
|
||||
|
||||
switch (index) {
|
||||
case STICK_AXIS_LH :
|
||||
if (stickSide == 'L')
|
||||
setStickX(rvalue);
|
||||
break;
|
||||
case STICK_AXIS_RH :
|
||||
if (stickSide == 'R')
|
||||
setStickX(rvalue);
|
||||
break;
|
||||
case STICK_AXIS_LV :
|
||||
if (stickSide == 'L')
|
||||
setStickY(rvalue);
|
||||
break;
|
||||
case STICK_AXIS_RV :
|
||||
if (stickSide == 'R')
|
||||
setStickY(rvalue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::centerStick()
|
||||
{
|
||||
node->stepToCenter();
|
||||
@@ -178,20 +210,55 @@ QPointF VirtualJoystickWidget::getStickPos()
|
||||
return QPointF(node->getX(), node->getY());
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setTrimValue(int which, int value)
|
||||
void VirtualJoystickWidget::setTrimsRange(int min, int max)
|
||||
{
|
||||
RadioTrimWidget * trim = getTrimWidget(which);
|
||||
if (hTrimWidget)
|
||||
hTrimWidget->setTrimRange(min, max);
|
||||
if (vTrimWidget)
|
||||
vTrimWidget->setTrimRange(min, max);
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setTrimsRange(int rng)
|
||||
{
|
||||
setTrimsRange(-rng, rng);
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setTrimRange(int index, int min, int max)
|
||||
{
|
||||
if (index == Board::TRIM_AXIS_COUNT) {
|
||||
setTrimsRange(min, max);
|
||||
return;
|
||||
}
|
||||
RadioTrimWidget * trim = getTrimWidget(index);
|
||||
if (trim) {
|
||||
trim->setTrimRange(min, max);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setTrimValue(int index, int value)
|
||||
{
|
||||
RadioTrimWidget * trim = getTrimWidget(index);
|
||||
if (trim) {
|
||||
trim->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setTrimRange(int which, int min, int max)
|
||||
int VirtualJoystickWidget::getStickScale() const
|
||||
{
|
||||
RadioTrimWidget * trim = getTrimWidget(which);
|
||||
if (trim) {
|
||||
trim->setTrimRange(min, max);
|
||||
}
|
||||
return m_stickScale;
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setStickScale(int stickScale)
|
||||
{
|
||||
m_stickScale = stickScale;
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setWidgetValue(const RadioWidget::RadioWidgetType type, const int index, const int value)
|
||||
{
|
||||
if (type == RadioWidget::RADIO_WIDGET_TRIM)
|
||||
setTrimValue(index, value);
|
||||
else if (type == RadioWidget::RADIO_WIDGET_STICK)
|
||||
setStickAxisValue(index, value);
|
||||
}
|
||||
|
||||
int VirtualJoystickWidget::getTrimValue(int which)
|
||||
@@ -203,27 +270,25 @@ int VirtualJoystickWidget::getTrimValue(int which)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setStickConstraint(int which, bool active)
|
||||
void VirtualJoystickWidget::setStickIndices(int xIdx, int yIdx)
|
||||
{
|
||||
if (btnHoldX == NULL)
|
||||
m_xIndex = xIdx;
|
||||
m_yIndex = yIdx;
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setStickConstraint(quint8 index, bool active)
|
||||
{
|
||||
if (btnHoldX == NULL || !index)
|
||||
return; // no buttons
|
||||
|
||||
switch (which) {
|
||||
case HOLD_X:
|
||||
btnHoldX->setChecked(active);
|
||||
break;
|
||||
case HOLD_Y:
|
||||
btnHoldY->setChecked(active);
|
||||
break;
|
||||
case FIX_X:
|
||||
btnFixX->setChecked(active);
|
||||
break;
|
||||
case FIX_Y:
|
||||
btnFixY->setChecked(active);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (index & HOLD_X)
|
||||
btnHoldX->setChecked(active);
|
||||
if (index & HOLD_Y)
|
||||
btnHoldY->setChecked(active);
|
||||
if (index & FIX_X)
|
||||
btnFixX->setChecked(active);
|
||||
if (index & FIX_Y)
|
||||
btnFixY->setChecked(active);
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setStickColor(const QColor & color)
|
||||
@@ -231,6 +296,15 @@ void VirtualJoystickWidget::setStickColor(const QColor & color)
|
||||
node->setColor(color);
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::loadDefaultsForMode(const unsigned mode)
|
||||
{
|
||||
if (((mode & 1) && stickSide == 'L') || (!(mode & 1) && stickSide == 'R')) {
|
||||
setStickConstraint(HOLD_Y, true);
|
||||
setStickY(1.0);
|
||||
onNodeYChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QSize VirtualJoystickWidget::sizeHint() const {
|
||||
return prefSize;
|
||||
}
|
||||
@@ -241,6 +315,18 @@ void VirtualJoystickWidget::resizeEvent(QResizeEvent * event)
|
||||
setSize(event->size(), event->oldSize());
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::onNodeXChanged()
|
||||
{
|
||||
emit valueChange(RadioWidget::RADIO_WIDGET_STICK, m_xIndex, int(m_stickScale * getStickX()));
|
||||
updateNodeValueLabels();
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::onNodeYChanged()
|
||||
{
|
||||
emit valueChange(RadioWidget::RADIO_WIDGET_STICK, m_yIndex, int(-m_stickScale * getStickY()));
|
||||
updateNodeValueLabels();
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::setSize(const QSize & size, const QSize &)
|
||||
{
|
||||
float thisAspectRatio = (float)size.width() / size.height();
|
||||
@@ -301,9 +387,7 @@ RadioTrimWidget * VirtualJoystickWidget::createTrimWidget(QChar type)
|
||||
RadioTrimWidget * trimWidget = new RadioTrimWidget(type == 'H' ? Qt::Horizontal : Qt::Vertical);
|
||||
trimWidget->setIndices(getTrimSliderType(type), getTrimButtonType(type, 0), getTrimButtonType(type, 1));
|
||||
|
||||
connect(trimWidget, &RadioTrimWidget::trimButtonPressed, this, &VirtualJoystickWidget::trimButtonPressed);
|
||||
connect(trimWidget, &RadioTrimWidget::trimButtonReleased, this, &VirtualJoystickWidget::trimButtonReleased);
|
||||
connect(trimWidget, &RadioTrimWidget::trimSliderMoved, this, &VirtualJoystickWidget::trimSliderMoved);
|
||||
connect(trimWidget, &RadioTrimWidget::valueChange, this, &VirtualJoystickWidget::valueChange);
|
||||
|
||||
return trimWidget;
|
||||
}
|
||||
@@ -371,6 +455,24 @@ QLayout *VirtualJoystickWidget::createNodeValueLayout(QChar type, QLabel *& valL
|
||||
return layout;
|
||||
}
|
||||
|
||||
int VirtualJoystickWidget::getStickIndex(QChar type)
|
||||
{
|
||||
using namespace Board;
|
||||
|
||||
if (stickSide == 'L') {
|
||||
if (type == 'H')
|
||||
return STICK_AXIS_LH;
|
||||
else
|
||||
return STICK_AXIS_LV;
|
||||
}
|
||||
else {
|
||||
if (type == 'H')
|
||||
return STICK_AXIS_RH;
|
||||
else
|
||||
return STICK_AXIS_RV;
|
||||
}
|
||||
}
|
||||
|
||||
int VirtualJoystickWidget::getTrimSliderType(QChar type)
|
||||
{
|
||||
using namespace Board;
|
||||
@@ -426,10 +528,12 @@ int VirtualJoystickWidget::getTrimButtonType(QChar type, int pos)
|
||||
|
||||
RadioTrimWidget * VirtualJoystickWidget::getTrimWidget(int which)
|
||||
{
|
||||
if (which == Board::TRIM_AXIS_LH || which == Board::TRIM_AXIS_RH)
|
||||
if ((stickSide == 'L' && which == Board::TRIM_AXIS_LH) || (stickSide == 'R' && which == Board::TRIM_AXIS_RH))
|
||||
return hTrimWidget;
|
||||
else
|
||||
else if ((stickSide == 'L' && which == Board::TRIM_AXIS_LV) || (stickSide == 'R' && which == Board::TRIM_AXIS_RV))
|
||||
return vTrimWidget;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::onButtonChange(bool checked)
|
||||
@@ -456,9 +560,9 @@ void VirtualJoystickWidget::onButtonChange(bool checked)
|
||||
void VirtualJoystickWidget::updateNodeValueLabels()
|
||||
{
|
||||
if (nodeLabelX)
|
||||
nodeLabelX->setText(QString("%1").arg((qreal)node->getX() * 100 + getTrimValue(0) / 5, 2, 'f', 0));
|
||||
nodeLabelX->setText(QString("%1").arg(node->getX() * 100.0f, 2, 'f', 0));
|
||||
if (nodeLabelY)
|
||||
nodeLabelY->setText(QString("%1").arg((qreal)node->getY() * -100 + getTrimValue(1) / 5, 2, 'f', 0));
|
||||
nodeLabelY->setText(QString("%1").arg(node->getY() * -100.0f, 2, 'f', 0));
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::onGsMouseEvent(QGraphicsSceneMouseEvent * event)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef VIRTUALJOYSTICKWIDGET_H
|
||||
#define VIRTUALJOYSTICKWIDGET_H
|
||||
|
||||
#include "radiowidget.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QResizeEvent>
|
||||
#include <QBoxLayout>
|
||||
@@ -28,6 +30,7 @@
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QToolButton>
|
||||
#include <QTimer>
|
||||
#include <QLabel>
|
||||
|
||||
class CustomGraphicsScene;
|
||||
@@ -40,38 +43,47 @@ class VirtualJoystickWidget : public QWidget
|
||||
|
||||
public:
|
||||
enum ConstraintTypes {
|
||||
HOLD_X = 0,
|
||||
HOLD_Y,
|
||||
FIX_X,
|
||||
FIX_Y
|
||||
HOLD_X = 0x01,
|
||||
HOLD_Y = 0x02,
|
||||
FIX_X = 0x04,
|
||||
FIX_Y = 0x08
|
||||
};
|
||||
|
||||
explicit VirtualJoystickWidget(QWidget * parent = NULL, QChar side = 'L', bool showTrims = true, bool showBtns = true, bool showValues = true, QSize size = QSize(125, 125));
|
||||
|
||||
void setStickX(qreal x);
|
||||
void setStickY(qreal y);
|
||||
void setStickPos(QPointF xy);
|
||||
void centerStick();
|
||||
qreal getStickX();
|
||||
qreal getStickY();
|
||||
QPointF getStickPos();
|
||||
|
||||
void setTrimValue(int which, int value);
|
||||
void setTrimRange(int which, int min, int max);
|
||||
int getTrimValue(int which);
|
||||
|
||||
void setStickConstraint(int which, bool active);
|
||||
void setStickColor(const QColor & color);
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
int getStickScale() const;
|
||||
void setStickScale(int stickScale);
|
||||
|
||||
public slots:
|
||||
void setStickX(qreal x);
|
||||
void setStickY(qreal y);
|
||||
void setStickPos(QPointF xy);
|
||||
void setStickAxisValue(int index, int value);
|
||||
void centerStick();
|
||||
void setTrimsRange(int min, int max);
|
||||
void setTrimsRange(int rng);
|
||||
void setTrimRange(int index, int min, int max);
|
||||
void setTrimValue(int index, int value);
|
||||
void setWidgetValue(const RadioWidget::RadioWidgetType type, const int index, const int value);
|
||||
|
||||
void setStickIndices(int xIdx = -1, int yIdx = -1);
|
||||
void setStickConstraint(quint8 index, bool active);
|
||||
void setStickColor(const QColor & color);
|
||||
void loadDefaultsForMode(const unsigned mode);
|
||||
|
||||
signals:
|
||||
void trimButtonPressed(int index);
|
||||
void trimButtonReleased(int index);
|
||||
void trimSliderMoved(int index, int value);
|
||||
void valueChange(const RadioWidget::RadioWidgetType type, const int index, int value);
|
||||
|
||||
protected slots:
|
||||
void onNodeXChanged();
|
||||
void onNodeYChanged();
|
||||
void onButtonChange(bool checked);
|
||||
void updateNodeValueLabels();
|
||||
void onGsMouseEvent(QGraphicsSceneMouseEvent * event);
|
||||
@@ -81,6 +93,7 @@ class VirtualJoystickWidget : public QWidget
|
||||
RadioTrimWidget * createTrimWidget(QChar type);
|
||||
QToolButton * createButtonWidget(int type);
|
||||
QLayout * createNodeValueLayout(QChar type, QLabel *& valLabel);
|
||||
int getStickIndex(QChar type);
|
||||
int getTrimSliderType(QChar type);
|
||||
int getTrimButtonType(QChar type, int pos);
|
||||
RadioTrimWidget * getTrimWidget(int which);
|
||||
@@ -97,7 +110,11 @@ class VirtualJoystickWidget : public QWidget
|
||||
QToolButton * btnFixX, * btnFixY;
|
||||
QLabel * nodeLabelX, * nodeLabelY;
|
||||
QSize extraSize;
|
||||
QTimer centerStickTimer;
|
||||
float ar; // aspect ratio
|
||||
int m_xIndex;
|
||||
int m_yIndex;
|
||||
int m_stickScale;
|
||||
bool m_stickPressed;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user