diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index dd9f5b51c105f7f5b3936b85b614ae0905ae5b3f..0062c929e5afe53d5837acf45922c78e885b7372 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -258,6 +258,7 @@ HEADERS += \
src/QGCFileDialog.h \
src/QGCGeo.h \
src/QGCLoggingCategory.h \
+ src/QGCMapPalette.h \
src/QGCMessageBox.h \
src/QGCPalette.h \
src/QGCQmlWidgetHolder.h \
@@ -371,6 +372,7 @@ SOURCES += \
src/QGCDockWidget.cc \
src/QGCFileDialog.cc \
src/QGCLoggingCategory.cc \
+ src/QGCMapPalette.cc \
src/QGCPalette.cc \
src/QGCQmlWidgetHolder.cpp \
src/QGCQuickWidget.cc \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index ce6f49b7fb721de2c9ef52ae464f5d1580441e34..3126d5c9dabb035e2aad2b51d1ac9b8c149c9a3c 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -32,6 +32,7 @@
src/QmlControls/DropButton.qml
src/QmlControls/ExclusiveGroupItem.qml
src/QmlControls/IndicatorButton.qml
+ src/QmlControls/JoystickThumbPad.qml
src/ui/toolbar/MainToolBar.qml
src/ui/toolbar/MainToolBarIndicators.qml
src/QmlControls/MissionItemEditor.qml
diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml
index 3735d29bec2773d624adbb31e3cf7d57529a4831..36bc167c0f875484ee6467e9eb46d6314979215e 100644
--- a/src/FlightDisplay/FlightDisplayView.qml
+++ b/src/FlightDisplay/FlightDisplayView.qml
@@ -21,7 +21,7 @@ This file is part of the QGROUNDCONTROL project
======================================================================*/
-import QtQuick 2.4
+import QtQuick 2.5
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2
@@ -216,4 +216,117 @@ Item {
height: availableHeight
}
+ Item {
+ id: multiTouchItem
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ height: thumbAreaHeight
+ visible: QGroundControl.virtualTabletJoystick
+
+ readonly property real thumbAreaHeight: parent.height / 4
+
+ QGCMapPalette { id: mapPal; lightColors: !isBackgroundDark }
+
+ Component.onCompleted: console.log("test", mapPal)
+
+ MultiPointTouchArea {
+ anchors.fill: parent
+ maximumTouchPoints: 2
+
+ property var leftRect: Qt.rect(0, 0, parent.thumbAreaHeight, parent.thumbAreaHeight)
+ property var rightRect: Qt.rect(parent.width - parent.thumbAreaHeight, 0, parent.thumbAreaHeight, parent.thumbAreaHeight)
+
+ function pointInRect(rect, point) {
+ return point.x >= rect.x &&
+ point.y >= rect.y &&
+ point.x <= rect.x + rect.width &&
+ point.y <= rect.y + rect.height
+ }
+
+ function newTouchPoints(touchPoints)
+ {
+ var point1Location = 0
+ var point2Location = 0
+
+ var point1
+ if (touchPoints.length > 0) {
+ point1 = touchPoints[0]
+ if (pointInRect(leftRect, point1)) {
+ point1Location = -1
+ } else if (pointInRect(rightRect, point1)) {
+ point1Location = 1
+ }
+ }
+
+ var point2
+ if (touchPoints.length == 2) {
+ point2 = touchPoints[1]
+ if (pointInRect(leftRect, point2)) {
+ point2Location = -1
+ } else if (pointInRect(rightRect, point2)) {
+ point2Location = 1
+ }
+ }
+
+ // Make sure points are not both in the same rect
+ if (point1Location != point2Location) {
+ if (point1Location != 0) {
+ if (point1Location == -1) {
+ leftStick.stickPosition = point1
+ } else {
+ rightStick.stickPosition = Qt.point(point1.x - (multiTouchItem.width - multiTouchItem.thumbAreaHeight), point1.y)
+ }
+ }
+ if (point2Location != 0) {
+ if (point2Location == -1) {
+ rightStick.stickPosition = Qt.point(point2.x - (multiTouchItem.width - multiTouchItem.thumbAreaHeight), point2.y)
+ } else {
+ leftStick.stickPosition = point2
+ }
+ }
+ }
+ }
+
+ onPressed: newTouchPoints(touchPoints)
+ onTouchUpdated: newTouchPoints(touchPoints)
+
+ onReleased: {
+ leftStick.reCenter()
+ rightStick.reCenter()
+ }
+
+ }
+
+ Timer {
+ interval: 10
+ running: QGroundControl.virtualTabletJoystick
+ repeat: true
+
+ onTriggered: {
+ if (_activeVehicle) {
+ _activeVehicle.virtualTabletJoystickValue(rightStick.xAxis, rightStick.yAxis, leftStick.xAxis, leftStick.yAxis)
+ }
+ }
+ }
+
+ JoystickThumbPad {
+ id: leftStick
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ width: parent.thumbAreaHeight
+ height: parent.thumbAreaHeight
+ yAxisThrottle: true
+ lightColors: !isBackgroundDark
+ }
+
+ JoystickThumbPad {
+ id: rightStick
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ width: parent.thumbAreaHeight
+ height: parent.thumbAreaHeight
+ lightColors: !isBackgroundDark
+ }
+ }
}
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index 2665303166527f16237049ae81df2daa09cb060d..7b6f923a1318489260c033046b783d66eeca0bf2 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -56,6 +56,7 @@
#include "QGCTemporaryFile.h"
#include "QGCFileDialog.h"
#include "QGCPalette.h"
+#include "QGCMapPalette.h"
#include "QGCLoggingCategory.h"
#include "ViewWidgetController.h"
#include "ParameterEditorController.h"
@@ -334,7 +335,8 @@ void QGCApplication::_initCommon(void)
// Register our Qml objects
- qmlRegisterType("QGroundControl.Palette", 1, 0, "QGCPalette");
+ qmlRegisterType ("QGroundControl.Palette", 1, 0, "QGCPalette");
+ qmlRegisterType ("QGroundControl.Palette", 1, 0, "QGCMapPalette");
qmlRegisterUncreatableType ("QGroundControl.AutoPilotPlugin", 1, 0, "AutoPilotPlugin", "Reference only");
qmlRegisterUncreatableType ("QGroundControl.AutoPilotPlugin", 1, 0, "VehicleComponent", "Reference only");
diff --git a/src/QGCMapPalette.cc b/src/QGCMapPalette.cc
new file mode 100644
index 0000000000000000000000000000000000000000..96487f45579854cd15460dd702e92368ebb73967
--- /dev/null
+++ b/src/QGCMapPalette.cc
@@ -0,0 +1,43 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 QGROUNDCONTROL PROJECT
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL 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.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see .
+
+ ======================================================================*/
+
+#include "QGCMapPalette.h"
+
+#include
+#include
+
+QColor QGCMapPalette::_thumbJoystick[QGCMapPalette::_cColorGroups] = { QColor("#ffffff"), QColor("#f000000") };
+
+QGCMapPalette::QGCMapPalette(QObject* parent) :
+ QObject(parent)
+{
+
+}
+
+void QGCMapPalette::setLightColors(bool lightColors)
+{
+ if ( _lightColors != lightColors) {
+ _lightColors = lightColors;
+ emit paletteChanged();
+ }
+}
diff --git a/src/QGCMapPalette.h b/src/QGCMapPalette.h
new file mode 100644
index 0000000000000000000000000000000000000000..80cb52acbffa38c5e89421fe44ff6b80398f3bbe
--- /dev/null
+++ b/src/QGCMapPalette.h
@@ -0,0 +1,64 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 QGROUNDCONTROL PROJECT
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL 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.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see .
+
+ ======================================================================*/
+
+/// QGCMapPalette is a variant of QGCPalette which is used to hold colors used for display over
+/// the map control. Since the coloring of a satellite map differs greatly from the coloring of
+/// a street map you need to be able to switch between sets of color based on map type.
+
+#ifndef QGCMapPalette_h
+#define QGCMapPalette_h
+
+#include
+#include
+
+class QGCMapPalette : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool lightColors READ lightColors WRITE setLightColors NOTIFY paletteChanged)
+
+ // The colors are:
+ // thumbJoystick - Thumb joystick indicator
+
+ Q_PROPERTY(QColor thumbJoystick READ thumbJoystick NOTIFY paletteChanged)
+
+public:
+ QGCMapPalette(QObject* parent = NULL);
+
+ bool lightColors(void) const { return _lightColors; }
+ void setLightColors(bool lightColors);
+
+ QColor thumbJoystick(void) const { return _thumbJoystick[_lightColors]; }
+
+signals:
+ void paletteChanged(void);
+
+private:
+ bool _lightColors;
+
+ static const int _cColorGroups = 2;
+
+ static QColor _thumbJoystick[_cColorGroups];
+};
+
+#endif
diff --git a/src/QGCQuickWidget.cc b/src/QGCQuickWidget.cc
index db7a4cf4c2782df0624fcf9a58fd7c1933f0d3a7..da302323eba82b43c1a665269a454998a5487325 100644
--- a/src/QGCQuickWidget.cc
+++ b/src/QGCQuickWidget.cc
@@ -39,6 +39,7 @@
QGCQuickWidget::QGCQuickWidget(QWidget* parent) :
QQuickWidget(parent)
{
+ setAttribute(Qt::WA_AcceptTouchEvents);
rootContext()->engine()->addImportPath("qrc:/qml");
rootContext()->setContextProperty("multiVehicleManager", qgcApp()->toolbox()->multiVehicleManager());
rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
diff --git a/src/QmlControls/JoystickThumbPad.qml b/src/QmlControls/JoystickThumbPad.qml
new file mode 100644
index 0000000000000000000000000000000000000000..03c43ece44252416c9b848b72f55afbfeab5825e
--- /dev/null
+++ b/src/QmlControls/JoystickThumbPad.qml
@@ -0,0 +1,74 @@
+import QtQuick 2.5
+import QtQuick.Controls 1.2
+
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+
+Rectangle {
+ radius: width / 2
+ border.color: mapPal.thumbJoystick
+ border.width: 2
+ color: "transparent"
+
+ property alias lightColors: mapPal.lightColors /// true: use light colors from QGCMapPalette for drawing
+ property var stickPosition: Qt.point(0, 0)
+ property real xAxis: 0 /// Value range [-1,1], negative values left stick, positive values right stick
+ property real yAxis: 0 /// Value range [-1,1], negative values up stick, positive values down stick
+ property bool yAxisThrottle: false /// true: yAxis used for throttle, range [1,0], positive value are stick up
+
+ property bool _stickCenteredOnce: false
+
+ QGCMapPalette { id: mapPal }
+
+ onWidthChanged: {
+ if (!_stickCenteredOnce && width != 0) {
+ reCenter()
+ }
+ }
+
+ onStickPositionChanged: {
+ var xAxisTemp = stickPosition.x / width
+ xAxisTemp *= 2.0
+ xAxisTemp -= 1.0
+ xAxis = xAxisTemp
+
+ var yAxisTemp = stickPosition.y / width
+ yAxisTemp *= 2.0
+ yAxisTemp -= 1.0
+ if (yAxisThrottle) {
+ yAxisTemp = ((yAxisTemp * -1.0) / 2.0) + 0.5
+ }
+ yAxis = yAxisTemp
+ }
+
+ function reCenter()
+ {
+ stickPosition = Qt.point(width / 2, width / 2)
+ }
+
+ Column {
+ QGCLabel { text: xAxis }
+ QGCLabel { text: yAxis }
+ }
+
+ Rectangle {
+ anchors.margins: parent.width / 4
+ anchors.fill: parent
+ radius: width / 2
+ border.color: mapPal.thumbJoystick
+ border.width: 2
+ color: "transparent"
+ }
+
+ Rectangle {
+ width: hatWidth
+ height: hatWidth
+ radius: hatWidthHalf
+ color: mapPal.thumbJoystick
+ x: stickPosition.x - hatWidthHalf
+ y: stickPosition.y - hatWidthHalf
+
+ readonly property real hatWidth: ScreenTools.defaultFontPixelHeight
+ readonly property real hatWidthHalf: ScreenTools.defaultFontPixelHeight / 2
+ }
+}
diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir
index 681ab7bf4867aaef1d960c8f03b3246e59a6b602..950bf43cbee96956eb6ab1a50fe70c283cf11005 100644
--- a/src/QmlControls/QGroundControl.Controls.qmldir
+++ b/src/QmlControls/QGroundControl.Controls.qmldir
@@ -1,38 +1,32 @@
Module QGroundControl.Controls
-QGCLabel 1.0 QGCLabel.qml
-QGCButton 1.0 QGCButton.qml
-QGCRadioButton 1.0 QGCRadioButton.qml
-QGCCheckBox 1.0 QGCCheckBox.qml
-QGCTextField 1.0 QGCTextField.qml
-QGCComboBox 1.0 QGCComboBox.qml
-QGCColoredImage 1.0 QGCColoredImage.qml
-QGCToolBarButton 1.0 QGCToolBarButton.qml
-QGCMovableItem 1.0 QGCMovableItem.qml
-
-SubMenuButton 1.0 SubMenuButton.qml
-IndicatorButton 1.0 IndicatorButton.qml
-DropButton 1.0 DropButton.qml
-RoundButton 1.0 RoundButton.qml
-VehicleRotationCal 1.0 VehicleRotationCal.qml
-VehicleSummaryRow 1.0 VehicleSummaryRow.qml
-ViewWidget 1.0 ViewWidget.qml
-ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml
-
+ClickableColor 1.0 ClickableColor.qml
+DropButton 1.0 DropButton.qml
+ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml
+IndicatorButton 1.0 IndicatorButton.qml
+JoystickThumbPad 1.0 JoystickThumbPad.qml
+MainToolBar 1.0 MainToolBar.qml
+MissionItemEditor 1.0 MissionItemEditor.qml
+MissionItemIndexLabel 1.0 MissionItemIndexLabel.qml
+ModeSwitchDisplay 1.0 ModeSwitchDisplay.qml
ParameterEditor 1.0 ParameterEditor.qml
ParameterEditorDialog 1.0 ParameterEditorDialog.qml
-
-ModeSwitchDisplay 1.0 ModeSwitchDisplay.qml
-
-QGCView 1.0 QGCView.qml
-QGCViewPanel 1.0 QGCViewPanel.qml
-QGCViewDialog 1.0 QGCViewDialog.qml
-QGCViewMessage 1.0 QGCViewMessage.qml
-
-MissionItemIndexLabel 1.0 MissionItemIndexLabel.qml
-MissionItemEditor 1.0 MissionItemEditor.qml
-
-MainToolBar 1.0 MainToolBar.qml
-SignalStrength 1.0 SignalStrength.qml
-
-ClickableColor 1.0 ClickableColor.qml
+QGCButton 1.0 QGCButton.qml
+QGCCheckBox 1.0 QGCCheckBox.qml
+QGCColoredImage 1.0 QGCColoredImage.qml
+QGCComboBox 1.0 QGCComboBox.qml
+QGCLabel 1.0 QGCLabel.qml
+QGCMovableItem 1.0 QGCMovableItem.qml
+QGCRadioButton 1.0 QGCRadioButton.qml
+QGCTextField 1.0 QGCTextField.qml
+QGCToolBarButton 1.0 QGCToolBarButton.qml
+QGCView 1.0 QGCView.qml
+QGCViewDialog 1.0 QGCViewDialog.qml
+QGCViewMessage 1.0 QGCViewMessage.qml
+QGCViewPanel 1.0 QGCViewPanel.qml
+RoundButton 1.0 RoundButton.qml
+SignalStrength 1.0 SignalStrength.qml
+SubMenuButton 1.0 SubMenuButton.qml
+VehicleRotationCal 1.0 VehicleRotationCal.qml
+VehicleSummaryRow 1.0 VehicleSummaryRow.qml
+ViewWidget 1.0 ViewWidget.qml
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 7c25b4724c5ad3a67cd9fc300eb2d878c163e06b..92e83015ebf80ba4e0fa69d4d4215da1eb73265b 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -1074,3 +1074,8 @@ void Vehicle::_remoteControlRSSIChanged(uint8_t rssi)
emit rcRSSIChanged(_rcRSSI);
}
}
+
+void Vehicle::virtualTabletJoystickValue(double roll, double pitch, double yaw, double thrust)
+{
+ _uas->setExternalControlSetpoint(roll, pitch, yaw, thrust, 0, JoystickModeRC);
+}
diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h
index 823af1a9a2467667c87c7edb0ebba27b8d679225..75acee29a4b23dda91f8d092588305ebe8246fe6 100644
--- a/src/Vehicle/Vehicle.h
+++ b/src/Vehicle/Vehicle.h
@@ -124,13 +124,14 @@ public:
// Called when the message drop-down is invoked to clear current count
Q_INVOKABLE void resetMessages();
+ Q_INVOKABLE void virtualTabletJoystickValue(double roll, double pitch, double yaw, double thrust);
+
// Property accessors
QGeoCoordinate coordinate(void) { return _coordinate; }
bool coordinateValid(void) { return _coordinateValid; }
QmlObjectListModel* missionItemsModel(void);
-
typedef enum {
JoystickModeRC, ///< Joystick emulates an RC Transmitter
JoystickModeAttitude,
diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc
index 8d0ff0bd04fd2abd2cef69b84aa2c7f372fcea45..c72c4fcab203946d850280b1edc5bb62ec5909d6 100644
--- a/src/uas/UAS.cc
+++ b/src/uas/UAS.cc
@@ -1508,7 +1508,6 @@ void UAS::executeCommand(MAV_CMD command, int confirmation, float param1, float
* Set the manual control commands.
* This can only be done if the system has manual inputs enabled and is armed.
*/
-#ifndef __mobile__
void UAS::setExternalControlSetpoint(float roll, float pitch, float yaw, float thrust, quint16 buttons, int joystickMode)
{
if (!_vehicle) {
@@ -1690,7 +1689,6 @@ void UAS::setExternalControlSetpoint(float roll, float pitch, float yaw, float t
emit attitudeThrustSetPointChanged(this, roll, pitch, yaw, thrust, QGC::groundTimeMilliseconds());
}
}
-#endif
#ifndef __mobile__
void UAS::setManual6DOFControlCommands(double x, double y, double z, double roll, double pitch, double yaw)
diff --git a/src/uas/UAS.h b/src/uas/UAS.h
index 45ab119d7f9e5597fd97819156bf42e3b2470ed4..eb8fc21c45db13781838b1bbfaa4bd72e066cbf8 100644
--- a/src/uas/UAS.h
+++ b/src/uas/UAS.h
@@ -555,9 +555,7 @@ public slots:
void stopLowBattAlarm();
/** @brief Set the values for the manual control of the vehicle */
-#ifndef __mobile__
void setExternalControlSetpoint(float roll, float pitch, float yaw, float thrust, quint16 buttons, int joystickMode);
-#endif
/** @brief Set the values for the 6dof manual control of the vehicle */
#ifndef __mobile__
diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml
index 109895ba70927f702141fa35dbf3e318ba395685..0e9d4c3ddc3408bbc20a3e9cb99f78955cf962a9 100644
--- a/src/ui/preferences/GeneralSettings.qml
+++ b/src/ui/preferences/GeneralSettings.qml
@@ -234,10 +234,9 @@ Rectangle {
//-----------------------------------------------------------------
//-- Virtual joystick settings
QGCCheckBox {
- text: "Thumb Joystick (WIP - be careful!)"
+ text: "Virtual Joystick"
checked: QGroundControl.virtualTabletJoystick
onClicked: QGroundControl.virtualTabletJoystick = checked
- visible: ScreenTools.isMobile
}
}
}