From 20485a469238501d2c10299e12c4086d442d2796 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 5 Dec 2018 11:24:28 -0800 Subject: [PATCH] * Add support for showing rotation on QGCMapCircle. * Support rotation change for Orbit --- src/FlightDisplay/FlightDisplayViewMap.qml | 13 ++-- src/FlightDisplay/GuidedActionsController.qml | 2 +- src/MissionManager/QGCFenceCircle.cc | 2 +- src/MissionManager/QGCMapCircle.cc | 53 +++++++++---- src/MissionManager/QGCMapCircle.h | 39 ++++++---- src/MissionManager/QGCMapCircleVisuals.qml | 78 +++++++++++++++++-- 6 files changed, 145 insertions(+), 42 deletions(-) diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlightDisplayViewMap.qml index d6a92e863..7ee772ef7 100644 --- a/src/FlightDisplay/FlightDisplayViewMap.qml +++ b/src/FlightDisplay/FlightDisplayViewMap.qml @@ -319,12 +319,13 @@ FlightMap { } QGCMapCircleVisuals { - id: orbitMapCircle - mapControl: parent - mapCircle: _mapCircle - visible: false + id: orbitMapCircle + mapControl: parent + mapCircle: _mapCircle + visible: false - property alias center: _mapCircle.center + property alias center: _mapCircle.center + property alias clockwiseRotation: _mapCircle.clockwiseRotation readonly property real defaultRadius: 30 @@ -348,6 +349,8 @@ FlightMap { id: _mapCircle interactive: true radius.rawValue: 30 + showRotation: true + clockwiseRotation: true } } diff --git a/src/FlightDisplay/GuidedActionsController.qml b/src/FlightDisplay/GuidedActionsController.qml index b1724758b..8876e8fb8 100644 --- a/src/FlightDisplay/GuidedActionsController.qml +++ b/src/FlightDisplay/GuidedActionsController.qml @@ -384,7 +384,7 @@ Item { _activeVehicle.setCurrentMissionSequence(actionData) break case actionOrbit: - _activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius(), _activeVehicle.altitudeAMSL.rawValue + actionAltitudeChange) + _activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius() * (orbitMapCircle.clockWiseRotation ? 1 : -1), _activeVehicle.altitudeAMSL.rawValue + actionAltitudeChange) orbitMapCircle.hide() break case actionLandAbort: diff --git a/src/MissionManager/QGCFenceCircle.cc b/src/MissionManager/QGCFenceCircle.cc index b174ed498..79dd080b6 100644 --- a/src/MissionManager/QGCFenceCircle.cc +++ b/src/MissionManager/QGCFenceCircle.cc @@ -20,7 +20,7 @@ QGCFenceCircle::QGCFenceCircle(QObject* parent) } QGCFenceCircle::QGCFenceCircle(const QGeoCoordinate& center, double radius, bool inclusion, QObject* parent) - : QGCMapCircle (center, radius, parent) + : QGCMapCircle (center, radius, false /* showRotation */, true /* clockwiseRotation */, parent) , _inclusion (inclusion) { _init(); diff --git a/src/MissionManager/QGCMapCircle.cc b/src/MissionManager/QGCMapCircle.cc index fd3ab5df1..5433f01e8 100644 --- a/src/MissionManager/QGCMapCircle.cc +++ b/src/MissionManager/QGCMapCircle.cc @@ -22,30 +22,36 @@ const char* QGCMapCircle::_jsonRadiusKey = "radius"; const char* QGCMapCircle::_radiusFactName = "Radius"; QGCMapCircle::QGCMapCircle(QObject* parent) - : QObject (parent) - , _dirty (false) - , _interactive (false) + : QObject (parent) + , _dirty (false) + , _interactive (false) + , _showRotation (false) + , _clockwiseRotation(true) { _init(); } -QGCMapCircle::QGCMapCircle(const QGeoCoordinate& center, double radius, QObject* parent) - : QObject (parent) - , _dirty (false) - , _center (center) - , _radius (FactSystem::defaultComponentId, _radiusFactName, FactMetaData::valueTypeDouble) - , _interactive (false) +QGCMapCircle::QGCMapCircle(const QGeoCoordinate& center, double radius, bool showRotation, bool clockwiseRotation, QObject* parent) + : QObject (parent) + , _dirty (false) + , _center (center) + , _radius (FactSystem::defaultComponentId, _radiusFactName, FactMetaData::valueTypeDouble) + , _interactive (false) + , _showRotation (showRotation) + , _clockwiseRotation(clockwiseRotation) { _radius.setRawValue(radius); _init(); } QGCMapCircle::QGCMapCircle(const QGCMapCircle& other, QObject* parent) - : QObject (parent) - , _dirty (false) - , _center (other._center) - , _radius (FactSystem::defaultComponentId, _radiusFactName, FactMetaData::valueTypeDouble) - , _interactive (false) + : QObject (parent) + , _dirty (false) + , _center (other._center) + , _radius (FactSystem::defaultComponentId, _radiusFactName, FactMetaData::valueTypeDouble) + , _interactive (false) + , _showRotation (other._showRotation) + , _clockwiseRotation(other._clockwiseRotation) { _radius.setRawValue(other._radius.rawValue()); _init(); @@ -117,6 +123,10 @@ bool QGCMapCircle::loadFromJson(const QJsonObject& json, QString& errorString) setCenter(center); _radius.setRawValue(circleObject[_jsonRadiusKey].toDouble()); + _interactive = false; + _showRotation = false; + _clockwiseRotation = true; + return true; } @@ -142,3 +152,18 @@ void QGCMapCircle::setInteractive(bool interactive) } } +void QGCMapCircle::setShowRotation(bool showRotation) +{ + if (showRotation != _showRotation) { + _showRotation = showRotation; + emit showRotationChanged(showRotation); + } +} + +void QGCMapCircle::setClockwiseRotation(bool clockwiseRotation) +{ + if (clockwiseRotation != _clockwiseRotation) { + _clockwiseRotation = clockwiseRotation; + emit clockwiseRotationChanged(clockwiseRotation); + } +} diff --git a/src/MissionManager/QGCMapCircle.h b/src/MissionManager/QGCMapCircle.h index 024f9c595..3cb28574a 100644 --- a/src/MissionManager/QGCMapCircle.h +++ b/src/MissionManager/QGCMapCircle.h @@ -25,14 +25,17 @@ class QGCMapCircle : public QObject public: QGCMapCircle(QObject* parent = nullptr); QGCMapCircle(const QGeoCoordinate& center, double radius, QObject* parent = nullptr); + QGCMapCircle(const QGeoCoordinate& center, double radius, bool showRotation, bool clockwiseRotation, QObject* parent = nullptr); QGCMapCircle(const QGCMapCircle& other, QObject* parent = nullptr); const QGCMapCircle& operator=(const QGCMapCircle& other); - Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) - Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged) - Q_PROPERTY(Fact* radius READ radius CONSTANT) - Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged) + Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged) + Q_PROPERTY(Fact* radius READ radius CONSTANT) + Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged) + Q_PROPERTY(bool showRotation READ showRotation WRITE setShowRotation NOTIFY showRotationChanged) + Q_PROPERTY(bool clockwiseRotation READ clockwiseRotation WRITE setClockwiseRotation NOTIFY clockwiseRotationChanged) /// Saves the polygon to the json object. /// @param json Json object to save to @@ -46,21 +49,27 @@ public: // Property methods - bool dirty (void) const { return _dirty; } - QGeoCoordinate center (void) const { return _center; } - Fact* radius (void) { return &_radius; } - bool interactive (void) const { return _interactive; } + bool dirty (void) const { return _dirty; } + QGeoCoordinate center (void) const { return _center; } + Fact* radius (void) { return &_radius; } + bool interactive (void) const { return _interactive; } + bool showRotation (void) const { return _showRotation; } + bool clockwiseRotation (void) const { return _clockwiseRotation; } - void setDirty (bool dirty); - void setCenter (QGeoCoordinate newCenter); - void setInteractive (bool interactive); + void setDirty (bool dirty); + void setCenter (QGeoCoordinate newCenter); + void setInteractive (bool interactive); + void setShowRotation (bool showRotation); + void setClockwiseRotation (bool clockwiseRotation); static const char* jsonCircleKey; signals: - void dirtyChanged (bool dirty); - void centerChanged (QGeoCoordinate center); - void interactiveChanged (bool interactive); + void dirtyChanged (bool dirty); + void centerChanged (QGeoCoordinate center); + void interactiveChanged (bool interactive); + void showRotationChanged (bool showRotation); + void clockwiseRotationChanged (bool clockwiseRotation); private slots: void _setDirty(void); @@ -72,6 +81,8 @@ private: QGeoCoordinate _center; Fact _radius; bool _interactive; + bool _showRotation; + bool _clockwiseRotation; QMap _nameToMetaDataMap; diff --git a/src/MissionManager/QGCMapCircleVisuals.qml b/src/MissionManager/QGCMapCircleVisuals.qml index d9a9a3e1f..f516d02ab 100644 --- a/src/MissionManager/QGCMapCircleVisuals.qml +++ b/src/MissionManager/QGCMapCircleVisuals.qml @@ -30,14 +30,23 @@ Item { property int borderWidth: 2 property color borderColor: "orange" - property var _circleComponent - property var _dragHandlesComponent + property var _circleComponent + property var _topRotationIndicatorComponent + property var _bottomRotationIndicatorComponent + property var _dragHandlesComponent + property real _radius: mapCircle.radius.rawValue function addVisuals() { if (!_circleComponent) { _circleComponent = circleComponent.createObject(mapControl) mapControl.addMapItem(_circleComponent) } + if (!_topRotationIndicatorComponent) { + _topRotationIndicatorComponent = rotationIndicatorComponent.createObject(mapControl, { "topIndicator": true }) + _bottomRotationIndicatorComponent = rotationIndicatorComponent.createObject(mapControl, { "topIndicator": false }) + mapControl.addMapItem(_topRotationIndicatorComponent) + mapControl.addMapItem(_bottomRotationIndicatorComponent) + } } function removeVisuals() { @@ -45,6 +54,12 @@ Item { _circleComponent.destroy() _circleComponent = undefined } + if (_topRotationIndicatorComponent) { + _topRotationIndicatorComponent.destroy() + _bottomRotationIndicatorComponent.destroy() + _topRotationIndicatorComponent = undefined + _bottomRotationIndicatorComponent = undefined + } } function addDragHandles() { @@ -74,15 +89,64 @@ Item { } } - Component.onCompleted: updateInternalComponents() - onInteractiveChanged: updateInternalComponents() - onVisibleChanged: updateInternalComponents() + Component.onCompleted: { + updateInternalComponents() + } Component.onDestruction: { removeVisuals() removeDragHandles() } + onInteractiveChanged: updateInternalComponents() + onVisibleChanged: updateInternalComponents() + + Component { + id: rotationIndicatorComponent + + MapQuickItem { + z: QGroundControl.zOrderMapItems + 2 + visible: mapCircle.showRotation + + property bool topIndicator: true + + property real _rotationRadius: _radius + + function updateCoordinate() { + coordinate = mapCircle.center.atDistanceAndAzimuth(_radius, topIndicator ? 0 : 180) + } + + Component.onCompleted: updateCoordinate() + + on_RotationRadiusChanged: updateCoordinate() + + Connections { + target: mapCircle + onCenterChanged: updateCoordinate() + } + + sourceItem: QGCColoredImage { + anchors.centerIn: parent + width: ScreenTools.defaultFontPixelHeight / 2 + height: ScreenTools.defaultFontPixelHeight + source: "/qmlimages/arrow-down.png" + color: borderColor + + transform: Rotation { + origin.x: width / 2 + origin.y: height / 2 + angle: (mapCircle.clockwiseRotation ? 1 : -1) * (topIndicator ? -90 : 90) + } + + QGCMouseArea { + fillItem: parent + onClicked: mapCircle.clockwiseRotation = !mapCircle.clockwiseRotation + visible: mapCircle.interactive + } + } + } + } + Component { id: circleComponent @@ -92,7 +156,7 @@ Item { border.color: borderColor border.width: borderWidth center: mapCircle.center - radius: mapCircle.radius.rawValue + radius: _radius } } @@ -146,7 +210,7 @@ Item { property var radiusDragArea property var radiusDragCoord: QtPositioning.coordinate() property var circleCenterCoord: mapCircle.center - property real circleRadius: mapCircle.radius.rawValue + property real circleRadius: _radius function calcRadiusDragCoord() { radiusDragCoord = mapCircle.center.atDistanceAndAzimuth(circleRadius, 90) -- 2.22.0