diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 231e970ce2f8811f42ea392dea4a57fcc6d4efcb..a2ea31659537dc37e4984fe753c28127c5951cfb 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -50,7 +50,6 @@ src/VehicleSetup/PX4FlowSensor.qml src/AnalyzeView/AnalyzePage.qml src/QmlControls/AppMessages.qml - src/MissionEditor/ComplexMissionItem.qml src/QmlControls/ClickableColor.qml src/QmlControls/DropButton.qml src/QmlControls/ExclusiveGroupItem.qml @@ -66,6 +65,7 @@ src/QmlControls/MissionCommandDialog.qml src/MissionEditor/MissionItemEditor.qml src/QmlControls/MissionItemIndexLabel.qml + src/MissionEditor/MissionItemMapVisual.qml src/MissionEditor/MissionItemStatus.qml src/QmlControls/ModeSwitchDisplay.qml src/QmlControls/MultiRotorMotorDisplay.qml @@ -102,9 +102,10 @@ src/QmlControls/RoundButton.qml src/AutoPilotPlugins/Common/SetupPage.qml src/ui/toolbar/SignalStrength.qml + src/MissionEditor/SimpleItemMapVisual.qml src/QmlControls/SliderSwitch.qml src/QmlControls/SubMenuButton.qml - src/MissionEditor/SurveyComplexItem.qml + src/MissionEditor/SurveyMapVisual.qml src/QmlControls/VehicleRotationCal.qml src/QmlControls/VehicleSummaryRow.qml src/QmlControls/ToolStrip.qml diff --git a/src/MissionEditor/FWLandingPatternMapVisual.qml b/src/MissionEditor/FWLandingPatternMapVisual.qml index ec4af323614af5746bebbf157a8bb6221023af7d..a47056e3b5dc57fe491153fc175e4e8d57dd7b7b 100644 --- a/src/MissionEditor/FWLandingPatternMapVisual.qml +++ b/src/MissionEditor/FWLandingPatternMapVisual.qml @@ -151,10 +151,10 @@ Item { Rectangle { id: itemDragger - x: mapQuickItem ? (mapQuickItem.x + mapQuickItem.anchorPoint.x - (itemDragger.width / 2)) : 100 - y: mapQuickItem ? (mapQuickItem.y + mapQuickItem.anchorPoint.y - (itemDragger.height / 2)) : 100 - width: ScreenTools.defaultFontPixelHeight * 2 - height: ScreenTools.defaultFontPixelHeight * 2 + x: mapQuickItem.x + y: mapQuickItem.y + width: mapQuickItem.width + height: mapQuickItem.height color: "transparent" z: QGroundControl.zOrderMapItems + 1 // Above item icons @@ -167,7 +167,7 @@ Item { function liveDrag() { if (!itemDragger._preventCoordinateBindingLoop && Drag.active) { - var point = Qt.point(itemDragger.x + (itemDragger.width / 2), itemDragger.y + (itemDragger.height / 2)) + var point = Qt.point(itemDragger.x + mapQuickItem.anchorPoint.x, itemDragger.y + mapQuickItem.anchorPoint.y) var coordinate = map.toCoordinate(point) itemDragger._preventCoordinateBindingLoop = true if (dragLoiter) { @@ -182,8 +182,8 @@ Item { } Drag.active: itemDrag.drag.active - Drag.hotSpot.x: width / 2 - Drag.hotSpot.y: height / 2 + Drag.hotSpot.x: mapQuickItem.anchorPoint.x + Drag.hotSpot.y: mapQuickItem.anchorPoint.y MouseArea { id: itemDrag diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml index 49e863200ed7a3ee1fdc338eca45ced12f662eb2..bc05d7d220d1c0fd40976fc73fd73585c35279da 100644 --- a/src/MissionEditor/MissionEditor.qml +++ b/src/MissionEditor/MissionEditor.qml @@ -448,21 +448,15 @@ QGCView { } } - // Add the complex mission item to the map + // Add the mission item visuals to the map Repeater { - model: missionController.complexVisualItems + model: missionController.visualItems - delegate: ComplexMissionItem { + delegate: MissionItemMapVisual { map: editorMap } } - // Add the simple mission items to the map - MapItemView { - model: missionController.visualItems - delegate: missionItemComponent - } - Component { id: missionItemComponent diff --git a/src/MissionEditor/ComplexMissionItem.qml b/src/MissionEditor/MissionItemMapVisual.qml similarity index 86% rename from src/MissionEditor/ComplexMissionItem.qml rename to src/MissionEditor/MissionItemMapVisual.qml index 5ee3527d3564f036f8f181b8dde19950b1c9130d..585d159ce0c1aff525ea1fcb554994cd165dc87c 100644 --- a/src/MissionEditor/ComplexMissionItem.qml +++ b/src/MissionEditor/MissionItemMapVisual.qml @@ -23,7 +23,7 @@ Item { property var map ///< Map control to place item in - property var _complexItem + property var _visualItem Component.onCompleted: { if (object.mapVisualQML) { @@ -31,13 +31,13 @@ Item { if (component.status === Component.Error) { console.log("Error loading Qml: ", object.mapVisualQML, component.errorString()) } - _complexItem = component.createObject(map, { "map": _root.map }) + _visualItem = component.createObject(map, { "map": _root.map }) } } Component.onDestruction: { - if (_complexItem) { - _complexItem.destroy() + if (_visualItem) { + _visualItem.destroy() } } } diff --git a/src/MissionEditor/SimpleItemMapVisual.qml b/src/MissionEditor/SimpleItemMapVisual.qml new file mode 100644 index 0000000000000000000000000000000000000000..c81b2563bd99fc37f385f358df35d88d208d7192 --- /dev/null +++ b/src/MissionEditor/SimpleItemMapVisual.qml @@ -0,0 +1,157 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtLocation 5.3 +import QtPositioning 5.2 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FlightMap 1.0 + +/// Simple Mission Item visuals +Item { + property var map ///< Map control to place item in + + property var _missionItem: object + property var _itemVisual + property var _dragArea + + function hideItemVisuals() { + _itemVisual.destroy() + _itemVisual = undefined + } + + function showItemVisuals() { + if (!_itemVisual) { + _itemVisual = indicatorComponent.createObject(map) + map.addMapItem(_itemVisual) + } + } + + function hideDragArea() { + if (_dragArea) { + _dragArea.destroy() + _dragArea = undefined + } + } + + function showDragArea() { + if (!_dragArea) { + _dragArea = dragAreaComponent.createObject(map) + } + } + + Component.onCompleted: { + showItemVisuals() + if (_missionItem.isCurrentItem) { + showDragArea() + } + } + + Component.onDestruction: { + hideDragArea() + hideItemVisuals() + } + + + Connections { + target: _missionItem + + onIsCurrentItemChanged: { + if (_missionItem.isCurrentItem) { + showDragArea() + } else { + hideDragArea() + } + } + } + + // Control which is used to drag items + Component { + id: dragAreaComponent + + Rectangle { + id: itemDragger + x: _itemVisual.x + y: _itemVisual.y + width: _itemVisual.width + height: _itemVisual.height + color: "transparent" + z: QGroundControl.zOrderMapItems + 1 // Above item icons + + property bool dragLoiter + property bool _preventCoordinateBindingLoop: false + + onXChanged: liveDrag() + onYChanged: liveDrag() + + function liveDrag() { + if (!itemDragger._preventCoordinateBindingLoop && Drag.active) { + var point = Qt.point(itemDragger.x + _itemVisual.anchorPoint.x, itemDragger.y + _itemVisual.anchorPoint.y) + var coordinate = map.toCoordinate(point) + itemDragger._preventCoordinateBindingLoop = true + coordinate.altitude = _missionItem.coordinate.altitude + _missionItem.coordinate = coordinate + itemDragger._preventCoordinateBindingLoop = false + } + } + + Drag.active: itemDrag.drag.active + Drag.hotSpot.x: _itemVisual.anchorPoint.x + Drag.hotSpot.y: _itemVisual.anchorPoint.y + + MouseArea { + id: itemDrag + anchors.fill: parent + drag.target: parent + drag.minimumX: 0 + drag.minimumY: 0 + drag.maximumX: itemDragger.parent.width - parent.width + drag.maximumY: itemDragger.parent.height - parent.height + } + } + } + + Component { + id: indicatorComponent + + MissionItemIndicator { + coordinate: _missionItem.coordinate + visible: _missionItem.specifiesCoordinate + z: QGroundControl.zOrderMapItems + missionItem: _missionItem + sequenceNumber: _missionItem.sequenceNumber + + onClicked: setCurrentItem(_missionItem.sequenceNumber) + + // These are the non-coordinate child mission items attached to this item + Row { + anchors.top: parent.top + anchors.left: parent.right + + Repeater { + model: _missionItem.childItems + + delegate: MissionItemIndexLabel { + label: object.abbreviation + checked: object.isCurrentItem + z: 2 + specifiesCoordinate: false + + onClicked: setCurrentItem(object.sequenceNumber) + } + } + } + } + } +} diff --git a/src/MissionEditor/SurveyComplexItem.qml b/src/MissionEditor/SurveyMapVisual.qml similarity index 100% rename from src/MissionEditor/SurveyComplexItem.qml rename to src/MissionEditor/SurveyMapVisual.qml diff --git a/src/MissionManager/ComplexMissionItem.h b/src/MissionManager/ComplexMissionItem.h index 5aa8b072da6c258c252ff5b3c485130f973c42eb..ad512e6eed13b4aa119a2f69bd5d76668b35b337 100644 --- a/src/MissionManager/ComplexMissionItem.h +++ b/src/MissionManager/ComplexMissionItem.h @@ -21,7 +21,6 @@ public: const ComplexMissionItem& operator=(const ComplexMissionItem& other); - Q_PROPERTY(QString mapVisualQML READ mapVisualQML CONSTANT) Q_PROPERTY(int lastSequenceNumber READ lastSequenceNumber NOTIFY lastSequenceNumberChanged) Q_PROPERTY(double complexDistance READ complexDistance NOTIFY complexDistanceChanged) @@ -53,9 +52,6 @@ public: /// This mission item attribute specifies the type of the complex item. static const char* jsonComplexItemTypeKey; - /// @return The QML resource file which contains the control which visualizes the item on the map. - virtual QString mapVisualQML(void) const = 0; - signals: void lastSequenceNumberChanged (int lastSequenceNumber); void complexDistanceChanged (double complexDistance); diff --git a/src/MissionManager/SimpleMissionItem.h b/src/MissionManager/SimpleMissionItem.h index e3d508ae92d458531494095c7a5cf1864a1cfd8f..cc5166d293746df39c49418960bc2192e0e665d3 100644 --- a/src/MissionManager/SimpleMissionItem.h +++ b/src/MissionManager/SimpleMissionItem.h @@ -90,6 +90,7 @@ public: QGeoCoordinate exitCoordinate (void) const final { return coordinate(); } int sequenceNumber (void) const final { return _missionItem.sequenceNumber(); } double flightSpeed (void) final; + QString mapVisualQML (void) const final { return QStringLiteral("SimpleItemMapVisual.qml"); } bool coordinateHasRelativeAltitude (void) const final { return _missionItem.relativeAltitude(); } bool exitCoordinateHasRelativeAltitude (void) const final { return coordinateHasRelativeAltitude(); } diff --git a/src/MissionManager/SurveyMissionItem.h b/src/MissionManager/SurveyMissionItem.h index 6ad612d57eccef3417f2d68863c11650f546add8..303222ff9155d2fc47e7aaf851b7729bd57feedf 100644 --- a/src/MissionManager/SurveyMissionItem.h +++ b/src/MissionManager/SurveyMissionItem.h @@ -83,7 +83,7 @@ public: bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final; double greatestDistanceTo (const QGeoCoordinate &other) const final; void setCruiseSpeed (double cruiseSpeed) final; - QString mapVisualQML (void) const final { return QStringLiteral("SurveyComplexItem.qml"); } + QString mapVisualQML (void) const final { return QStringLiteral("SurveyMapVisual.qml"); } // Overrides from VisualMissionItem diff --git a/src/MissionManager/VisualMissionItem.h b/src/MissionManager/VisualMissionItem.h index a4ad9419d12f2ea5bb48cb5ad0e476419cc36b60..65f38a861b265cdeac4a6c4a06e720f5fa5e7a42 100644 --- a/src/MissionManager/VisualMissionItem.h +++ b/src/MissionManager/VisualMissionItem.h @@ -79,6 +79,7 @@ public: Q_PROPERTY(bool isStandaloneCoordinate READ isStandaloneCoordinate NOTIFY isStandaloneCoordinateChanged) ///< Waypoint line does not go through item Q_PROPERTY(bool isSimpleItem READ isSimpleItem NOTIFY isSimpleItemChanged) ///< Simple or Complex MissionItem Q_PROPERTY(QString editorQml MEMBER _editorQml CONSTANT) ///< Qml code for editing this item + Q_PROPERTY(QString mapVisualQML READ mapVisualQML CONSTANT) ///< QMl code for map visuals /// List of child mission items. Child mission item are subsequent mision items which do not specify a coordinate. They /// are shown next to the exitCoordinate indidcator in the ui. @@ -128,6 +129,9 @@ public: /// @param saveObject Save the item to this json object virtual void save(QJsonObject& saveObject) const = 0; + /// @return The QML resource file which contains the control which visualizes the item on the map. + virtual QString mapVisualQML(void) const = 0; + static const char* jsonTypeKey; ///< Json file attribute which specifies the item type static const char* jsonTypeSimpleItemValue; ///< Item type is MISSION_ITEM static const char* jsonTypeComplexItemValue; ///< Item type is Complex Item diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index 97d45d62665e9b25cff1937e7b704527ec30b274..8426dc4e0b4ce5c6b67c5aad80632778b42838d2 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -3,7 +3,6 @@ Module QGroundControl.Controls AnalyzePage 1.0 AnalyzePage.qml AppMessages 1.0 AppMessages.qml ClickableColor 1.0 ClickableColor.qml -ComplexMissionItem 1.0 ComplexMissionItem.qml DropButton 1.0 DropButton.qml DropPanel 1.0 DropPanel.qml ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml @@ -18,6 +17,7 @@ MainToolBarIndicators 1.0 MainToolBarIndicators.qml MissionCommandDialog 1.0 MissionCommandDialog.qml MissionItemEditor 1.0 MissionItemEditor.qml MissionItemIndexLabel 1.0 MissionItemIndexLabel.qml +MissionItemMapVisual 1.0 MissionItemMapVisual.qml MissionItemStatus 1.0 MissionItemStatus.qml ModeSwitchDisplay 1.0 ModeSwitchDisplay.qml MultiRotorMotorDisplay 1.0 MultiRotorMotorDisplay.qml @@ -50,9 +50,10 @@ QGCViewPanel 1.0 QGCViewPanel.qml RoundButton 1.0 RoundButton.qml SetupPage 1.0 SetupPage.qml SignalStrength 1.0 SignalStrength.qml +SimpleItemMapVisuals 1.0 SimpleItemMapVisuals.qml SliderSwitch 1.0 SliderSwitch.qml SubMenuButton 1.0 SubMenuButton.qml -SurveyComplexItem 1.0 SurveyComplexItem.qml +SurveyMapVisuals 1.0 SurveyMapVisuals.qml ToolStrip 1.0 ToolStrip.qml VehicleRotationCal 1.0 VehicleRotationCal.qml VehicleSummaryRow 1.0 VehicleSummaryRow.qml