Multi Vehicle Panel Overhaul
This commit is contained in:
committed by
Don Gagne
parent
43504cb7ca
commit
d32d5f4cf1
@@ -127,6 +127,7 @@
|
||||
<file alias="QGroundControl/Controls/MissionItemIndexLabel.qml">src/QmlControls/MissionItemIndexLabel.qml</file>
|
||||
<file alias="QGroundControl/Controls/MissionItemMapVisual.qml">src/PlanView/MissionItemMapVisual.qml</file>
|
||||
<file alias="QGroundControl/Controls/MissionItemStatus.qml">src/PlanView/MissionItemStatus.qml</file>
|
||||
<file alias="QGroundControl/Controls/MvPanelPage.qml">src/QmlControls/MvPanelPage.qml</file>
|
||||
<file alias="QGroundControl/Controls/OfflineMapButton.qml">src/QmlControls/OfflineMapButton.qml</file>
|
||||
<file alias="QGroundControl/Controls/OfflineMapEditor.qml">src/QtLocationPlugin/QMLControl/OfflineMapEditor.qml</file>
|
||||
<file alias="QGroundControl/Controls/OfflineMapInfo.qml">src/UI/preferences/OfflineMapInfo.qml</file>
|
||||
@@ -161,12 +162,14 @@
|
||||
<file alias="QGroundControl/Controls/QGCMenuSeparator.qml">src/QmlControls/QGCMenuSeparator.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCMouseArea.qml">src/QmlControls/QGCMouseArea.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCMovableItem.qml">src/QmlControls/QGCMovableItem.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCPageIndicator.qml">src/QmlControls/QGCPageIndicator.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCPopupDialog.qml">src/QmlControls/QGCPopupDialog.qml</file>
|
||||
<file alias="QGroundControl/Controls/PipView.qml">src/QmlControls/PipView.qml</file>
|
||||
<file alias="QGroundControl/Controls/PipState.qml">src/QmlControls/PipState.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCRadioButton.qml">src/QmlControls/QGCRadioButton.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCSimpleMessageDialog.qml">src/QmlControls/QGCSimpleMessageDialog.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCSlider.qml">src/QmlControls/QGCSlider.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCSwipeView.qml">src/QmlControls/QGCSwipeView.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCSwitch.qml">src/QmlControls/QGCSwitch.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCTabBar.qml">src/QmlControls/QGCTabBar.qml</file>
|
||||
<file alias="QGroundControl/Controls/QGCTabButton.qml">src/QmlControls/QGCTabButton.qml</file>
|
||||
@@ -342,6 +345,7 @@
|
||||
<file alias="Viewer3D/Models3D/Line3D.qml">src/Viewer3D/Viewer3DQml/Models3D/Line3D.qml</file>
|
||||
<file alias="Viewer3D/Models3D/Viewer3DVehicleItems.qml">src/Viewer3D/Viewer3DQml/Models3D/Viewer3DVehicleItems.qml</file>
|
||||
<file alias="Viewer3D/Viewer3DProgressBar.qml">src/Viewer3D/Viewer3DQml/Viewer3DProgressBar.qml</file>
|
||||
<file alias="QGroundControl/FlightDisplay/FlyViewTopRightPanel.qml">src/FlightDisplay/FlyViewTopRightPanel.qml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/FirstRunPromptDialogs">
|
||||
<file alias="UnitsFirstRunPrompt.qml">src/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml</file>
|
||||
|
||||
@@ -20,29 +20,6 @@ import QGroundControl.ScreenTools
|
||||
ColumnLayout {
|
||||
width: _rightPanelWidth
|
||||
|
||||
RowLayout {
|
||||
id: multiVehiclePanelSelector
|
||||
Layout.alignment: Qt.AlignTop
|
||||
spacing: ScreenTools.defaultFontPixelWidth
|
||||
visible: QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.flyView.showMultiVehicleList
|
||||
|
||||
QGCMapPalette { id: mapPal; lightColors: true }
|
||||
|
||||
QGCRadioButton {
|
||||
id: singleVehicleRadio
|
||||
text: qsTr("Single")
|
||||
checked: _showSingleVehicleUI
|
||||
onClicked: _showSingleVehicleUI = true
|
||||
textColor: mapPal.text
|
||||
}
|
||||
|
||||
QGCRadioButton {
|
||||
text: qsTr("Multi-Vehicle")
|
||||
textColor: mapPal.text
|
||||
onClicked: _showSingleVehicleUI = false
|
||||
}
|
||||
}
|
||||
|
||||
TerrainProgress {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.preferredWidth: _rightPanelWidth
|
||||
@@ -54,7 +31,7 @@ ColumnLayout {
|
||||
Loader {
|
||||
id: photoVideoControlLoader
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
sourceComponent: globals.activeVehicle && _showSingleVehicleUI ? photoVideoControlComponent : undefined
|
||||
sourceComponent: globals.activeVehicle ? photoVideoControlComponent : undefined
|
||||
|
||||
property real rightEdgeCenterInset: visible ? parent.width - x : 0
|
||||
|
||||
@@ -65,10 +42,4 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MultiVehicleList {
|
||||
Layout.preferredWidth: _rightPanelWidth
|
||||
Layout.fillHeight: true
|
||||
visible: !_showSingleVehicleUI
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
*
|
||||
* QGroundControl is licensed according to the terms in the file
|
||||
* COPYING.md in the root of the source code directory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
import QGroundControl
|
||||
import QGroundControl.FactSystem
|
||||
import QGroundControl.FactControls
|
||||
import QGroundControl.Controls
|
||||
import QGroundControl.FlightDisplay
|
||||
import QGroundControl.FlightMap
|
||||
import QGroundControl.Palette
|
||||
import QGroundControl.ScreenTools
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: topRightPanel
|
||||
width: contentWidth
|
||||
height: Math.max(contentHeight, minimumHeight)
|
||||
color: qgcPal.toolbarBackground
|
||||
radius: ScreenTools.defaultFontPixelHeight / 2
|
||||
visible: !QGroundControl.videoManager.fullScreen && _multipleVehicles && _settingEnableMVPanel
|
||||
clip: true
|
||||
|
||||
property bool _settingEnableMVPanel: QGroundControl.settingsManager.appSettings.enableMultiVehiclePanel.value
|
||||
property bool _multipleVehicles: QGroundControl.multiVehicleManager.vehicles.count > 1
|
||||
property var vehicles: QGroundControl.multiVehicleManager.vehicles
|
||||
property var selectedVehicles: QGroundControl.multiVehicleManager.selectedVehicles
|
||||
property real contentWidth: Math.max(
|
||||
multiVehicleList.implicitWidth,
|
||||
swipeViewContainer.implicitWidth
|
||||
) + ScreenTools.defaultFontPixelHeight
|
||||
property real contentHeight: Math.min(
|
||||
maximumHeight,
|
||||
topRightPanelColumnLayout.implicitHeight + topRightPanelColumnLayout.spacing * ( topRightPanelColumnLayout.children.length - 1)
|
||||
)
|
||||
property real minimumHeight: selectedVehiclesLabel.height + swipeViewContainer.height
|
||||
property real maximumHeight
|
||||
|
||||
QGCPalette { id: qgcPal }
|
||||
|
||||
ColumnLayout {
|
||||
id: topRightPanelColumnLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
|
||||
spacing: ScreenTools.defaultFontPixelHeight / 2
|
||||
|
||||
QGCLabel {
|
||||
id: selectedVehiclesLabel
|
||||
text: {
|
||||
let ids = Array.from({length: selectedVehicles.count}, (_, i) =>
|
||||
selectedVehicles.get(i).id
|
||||
).sort((a, b) => a - b)
|
||||
.join(", ")
|
||||
return qsTr("Selected: ") + ids
|
||||
}
|
||||
}
|
||||
|
||||
MultiVehicleList {
|
||||
id: multiVehicleList
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
implicitHeight: multiVehicleList.innerColumnHeight * vehicles.count - _margins * 3
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: topRightPanel.height === maximumHeight
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 0
|
||||
height: 1
|
||||
color: QGroundControl.globalPalette.groupBorder
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Vertical
|
||||
GradientStop { position: 0.00; color: topRightPanel.color }
|
||||
GradientStop { position: 0.05; color: "transparent" }
|
||||
|
||||
GradientStop { position: 0.95; color: "transparent" }
|
||||
GradientStop { position: 1.00; color: topRightPanel.color }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 0
|
||||
height: 1
|
||||
color: QGroundControl.globalPalette.groupBorder
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: swipeViewContainer
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: swipePages.implicitHeight
|
||||
implicitWidth: swipePages.implicitWidth
|
||||
color: "transparent"
|
||||
|
||||
QGCSwipeView {
|
||||
id: swipePages
|
||||
anchors.fill: parent
|
||||
spacing: ScreenTools.defaultFontPixelHeight
|
||||
implicitHeight: Math.max(buttonsPage.implicitHeight, photoVideoPage.implicitHeight)
|
||||
implicitWidth: Math.max(buttonsPage.implicitWidth, photoVideoPage.implicitWidth)
|
||||
|
||||
MvPanelPage {
|
||||
id: buttonsPage
|
||||
implicitHeight: buttonsColumnLayout.implicitHeight + ScreenTools.defaultFontPixelHeight * 2
|
||||
implicitWidth: buttonsColumnLayout.implicitWidth + ScreenTools.defaultFontPixelHeight * 2
|
||||
|
||||
ColumnLayout {
|
||||
id: buttonsColumnLayout
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: ScreenTools.defaultFontPixelHeight / 2
|
||||
implicitHeight: Math.max(selectionRowLayout.height, actionRowLayout.height) + ScreenTools.defaultFontPixelHeight * 2
|
||||
implicitWidth: Math.max(selectionRowLayout.width, actionRowLayout.width) + ScreenTools.defaultFontPixelHeight * 4
|
||||
|
||||
QGCLabel {
|
||||
text: qsTr("Multi Vehicle Selection")
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: selectionRowLayout
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Select All")
|
||||
enabled: multiVehicleList.selectedVehicles && multiVehicleList.selectedVehicles.count !== QGroundControl.multiVehicleManager.vehicles.count
|
||||
onClicked: multiVehicleList.selectAll()
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Deselect All")
|
||||
enabled: multiVehicleList.selectedVehicles && multiVehicleList.selectedVehicles.count > 0
|
||||
onClicked: multiVehicleList.deselectAll()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
QGCLabel {
|
||||
text: qsTr("Multi Vehicle Actions")
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: actionRowLayout
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Arm")
|
||||
enabled: multiVehicleList.armAvailable()
|
||||
onClicked: _guidedController.confirmAction(_guidedController.actionMVArm)
|
||||
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 2.75
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Disarm")
|
||||
enabled: multiVehicleList.disarmAvailable()
|
||||
onClicked: _guidedController.confirmAction(_guidedController.actionMVDisarm)
|
||||
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 2.75
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Start")
|
||||
enabled: multiVehicleList.startAvailable()
|
||||
onClicked: _guidedController.confirmAction(_guidedController.actionMVStartMission)
|
||||
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 2.75
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Pause")
|
||||
enabled: multiVehicleList.pauseAvailable()
|
||||
onClicked: _guidedController.confirmAction(_guidedController.actionMVPause)
|
||||
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 2.75
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Page 1
|
||||
|
||||
MvPanelPage {
|
||||
|
||||
id: photoVideoPage
|
||||
implicitHeight: photoVideoControlLoader.implicitHeight + ScreenTools.defaultFontPixelHeight * 2
|
||||
implicitWidth: photoVideoControlLoader.implicitWidth + ScreenTools.defaultFontPixelHeight * 2
|
||||
|
||||
// We use a Loader to load the photoVideoControlComponent only when the active vehicle is not null
|
||||
// This make it easier to implement PhotoVideoControl without having to check for the mavlink camera
|
||||
// to be null all over the place
|
||||
|
||||
Loader {
|
||||
id: photoVideoControlLoader
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
sourceComponent: globals.activeVehicle ? photoVideoControlComponent : undefined
|
||||
|
||||
property real rightEdgeCenterInset: visible ? parent.width - x : 0
|
||||
|
||||
Component {
|
||||
id: photoVideoControlComponent
|
||||
|
||||
PhotoVideoControl {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Page 2
|
||||
} // QGCSwipeView
|
||||
|
||||
QGCPageIndicator {
|
||||
id: pageIndicator
|
||||
count: swipePages.count
|
||||
currentIndex: swipePages.currentIndex
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.margins: ScreenTools.defaultFontPixelHeight / 4
|
||||
|
||||
delegate: Rectangle {
|
||||
height: ScreenTools.defaultFontPixelHeight / 2
|
||||
width: height
|
||||
radius: width / 2
|
||||
color: model.index === pageIndicator.currentIndex ? qgcPal.text : qgcPal.button
|
||||
opacity: model.index === pageIndicator.currentIndex ? 0.9 : 0.3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,17 +59,30 @@ Item {
|
||||
leftEdgeTopInset: toolStrip.leftEdgeTopInset
|
||||
leftEdgeCenterInset: toolStrip.leftEdgeCenterInset
|
||||
leftEdgeBottomInset: virtualJoystickMultiTouch.visible ? virtualJoystickMultiTouch.leftEdgeBottomInset : parentToolInsets.leftEdgeBottomInset
|
||||
rightEdgeTopInset: topRightColumnLayout.rightEdgeTopInset
|
||||
rightEdgeCenterInset: topRightColumnLayout.rightEdgeCenterInset
|
||||
rightEdgeTopInset: topRightPanel.rightEdgeTopInset
|
||||
rightEdgeCenterInset: topRightPanel.rightEdgeCenterInset
|
||||
rightEdgeBottomInset: bottomRightRowLayout.rightEdgeBottomInset
|
||||
topEdgeLeftInset: toolStrip.topEdgeLeftInset
|
||||
topEdgeCenterInset: mapScale.topEdgeCenterInset
|
||||
topEdgeRightInset: topRightColumnLayout.topEdgeRightInset
|
||||
topEdgeRightInset: topRightPanel.topEdgeRightInset
|
||||
bottomEdgeLeftInset: virtualJoystickMultiTouch.visible ? virtualJoystickMultiTouch.bottomEdgeLeftInset : parentToolInsets.bottomEdgeLeftInset
|
||||
bottomEdgeCenterInset: bottomRightRowLayout.bottomEdgeCenterInset
|
||||
bottomEdgeRightInset: virtualJoystickMultiTouch.visible ? virtualJoystickMultiTouch.bottomEdgeRightInset : bottomRightRowLayout.bottomEdgeRightInset
|
||||
}
|
||||
|
||||
FlyViewTopRightPanel {
|
||||
id: topRightPanel
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: _layoutMargin
|
||||
anchors.rightMargin: _layoutMargin
|
||||
maximumHeight: parent.height - (bottomRightRowLayout.height + _margins * 5)
|
||||
|
||||
property real topEdgeRightInset: height + _layoutMargin
|
||||
property real rightEdgeTopInset: width + _layoutMargin
|
||||
property real rightEdgeCenterInset: rightEdgeTopInset
|
||||
}
|
||||
|
||||
FlyViewTopRightColumnLayout {
|
||||
id: topRightColumnLayout
|
||||
anchors.margins: _layoutMargin
|
||||
@@ -77,6 +90,7 @@ Item {
|
||||
anchors.bottom: bottomRightRowLayout.top
|
||||
anchors.right: parent.right
|
||||
spacing: _layoutSpacing
|
||||
visible: !topRightPanel.visible
|
||||
|
||||
property real topEdgeRightInset: childrenRect.height + _layoutMargin
|
||||
property real rightEdgeTopInset: width + _layoutMargin
|
||||
|
||||
@@ -34,8 +34,10 @@ Item {
|
||||
|
||||
readonly property string emergencyStopTitle: qsTr("EMERGENCY STOP")
|
||||
readonly property string armTitle: qsTr("Arm")
|
||||
readonly property string mvArmTitle: qsTr("Arm (MV)")
|
||||
readonly property string forceArmTitle: qsTr("Force Arm")
|
||||
readonly property string disarmTitle: qsTr("Disarm")
|
||||
readonly property string mvDisarmTitle: qsTr("Disarm (MV)")
|
||||
readonly property string rtlTitle: qsTr("Return")
|
||||
readonly property string takeoffTitle: qsTr("Takeoff")
|
||||
readonly property string gripperTitle: qsTr("Gripper Function")
|
||||
@@ -62,12 +64,15 @@ Item {
|
||||
readonly property string changeHeadingTitle: qsTr("Change Heading")
|
||||
|
||||
readonly property string armMessage: qsTr("Arm the vehicle.")
|
||||
readonly property string mvArmMessage: qsTr("Arm selected vehicles.")
|
||||
readonly property string forceArmMessage: qsTr("WARNING: This will force arming of the vehicle bypassing any safety checks.")
|
||||
readonly property string disarmMessage: qsTr("Disarm the vehicle")
|
||||
readonly property string mvDisarmMessage: qsTr("Disarm selected vehicles.")
|
||||
readonly property string emergencyStopMessage: qsTr("WARNING: THIS WILL STOP ALL MOTORS. IF VEHICLE IS CURRENTLY IN THE AIR IT WILL CRASH.")
|
||||
readonly property string takeoffMessage: qsTr("Takeoff from ground and hold position.")
|
||||
readonly property string gripperMessage: qsTr("Grab or Release the cargo")
|
||||
readonly property string gripperMessage: qsTr("Grab or Release the cargo")
|
||||
readonly property string startMissionMessage: qsTr("Takeoff from ground and start the current mission.")
|
||||
readonly property string mvStartMissionMessage: qsTr("Takeoff from ground and start the current mission for selected vehicles.")
|
||||
readonly property string continueMissionMessage: qsTr("Continue the mission from the current waypoint.")
|
||||
readonly property string resumeMissionUploadFailMessage: qsTr("Upload of resume mission failed. Confirm to retry upload")
|
||||
readonly property string landMessage: qsTr("Land the vehicle at the current position.")
|
||||
@@ -80,7 +85,7 @@ Item {
|
||||
readonly property string orbitMessage: qsTr("Orbit the vehicle around the specified location.")
|
||||
readonly property string landAbortMessage: qsTr("Abort the landing sequence.")
|
||||
readonly property string pauseMessage: qsTr("Pause the vehicle at it's current position, adjusting altitude up or down as needed.")
|
||||
readonly property string mvPauseMessage: qsTr("Pause all vehicles at their current position.")
|
||||
readonly property string mvPauseMessage: qsTr("Pause selected vehicles at their current position.")
|
||||
readonly property string vtolTransitionFwdMessage: qsTr("Transition VTOL to fixed wing flight.")
|
||||
readonly property string vtolTransitionMRMessage: qsTr("Transition VTOL to multi-rotor flight.")
|
||||
readonly property string roiMessage: qsTr("Make the specified location a Region Of Interest.")
|
||||
@@ -119,6 +124,10 @@ Item {
|
||||
readonly property int actionSetEstimatorOrigin: 28
|
||||
readonly property int actionSetFlightMode: 29
|
||||
readonly property int actionChangeHeading: 30
|
||||
readonly property int actionMVArm: 31
|
||||
readonly property int actionMVDisarm: 32
|
||||
|
||||
|
||||
|
||||
readonly property int customActionStart: 10000 // Custom actions ids should start here so that they don't collide with the built in actions
|
||||
|
||||
@@ -417,6 +426,11 @@ Item {
|
||||
confirmDialog.message = armMessage
|
||||
confirmDialog.hideTrigger = Qt.binding(function() { return !showArm })
|
||||
break;
|
||||
case actionMVArm:
|
||||
confirmDialog.title = mvArmTitle
|
||||
confirmDialog.message = mvArmMessage
|
||||
confirmDialog.hideTrigger = true
|
||||
break;
|
||||
case actionForceArm:
|
||||
confirmDialog.title = forceArmTitle
|
||||
confirmDialog.message = forceArmMessage
|
||||
@@ -430,6 +444,11 @@ Item {
|
||||
confirmDialog.message = disarmMessage
|
||||
confirmDialog.hideTrigger = Qt.binding(function() { return !showDisarm })
|
||||
break;
|
||||
case actionMVDisarm:
|
||||
confirmDialog.title = mvDisarmTitle
|
||||
confirmDialog.message = mvDisarmMessage
|
||||
confirmDialog.hideTrigger = true
|
||||
break;
|
||||
case actionEmergencyStop:
|
||||
confirmDialog.title = emergencyStopTitle
|
||||
confirmDialog.message = emergencyStopMessage
|
||||
@@ -449,7 +468,7 @@ Item {
|
||||
break;
|
||||
case actionMVStartMission:
|
||||
confirmDialog.title = mvStartMissionTitle
|
||||
confirmDialog.message = startMissionMessage
|
||||
confirmDialog.message = mvStartMissionMessage
|
||||
confirmDialog.hideTrigger = true
|
||||
break;
|
||||
case actionContinueMission:
|
||||
@@ -576,7 +595,7 @@ Item {
|
||||
// Executes the specified action
|
||||
function executeAction(actionCode, actionData, sliderOutputValue, optionChecked) {
|
||||
var i;
|
||||
var rgVehicle;
|
||||
var selectedVehicles;
|
||||
switch (actionCode) {
|
||||
case actionRTL:
|
||||
_activeVehicle.guidedModeRTL(optionChecked)
|
||||
@@ -597,20 +616,35 @@ Item {
|
||||
_activeVehicle.startMission()
|
||||
break
|
||||
case actionMVStartMission:
|
||||
rgVehicle = QGroundControl.multiVehicleManager.vehicles
|
||||
for (i = 0; i < rgVehicle.count; i++) {
|
||||
rgVehicle.get(i).startMission()
|
||||
selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
|
||||
for (i = 0; i < selectedVehicles.count; i++) {
|
||||
var vehicle = selectedVehicles.get(i)
|
||||
if (vehicle.armed === true){
|
||||
vehicle.startMission()
|
||||
}
|
||||
}
|
||||
break
|
||||
case actionArm:
|
||||
_activeVehicle.armed = true
|
||||
break
|
||||
case actionMVArm:
|
||||
selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
|
||||
for (i = 0; i < selectedVehicles.count; i++) {
|
||||
selectedVehicles.get(i).armed = true
|
||||
}
|
||||
break
|
||||
case actionForceArm:
|
||||
_activeVehicle.forceArm()
|
||||
break
|
||||
case actionDisarm:
|
||||
_activeVehicle.armed = false
|
||||
break
|
||||
case actionMVDisarm:
|
||||
selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
|
||||
for (i = 0; i < selectedVehicles.count; i++) {
|
||||
selectedVehicles.get(i).armed = false
|
||||
}
|
||||
break
|
||||
case actionEmergencyStop:
|
||||
_activeVehicle.emergencyStop()
|
||||
break
|
||||
@@ -638,9 +672,9 @@ Item {
|
||||
_activeVehicle.guidedModeChangeAltitude(altitudeChangeInMeters, true /* pauseVehicle */)
|
||||
break
|
||||
case actionMVPause:
|
||||
rgVehicle = QGroundControl.multiVehicleManager.vehicles
|
||||
for (i = 0; i < rgVehicle.count; i++) {
|
||||
rgVehicle.get(i).pauseVehicle()
|
||||
selectedVehicles = QGroundControl.multiVehicleManager.selectedVehicles
|
||||
for (i = 0; i < selectedVehicles.count; i++) {
|
||||
selectedVehicles.get(i).pauseVehicle()
|
||||
}
|
||||
break
|
||||
case actionVtolTransitionToFwdFlight:
|
||||
|
||||
@@ -19,66 +19,102 @@ import QGroundControl.Vehicle
|
||||
import QGroundControl.FlightMap
|
||||
|
||||
Item {
|
||||
property real _margin: ScreenTools.defaultFontPixelWidth / 2
|
||||
property real _widgetHeight: ScreenTools.defaultFontPixelHeight * 3
|
||||
property color _textColor: "black"
|
||||
property real _rectOpacity: 0.8
|
||||
property var _guidedController: globals.guidedControllerFlyView
|
||||
property real _margin: ScreenTools.defaultFontPixelWidth / 2
|
||||
property real _widgetHeight: ScreenTools.defaultFontPixelHeight * 2
|
||||
property var _guidedController: globals.guidedControllerFlyView
|
||||
property var _activeVehicleColor: "green"
|
||||
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
|
||||
property var selectedVehicles: QGroundControl.multiVehicleManager.selectedVehicles
|
||||
|
||||
QGCPalette { id: qgcPal }
|
||||
property real innerColumnHeight
|
||||
|
||||
Rectangle {
|
||||
id: mvCommands
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: mvCommandsColumn.height + (_margin *2)
|
||||
color: qgcPal.missionItemEditor
|
||||
opacity: _rectOpacity
|
||||
radius: _margin
|
||||
|
||||
DeadMouseArea {
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Column {
|
||||
id: mvCommandsColumn
|
||||
anchors.margins: _margin
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: _margin
|
||||
|
||||
QGCLabel {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: qsTr("The following commands will be applied to all vehicles")
|
||||
color: _textColor
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: ScreenTools.smallFontPointSize
|
||||
function armAvailable() {
|
||||
for (var i = 0; i < selectedVehicles.count; i++) {
|
||||
var vehicle = selectedVehicles.get(i)
|
||||
if (vehicle.armed === false) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: _margin
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Pause")
|
||||
onClicked: _guidedController.confirmAction(_guidedController.actionMVPause)
|
||||
}
|
||||
function disarmAvailable() {
|
||||
for (var i = 0; i < selectedVehicles.count; i++) {
|
||||
var vehicle = selectedVehicles.get(i)
|
||||
if (vehicle.armed === true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Start Mission")
|
||||
onClicked: _guidedController.confirmAction(_guidedController.actionMVStartMission)
|
||||
}
|
||||
function startAvailable() {
|
||||
for (var i = 0; i < selectedVehicles.count; i++) {
|
||||
var vehicle = selectedVehicles.get(i)
|
||||
if (vehicle.armed === true && vehicle.flightMode !== vehicle.missionFlightMode){
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function pauseAvailable() {
|
||||
for (var i = 0; i < selectedVehicles.count; i++) {
|
||||
var vehicle = selectedVehicles.get(i)
|
||||
if (vehicle.armed === true && vehicle.pauseVehicleSupported) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function selectVehicle(vehicleId) {
|
||||
QGroundControl.multiVehicleManager.selectVehicle(vehicleId)
|
||||
}
|
||||
|
||||
function deselectVehicle(vehicleId) {
|
||||
QGroundControl.multiVehicleManager.deselectVehicle(vehicleId)
|
||||
}
|
||||
|
||||
function toggleSelect(vehicleId) {
|
||||
if (!vehicleSelected(vehicleId)) {
|
||||
selectVehicle(vehicleId)
|
||||
} else {
|
||||
deselectVehicle(vehicleId)
|
||||
}
|
||||
}
|
||||
|
||||
function selectAll() {
|
||||
var vehicles = QGroundControl.multiVehicleManager.vehicles
|
||||
for (var i = 0; i < vehicles.count; i++) {
|
||||
var vehicle = vehicles.get(i)
|
||||
var vehicleId = vehicle.id
|
||||
if (!vehicleSelected(vehicleId)) {
|
||||
selectVehicle(vehicleId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function deselectAll() {
|
||||
QGroundControl.multiVehicleManager.deselectAllVehicles()
|
||||
}
|
||||
|
||||
function vehicleSelected(vehicleId) {
|
||||
for (var i = 0; i < selectedVehicles.count; i++ ) {
|
||||
var currentId = selectedVehicles.get(i).id
|
||||
if (vehicleId === currentId) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
QGCListView {
|
||||
id: missionItemEditorListView
|
||||
id: vehicleList
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: _margin
|
||||
anchors.top: mvCommands.bottom
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
spacing: ScreenTools.defaultFontPixelHeight / 2
|
||||
orientation: ListView.Vertical
|
||||
@@ -89,95 +125,80 @@ Item {
|
||||
property real _cacheBuffer: height * 2
|
||||
|
||||
delegate: Rectangle {
|
||||
width: missionItemEditorListView.width
|
||||
height: innerColumn.y + innerColumn.height + _margin
|
||||
color: qgcPal.missionItemEditor
|
||||
opacity: _rectOpacity
|
||||
radius: _margin
|
||||
width: vehicleList.width
|
||||
height: innerColumn.y + innerColumn.height + _margin
|
||||
color: QGroundControl.multiVehicleManager.activeVehicle == _vehicle ? _activeVehicleColor : qgcPal.button
|
||||
radius: _margin
|
||||
border.width: _vehicle && vehicleSelected(_vehicle.id) ? 2 : 0
|
||||
border.color: qgcPal.text
|
||||
|
||||
property var _vehicle: object
|
||||
|
||||
ColumnLayout {
|
||||
id: innerColumn
|
||||
anchors.margins: _margin
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.left
|
||||
spacing: _margin
|
||||
Rectangle {
|
||||
height: parent.height
|
||||
width: innerColumn.width
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: "transparent"
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
id: innerColumn
|
||||
anchors.margins: _margin
|
||||
spacing: _margin
|
||||
onHeightChanged: { innerColumnHeight = height + _margin * 2 + spacing * 2 }
|
||||
|
||||
QGCCompassWidget {
|
||||
id: compassWidget
|
||||
size: _widgetHeight
|
||||
usedByMultipleVehicleList: true
|
||||
vehicle: _vehicle
|
||||
}
|
||||
|
||||
QGCLabel {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
text: _vehicle ? _vehicle.id : ""
|
||||
color: _textColor
|
||||
text: " | "
|
||||
font.pointSize: ScreenTools.largeFontPointSize
|
||||
color: qgcPal.text
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
QGCLabel {
|
||||
text: _vehicle ? _vehicle.id : ""
|
||||
font.pointSize: ScreenTools.largeFontPointSize
|
||||
color: qgcPal.text
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
QGCLabel {
|
||||
text: " | "
|
||||
font.pointSize: ScreenTools.largeFontPointSize
|
||||
color: qgcPal.text
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
spacing: _margin
|
||||
spacing: _margin
|
||||
Layout.rightMargin: compassWidget.width / 4
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
FlightModeMenu {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.pointSize: ScreenTools.largeFontPointSize
|
||||
color: _textColor
|
||||
currentVehicle: _vehicle
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.pointSize: ScreenTools.largeFontPointSize
|
||||
color: qgcPal.text
|
||||
currentVehicle: _vehicle
|
||||
}
|
||||
|
||||
QGCLabel {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: _vehicle && _vehicle.armed ? qsTr("Armed") : qsTr("Disarmed")
|
||||
color: _textColor
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: _vehicle && _vehicle.armed ? qsTr("Armed") : qsTr("Disarmed")
|
||||
color: qgcPal.text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QGCCompassWidget {
|
||||
size: _widgetHeight
|
||||
usedByMultipleVehicleList: true
|
||||
vehicle: _vehicle
|
||||
}
|
||||
|
||||
QGCAttitudeWidget {
|
||||
size: _widgetHeight
|
||||
vehicle: _vehicle
|
||||
}
|
||||
} // RowLayout
|
||||
|
||||
Row {
|
||||
spacing: ScreenTools.defaultFontPixelWidth
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Arm")
|
||||
visible: _vehicle && !_vehicle.armed
|
||||
onClicked: _vehicle.armed = true
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Start Mission")
|
||||
visible: _vehicle && _vehicle.armed && _vehicle.flightMode !== _vehicle.missionFlightMode
|
||||
onClicked: _vehicle.startMission()
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Pause")
|
||||
visible: _vehicle && _vehicle.armed && _vehicle.pauseVehicleSupported
|
||||
onClicked: _vehicle.pauseVehicle()
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("RTL")
|
||||
visible: _vehicle && _vehicle.armed && _vehicle.flightMode !== _vehicle.rtlFlightMode
|
||||
onClicked: _vehicle.flightMode = _vehicle.rtlFlightMode
|
||||
}
|
||||
|
||||
QGCButton {
|
||||
text: qsTr("Take control")
|
||||
visible: _vehicle && _vehicle.armed && _vehicle.flightMode !== _vehicle.takeControlFlightMode
|
||||
onClicked: _vehicle.flightMode = _vehicle.takeControlFlightMode
|
||||
}
|
||||
} // Row
|
||||
} // ColumnLayout
|
||||
} // delegate - Rectangle
|
||||
} // QGCListView
|
||||
} // Item
|
||||
QGCMouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: toggleSelect(_vehicle.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ Canvas {
|
||||
|
||||
property real compassSize
|
||||
property real heading
|
||||
property bool simplified: false
|
||||
|
||||
property var _qgcPal: QGroundControl.globalPalette
|
||||
|
||||
@@ -33,7 +34,7 @@ Canvas {
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
ctx.strokeStyle = _qgcPal.text
|
||||
ctx.strokeStyle = simplified ? "#EE3424" : _qgcPal.text
|
||||
ctx.fillStyle = "#EE3424"
|
||||
ctx.lineWidth = 1
|
||||
ctx.beginPath()
|
||||
|
||||
@@ -21,13 +21,16 @@ Rectangle {
|
||||
height: size
|
||||
radius: width / 2
|
||||
color: qgcPal.window
|
||||
border.color: qgcPal.text
|
||||
border.width: usedByMultipleVehicleList ? 1 : 0
|
||||
opacity: vehicle && usedByMultipleVehicleList && !vehicle.armed ? 0.5 : 1
|
||||
|
||||
property real size: _defaultSize
|
||||
property var vehicle: null
|
||||
property bool usedByMultipleVehicleList: false
|
||||
|
||||
property real _defaultSize: ScreenTools.defaultFontPixelHeight * (10)
|
||||
property real _sizeRatio: ScreenTools.isTinyScreen ? (size / _defaultSize) * 0.5 : size / _defaultSize
|
||||
property real _defaultSize: usedByMultipleVehicleList ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight * 10
|
||||
property real _sizeRatio: (usedByMultipleVehicleList || ScreenTools.isTinyScreen) ? (size / _defaultSize) * 0.5 : size / _defaultSize
|
||||
property int _fontSize: ScreenTools.defaultFontPointSize * _sizeRatio < 8 ? 8 : ScreenTools.defaultFontPointSize * _sizeRatio
|
||||
property real _heading: vehicle ? vehicle.heading.rawValue : 0
|
||||
property real _headingToHome: vehicle ? vehicle.headingToHome.rawValue : 0
|
||||
@@ -36,7 +39,7 @@ Rectangle {
|
||||
property real _courseOverGround: vehicle ? vehicle.gps.courseOverGround.rawValue : 0
|
||||
property var _flyViewSettings: QGroundControl.settingsManager.flyViewSettings
|
||||
property bool _showAdditionalIndicators: _flyViewSettings.showAdditionalIndicatorsCompass.value && !usedByMultipleVehicleList
|
||||
property bool _lockNoseUpCompass: _flyViewSettings.lockNoseUpCompass.value
|
||||
property bool _lockNoseUpCompass: _flyViewSettings.lockNoseUpCompass.value && !usedByMultipleVehicleList
|
||||
|
||||
function showCOG(){
|
||||
if (_groundSpeed < 0.5) {
|
||||
@@ -75,12 +78,14 @@ Rectangle {
|
||||
}
|
||||
|
||||
CompassDial {
|
||||
anchors.fill: parent
|
||||
anchors.fill: parent
|
||||
visible: !usedByMultipleVehicleList
|
||||
}
|
||||
|
||||
CompassHeadingIndicator {
|
||||
compassSize: size
|
||||
heading: _heading
|
||||
simplified: usedByMultipleVehicleList
|
||||
}
|
||||
|
||||
Image {
|
||||
@@ -144,7 +149,7 @@ Rectangle {
|
||||
QGCLabel {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: size * 0.74
|
||||
text: vehicle ? _heading.toFixed(0) + "°" : ""
|
||||
text: vehicle && !usedByMultipleVehicleList ? _heading.toFixed(0) + "°" : ""
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
import QGroundControl
|
||||
import QGroundControl.ScreenTools
|
||||
import QGroundControl.Palette
|
||||
|
||||
Item {
|
||||
property bool showBorder: true
|
||||
property real contentMargin: ScreenTools.defaultFontPixelHeight
|
||||
default property alias contentChildren: contentContainer.data
|
||||
|
||||
Rectangle {
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
border.color: QGroundControl.globalPalette.groupBorder
|
||||
border.width: showBorder ? 1 : 0
|
||||
radius: ScreenTools.defaultFontPixelHeight / 3
|
||||
|
||||
Item {
|
||||
id: contentContainer
|
||||
anchors.fill: parent
|
||||
anchors.margins: contentMargin / 2
|
||||
anchors.bottomMargin: contentMargin * 2
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
PageIndicator {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
|
||||
SwipeView {
|
||||
|
||||
}
|
||||
@@ -49,6 +49,7 @@ MissionItemEditor 1.0 MissionItemEditor.qml
|
||||
MissionItemIndexLabel 1.0 MissionItemIndexLabel.qml
|
||||
MissionItemMapVisual 1.0 MissionItemMapVisual.qml
|
||||
MissionItemStatus 1.0 MissionItemStatus.qml
|
||||
MvPanelPage 1.0 MvPanelPage.qml
|
||||
OfflineMapButton 1.0 OfflineMapButton.qml
|
||||
OfflineMapEditor 1.0 OfflineMapEditor.qml
|
||||
OfflineMapInfo 1.0 OfflineMapInfo.qml
|
||||
@@ -84,11 +85,13 @@ QGCMenuSeparator 1.0 QGCMenuSeparator.qml
|
||||
QGCMouseArea 1.0 QGCMouseArea.qml
|
||||
QGCMovableItem 1.0 QGCMovableItem.qml
|
||||
QGCOptionsComboBox 1.0 QGCOptionsComboBox.qml
|
||||
QGCPageIndicator 1.0 QGCPageIndicator.qml
|
||||
QGCPopupDialog 1.0 QGCPopupDialog.qml
|
||||
QGCRadioButton 1.0 QGCRadioButton.qml
|
||||
QGCRoundButton 1.0 QGCRoundButton.qml
|
||||
QGCSimpleMessageDialog 1.0 QGCSimpleMessageDialog.qml
|
||||
QGCSlider 1.0 QGCSlider.qml
|
||||
QGCSwipeView 1.0 QGCSwipeView.qml
|
||||
QGCSwitch 1.0 QGCSwitch.qml
|
||||
QGCTabBar 1.0 QGCTabBar.qml
|
||||
QGCTabButton 1.0 QGCTabButton.qml
|
||||
|
||||
@@ -16,6 +16,7 @@ FlyViewToolBarIndicators 1.0 FlyViewToolBarIndicators.qml
|
||||
FlyViewToolStrip 1.0 FlyViewToolStrip.qml
|
||||
FlyViewToolStripActionList 1.0 FlyViewToolStripActionList.qml
|
||||
FlyViewTopRightColumnLayout 1.0 FlyViewTopRightColumnLayout.qml
|
||||
FlyViewTopRightPanel 1.0 FlyViewTopRightPanel.qml
|
||||
FlyViewVideo 1.0 FlyViewVideo.qml
|
||||
FlyViewWidgetLayer 1.0 FlyViewWidgetLayer.qml
|
||||
GripperMenu 1.0 GripperMenu.qml
|
||||
|
||||
@@ -138,6 +138,13 @@
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "enableMultiVehiclePanel",
|
||||
"shortDesc": "Enable Multi-Vehicle Panel",
|
||||
"longDesc": "Enable Multi-Vehicle Panel when multiple vehicles are connected.",
|
||||
"type": "bool",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "appFontPointSize",
|
||||
"shortDesc": "Application font size",
|
||||
|
||||
@@ -157,6 +157,7 @@ DECLARE_SETTINGSFACT(AppSettings, savePath)
|
||||
DECLARE_SETTINGSFACT(AppSettings, androidSaveToSDCard)
|
||||
DECLARE_SETTINGSFACT(AppSettings, useChecklist)
|
||||
DECLARE_SETTINGSFACT(AppSettings, enforceChecklist)
|
||||
DECLARE_SETTINGSFACT(AppSettings, enableMultiVehiclePanel)
|
||||
DECLARE_SETTINGSFACT(AppSettings, mapboxToken)
|
||||
DECLARE_SETTINGSFACT(AppSettings, mapboxAccount)
|
||||
DECLARE_SETTINGSFACT(AppSettings, mapboxStyle)
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
DEFINE_SETTINGFACT(androidSaveToSDCard)
|
||||
DEFINE_SETTINGFACT(useChecklist)
|
||||
DEFINE_SETTINGFACT(enforceChecklist)
|
||||
DEFINE_SETTINGFACT(enableMultiVehiclePanel)
|
||||
DEFINE_SETTINGFACT(mapboxToken)
|
||||
DEFINE_SETTINGFACT(mapboxAccount)
|
||||
DEFINE_SETTINGFACT(mapboxStyle)
|
||||
|
||||
@@ -28,6 +28,7 @@ SettingsPage {
|
||||
property var _customMavlinkActionsSettings: _settingsManager.customMavlinkActionsSettings
|
||||
property Fact _virtualJoystick: _settingsManager.appSettings.virtualJoystick
|
||||
property Fact _virtualJoystickAutoCenterThrottle: _settingsManager.appSettings.virtualJoystickAutoCenterThrottle
|
||||
property Fact _enableMultiVehiclePanel: _settingsManager.appSettings.enableMultiVehiclePanel
|
||||
property Fact _showAdditionalIndicatorsCompass: _flyViewSettings.showAdditionalIndicatorsCompass
|
||||
property Fact _lockNoseUpCompass: _flyViewSettings.lockNoseUpCompass
|
||||
property Fact _guidedMinimumAltitude: _flyViewSettings.guidedMinimumAltitude
|
||||
@@ -69,6 +70,13 @@ SettingsPage {
|
||||
property Fact _enforceChecklist: _settingsManager.appSettings.enforceChecklist
|
||||
}
|
||||
|
||||
FactCheckBoxSlider {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Enable Multi-Vehicle Panel")
|
||||
fact: _enableMultiVehiclePanel
|
||||
visible: _enableMultiVehiclePanel.visible
|
||||
}
|
||||
|
||||
FactCheckBoxSlider {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Keep Map Centered On Vehicle")
|
||||
|
||||
@@ -7,61 +7,112 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import QGroundControl
|
||||
import QGroundControl.FactSystem
|
||||
import QGroundControl.FactControls
|
||||
import QGroundControl.Controls
|
||||
import QGroundControl.MultiVehicleManager
|
||||
import QGroundControl.ScreenTools
|
||||
import QGroundControl.Palette
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//-- Multiple Vehicle Selector
|
||||
QGCComboBox {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pointSize: ScreenTools.mediumFontPointSize
|
||||
currentIndex: -1
|
||||
sizeToContents: true
|
||||
model: _vehicleModel
|
||||
RowLayout {
|
||||
id: control
|
||||
spacing: 0
|
||||
|
||||
property bool showIndicator: _multipleVehicles
|
||||
|
||||
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
|
||||
property bool _multipleVehicles: QGroundControl.multiVehicleManager.vehicles.count > 1
|
||||
property var _vehicleModel: [ ]
|
||||
property bool showIndicator: _multipleVehicles
|
||||
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
|
||||
property bool _multipleVehicles: QGroundControl.multiVehicleManager.vehicles.count > 1
|
||||
property var _vehicleModel: [ ]
|
||||
|
||||
Connections {
|
||||
target: QGroundControl.multiVehicleManager.vehicles
|
||||
onCountChanged: _updateVehicleModel()
|
||||
onCountChanged: _updateVehicleModel()
|
||||
}
|
||||
|
||||
Component.onCompleted: _updateVehicleModel()
|
||||
on_ActiveVehicleChanged: _updateVehicleModel()
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
QGCColoredImage {
|
||||
width: ScreenTools.defaultFontPixelWidth * 4
|
||||
height: ScreenTools.defaultFontPixelHeight * 1.33
|
||||
fillMode: Image.PreserveAspectFit
|
||||
mipmap: true
|
||||
color: qgcPal.text
|
||||
source: "/InstrumentValueIcons/airplane.svg"
|
||||
}
|
||||
|
||||
QGCLabel {
|
||||
text: _activeVehicle ? qsTr("Vehicle") + " " + _activeVehicle.id : qsTr("N/A")
|
||||
font.pointSize: ScreenTools.mediumFontPointSize
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: mainWindow.showIndicatorDrawer(vehicleSelectorDrawer, control)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: vehicleSelectorDrawer
|
||||
|
||||
ToolIndicatorPage {
|
||||
showExpand: true
|
||||
|
||||
contentComponent: Component {
|
||||
ColumnLayout {
|
||||
spacing: ScreenTools.defaultFontPixelWidth / 2
|
||||
|
||||
Repeater {
|
||||
model: _vehicleModel
|
||||
|
||||
QGCButton {
|
||||
text: modelData
|
||||
Layout.fillWidth: true
|
||||
|
||||
onClicked: {
|
||||
var vehicleId = modelData.split(" ")[1]
|
||||
var vehicle = QGroundControl.multiVehicleManager.getVehicleById(vehicleId)
|
||||
QGroundControl.multiVehicleManager.activeVehicle = vehicle
|
||||
mainWindow.closeIndicatorDrawer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandedComponent: Component {
|
||||
SettingsGroupLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
FactCheckBoxSlider {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Enable Multi-Vehicle Panel")
|
||||
fact: _enableMultiVehiclePanel
|
||||
visible: _enableMultiVehiclePanel.visible
|
||||
|
||||
property Fact _enableMultiVehiclePanel: QGroundControl.settingsManager.appSettings.enableMultiVehiclePanel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _updateVehicleModel() {
|
||||
var newCurrentIndex = -1
|
||||
var newModel = [ ]
|
||||
if (_multipleVehicles) {
|
||||
for (var i = 0; i < QGroundControl.multiVehicleManager.vehicles.count; i++) {
|
||||
var vehicle = QGroundControl.multiVehicleManager.vehicles.get(i)
|
||||
newModel.push(qsTr("Vehicle") + " " + vehicle.id)
|
||||
|
||||
if (vehicle.id === _activeVehicle.id) {
|
||||
newCurrentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
currentIndex = -1
|
||||
_vehicleModel = newModel
|
||||
currentIndex = newCurrentIndex
|
||||
}
|
||||
|
||||
onActivated: (index) => {
|
||||
var vehicleId = textAt(index).split(" ")[1]
|
||||
var vehicle = QGroundControl.multiVehicleManager.getVehicleById(vehicleId)
|
||||
QGroundControl.multiVehicleManager.activeVehicle = vehicle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ MultiVehicleManager::MultiVehicleManager(QObject *parent)
|
||||
, _gcsHeartbeatTimer(new QTimer(this))
|
||||
, _offlineEditingVehicle(new Vehicle(Vehicle::MAV_AUTOPILOT_TRACK, Vehicle::MAV_TYPE_TRACK, this))
|
||||
, _vehicles(new QmlObjectListModel(this))
|
||||
, _selectedVehicles(new QmlObjectListModel(this))
|
||||
{
|
||||
// qCDebug(MultiVehicleManagerLog) << Q_FUNC_INFO << this;
|
||||
}
|
||||
@@ -206,6 +207,8 @@ void MultiVehicleManager::_deleteVehiclePhase1(Vehicle *vehicle)
|
||||
qCWarning(MultiVehicleManagerLog) << "Vehicle not found in map!";
|
||||
}
|
||||
|
||||
deselectVehicle(vehicle->id());
|
||||
|
||||
_setActiveVehicleAvailable(false);
|
||||
_setParameterReadyVehicleAvailable(false);
|
||||
emit vehicleRemoved(vehicle);
|
||||
@@ -333,6 +336,42 @@ void MultiVehicleManager::_sendGCSHeartbeat()
|
||||
}
|
||||
}
|
||||
|
||||
void MultiVehicleManager::selectVehicle(int vehicleId)
|
||||
{
|
||||
if(!_vehicleSelected(vehicleId)) {
|
||||
Vehicle *const vehicle = getVehicleById(vehicleId);
|
||||
_selectedVehicles->append(vehicle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiVehicleManager::deselectVehicle(int vehicleId)
|
||||
{
|
||||
for (int i = 0; i < _selectedVehicles->count(); i++) {
|
||||
Vehicle *const vehicle = qobject_cast<Vehicle*>(_selectedVehicles->get(i));
|
||||
if (vehicle->id() == vehicleId) {
|
||||
_selectedVehicles->removeAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiVehicleManager::deselectAllVehicles()
|
||||
{
|
||||
_selectedVehicles->clear();
|
||||
}
|
||||
|
||||
bool MultiVehicleManager::_vehicleSelected(int vehicleId)
|
||||
{
|
||||
for (int i = 0; i < _selectedVehicles->count(); i++) {
|
||||
Vehicle *const vehicle = qobject_cast<Vehicle*>(_selectedVehicles->get(i));
|
||||
if (vehicle->id() == vehicleId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Vehicle *MultiVehicleManager::getVehicleById(int vehicleId) const
|
||||
{
|
||||
for (int i = 0; i < _vehicles->count(); i++) {
|
||||
|
||||
@@ -33,6 +33,7 @@ class MultiVehicleManager : public QObject
|
||||
Q_PROPERTY(bool parameterReadyVehicleAvailable READ _getParameterReadyVehicleAvailable NOTIFY parameterReadyVehicleAvailableChanged)
|
||||
Q_PROPERTY(Vehicle *activeVehicle READ activeVehicle WRITE setActiveVehicle NOTIFY activeVehicleChanged)
|
||||
Q_PROPERTY(QmlObjectListModel *vehicles READ vehicles CONSTANT)
|
||||
Q_PROPERTY(QmlObjectListModel *selectedVehicles READ selectedVehicles CONSTANT)
|
||||
Q_PROPERTY(bool gcsHeartBeatEnabled READ _getGcsHeartbeatEnabled WRITE _setGcsHeartbeatEnabled NOTIFY gcsHeartBeatEnabledChanged)
|
||||
Q_PROPERTY(Vehicle *offlineEditingVehicle READ offlineEditingVehicle CONSTANT)
|
||||
|
||||
@@ -45,7 +46,11 @@ public:
|
||||
|
||||
void init();
|
||||
Q_INVOKABLE Vehicle *getVehicleById(int vehicleId) const;
|
||||
Q_INVOKABLE void selectVehicle(int vehicleId);
|
||||
Q_INVOKABLE void deselectVehicle(int vehicleId);
|
||||
Q_INVOKABLE void deselectAllVehicles();
|
||||
QmlObjectListModel *vehicles() const { return _vehicles; }
|
||||
QmlObjectListModel *selectedVehicles() const { return _selectedVehicles; }
|
||||
Vehicle *offlineEditingVehicle() const { return _offlineEditingVehicle; }
|
||||
Vehicle *activeVehicle() const { return _activeVehicle; }
|
||||
void setActiveVehicle(Vehicle *vehicle);
|
||||
@@ -69,6 +74,7 @@ private slots:
|
||||
|
||||
private:
|
||||
bool _vehicleExists(int vehicleId);
|
||||
bool _vehicleSelected(int vehicleId);
|
||||
void _setActiveVehicle(Vehicle *vehicle);
|
||||
bool _getGcsHeartbeatEnabled() const { return _gcsHeartbeatEnabled; }
|
||||
void _setGcsHeartbeatEnabled(bool gcsHeartBeatEnabled);
|
||||
@@ -80,6 +86,7 @@ private:
|
||||
QTimer *_gcsHeartbeatTimer = nullptr; ///< Timer to emit heartbeats
|
||||
Vehicle *_offlineEditingVehicle = nullptr; ///< Disconnected vechicle used for offline editing
|
||||
QmlObjectListModel *_vehicles = nullptr;
|
||||
QmlObjectListModel *_selectedVehicles = nullptr;
|
||||
bool _activeVehicleAvailable = false; ///< true: An active vehicle is available
|
||||
bool _gcsHeartbeatEnabled = false; ///< Enabled/disable heartbeat emission
|
||||
bool _parameterReadyVehicleAvailable = false; ///< true: An active vehicle with ready parameters is available
|
||||
|
||||
Reference in New Issue
Block a user