Skip to content

Commit

Permalink
Multi Vehicle Panel Overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
demirciAhmet authored and DonLakeFlyer committed Jan 17, 2025
1 parent 43504cb commit d32d5f4
Show file tree
Hide file tree
Showing 20 changed files with 660 additions and 199 deletions.
4 changes: 4 additions & 0 deletions qgroundcontrol.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
31 changes: 1 addition & 30 deletions src/FlightDisplay/FlyViewTopRightColumnLayout.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -65,10 +42,4 @@ ColumnLayout {
}
}
}

MultiVehicleList {
Layout.preferredWidth: _rightPanelWidth
Layout.fillHeight: true
visible: !_showSingleVehicleUI
}
}
252 changes: 252 additions & 0 deletions src/FlightDisplay/FlyViewTopRightPanel.qml
Original file line number Diff line number Diff line change
@@ -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
}
}
}
}
}

20 changes: 17 additions & 3 deletions src/FlightDisplay/FlyViewWidgetLayer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,38 @@ 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
anchors.top: parent.top
anchors.bottom: bottomRightRowLayout.top
anchors.right: parent.right
spacing: _layoutSpacing
visible: !topRightPanel.visible

property real topEdgeRightInset: childrenRect.height + _layoutMargin
property real rightEdgeTopInset: width + _layoutMargin
Expand Down
Loading

0 comments on commit d32d5f4

Please sign in to comment.