From 7644653c89b537c23c6eb118d9d386934c523d54 Mon Sep 17 00:00:00 2001 From: DoinLakeFlyer Date: Wed, 6 May 2020 08:54:39 -0700 Subject: [PATCH] Rework Fly View into separate layers which can be customized at each layer. --- custom-example/custom.qrc | 3 + custom-example/qgcresources.exclusion | 1 + custom-example/qgroundcontrol.qrc | 19 +- custom-example/res/CustomFlyViewOverlay.qml | 134 ++++---- custom-example/src/CustomPlugin.cc | 36 ++- custom-example/src/CustomPlugin.h | 20 +- qgroundcontrol.qrc | 10 +- src/FlightDisplay/FlightDisplayView.qml | 301 ------------------ src/FlightDisplay/FlightDisplayViewVideo.qml | 13 - .../FlightDisplayViewWidgets.qml | 237 +------------- src/FlightDisplay/FlyView.qml | 165 ++++++++++ src/FlightDisplay/FlyViewCustomLayer.qml | 56 ++++ src/FlightDisplay/FlyViewInstrumentPanel.qml | 48 +++ ...lightDisplayViewMap.qml => FlyViewMap.qml} | 176 +++++----- src/FlightDisplay/FlyViewVideo.qml | 70 ++++ src/FlightDisplay/FlyViewWidgetLayer.qml | 157 +++++++++ src/FlightDisplay/GuidedActionsController.qml | 2 +- src/FlightDisplay/MultiVehiclePanel.qml | 10 +- src/FlightDisplay/VehicleWarnings.qml | 59 ++++ src/FlightDisplay/VirtualJoystick.qml | 6 +- src/FlightMap/FlightMap.qml | 9 - src/FlightMap/Widgets/MapFitFunctions.qml | 2 +- src/FlightMap/Widgets/QGCInstrumentWidget.qml | 14 +- .../Widgets/QGCInstrumentWidgetAlternate.qml | 14 +- src/PlanView/PlanToolBarIndicators.qml | 2 +- src/PlanView/PlanView.qml | 2 +- src/QGCMapPalette.cc | 1 - src/QGCMapPalette.h | 5 - src/QmlControls/DropPanel.qml | 9 +- src/QmlControls/JoystickThumbPad.qml | 75 +++-- src/QmlControls/QGCControlDebug.qml | 2 + src/QmlControls/QGCPipOverlay.qml | 10 +- src/QmlControls/QGCToolInsets.qml | 40 +++ .../QGroundControl/Controls/qmldir | 2 + .../QGroundControl/FlightDisplay/qmldir | 10 +- src/QmlControls/ToolStrip.qml | 3 +- src/api/QGCCorePlugin.cc | 13 +- src/api/QGCOptions.cc | 42 ++- src/api/QGCOptions.h | 90 +++--- src/ui/MainRootWindow.qml | 31 +- 40 files changed, 960 insertions(+), 939 deletions(-) delete mode 100644 src/FlightDisplay/FlightDisplayView.qml create mode 100644 src/FlightDisplay/FlyView.qml create mode 100644 src/FlightDisplay/FlyViewCustomLayer.qml create mode 100644 src/FlightDisplay/FlyViewInstrumentPanel.qml rename src/FlightDisplay/{FlightDisplayViewMap.qml => FlyViewMap.qml} (78%) create mode 100644 src/FlightDisplay/FlyViewVideo.qml create mode 100644 src/FlightDisplay/FlyViewWidgetLayer.qml create mode 100644 src/FlightDisplay/VehicleWarnings.qml create mode 100644 src/QmlControls/QGCToolInsets.qml diff --git a/custom-example/custom.qrc b/custom-example/custom.qrc index c277e0fd6..4c725d9ef 100644 --- a/custom-example/custom.qrc +++ b/custom-example/custom.qrc @@ -31,4 +31,7 @@ res/Custom/Widgets/CustomVehicleButton.qml res/Custom/Widgets/qmldir + + res/CustomFlyViewOverlay.qml + diff --git a/custom-example/qgcresources.exclusion b/custom-example/qgcresources.exclusion index 24807753b..2b464b95e 100644 --- a/custom-example/qgcresources.exclusion +++ b/custom-example/qgcresources.exclusion @@ -1,2 +1,3 @@ src/ui/toolbar/Images/PaperPlane.svg + src/FlightDisplay/FlyViewCustomLayer.qml diff --git a/custom-example/qgroundcontrol.qrc b/custom-example/qgroundcontrol.qrc index c0f7bae97..df70d13a4 100644 --- a/custom-example/qgroundcontrol.qrc +++ b/custom-example/qgroundcontrol.qrc @@ -127,6 +127,7 @@ ../src/QmlControls/QGCButton.qml ../src/QmlControls/QGCCheckBox.qml ../src/QmlControls/QGCColoredImage.qml + ../src/QmlControls/QGCControlDebug.qml ../src/QmlControls/QGCComboBox.qml ../src/QmlControls/QGCFileDialog.qml ../src/QmlControls/QGCFlickable.qml @@ -147,7 +148,8 @@ ../src/QmlControls/QGCMovableItem.qml ../src/QmlControls/QGCPopupDialog.qml ../src/QmlControls/QGCPopupDialogContainer.qml - ../src/QmlControls/QGCPipable.qml + ../src/QmlControls/QGCPipOverlay.qml + ../src/QmlControls/QGCPipState.qml ../src/QmlControls/QGCRadioButton.qml ../src/QmlControls/QGCSlider.qml ../src/QmlControls/QGCSwitch.qml @@ -155,6 +157,7 @@ ../src/QmlControls/QGCTabButton.qml ../src/QmlControls/QGCTextField.qml ../src/QmlControls/QGCToolBarButton.qml + ../src/QmlControls/QGCToolInsets.qml ../src/QmlControls/QGCViewDialog.qml ../src/QmlControls/QGCViewMessage.qml ../src/QmlControls/QGroundControl/Controls/qmldir @@ -190,21 +193,31 @@ ../src/FactSystem/FactControls/FactTextFieldSlider.qml ../src/FactSystem/FactControls/FactValueSlider.qml ../src/QmlControls/QGroundControl/FactControls/qmldir - ../src/FlightDisplay/FlightDisplayView.qml - ../src/FlightDisplay/FlightDisplayViewMap.qml ../src/FlightDisplay/FlightDisplayViewVideo.qml ../src/FlightDisplay/FlightDisplayViewWidgets.qml + ../src/FlightDisplay/FlyViewAirspaceIndicator.qml + ../src/FlightDisplay/FlyView.qml + ../src/FlightDisplay/FlyViewCustomLayer.qml + ../src/FlightDisplay/FlyViewInstrumentPanel.qml + ../src/FlightDisplay/FlyViewMap.qml + ../src/FlightDisplay/FlyViewMissionCompleteDialog.qml + ../src/FlightDisplay/FlyViewPreFlightChecklistPopup.qml + ../src/FlightDisplay/FlyViewToolStrip.qml + ../src/FlightDisplay/FlyViewVideo.qml + ../src/FlightDisplay/FlyViewWidgetLayer.qml ../src/FlightDisplay/GuidedActionConfirm.qml ../src/FlightDisplay/GuidedActionList.qml ../src/FlightDisplay/GuidedActionsController.qml ../src/FlightDisplay/GuidedAltitudeSlider.qml ../src/FlightDisplay/MultiVehicleList.qml + ../src/FlightDisplay/MultiVehiclePanel.qml ../src/FlightDisplay/PreFlightBatteryCheck.qml ../src/FlightDisplay/PreFlightGPSCheck.qml ../src/FlightDisplay/PreFlightRCCheck.qml ../src/FlightDisplay/PreFlightSensorsHealthCheck.qml ../src/FlightDisplay/PreFlightSoundCheck.qml ../src/FlightDisplay/TerrainProgress.qml + ../src/FlightDisplay/VehicleWarnings.qml ../src/QmlControls/QGroundControl/FlightDisplay/qmldir ../src/FlightMap/MapItems/CameraTriggerIndicator.qml ../src/FlightMap/Widgets/CenterMapDropButton.qml diff --git a/custom-example/res/CustomFlyViewOverlay.qml b/custom-example/res/CustomFlyViewOverlay.qml index 50bd38f3c..73a51484d 100644 --- a/custom-example/res/CustomFlyViewOverlay.qml +++ b/custom-example/res/CustomFlyViewOverlay.qml @@ -9,44 +9,38 @@ * @author Gus Grubba */ -import QtQuick 2.11 -import QtQuick.Controls 2.4 -import QtQuick.Layouts 1.11 -import QtQuick.Dialogs 1.3 -import QtPositioning 5.2 +import QtQuick 2.12 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.11 -import QGroundControl 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.FlightMap 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Vehicle 1.0 -import QGroundControl.QGCPositionManager 1.0 +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 import Custom.Widgets 1.0 Item { - anchors.fill: parent - visible: !QGroundControl.videoManager.fullScreen + property var parentToolInsets // These insets tell you what screen real estate is available for positioning the controls in your overlay + property var totalToolInsets: _totalToolInsets // The insets updated for the custom overlay additions + property var mapControl - readonly property string scaleState: "topMode" readonly property string noGPS: qsTr("NO GPS") readonly property real indicatorValueWidth: ScreenTools.defaultFontPixelWidth * 7 + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle property real _indicatorDiameter: ScreenTools.defaultFontPixelWidth * 18 property real _indicatorsHeight: ScreenTools.defaultFontPixelHeight property var _sepColor: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.5) : Qt.rgba(1,1,1,0.5) property color _indicatorsColor: qgcPal.text - - property bool _isVehicleGps: activeVehicle && activeVehicle.gps && activeVehicle.gps.count.rawValue > 1 && activeVehicle.gps.hdop.rawValue < 1.4 - - property string _altitude: activeVehicle ? (isNaN(activeVehicle.altitudeRelative.value) ? "0.0" : activeVehicle.altitudeRelative.value.toFixed(1)) + ' ' + activeVehicle.altitudeRelative.units : "0.0" - property string _distanceStr: isNaN(_distance) ? "0" : _distance.toFixed(0) + ' ' + (activeVehicle ? activeVehicle.altitudeRelative.units : "") - property real _heading: activeVehicle ? activeVehicle.heading.rawValue : 0 - - property real _distance: 0.0 + property bool _isVehicleGps: _activeVehicle ? _activeVehicle.gps.count.rawValue > 1 && _activeVehicle.gps.hdop.rawValue < 1.4 : false + property string _altitude: _activeVehicle ? (isNaN(_activeVehicle.altitudeRelative.value) ? "0.0" : _activeVehicle.altitudeRelative.value.toFixed(1)) + ' ' + _activeVehicle.altitudeRelative.units : "0.0" + property string _distanceStr: isNaN(_distance) ? "0" : _distance.toFixed(0) + ' ' + QGroundControl.unitsConversion.appSettingsHorizontalDistanceUnitsString + property real _heading: _activeVehicle ? _activeVehicle.heading.rawValue : 0 + property real _distance: _activeVehicle ? _activeVehicle.distanceToHome.rawValue : 0 property string _messageTitle: "" property string _messageText: "" + property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75 function secondsToHHMMSS(timeS) { var sec_num = parseInt(timeS, 10); @@ -59,41 +53,27 @@ Item { return hours+':'+minutes+':'+seconds; } - // FIXE: Isn't distance to home in factgroup - Connections { - target: QGroundControl.qgcPositionManger - onGcsPositionChanged: { - if (activeVehicle && gcsPosition.latitude && Math.abs(gcsPosition.latitude) > 0.001 && gcsPosition.longitude && Math.abs(gcsPosition.longitude) > 0.001) { - var gcs = QtPositioning.coordinate(gcsPosition.latitude, gcsPosition.longitude) - var veh = activeVehicle.coordinate; - _distance = QGroundControl.unitsConversion.metersToAppSettingsHorizontalDistanceUnits(gcs.distanceTo(veh)); - //-- Ignore absurd values - if(_distance > 99999) - _distance = 0; - if(_distance < 0) - _distance = 0; - } else { - _distance = 0; - } - } + QGCToolInsets { + id: _totalToolInsets + topEdgeCenterInset: compassArrowIndicator.y + compassArrowIndicator.height + bottomEdgeRightInset: parent.height - vehicleIndicator.y + bottomEdgeCenterInset: bottomEdgeRightInset } //------------------------------------------------------------------------- //-- Heading Indicator Rectangle { - id: compassBar - height: ScreenTools.defaultFontPixelHeight * 1.5 - width: ScreenTools.defaultFontPixelWidth * 50 - color: "#DEDEDE" - radius: 2 - clip: true - anchors.top: parent.top - anchors.topMargin: ScreenTools.defaultFontPixelHeight - anchors.horizontalCenter: parent.horizontalCenter - visible: !mainIsMap + id: compassBar + height: ScreenTools.defaultFontPixelHeight * 1.5 + width: ScreenTools.defaultFontPixelWidth * 50 + color: "#DEDEDE" + radius: 2 + clip: true + anchors.top: headingIndicator.bottom + anchors.topMargin: -headingIndicator.height / 2 + anchors.horizontalCenter: parent.horizontalCenter Repeater { model: 720 - visible: !mainIsMap QGCLabel { function _normalize(degrees) { var a = degrees % 360 @@ -128,9 +108,8 @@ Item { height: ScreenTools.defaultFontPixelHeight width: ScreenTools.defaultFontPixelWidth * 4 color: qgcPal.windowShadeDark - visible: !mainIsMap - anchors.bottom: compassBar.top - anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * -0.1 + anchors.top: parent.top + anchors.topMargin: _toolsMargin anchors.horizontalCenter: parent.horizontalCenter QGCLabel { text: _heading @@ -140,14 +119,14 @@ Item { } } Image { + id: compassArrowIndicator height: _indicatorsHeight width: height source: "/custom/img/compass_pointer.svg" - visible: !mainIsMap fillMode: Image.PreserveAspectFit sourceSize.height: height anchors.top: compassBar.bottom - anchors.topMargin: ScreenTools.defaultFontPixelHeight * -0.5 + anchors.topMargin: -height / 2 anchors.horizontalCenter: parent.horizontalCenter } //------------------------------------------------------------------------- @@ -158,10 +137,11 @@ Item { width: vehicleStatusGrid.width + (ScreenTools.defaultFontPixelWidth * 3) height: vehicleStatusGrid.height + (ScreenTools.defaultFontPixelHeight * 1.5) radius: 2 + //anchors.bottomMargin: parentToolInsets.bottomEdgeRightInset anchors.bottom: parent.bottom - anchors.bottomMargin: ScreenTools.defaultFontPixelWidth - anchors.right: attitudeIndicator.visible ? attitudeIndicator.left : parent.right - anchors.rightMargin: attitudeIndicator.visible ? -ScreenTools.defaultFontPixelWidth : ScreenTools.defaultFontPixelWidth + anchors.bottomMargin: _toolsMargin + anchors.right: attitudeIndicator.left + anchors.rightMargin: -ScreenTools.defaultFontPixelWidth GridLayout { id: vehicleStatusGrid @@ -174,27 +154,25 @@ Item { Item { Layout.rowSpan: 3 Layout.column: 6 - Layout.minimumWidth: mainIsMap ? parent.height * 1.25 : 0 + Layout.minimumWidth: parent.height * 1.25 Layout.fillHeight: true Layout.fillWidth: true //-- Large circle Rectangle { - height: mainIsMap ? parent.height : 0 - width: mainIsMap ? height : 0 + height: parent.height + width: height radius: height * 0.5 border.color: qgcPal.text border.width: 1 color: Qt.rgba(0,0,0,0) anchors.centerIn: parent - visible: mainIsMap } //-- North Label Rectangle { - height: mainIsMap ? ScreenTools.defaultFontPixelHeight * 0.75 : 0 - width: mainIsMap ? ScreenTools.defaultFontPixelWidth * 2 : 0 + height: ScreenTools.defaultFontPixelHeight * 0.75 + width: ScreenTools.defaultFontPixelWidth * 2 radius: ScreenTools.defaultFontPixelWidth * 0.25 color: qgcPal.windowShade - visible: mainIsMap anchors.top: parent.top anchors.topMargin: ScreenTools.defaultFontPixelHeight * -0.25 anchors.horizontalCenter: parent.horizontalCenter @@ -209,11 +187,10 @@ Item { Image { id: compassNeedle anchors.centerIn: parent - height: mainIsMap ? parent.height * 0.75 : 0 + height: parent.height * 0.75 width: height source: "/custom/img/compass_needle.svg" fillMode: Image.PreserveAspectFit - visible: mainIsMap sourceSize.height: height transform: [ Rotation { @@ -224,11 +201,10 @@ Item { } //-- Heading Rectangle { - height: mainIsMap ? ScreenTools.defaultFontPixelHeight * 0.75 : 0 - width: mainIsMap ? ScreenTools.defaultFontPixelWidth * 3.5 : 0 + height: ScreenTools.defaultFontPixelHeight * 0.75 + width: ScreenTools.defaultFontPixelWidth * 3.5 radius: ScreenTools.defaultFontPixelWidth * 0.25 color: qgcPal.windowShade - visible: mainIsMap anchors.bottom: parent.bottom anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * -0.25 anchors.horizontalCenter: parent.horizontalCenter @@ -254,8 +230,8 @@ Item { QGCLabel { id: firstLabel text: { - if(activeVehicle) - return secondsToHHMMSS(activeVehicle.getFact("flightTime").value) + if(_activeVehicle) + return secondsToHHMMSS(_activeVehicle.getFact("flightTime").value) return "00:00:00" } color: _indicatorsColor @@ -275,7 +251,7 @@ Item { color: qgcPal.text } QGCLabel { - text: activeVehicle ? activeVehicle.groundSpeed.value.toFixed(1) + ' ' + activeVehicle.groundSpeed.units : "0.0" + text: _activeVehicle ? _activeVehicle.groundSpeed.value.toFixed(1) + ' ' + _activeVehicle.groundSpeed.units : "0.0" color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true @@ -294,7 +270,7 @@ Item { } QGCLabel { - text: activeVehicle ? activeVehicle.climbRate.value.toFixed(1) + ' ' + activeVehicle.climbRate.units : "0.0" + text: _activeVehicle ? _activeVehicle.climbRate.value.toFixed(1) + ' ' + _activeVehicle.climbRate.units : "0.0" color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true @@ -314,7 +290,7 @@ Item { } QGCLabel { - text: activeVehicle ? ('00000' + activeVehicle.flightDistance.value.toFixed(0)).slice(-5) + ' ' + activeVehicle.flightDistance.units : "00000" + text: _activeVehicle ? ('00000' + _activeVehicle.flightDistance.value.toFixed(0)).slice(-5) + ' ' + _activeVehicle.flightDistance.units : "00000" color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true @@ -374,15 +350,15 @@ Item { id: attitudeIndicator anchors.bottom: vehicleIndicator.bottom anchors.bottomMargin: ScreenTools.defaultFontPixelWidth * -0.5 - anchors.right: parent.right - anchors.rightMargin: ScreenTools.defaultFontPixelWidth + anchors.right: parent.right + anchors.rightMargin: _toolsMargin height: ScreenTools.defaultFontPixelHeight * 6 width: height radius: height * 0.5 color: qgcPal.windowShade CustomAttitudeWidget { size: parent.height * 0.95 - vehicle: activeVehicle + vehicle: _activeVehicle showHeading: false anchors.centerIn: parent } diff --git a/custom-example/src/CustomPlugin.cc b/custom-example/src/CustomPlugin.cc index 4057d619d..ace69a877 100644 --- a/custom-example/src/CustomPlugin.cc +++ b/custom-example/src/CustomPlugin.cc @@ -26,33 +26,41 @@ QGC_LOGGING_CATEGORY(CustomLog, "CustomLog") -CustomOptions::CustomOptions(CustomPlugin*, QObject* parent) - : QGCOptions(parent) +CustomFlyViewOptions::CustomFlyViewOptions(CustomOptions* options, QObject* parent) + : QGCFlyViewOptions(options, parent) { + } -// Firmware upgrade page is only shown in Advanced Mode. -bool CustomOptions::showFirmwareUpgrade() const +// This custom build does not support conecting multiple vehicles to it. This in turn simplifies various parts of the QGC ui. +bool CustomFlyViewOptions::showMultiVehicleList(void) const { - return qgcApp()->toolbox()->corePlugin()->showAdvancedUI(); + return false; } -// This custom build does not support conecting multiple vehicles to it. This in turn simplifies various parts of the QGC ui. -bool CustomOptions::enableMultiVehicleList(void) const +// This custom build has it's own custom instrument panel. Don't show regular one. +bool CustomFlyViewOptions::showInstrumentPanel(void) const { return false; } -// This allows you to show a custom overlay on the fly screen. -QUrl CustomOptions::flyViewOverlay(void) const +CustomOptions::CustomOptions(CustomPlugin*, QObject* parent) + : QGCOptions(parent) +{ +} + +QGCFlyViewOptions* CustomOptions::flyViewOptions(void) { - return QUrl::fromUserInput("qrc:/custom/CustomFlyViewOverlay.qml"); + if (!_flyViewOptions) { + _flyViewOptions = new CustomFlyViewOptions(this, this); + } + return _flyViewOptions; } -// The standard instrement widget is now show. Only the custom overlay is shown. -CustomInstrumentWidget* CustomOptions::instrumentWidget(void) +// Firmware upgrade page is only shown in Advanced Mode. +bool CustomOptions::showFirmwareUpgrade() const { - return nullptr; + return qgcApp()->toolbox()->corePlugin()->showAdvancedUI(); } // Normal QGC needs to work with an ESP8266 WiFi thing which is remarkably crappy. This in turns causes PX4 Pro calibration to fail @@ -63,11 +71,9 @@ bool CustomOptions::wifiReliableForCalibration(void) const return true; } - CustomPlugin::CustomPlugin(QGCApplication *app, QGCToolbox* toolbox) : QGCCorePlugin(app, toolbox) { - _options = new CustomOptions(this, this); _showAdvancedUI = false; } diff --git a/custom-example/src/CustomPlugin.h b/custom-example/src/CustomPlugin.h index 53b63fc9f..9b4e1c6bb 100644 --- a/custom-example/src/CustomPlugin.h +++ b/custom-example/src/CustomPlugin.h @@ -19,25 +19,35 @@ #include +class CustomOptions; class CustomPlugin; class CustomSettings; Q_DECLARE_LOGGING_CATEGORY(CustomLog) +class CustomFlyViewOptions : public QGCFlyViewOptions +{ +public: + CustomFlyViewOptions(CustomOptions* options, QObject* parent = nullptr); + + // Overrides from CustomFlyViewOptions + bool showInstrumentPanel (void) const final; + bool showMultiVehicleList (void) const final; +}; + class CustomOptions : public QGCOptions { public: CustomOptions(CustomPlugin*, QObject* parent = nullptr); // Overrides from QGCOptions - bool wifiReliableForCalibration (void) const final; - QUrl flyViewOverlay (void) const final; - CustomInstrumentWidget* instrumentWidget (void) final; bool showFirmwareUpgrade (void) const final; - bool enableMultiVehicleList (void) const final; -}; + QGCFlyViewOptions* flyViewOptions(void) final; +private: + CustomFlyViewOptions* _flyViewOptions = nullptr; +}; class CustomPlugin : public QGCCorePlugin { diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index f2cc59db8..1d2f9aaa3 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -157,6 +157,7 @@ src/QmlControls/QGCTabButton.qml src/QmlControls/QGCTextField.qml src/QmlControls/QGCToolBarButton.qml + src/QmlControls/QGCToolInsets.qml src/QmlControls/QGCViewDialog.qml src/QmlControls/QGCViewMessage.qml src/QmlControls/QGroundControl/Controls/qmldir @@ -192,14 +193,18 @@ src/FactSystem/FactControls/FactTextFieldSlider.qml src/FactSystem/FactControls/FactValueSlider.qml src/QmlControls/QGroundControl/FactControls/qmldir - src/FlightDisplay/FlightDisplayView.qml - src/FlightDisplay/FlightDisplayViewMap.qml src/FlightDisplay/FlightDisplayViewVideo.qml src/FlightDisplay/FlightDisplayViewWidgets.qml src/FlightDisplay/FlyViewAirspaceIndicator.qml + src/FlightDisplay/FlyView.qml + src/FlightDisplay/FlyViewCustomLayer.qml + src/FlightDisplay/FlyViewInstrumentPanel.qml + src/FlightDisplay/FlyViewMap.qml src/FlightDisplay/FlyViewMissionCompleteDialog.qml src/FlightDisplay/FlyViewPreFlightChecklistPopup.qml src/FlightDisplay/FlyViewToolStrip.qml + src/FlightDisplay/FlyViewVideo.qml + src/FlightDisplay/FlyViewWidgetLayer.qml src/FlightDisplay/GuidedActionConfirm.qml src/FlightDisplay/GuidedActionList.qml src/FlightDisplay/GuidedActionsController.qml @@ -212,6 +217,7 @@ src/FlightDisplay/PreFlightSensorsHealthCheck.qml src/FlightDisplay/PreFlightSoundCheck.qml src/FlightDisplay/TerrainProgress.qml + src/FlightDisplay/VehicleWarnings.qml src/QmlControls/QGroundControl/FlightDisplay/qmldir src/FlightMap/MapItems/CameraTriggerIndicator.qml src/FlightMap/Widgets/CenterMapDropButton.qml diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml deleted file mode 100644 index 5e3ec2246..000000000 --- a/src/FlightDisplay/FlightDisplayView.qml +++ /dev/null @@ -1,301 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 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.12 -import QtQuick.Controls 2.4 -import QtQuick.Dialogs 1.3 -import QtQuick.Layouts 1.12 - -import QtLocation 5.3 -import QtPositioning 5.3 -import QtQuick.Window 2.2 -import QtQml.Models 2.1 - -import QGroundControl 1.0 -import QGroundControl.Airspace 1.0 -import QGroundControl.Controllers 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.FactSystem 1.0 -import QGroundControl.FlightDisplay 1.0 -import QGroundControl.FlightMap 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Vehicle 1.0 - -/// Flight Display View -Item { - - PlanMasterController { - id: _planController - Component.onCompleted: { - start(true /* flyView */) - mainWindow.planMasterControllerView = _planController - } - } - - property bool _mainWindowIsMap: mapControl.pipState.state === mapControl.pipState.fullState - property bool _isMapDark: _mainWindowIsMap ? mapControl.isSatelliteMap : true - property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle - property var _missionController: _planController.missionController - property var _geoFenceController: _planController.geoFenceController - property var _rallyPointController: _planController.rallyPointController - property real _margins: ScreenTools.defaultFontPixelWidth / 2 - property alias _guidedController: guidedActionsController - property alias _guidedConfirm: guidedActionConfirm - property alias _guidedList: guidedActionList - property alias _guidedSlider: altitudeSlider - property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75 - - readonly property string _mapName: "FlightDisplayView" - - function setPipVisibility(state) { - _isPipVisible = state; - QGroundControl.saveBoolGlobalSetting(_PIPVisibleKey, state) - } - - function isInstrumentRight() { - if(QGroundControl.corePlugin.options.instrumentWidget) { - if(QGroundControl.corePlugin.options.instrumentWidget.source.toString().length) { - switch(QGroundControl.corePlugin.options.instrumentWidget.widgetPosition) { - case CustomInstrumentWidget.POS_TOP_LEFT: - case CustomInstrumentWidget.POS_BOTTOM_LEFT: - case CustomInstrumentWidget.POS_CENTER_LEFT: - return false; - } - } - } - return true; - } - - Component.onCompleted: { - if(QGroundControl.corePlugin.options.flyViewOverlay.toString().length) { - flyViewOverlay.source = QGroundControl.corePlugin.options.flyViewOverlay - } - } - - FlyViewMissionCompleteDialog { - missionController: _missionController - geoFenceController: _geoFenceController - rallyPointController: _rallyPointController - guidedController: _guidedController - } - - QGCMapPalette { id: mapPal; lightColors: _mainWindowIsMap ? mapControl.isSatelliteMap : true } - - Item { - id: _mapAndVideo - anchors.fill: parent - - FlightDisplayViewMap { - id: mapControl - guidedActionsController: _guidedController - planMasterController: _planController - flightWidgets: flightDisplayViewWidgets - rightPanelWidth: ScreenTools.defaultFontPixelHeight * 9 - scaleState: (_mainWindowIsMap && flyViewOverlay.item) ? (flyViewOverlay.item.scaleState ? flyViewOverlay.item.scaleState : "bottomMode") : "bottomMode" - mainWindowIsMap: _mainWindowIsMap - - property var pipState: mapPipState - QGCPipState { - id: mapPipState - pipOverlay: _pipOverlay - isDark: _isMapDark - } - } - - //-- Video View - Item { - id: videoControl - visible: QGroundControl.videoManager.hasVideo - - property var pipState: videoPipState - QGCPipState { - id: videoPipState - pipOverlay: _pipOverlay - isDark: true - - onWindowAboutToOpen: { - console.log("about to open") - QGroundControl.videoManager.stopVideo() - videoStartDelay.start() - } - - onWindowAboutToClose: { - console.log("about to close") - QGroundControl.videoManager.stopVideo() - videoStartDelay.start() - } - } - - Timer { - id: videoStartDelay - interval: 2000; - running: false - repeat: false - onTriggered: QGroundControl.videoManager.startVideo() - } - - //-- Video Streaming - FlightDisplayViewVideo { - id: videoStreaming - anchors.fill: parent - useSmallFont: videoControl.pipState.state !== videoControl.pipState.fullState - visible: QGroundControl.videoManager.isGStreamer - } - //-- UVC Video (USB Camera or Video Device) - Loader { - id: cameraLoader - anchors.fill: parent - visible: !QGroundControl.videoManager.isGStreamer - source: visible ? (QGroundControl.videoManager.uvcEnabled ? "qrc:/qml/FlightDisplayViewUVC.qml" : "qrc:/qml/FlightDisplayViewDummy.qml") : "" - } - } - - QGCPipOverlay { - id: _pipOverlay - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.margins: ScreenTools.defaultFontPixelHeight - item1IsFullSettingsKey: "MainFlyWindowIsMap" - item1: mapControl - item2: QGroundControl.videoManager.hasVideo ? videoControl : null - fullZOrder: 0 - pipZOrder: QGroundControl.zOrderWidgets - } - - MultiVehiclePanel { - id: singleMultiSelector - anchors.margins: _toolsMargin - anchors.top: parent.top - anchors.right: parent.right - z: QGroundControl.zOrderWidgets - availableHeight: mainWindow.availableHeight - (anchors.margins * 2) - guidedActionsController: _guidedController - } - - FlightDisplayViewWidgets { - id: flightDisplayViewWidgets - z: QGroundControl.zOrderWidgets - height: availableHeight - (singleMultiSelector.visible ? singleMultiSelector.height + _toolsMargin : 0) - _toolsMargin - anchors.left: parent.left - anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right - anchors.bottom: parent.bottom - anchors.top: singleMultiSelector.visible? singleMultiSelector.bottom : undefined - useLightColors: _isMapDark - missionController: _missionController - visible: singleMultiSelector.singleVehiclePanel && !QGroundControl.videoManager.fullScreen - } - - //------------------------------------------------------------------------- - //-- Loader helper for plugins to overlay elements over the fly view - Loader { - id: flyViewOverlay - z: QGroundControl.zOrderWidgets - visible: !QGroundControl.videoManager.fullScreen - height: mainWindow.height - mainWindow.header.height - anchors.left: parent.left - anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right - anchors.bottom: parent.bottom - } - - //-- Virtual Joystick - Loader { - id: virtualJoystickMultiTouch - z: QGroundControl.zOrderTopMost + 1 - width: parent.width - (_pipOverlay.width / 2) - height: Math.min(mainWindow.height * 0.25, ScreenTools.defaultFontPixelWidth * 16) - visible: (_virtualJoystick ? _virtualJoystick.value : false) && !QGroundControl.videoManager.fullScreen && !(_activeVehicle ? _activeVehicle.highLatencyLink : false) - anchors.bottom: _pipOverlay.top - anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 2 - anchors.horizontalCenter: flightDisplayViewWidgets.horizontalCenter - source: "qrc:/qml/VirtualJoystick.qml" - active: (_virtualJoystick ? _virtualJoystick.value : false) && !(_activeVehicle ? _activeVehicle.highLatencyLink : false) - - property bool useLightColors: _isMapDark - // The default behaviour is not centralized throttle - property bool centralizeThrottle: _virtualJoystickCentralized ? _virtualJoystickCentralized.value : false - - property Fact _virtualJoystick: QGroundControl.settingsManager.appSettings.virtualJoystick - property Fact _virtualJoystickCentralized: QGroundControl.settingsManager.appSettings.virtualJoystickCentralized - } - - FlyViewToolStrip { - id: toolStrip - anchors.leftMargin: isInstrumentRight() ? _toolsMargin : undefined - anchors.left: isInstrumentRight() ? _mapAndVideo.left : undefined - anchors.rightMargin: isInstrumentRight() ? undefined : ScreenTools.defaultFontPixelWidth - anchors.right: isInstrumentRight() ? undefined : _mapAndVideo.right - anchors.topMargin: _toolsMargin - anchors.top: parent.top - z: QGroundControl.zOrderWidgets - maxHeight: parent.height - toolStrip.y + (_pipOverlay.visible ? (_pipOverlay.y - parent.height) : 0) - guidedActionsController: _guidedController - guidedActionList: _guidedList - usePreFlightChecklist: preFlightChecklistPopup.useChecklist - visible: (_activeVehicle ? _activeVehicle.guidedModeSupported : true) && !QGroundControl.videoManager.fullScreen - - onDisplayPreFlightChecklist: preFlightChecklistPopup.open() - } - - GuidedActionsController { - id: guidedActionsController - missionController: _missionController - confirmDialog: _guidedConfirm - actionList: _guidedList - altitudeSlider: _guidedSlider - } - - GuidedActionConfirm { - id: guidedActionConfirm - anchors.margins: _margins - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - z: QGroundControl.zOrderTopMost - guidedController: _guidedController - altitudeSlider: _guidedSlider - } - - GuidedActionList { - id: guidedActionList - anchors.margins: _margins - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - z: QGroundControl.zOrderTopMost - guidedController: _guidedController - } - - //-- Altitude slider - GuidedAltitudeSlider { - id: altitudeSlider - anchors.margins: _margins - anchors.right: parent.right - anchors.topMargin: ScreenTools.toolbarHeight + _margins - anchors.top: parent.top - anchors.bottom: parent.bottom - z: QGroundControl.zOrderTopMost - radius: ScreenTools.defaultFontPixelWidth / 2 - width: ScreenTools.defaultFontPixelWidth * 10 - color: qgcPal.window - visible: false - } - } - - FlyViewAirspaceIndicator { - anchors.top: parent.top - anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 - anchors.horizontalCenter: parent.horizontalCenter - show: _mainWindowIsMap - } - - FlyViewPreFlightChecklistPopup { - id: preFlightChecklistPopup - x: toolStrip.x + toolStrip.width + (ScreenTools.defaultFontPixelWidth * 2) - y: toolStrip.y - } -} diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml index 4ce95246d..47bb72091 100644 --- a/src/FlightDisplay/FlightDisplayViewVideo.qml +++ b/src/FlightDisplay/FlightDisplayViewVideo.qml @@ -50,12 +50,6 @@ Item { font.pointSize: useSmallFont ? ScreenTools.smallFontPointSize : ScreenTools.largeFontPointSize anchors.centerIn: parent } - MouseArea { - anchors.fill: parent - onDoubleClicked: { - QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen - } - } } Rectangle { anchors.fill: parent @@ -176,13 +170,6 @@ Item { opacity: _camera ? (_camera.thermalMode === QGCCameraControl.THERMAL_BLEND ? _camera.thermalOpacity / 100 : 1.0) : 0 } } - //-- Full screen toggle - MouseArea { - anchors.fill: parent - onDoubleClicked: { - QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen - } - } //-- Zoom PinchArea { id: pinchZoom diff --git a/src/FlightDisplay/FlightDisplayViewWidgets.qml b/src/FlightDisplay/FlightDisplayViewWidgets.qml index 27c4f1834..cf316ea60 100644 --- a/src/FlightDisplay/FlightDisplayViewWidgets.qml +++ b/src/FlightDisplay/FlightDisplayViewWidgets.qml @@ -21,237 +21,20 @@ import QGroundControl.Controls 1.0 import QGroundControl.Palette 1.0 import QGroundControl.Vehicle 1.0 import QGroundControl.FlightMap 1.0 -import QGroundControl.Airspace 1.0 -import QGroundControl.Airmap 1.0 -Item { - id: widgetRoot +Column { + id: _root + spacing: ScreenTools.defaultFontPixelHeight * 0.25 - readonly property real _rightPanelWidth: Math.min(parent.width / 3, ScreenTools.defaultFontPixelWidth * 30) - - property bool useLightColors property var missionController - property bool showValues: !QGroundControl.airspaceManager.airspaceVisible - - property bool _lightWidgetBorders: true - property bool _airspaceEnabled: QGroundControl.airmapSupported ? QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue : false - - readonly property real _margins: ScreenTools.defaultFontPixelHeight * 0.5 - readonly property bool _useAlternateInstrumentPanel: QGroundControl.settingsManager.flyViewSettings.alternateInstrumentPanel.value - - function getPreferredInstrumentWidth() { - // Don't allow instrument panel to chew more than 1/4 of full window - var defaultWidth = ScreenTools.defaultFontPixelWidth * 30 - var maxWidth = mainWindow.width * 0.25 - return Math.min(maxWidth, defaultWidth) - } - - function _setInstrumentWidget() { - if(QGroundControl.corePlugin.options.instrumentWidget) { - if(QGroundControl.corePlugin.options.instrumentWidget.source.toString().length) { - instrumentsLoader.source = QGroundControl.corePlugin.options.instrumentWidget.source - switch(QGroundControl.corePlugin.options.instrumentWidget.widgetPosition) { - case CustomInstrumentWidget.POS_TOP_LEFT: - instrumentsLoader.state = "topLeftMode" - break; - case CustomInstrumentWidget.POS_BOTTOM_LEFT: - instrumentsLoader.state = "bottomLeftMode" - break; - case CustomInstrumentWidget.POS_CENTER_LEFT: - instrumentsLoader.state = "centerLeftMode" - break; - case CustomInstrumentWidget.POS_TOP_RIGHT: - instrumentsLoader.state = "topRightMode" - break; - case CustomInstrumentWidget.POS_BOTTOM_RIGHT: - instrumentsLoader.state = "bottomRightMode" - break; - case CustomInstrumentWidget.POS_CENTER_RIGHT: - default: - instrumentsLoader.state = "centerRightMode" - break; - } - } else { - if(_useAlternateInstrumentPanel){ - instrumentsLoader.source = "qrc:/qml/QGCInstrumentWidgetAlternate.qml" - } - else{ - instrumentsLoader.source = "qrc:/qml/QGCInstrumentWidget.qml" - } - } - } else { - instrumentsLoader.source = "" - } - } - Connections { - target: QGroundControl.settingsManager.flyViewSettings.alternateInstrumentPanel - onValueChanged: _setInstrumentWidget() - } - - Connections { - target: QGroundControl.settingsManager.appSettings.virtualJoystick - onValueChanged: _setInstrumentWidget() - } - Connections { - target: QGroundControl.settingsManager.appSettings.virtualJoystickCentralized - onValueChanged: _setInstrumentWidget() - } - - Connections { - target: QGroundControl.settingsManager.appSettings.showLargeCompass - onValueChanged: _setInstrumentWidget() - } - - Connections { - target: QGroundControl.airspaceManager - onAirspaceVisibleChanged: { - widgetRoot.showValues = !QGroundControl.airspaceManager.airspaceVisible - } - } - - Component.onCompleted: { - _setInstrumentWidget() - } - - //-- Map warnings + property real availableHeight - Rectangle { - anchors.margins: -ScreenTools.defaultFontPixelHeight - anchors.fill: warningsCol - color: "white" - opacity: 0.5 - radius: ScreenTools.defaultFontPixelWidth / 2 - visible: warningsCol.noGPSLockVisible || warningsCol.prearmErrorVisible - } - - Column { - id: warningsCol - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.verticalCenter - spacing: ScreenTools.defaultFontPixelHeight - - property bool noGPSLockVisible: activeVehicle && !activeVehicle.coordinate.isValid && mainIsMap - property bool prearmErrorVisible: activeVehicle && !activeVehicle.armed && activeVehicle.prearmError + Loader { + width: parent.width + source: QGroundControl.settingsManager.flyViewSettings.alternateInstrumentPanel.rawValue ? + "qrc:/qml/QGCInstrumentWidgetAlternate.qml" : "qrc:/qml/QGCInstrumentWidget.qml" - QGCLabel { - anchors.horizontalCenter: parent.horizontalCenter - visible: warningsCol.noGPSLockVisible - z: QGroundControl.zOrderTopMost - color: "black" - font.pointSize: ScreenTools.largeFontPointSize - text: qsTr("No GPS Lock for Vehicle") - } - - QGCLabel { - anchors.horizontalCenter: parent.horizontalCenter - visible: warningsCol.prearmErrorVisible - z: QGroundControl.zOrderTopMost - color: "black" - font.pointSize: ScreenTools.largeFontPointSize - text: activeVehicle ? activeVehicle.prearmError : "" - } - - QGCLabel { - anchors.horizontalCenter: parent.horizontalCenter - visible: warningsCol.prearmErrorVisible - width: ScreenTools.defaultFontPixelWidth * 50 - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - z: QGroundControl.zOrderTopMost - color: "black" - font.pointSize: ScreenTools.largeFontPointSize - text: "The vehicle has failed a pre-arm check. In order to arm the vehicle, resolve the failure." - } - } - Column { - id: instrumentsColumn - spacing: ScreenTools.defaultFontPixelHeight * 0.25 - anchors.top: parent.top - anchors.topMargin: QGroundControl.corePlugin.options.instrumentWidget ? (QGroundControl.corePlugin.options.instrumentWidget.widgetTopMargin + _toolsMargin) : 0 - anchors.margins: _toolsMargin - anchors.right: parent.right - //------------------------------------------------------- - // Airmap Airspace Control - AirspaceControl { - id: airspaceControl - width: _rightPanelWidth - planView: false - visible: _airspaceEnabled - } - //------------------------------------------------------- - //-- Instrument Panel - Loader { - id: instrumentsLoader - anchors.margins: _toolsMargin - property real maxHeight: widgetRoot ? widgetRoot.height - instrumentsColumn.y - airspaceControl.height - (ScreenTools.defaultFontPixelHeight * 4) : 0 - states: [ - State { - name: "topRightMode" - AnchorChanges { - target: instrumentsLoader - anchors.verticalCenter: undefined - anchors.bottom: undefined - anchors.top: widgetRoot ? widgetRoot.top : undefined - anchors.right: widgetRoot ? widgetRoot.right : undefined - anchors.left: undefined - } - }, - State { - name: "centerRightMode" - AnchorChanges { - target: instrumentsLoader - anchors.top: undefined - anchors.bottom: undefined - anchors.verticalCenter: widgetRoot ? widgetRoot.verticalCenter : undefined - anchors.right: widgetRoot ? widgetRoot.right : undefined - anchors.left: undefined - } - }, - State { - name: "bottomRightMode" - AnchorChanges { - target: instrumentsLoader - anchors.top: undefined - anchors.verticalCenter: undefined - anchors.bottom: widgetRoot ? widgetRoot.bottom : undefined - anchors.right: widgetRoot ? widgetRoot.right : undefined - anchors.left: undefined - } - }, - State { - name: "topLeftMode" - AnchorChanges { - target: instrumentsLoader - anchors.verticalCenter: undefined - anchors.bottom: undefined - anchors.top: widgetRoot ? widgetRoot.top : undefined - anchors.right: undefined - anchors.left: widgetRoot ? widgetRoot.left : undefined - } - }, - State { - name: "centerLeftMode" - AnchorChanges { - target: instrumentsLoader - anchors.top: undefined - anchors.bottom: undefined - anchors.verticalCenter: widgetRoot ? widgetRoot.verticalCenter : undefined - anchors.right: undefined - anchors.left: widgetRoot ? widgetRoot.left : undefined - } - }, - State { - name: "bottomLeftMode" - AnchorChanges { - target: instrumentsLoader - anchors.top: undefined - anchors.verticalCenter: undefined - anchors.bottom: widgetRoot ? widgetRoot.bottom : undefined - anchors.right: undefined - anchors.left: widgetRoot ? widgetRoot.left : undefined - } - } - ] - } + property real maxHeight: availableHeight - y + property bool showValues: !QGroundControl.airspaceManager.airspaceVisible } } diff --git a/src/FlightDisplay/FlyView.qml b/src/FlightDisplay/FlyView.qml new file mode 100644 index 000000000..21c13bad4 --- /dev/null +++ b/src/FlightDisplay/FlyView.qml @@ -0,0 +1,165 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.12 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.12 + +import QtLocation 5.3 +import QtPositioning 5.3 +import QtQuick.Window 2.2 +import QtQml.Models 2.1 + +import QGroundControl 1.0 +import QGroundControl.Airspace 1.0 +import QGroundControl.Airmap 1.0 +import QGroundControl.Controllers 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FactSystem 1.0 +import QGroundControl.FlightDisplay 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Vehicle 1.0 + +Item { + id: _root + + PlanMasterController { + id: _planController + Component.onCompleted: { + start(true /* flyView */) + mainWindow.planMasterControllerFlyView = _planController + } + } + + property bool _mainWindowIsMap: mapControl.pipState.state === mapControl.pipState.fullState + property bool _isFullWindowItemDark: _mainWindowIsMap ? mapControl.isSatelliteMap : true + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property var _missionController: _planController.missionController + property var _geoFenceController: _planController.geoFenceController + property var _rallyPointController: _planController.rallyPointController + property real _margins: ScreenTools.defaultFontPixelWidth / 2 + property var _guidedController: guidedActionsController + property var _guidedActionList: guidedActionList + property var _guidedAltSlider: guidedAltSlider + property var _guidedConfirm: guidedActionConfirm + property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75 + property rect _centerViewport: Qt.rect(0, 0, width, height) + property real _rightPanelWidth: ScreenTools.defaultFontPixelWidth * 30 + property var _mapControl: mapControl + + property real _fullItemZorder: 0 + property real _pipItemZorder: QGroundControl.zOrderWidgets + + function _calcCenterViewPort() { + var newToolInset = Qt.rect(0, 0, width, height) + toolstrip.adjustToolInset(newToolInset) + if (QGroundControl.corePlugin.options.instrumentWidget) { + flightDisplayViewWidgets.adjustToolInset(newToolInset) + } + } + + QGCToolInsets { + id: _toolInsets + leftEdgeBottomInset: _pipOverlay.visible ? _pipOverlay.x + _pipOverlay.width : 0 + bottomEdgeLeftInset: _pipOverlay.visible ? parent.height - _pipOverlay.y : 0 + } + + FlyViewWidgetLayer { + id: widgetLayer + anchors.rightMargin: _toolsMargin + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: guidedAltSlider.visible ? guidedAltSlider.left : parent.right + z: _fullItemZorder + 1 + parentToolInsets: _toolInsets + mapControl: _mapControl + visible: !QGroundControl.videoManager.fullScreen + } + + FlyViewCustomLayer { + id: customOverlay + anchors.fill: widgetLayer + z: _fullItemZorder + 2 + parentToolInsets: widgetLayer.totalToolInsets + mapControl: _mapControl + visible: !QGroundControl.videoManager.fullScreen + } + + GuidedActionsController { + id: guidedActionsController + missionController: _missionController + confirmDialog: _guidedConfirm + actionList: _guidedActionList + altitudeSlider: _guidedAltSlider + } + + GuidedActionConfirm { + id: guidedActionConfirm + anchors.margins: _margins + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + z: QGroundControl.zOrderTopMost + guidedController: _guidedController + altitudeSlider: _guidedAltSlider + } + + GuidedActionList { + id: guidedActionList + anchors.margins: _margins + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + z: QGroundControl.zOrderTopMost + guidedController: _guidedController + } + + //-- Altitude slider + GuidedAltitudeSlider { + id: guidedAltSlider + anchors.margins: _toolsMargin + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + z: QGroundControl.zOrderTopMost + radius: ScreenTools.defaultFontPixelWidth / 2 + width: ScreenTools.defaultFontPixelWidth * 10 + color: qgcPal.window + visible: false + } + + FlyViewMap { + id: mapControl + guidedActionsController: _guidedController + planMasterController: _planController + rightPanelWidth: ScreenTools.defaultFontPixelHeight * 9 + pipMode: !_mainWindowIsMap + toolInsets: customOverlay.totalToolInsets + mapName: "FlightDisplayView" + } + + FlyViewVideo { + id: videoControl + } + + QGCPipOverlay { + id: _pipOverlay + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: _toolsMargin + item1IsFullSettingsKey: "MainFlyWindowIsMap" + item1: mapControl + item2: QGroundControl.videoManager.hasVideo ? videoControl : null + fullZOrder: _fullItemZorder + pipZOrder: _pipItemZorder + show: !QGroundControl.videoManager.fullScreen + } +} diff --git a/src/FlightDisplay/FlyViewCustomLayer.qml b/src/FlightDisplay/FlyViewCustomLayer.qml new file mode 100644 index 000000000..a123f475b --- /dev/null +++ b/src/FlightDisplay/FlyViewCustomLayer.qml @@ -0,0 +1,56 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.12 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.12 + +import QtLocation 5.3 +import QtPositioning 5.3 +import QtQuick.Window 2.2 +import QtQml.Models 2.1 + +import QGroundControl 1.0 +import QGroundControl.Airspace 1.0 +import QGroundControl.Airmap 1.0 +import QGroundControl.Controllers 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FactSystem 1.0 +import QGroundControl.FlightDisplay 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Vehicle 1.0 + +// To implement a custom overlay copy this code to your own control in your custom code source. Then override the +// FlyViewCustomLayer.qml resource with your own qml. See the custom example and documentation for details. +Item { + id: _root + + property var parentToolInsets // These insets tell you what screen real estate is available for positioning the controls in your overlay + property var toolInsets: _toolInsets // These are the insets for your custom overlay additions + property var mapControl + + QGCToolInsets { + id: _toolInsets + leftEdgeCenterInset: 0 + leftEdgeTopInset: 0 + leftEdgeBottomInset: 0 + rightEdgeCenterInset: 0 + rightEdgeTopInset: 0 + rightEdgeBottomInset: 0 + topEdgeCenterInset: 0 + topEdgeLeftInset: 0 + topEdgeRightInset: 0 + bottomEdgeCenterInset: 0 + bottomEdgeLeftInset: 0 + bottomEdgeRightInset: 0 + } +} diff --git a/src/FlightDisplay/FlyViewInstrumentPanel.qml b/src/FlightDisplay/FlyViewInstrumentPanel.qml new file mode 100644 index 000000000..e49477a0c --- /dev/null +++ b/src/FlightDisplay/FlyViewInstrumentPanel.qml @@ -0,0 +1,48 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.12 + +import QGroundControl 1.0 +import QGroundControl.Airspace 1.0 +import QGroundControl.Airmap 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 + +// This control contains the instruments as well and the instrument pages which include values, camera, ... +Column { + id: _root + spacing: _toolsMargin + z: QGroundControl.zOrderWidgets + + property real availableHeight + property var guidedActionsController + + MultiVehiclePanel { + id: multiVehiclePanel + width: parent.width + availableHeight: parent.height - y + guidedActionsController: _root.guidedActionsController + } + + AirspaceControl { + id: airspaceControl + width: parent.width + planView: false + visible: QGroundControl.airmapSupported ? QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue : false + } + + FlightDisplayViewWidgets { + id: flightDisplayViewWidgets + width: parent.width + missionController: _missionController + availableHeight: _root.availableHeight - y + visible: multiVehiclePanel.singleVehiclePanel + } +} diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlyViewMap.qml similarity index 78% rename from src/FlightDisplay/FlightDisplayViewMap.qml rename to src/FlightDisplay/FlyViewMap.qml index 248a50b5f..5e0fb2abc 100644 --- a/src/FlightDisplay/FlightDisplayViewMap.qml +++ b/src/FlightDisplay/FlyViewMap.qml @@ -7,7 +7,6 @@ * ****************************************************************************/ - import QtQuick 2.11 import QtQuick.Controls 2.4 import QtLocation 5.3 @@ -25,21 +24,25 @@ import QGroundControl.ScreenTools 1.0 import QGroundControl.Vehicle 1.0 FlightMap { - id: flightMap - mapName: _mapName - allowGCSLocationCenter: !userPanned + id: _root + allowGCSLocationCenter: true allowVehicleLocationCenter: !_keepVehicleCentered planView: false zoomLevel: QGroundControl.flightMapZoom center: QGroundControl.flightMapPosition + property Item pipState: _pipState + QGCPipState { + id: _pipState + pipOverlay: _pipOverlay + isDark: _isFullWindowItemDark + } + property var guidedActionsController - property var flightWidgets property var rightPanelWidth property var planMasterController - property alias scaleState: mapScale.state - property rect centerViewport: Qt.rect(0, 0, width, height) - property bool mainWindowIsMap: true + property bool pipMode: false // true: map is shown in a small pip mode + property var toolInsets // Insets for the center viewport area property var _planMasterController: planMasterController property var _geoFenceController: planMasterController.geoFenceController @@ -51,51 +54,42 @@ FlightMap { property bool _keepMapCenteredOnVehicle: _flyViewSettings.keepMapCenteredOnVehicle.rawValue property bool _disableVehicleTracking: false - property bool _keepVehicleCentered: mainWindowIsMap ? false : true - property bool _pipping: false + property bool _keepVehicleCentered: pipMode ? true : false + property bool _saveZoomLevelSetting: true function updateAirspace(reset) { if(_airspaceEnabled) { - var coordinateNW = flightMap.toCoordinate(Qt.point(0,0), false /* clipToViewPort */) - var coordinateSE = flightMap.toCoordinate(Qt.point(width,height), false /* clipToViewPort */) + var coordinateNW = _root.toCoordinate(Qt.point(0,0), false /* clipToViewPort */) + var coordinateSE = _root.toCoordinate(Qt.point(width,height), false /* clipToViewPort */) if(coordinateNW.isValid && coordinateSE.isValid) { QGroundControl.airspaceManager.setROI(coordinateNW, coordinateSE, false /*planView*/, reset) } } } - function pipIn() { - if(QGroundControl.flightMapZoom > 3) { - _pipping = true; - zoomLevel = QGroundControl.flightMapZoom - 3 - _pipping = false; + function _adjustMapZoomForPipMode() { + _saveZoomLevelSetting = false + if (pipMode) { + if (QGroundControl.flightMapZoom > 3) { + zoomLevel = QGroundControl.flightMapZoom - 3 + } + } else { + zoomLevel = QGroundControl.flightMapZoom } + _saveZoomLevelSetting = true } - function pipOut() { - _pipping = true; - zoomLevel = QGroundControl.flightMapZoom - _pipping = false; - } - - function adjustMapSize() { - if(mainWindowIsMap) - pipOut() - else - pipIn() - } - - // Track last known map position and zoom from Fly view in settings + onPipModeChanged: _adjustMapZoomForPipMode() onVisibleChanged: { - if(visible) { - adjustMapSize() - center = QGroundControl.flightMapPosition + if (visible) { + // Synchronize center position with Plan View + center = QGroundControl.flightMapPosition } } onZoomLevelChanged: { - if(!_pipping) { + if (_saveZoomLevelSetting) { QGroundControl.flightMapZoom = zoomLevel updateAirspace(false) } @@ -105,19 +99,20 @@ FlightMap { updateAirspace(false) } - // When the user pans the map we stop responding to vehicle coordinate updates until the panRecenterTimer fires - onUserPannedChanged: { - if (userPanned) { - userPanned = false - _disableVehicleTracking = true - panRecenterTimer.restart() - } - } - on_AirspaceEnabledChanged: { updateAirspace(true) } + // We track whether the user has panned or not to correctly handle automatic map positioning + Connections { + target: gesture + + onPanStarted: _disableVehicleTracking = true + onFlickStarted: _disableVehicleTracking = true + onPanFinished: panRecenterTimer.restart() + onFlickFinished: panRecenterTimer.restart() + } + function pointInRect(point, rect) { return point.x > rect.x && point.x < rect.x + rect.width && @@ -132,8 +127,8 @@ FlightMap { property real animatedLatitude property real animatedLongitude - onAnimatedLatitudeChanged: flightMap.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude) - onAnimatedLongitudeChanged: flightMap.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude) + onAnimatedLatitudeChanged: _root.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude) + onAnimatedLongitudeChanged: _root.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude) NumberAnimation on animatedLatitude { id: animateLat; from: _animatedLatitudeStart; to: _animatedLatitudeStop; duration: 1000 } NumberAnimation on animatedLongitude { id: animateLong; from: _animatedLongitudeStart; to: _animatedLongitudeStop; duration: 1000 } @@ -147,26 +142,37 @@ FlightMap { animateLong.start() } + function _insetRect() { + return Qt.rect(toolInsets.leftEdgeCenterInset, + toolInsets.topEdgeCenterInset, + _root.width - toolInsets.leftEdgeCenterInset - toolInsets.rightEdgeCenterInset, + _root.height - toolInsets.topEdgeCenterInset - toolInsets.bottomEdgeCenterInset) + } + function recenterNeeded() { - var vehiclePoint = flightMap.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */) - var toolStripRightEdge = mapFromItem(toolStrip, toolStrip.x, 0).x + toolStrip.width - var instrumentsWidth = 0 - if (QGroundControl.corePlugin.options.instrumentWidget && QGroundControl.corePlugin.options.instrumentWidget.widgetPosition === CustomInstrumentWidget.POS_TOP_RIGHT) { - // Assume standard instruments - instrumentsWidth = flightDisplayViewWidgets.getPreferredInstrumentWidth() - } - var centerViewport = Qt.rect(toolStripRightEdge, 0, width - toolStripRightEdge - instrumentsWidth, height) - return !pointInRect(vehiclePoint, centerViewport) + var vehiclePoint = _root.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */) + var insetRect = _insetRect() + return !pointInRect(vehiclePoint, insetRect) } function updateMapToVehiclePosition() { + if (animateLat.running || animateLong.running) { + return + } // We let FlightMap handle first vehicle position if (!_keepMapCenteredOnVehicle && firstVehiclePositionReceived && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) { if (_keepVehicleCentered) { - flightMap.center = _activeVehicleCoordinate + _root.center = _activeVehicleCoordinate } else { if (firstVehiclePositionReceived && recenterNeeded()) { - animatedMapRecenter(flightMap.center, _activeVehicleCoordinate) + // Move the map such that the vehicle is centered within the inset area + var vehiclePoint = _root.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */) + var insetRect = _insetRect() + var centerInsetPoint = Qt.point(insetRect.x + insetRect.width / 2, insetRect.y + insetRect.height / 2) + var centerOffset = Qt.point((_root.width / 2) - centerInsetPoint.x, (_root.height / 2) - centerInsetPoint.y) + var vehicleOffsetPoint = Qt.point(vehiclePoint.x + centerOffset.x, vehiclePoint.y + centerOffset.y) + var vehicleOffsetCoord = _root.toCoordinate(vehicleOffsetPoint, false /* clipToViewport */) + animatedMapRecenter(_root.center, vehicleOffsetCoord) } } } @@ -174,7 +180,7 @@ FlightMap { on_ActiveVehicleCoordinateChanged: { if (_keepMapCenteredOnVehicle && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) { - flightMap.center = _activeVehicleCoordinate + _root.center = _activeVehicleCoordinate } } @@ -211,10 +217,9 @@ FlightMap { MapFitFunctions { id: mapFitFunctions // The name for this id cannot be changed without breaking references outside of this code. Beware! - map: flightMap + map: _root usePlannedHomePosition: false planMasterController: _planMasterController - property real leftToolWidth: toolStrip.x + toolStrip.width } // Add trajectory lines to the map @@ -223,7 +228,7 @@ FlightMap { line.width: 3 line.color: "red" z: QGroundControl.zOrderTrajectoryLines - visible: mainWindowIsMap + visible: !pipMode Connections { target: QGroundControl.multiVehicleManager @@ -244,8 +249,8 @@ FlightMap { delegate: VehicleMapItem { vehicle: object coordinate: object.coordinate - map: flightMap - size: mainWindowIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight + map: _root + size: pipMode ? ScreenTools.defaultFontPixelHeight : ScreenTools.defaultFontPixelHeight * 3 z: QGroundControl.zOrderVehicles } } @@ -259,7 +264,7 @@ FlightMap { callsign: object.callsign heading: object.heading alert: object.alert - map: flightMap + map: _root z: QGroundControl.zOrderVehicles } } @@ -269,8 +274,8 @@ FlightMap { model: QGroundControl.multiVehicleManager.vehicles PlanMapItems { - map: flightMap - largeMapView: mainWindowIsMap + map: _root + largeMapView: !pipMode planMasterController: _planMasterController vehicle: _vehicle @@ -284,7 +289,7 @@ FlightMap { } MapItemView { - model: mainWindowIsMap ? _missionController.directionArrows : undefined + model: pipMode ? undefined : _missionController.directionArrows delegate: MapLineArrow { fromCoord: object ? object.coordinate1 : undefined @@ -296,12 +301,12 @@ FlightMap { // Allow custom builds to add map items CustomMapItems { - map: flightMap - largeMapView: mainWindowIsMap + map: _root + largeMapView: !pipMode } GeoFenceMapVisuals { - map: flightMap + map: _root myGeoFenceController: _geoFenceController interactive: false planView: false @@ -533,7 +538,7 @@ FlightMap { } orbitMapCircle.hide() gotoLocationItem.hide() - var clickCoord = flightMap.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */) + var clickCoord = _root.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */) if (guidedActionsController.showGotoLocation && guidedActionsController.showOrbit) { clickMenu.coord = clickCoord clickMenu.popup() @@ -547,35 +552,6 @@ FlightMap { } } - MapScale { - id: mapScale - anchors.right: parent.right - anchors.margins: _toolsMargin - anchors.topMargin: _toolsMargin + state === "bottomMode" ? 0 : ScreenTools.toolbarHeight - mapControl: flightMap - buttonsOnLeft: false - visible: !ScreenTools.isTinyScreen && QGroundControl.corePlugin.options.enableMapScale && mainWindowIsMap - state: "bottomMode" - states: [ - State { - name: "topMode" - AnchorChanges { - target: mapScale - anchors.top: parent.top - anchors.bottom: undefined - } - }, - State { - name: "bottomMode" - AnchorChanges { - target: mapScale - anchors.top: undefined - anchors.bottom: parent.bottom - } - } - ] - } - // Airspace overlap support MapItemView { model: _airspaceEnabled && QGroundControl.settingsManager.airMapSettings.enableAirspace && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.circles : [] diff --git a/src/FlightDisplay/FlyViewVideo.qml b/src/FlightDisplay/FlyViewVideo.qml new file mode 100644 index 000000000..f90613aaa --- /dev/null +++ b/src/FlightDisplay/FlyViewVideo.qml @@ -0,0 +1,70 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.12 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 + +Item { + id: _root + visible: QGroundControl.videoManager.hasVideo + + property Item pipState: videoPipState + QGCPipState { + id: videoPipState + pipOverlay: _pipOverlay + isDark: true + + onWindowAboutToOpen: { + QGroundControl.videoManager.stopVideo() + videoStartDelay.start() + } + + onWindowAboutToClose: { + QGroundControl.videoManager.stopVideo() + videoStartDelay.start() + } + + onStateChanged: { + if (pipState.state !== pipState.fullState) { + QGroundControl.videoManager.fullScreen = false + } + } + } + + Timer { + id: videoStartDelay + interval: 2000; + running: false + repeat: false + onTriggered: QGroundControl.videoManager.startVideo() + } + + //-- Video Streaming + FlightDisplayViewVideo { + id: videoStreaming + anchors.fill: parent + useSmallFont: _root.pipState.state !== _root.pipState.fullState + visible: QGroundControl.videoManager.isGStreamer + } + //-- UVC Video (USB Camera or Video Device) + Loader { + id: cameraLoader + anchors.fill: parent + visible: !QGroundControl.videoManager.isGStreamer + source: visible ? (QGroundControl.videoManager.uvcEnabled ? "qrc:/qml/FlightDisplayViewUVC.qml" : "qrc:/qml/FlightDisplayViewDummy.qml") : "" + } + + MouseArea { + anchors.fill: parent + enabled: pipState.state === pipState.fullState + onDoubleClicked: QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen + } +} diff --git a/src/FlightDisplay/FlyViewWidgetLayer.qml b/src/FlightDisplay/FlyViewWidgetLayer.qml new file mode 100644 index 000000000..99f4a4d21 --- /dev/null +++ b/src/FlightDisplay/FlyViewWidgetLayer.qml @@ -0,0 +1,157 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.12 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.12 + +import QtLocation 5.3 +import QtPositioning 5.3 +import QtQuick.Window 2.2 +import QtQml.Models 2.1 + +import QGroundControl 1.0 +import QGroundControl.Airspace 1.0 +import QGroundControl.Airmap 1.0 +import QGroundControl.Controllers 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FactSystem 1.0 +import QGroundControl.FlightDisplay 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Vehicle 1.0 + +// This is the ui overlay layer for the widgets/tools for Fly View +Item { + id: _root + + property var parentToolInsets + property var totalToolInsets: _totalToolInsets + property var mapControl + + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property var _planMasterController: mainWindow.planMasterControllerPlanView + property var _missionController: _planMasterController.missionController + property var _geoFenceController: _planMasterController.geoFenceController + property var _rallyPointController: _planMasterController.rallyPointController + property real _margins: ScreenTools.defaultFontPixelWidth / 2 + property real _toolsMargin: ScreenTools.defaultFontPixelWidth * 0.75 + property rect _centerViewport: Qt.rect(0, 0, width, height) + property real _rightPanelWidth: ScreenTools.defaultFontPixelWidth * 30 + + QGCToolInsets { + id: _totalToolInsets + leftEdgeCenterInset: toolStrip.leftInset + leftEdgeTopInset: toolStrip.leftInset + leftEdgeBottomInset: parentToolInsets.leftEdgeBottomInset + rightEdgeCenterInset: instrumentPanel.rightInset + rightEdgeTopInset: instrumentPanel.rightInset + rightEdgeBottomInset: instrumentPanel.rightInset + topEdgeCenterInset: parentToolInsets.topEdgeCenterInset + topEdgeLeftInset: parentToolInsets.topEdgeLeftInset + topEdgeRightInset: parentToolInsets.topEdgeRightInset + bottomEdgeCenterInset: mapScale.centerInset + bottomEdgeLeftInset: parentToolInsets.bottomEdgeLeftInset + bottomEdgeRightInset: parentToolInsets.bottomEdgeRightInset + } + + FlyViewMissionCompleteDialog { + missionController: _missionController + geoFenceController: _geoFenceController + rallyPointController: _rallyPointController + guidedController: _root.guidedActionsController + } + + FlyViewInstrumentPanel { + id: instrumentPanel + anchors.margins: _toolsMargin + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + width: _rightPanelWidth + spacing: _toolsMargin + visible: QGroundControl.corePlugin.options.flyView.showInstrumentPanel + guidedActionsController: _guidedController + availableHeight: parent.height - y - _toolsMargin + + property real rightInset: visible ? parent.width - x : 0 + } + + //-- Virtual Joystick + Loader { + id: virtualJoystickMultiTouch + z: QGroundControl.zOrderTopMost + 1 + width: parent.width - (_pipOverlay.width / 2) + height: Math.min(parent.height * 0.25, ScreenTools.defaultFontPixelWidth * 16) + visible: (_virtualJoystick ? _virtualJoystick.value : false) && !(_activeVehicle ? _activeVehicle.highLatencyLink : false) + anchors.bottom: parent.bottom + anchors.bottomMargin: parentToolInsets.leftEdgeBottomInset + ScreenTools.defaultFontPixelHeight * 2 + anchors.horizontalCenter: parent.horizontalCenter + source: "qrc:/qml/VirtualJoystick.qml" + active: (_virtualJoystick ? _virtualJoystick.value : false) && !(_activeVehicle ? _activeVehicle.highLatencyLink : false) + + property bool centralizeThrottle: _virtualJoystickCentralized ? _virtualJoystickCentralized.value : false + property var parentToolInsets: _totalToolInsets + + property Fact _virtualJoystick: QGroundControl.settingsManager.appSettings.virtualJoystick + property Fact _virtualJoystickCentralized: QGroundControl.settingsManager.appSettings.virtualJoystickCentralized + } + + FlyViewToolStrip { + id: toolStrip + anchors.leftMargin: _toolsMargin + parentToolInsets.leftEdgeCenterInset + anchors.topMargin: _toolsMargin + parentToolInsets.leftEdgeTopInset + anchors.left: parent.left + anchors.top: parent.top + z: QGroundControl.zOrderWidgets + maxHeight: parent.height - y - parentToolInsets.leftEdgeBottomInset - _toolsMargin + guidedActionsController: _guidedController + guidedActionList: _guidedActionList + usePreFlightChecklist: preFlightChecklistPopup.useChecklist + visible: !QGroundControl.videoManager.fullScreen + + onDisplayPreFlightChecklist: preFlightChecklistPopup.open() + + property real leftInset: x + width + } + + FlyViewAirspaceIndicator { + anchors.top: parent.top + anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 + anchors.horizontalCenter: parent.horizontalCenter + z: QGroundControl.zOrderWidgets + show: mapControl.pipState.state !== mapControl.pipState.pipState + } + + VehicleWarnings { + anchors.centerIn: parent + z: QGroundControl.zOrderTopMost + } + + MapScale { + id: mapScale + anchors.leftMargin: parentToolInsets.leftEdgeBottomInset + _toolsMargin + anchors.bottomMargin: parentToolInsets.bottomEdgeCenterInset + _toolsMargin + anchors.left: parent.left + anchors.bottom: parent.bottom + mapControl: _mapControl + buttonsOnLeft: true + visible: !ScreenTools.isTinyScreen && QGroundControl.corePlugin.options.flyView.showMapScale && mapControl.pipState.state !== mapControl.pipState.pipState + + property real centerInset: visible ? parent.height - y : 0 + } + + FlyViewPreFlightChecklistPopup { + id: preFlightChecklistPopup + x: toolStrip.x + toolStrip.width + (ScreenTools.defaultFontPixelWidth * 2) + y: toolStrip.y + } +} diff --git a/src/FlightDisplay/GuidedActionsController.qml b/src/FlightDisplay/GuidedActionsController.qml index d434bc717..1179b66e6 100644 --- a/src/FlightDisplay/GuidedActionsController.qml +++ b/src/FlightDisplay/GuidedActionsController.qml @@ -118,7 +118,7 @@ Item { // Note: The '_missionItemCount - 2' is a hack to not trigger resume mission when a mission ends with an RTL item property bool showResumeMission: activeVehicle && !_vehicleArmed && _vehicleWasFlying && _missionAvailable && _resumeMissionIndex > 0 && (_resumeMissionIndex < _missionItemCount - 2) - property bool guidedUIVisible: guidedActionConfirm.visible || guidedActionList.visible + property bool guidedUIVisible: confirmDialog.visible || actionList.visible property var _corePlugin: QGroundControl.corePlugin property bool _guidedActionsEnabled: (!ScreenTools.isDebug && QGroundControl.corePlugin.options.guidedActionsRequireRCRSSI && activeVehicle) ? _rcRSSIAvailable : activeVehicle diff --git a/src/FlightDisplay/MultiVehiclePanel.qml b/src/FlightDisplay/MultiVehiclePanel.qml index f82d1640c..7075ae2df 100644 --- a/src/FlightDisplay/MultiVehiclePanel.qml +++ b/src/FlightDisplay/MultiVehiclePanel.qml @@ -15,18 +15,20 @@ import QGroundControl 1.0 import QGroundControl.Controls 1.0 import QGroundControl.FlightDisplay 1.0 import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 /// Multi vehicle panel for Fly View Item { id: _root - width: ScreenTools.defaultFontPixelWidth * 30 height: singleVehiclePanel ? selectorRow.height : availableHeight - visible: QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.enableMultiVehicleList + visible: QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.flyView.showMultiVehicleList - property alias singleVehiclePanel: singleVehicleView.checked + property alias singleVehiclePanel: singleVehicleView.checked property real availableHeight property var guidedActionsController + QGCMapPalette { id: mapPal; lightColors: true } + Row { id: selectorRow spacing: ScreenTools.defaultFontPixelWidth @@ -49,7 +51,7 @@ Item { anchors.top: selectorRow.bottom anchors.bottom: parent.bottom width: parent.width - visible: !singleVehiclePanel && !QGroundControl.videoManager.fullScreen && QGroundControl.corePlugin.options.enableMultiVehicleList + visible: !singleVehiclePanel && !QGroundControl.videoManager.fullScreen && QGroundControl.corePlugin.options.showMultiVehicleList guidedActionsController: _root.guidedActionsController } } diff --git a/src/FlightDisplay/VehicleWarnings.qml b/src/FlightDisplay/VehicleWarnings.qml new file mode 100644 index 000000000..ea6f932f0 --- /dev/null +++ b/src/FlightDisplay/VehicleWarnings.qml @@ -0,0 +1,59 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.3 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controls 1.0 + +Rectangle { + anchors.margins: -ScreenTools.defaultFontPixelHeight + height: warningsCol.height + width: warningsCol.width + color: Qt.rgba(1, 1, 1, 0.5) + radius: ScreenTools.defaultFontPixelWidth / 2 + visible: _noGPSLockVisible || _prearmErrorVisible + + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property bool _noGPSLockVisible: _activeVehicle && !_activeVehicle.coordinate.isValid + property bool _prearmErrorVisible: _activeVehicle && !_activeVehicle.armed && _activeVehicle.prearmError + + Column { + id: warningsCol + spacing: ScreenTools.defaultFontPixelHeight + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + visible: _noGPSLockVisible + color: "black" + font.pointSize: ScreenTools.largeFontPointSize + text: qsTr("No GPS Lock for Vehicle") + } + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + visible: _prearmErrorVisible + color: "black" + font.pointSize: ScreenTools.largeFontPointSize + text: _activeVehicle ? _activeVehicle.prearmError : "" + } + + QGCLabel { + anchors.horizontalCenter: parent.horizontalCenter + visible: _prearmErrorVisible + width: ScreenTools.defaultFontPixelWidth * 50 + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + color: "black" + font.pointSize: ScreenTools.largeFontPointSize + text: qsTr("The vehicle has failed a pre-arm check. In order to arm the vehicle, resolve the failure.") + } + } +} diff --git a/src/FlightDisplay/VirtualJoystick.qml b/src/FlightDisplay/VirtualJoystick.qml index c6c3f331a..3defd165f 100644 --- a/src/FlightDisplay/VirtualJoystick.qml +++ b/src/FlightDisplay/VirtualJoystick.qml @@ -17,8 +17,8 @@ import QGroundControl.Palette 1.0 import QGroundControl.Vehicle 1.0 Item { - //property bool useLightColors - Must be passed in from loaded - //property bool centralizeThrottle - Must be passed in from loaded + //property bool centralizeThrottle - Must be passed in from loader + Timer { interval: 40 // 25Hz, same as real joystick rate running: QGroundControl.settingsManager.appSettings.virtualJoystick.value && activeVehicle @@ -40,7 +40,6 @@ Item { height: parent.height yAxisThrottle: true yAxisThrottleCentered: centralizeThrottle - lightColors: useLightColors } JoystickThumbPad { @@ -51,6 +50,5 @@ Item { anchors.bottom: parent.bottom width: parent.height height: parent.height - lightColors: useLightColors } } diff --git a/src/FlightMap/FlightMap.qml b/src/FlightMap/FlightMap.qml index f3264f936..504070814 100644 --- a/src/FlightMap/FlightMap.qml +++ b/src/FlightMap/FlightMap.qml @@ -37,7 +37,6 @@ Map { property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1 property var gcsPosition: QGroundControl.qgcPositionManger.gcsPosition property real gcsHeading: QGroundControl.qgcPositionManger.gcsHeading - property bool userPanned: false ///< true: the user has manually panned the map property bool allowGCSLocationCenter: false ///< true: map will center/zoom to gcs location one time property bool allowVehicleLocationCenter: false ///< true: map will center/zoom to vehicle location one time property bool firstGCSPositionReceived: false ///< true: first gcs position update was responded to @@ -88,14 +87,6 @@ Map { } } - // We track whether the user has panned or not to correctly handle automatic map positioning - Connections { - target: gesture - - onPanFinished: userPanned = true - onFlickFinished: userPanned = true - } - function updateActiveMapType() { var settings = QGroundControl.settingsManager.flightMapSettings var fullMapName = settings.mapProvider.value + " " + settings.mapType.value diff --git a/src/FlightMap/Widgets/MapFitFunctions.qml b/src/FlightMap/Widgets/MapFitFunctions.qml index ac8bfa8cf..e8a3f6bdf 100644 --- a/src/FlightMap/Widgets/MapFitFunctions.qml +++ b/src/FlightMap/Widgets/MapFitFunctions.qml @@ -13,7 +13,7 @@ import QtPositioning 5.3 import QGroundControl 1.0 import QGroundControl.FlightMap 1.0 -/// Set of functions for fitting the map viewpoer to a specific constraint +/// Set of functions for fitting the map view to a specific constraint Item { property var map property bool usePlannedHomePosition ///< true: planned home position used for calculations, false: vehicle home position use for calculations diff --git a/src/FlightMap/Widgets/QGCInstrumentWidget.qml b/src/FlightMap/Widgets/QGCInstrumentWidget.qml index 4d6f8ce01..a21b457b3 100644 --- a/src/FlightMap/Widgets/QGCInstrumentWidget.qml +++ b/src/FlightMap/Widgets/QGCInstrumentWidget.qml @@ -20,16 +20,14 @@ import QGroundControl.Palette 1.0 ColumnLayout { id: root - width: getPreferredInstrumentWidth() spacing: ScreenTools.defaultFontPixelHeight / 4 + // These properties are expected to be in the Loader + // property real maxHeight + // property bool showValues - true: show value pages + property real _innerRadius: (width - (_topBottomMargin * 3)) / 4 property real _outerRadius: _innerRadius + _topBottomMargin - property real _defaultSize: ScreenTools.defaultFontPixelHeight * (9) - property real _sizeRatio: ScreenTools.isTinyScreen ? (width / _defaultSize) * 0.5 : width / _defaultSize - property real _bigFontSize: ScreenTools.defaultFontPointSize * 2.5 * _sizeRatio - property real _normalFontSize: ScreenTools.defaultFontPointSize * 1.5 * _sizeRatio - property real _labelFontSize: ScreenTools.defaultFontPointSize * 0.75 * _sizeRatio property real _spacing: ScreenTools.defaultFontPixelHeight * 0.33 property real _topBottomMargin: (width * 0.05) / 2 property real _availableValueHeight: maxHeight - _valuesItem.y @@ -42,8 +40,6 @@ ColumnLayout { Layout.fillWidth: true radius: _outerRadius color: qgcPal.window - border.width: 1 - border.color: qgcPal.mapWidgetBorderLight DeadMouseArea { anchors.fill: parent } @@ -74,7 +70,7 @@ ColumnLayout { id: _valuesItem Layout.fillWidth: true height: _valuesWidget.height - visible: widgetRoot.showValues + visible: showValues DeadMouseArea { anchors.fill: parent } diff --git a/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml b/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml index c272034d9..7123619ed 100644 --- a/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml +++ b/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml @@ -19,20 +19,16 @@ import QGroundControl.Palette 1.0 Rectangle { id: root - width: getPreferredInstrumentWidth() height: _outerRadius * 4 + _valuesWidget.height radius: _outerRadius color: qgcPal.window - border.width: 1 - border.color: _isSatellite ? qgcPal.mapWidgetBorderLight : qgcPal.mapWidgetBorderDark + + // These properties are expected to be in the Loader + // property real maxHeight + // property bool showValues - true: show value pages property real _innerRadius: (width - (_topBottomMargin * 2)) / 2 property real _outerRadius: _innerRadius + _topBottomMargin * 2 - property real _defaultSize: ScreenTools.defaultFontPixelHeight * (9) - property real _sizeRatio: ScreenTools.isTinyScreen ? (width / _defaultSize) * 0.5 : width / _defaultSize - property real _bigFontSize: ScreenTools.defaultFontPointSize * 2.5 * _sizeRatio - property real _normalFontSize: ScreenTools.defaultFontPointSize * 1.5 * _sizeRatio - property real _labelFontSize: ScreenTools.defaultFontPointSize * 0.75 * _sizeRatio property real _spacing: ScreenTools.defaultFontPixelHeight * 0.33 property real _topBottomMargin: (width * 0.05) / 2 property real _availableValueHeight: maxHeight - (attitude.height + compass.height) @@ -62,7 +58,7 @@ Rectangle { anchors.bottom: compass.top width: parent.width height: _valuesWidget.height - visible: widgetRoot.showValues + visible: showValues // Prevent all clicks from going through to lower layers DeadMouseArea { diff --git a/src/PlanView/PlanToolBarIndicators.qml b/src/PlanView/PlanToolBarIndicators.qml index 38f53eb0d..22b63c6a2 100644 --- a/src/PlanView/PlanToolBarIndicators.qml +++ b/src/PlanView/PlanToolBarIndicators.qml @@ -13,7 +13,7 @@ import QGroundControl.Palette 1.0 Item { anchors.fill: parent - property var _planMasterController: mainWindow.planMasterControllerPlan + property var _planMasterController: mainWindow.planMasterControllerPlanView property var _currentMissionItem: mainWindow.currentPlanMissionItem ///< Mission item to display status for property var missionItems: _controllerValid ? _planMasterController.missionController.visualItems : undefined diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index c444e7163..2a71bb7bd 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -182,7 +182,7 @@ Item { Component.onCompleted: { _planMasterController.start(false /* flyView */) _missionController.setCurrentPlanViewSeqNum(0, true) - mainWindow.planMasterControllerPlan = _planMasterController + mainWindow.planMasterControllerPlanView = _planMasterController } function waitingOnIncompleteDataMessage(save) { diff --git a/src/QGCMapPalette.cc b/src/QGCMapPalette.cc index 1aac1088c..32e3ef79e 100644 --- a/src/QGCMapPalette.cc +++ b/src/QGCMapPalette.cc @@ -13,7 +13,6 @@ #include #include -QColor QGCMapPalette::_thumbJoystick[QGCMapPalette::_cColorGroups] = { QColor(255,255,255,127), QColor(0,0,0,127) }; QColor QGCMapPalette::_text [QGCMapPalette::_cColorGroups] = { QColor(255,255,255), QColor(0,0,0) }; QColor QGCMapPalette::_textOutline [QGCMapPalette::_cColorGroups] = { QColor(0,0,0,192), QColor(255,255,255,192) }; diff --git a/src/QGCMapPalette.h b/src/QGCMapPalette.h index d2bac9d68..a609361d5 100644 --- a/src/QGCMapPalette.h +++ b/src/QGCMapPalette.h @@ -44,7 +44,6 @@ class QGCMapPalette : public QObject Q_PROPERTY(QColor text READ text NOTIFY paletteChanged) Q_PROPERTY(QColor textOutline READ textOutline NOTIFY paletteChanged) - Q_PROPERTY(QColor thumbJoystick READ thumbJoystick NOTIFY paletteChanged) public: QGCMapPalette(QObject* parent = nullptr); @@ -53,9 +52,6 @@ public: QColor text(void) const { return _text[_lightColors ? 0 : 1]; } QColor textOutline(void) const { return _textOutline[_lightColors ? 0 : 1]; } - /// Thumb joystick indicator - QColor thumbJoystick(void) const { return _thumbJoystick[_lightColors ? 0 : 1]; } - bool lightColors(void) const { return _lightColors; } void setLightColors(bool lightColors); @@ -68,7 +64,6 @@ private: static const int _cColorGroups = 2; - static QColor _thumbJoystick[_cColorGroups]; static QColor _text[_cColorGroups]; static QColor _textOutline[_cColorGroups]; }; diff --git a/src/QmlControls/DropPanel.qml b/src/QmlControls/DropPanel.qml index 22f0bb628..2137ccc68 100644 --- a/src/QmlControls/DropPanel.qml +++ b/src/QmlControls/DropPanel.qml @@ -17,7 +17,6 @@ import QGroundControl.Palette 1.0 Item { id: _root - z: QGroundControl.zOrderWidgets visible: false signal clicked() @@ -25,10 +24,6 @@ Item { property real viewportMargins: 0 property var toolStrip - - width: radius * 2 - height: radius * 2 - // Should be an enum but that get's into the whole problem of creating a singleton which isn't worth the effort readonly property int dropLeft: 1 readonly property int dropRight: 2 @@ -40,16 +35,14 @@ Item { readonly property real _dropMargin: ScreenTools.defaultFontPixelWidth property var _dropEdgeTopPoint - property real _dropEdgeHeight property alias _dropDownComponent: panelLoader.sourceComponent property real _viewportMaxTop: 0 property real _viewportMaxBottom: parent.parent.height - parent.y property real _viewportMaxHeight: _viewportMaxBottom - _viewportMaxTop property var _dropPanelCancel - function show(panelEdgeTopPoint, panelEdgeHeight, panelComponent) { + function show(panelEdgeTopPoint, panelComponent) { _dropEdgeTopPoint = panelEdgeTopPoint - _dropEdgeHeight = panelEdgeHeight _dropDownComponent = panelComponent _calcPositions() visible = true diff --git a/src/QmlControls/JoystickThumbPad.qml b/src/QmlControls/JoystickThumbPad.qml index 589b5efc3..18842d38b 100644 --- a/src/QmlControls/JoystickThumbPad.qml +++ b/src/QmlControls/JoystickThumbPad.qml @@ -1,13 +1,13 @@ -import QtQuick 2.3 +import QtQuick 2.12 import QtQuick.Controls 1.2 +import QGroundControl 1.0 import QGroundControl.Palette 1.0 import QGroundControl.ScreenTools 1.0 Item { id: _joyRoot - property alias lightColors: mapPal.lightColors ///< true: use light colors from QGCMapPalette for drawing 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 @@ -20,8 +20,8 @@ Item { property bool _processTouchPoints: false property real stickPositionX: _centerXY property real stickPositionY: yAxisThrottleCentered ? _centerXY : height - - QGCMapPalette { id: mapPal } + property color _fgColor: QGroundControl.globalPalette.text + property color _bgColor: QGroundControl.globalPalette.window onWidthChanged: calculateXAxis() onStickPositionXChanged: calculateXAxis() @@ -87,13 +87,37 @@ Item { Image { anchors.fill: parent - source: lightColors ? "/res/JoystickBezel.png" : "/res/JoystickBezelLight.png" + source: "/res/JoystickBezelLight.png" mipmap: true smooth: true } + Rectangle { + anchors.fill: parent + radius: width / 2 + color: _bgColor + opacity: 0.5 + + Rectangle { + anchors.margins: parent.width / 4 + anchors.fill: parent + radius: width / 2 + border.color: _fgColor + border.width: 2 + color: "transparent" + } + + Rectangle { + anchors.fill: parent + radius: width / 2 + border.color: _fgColor + border.width: 2 + color: "transparent" + } + } + QGCColoredImage { - color: lightColors ? "white" : "black" + color: _fgColor visible: yAxisThrottle height: ScreenTools.defaultFontPixelHeight width: height @@ -107,7 +131,7 @@ Item { } QGCColoredImage { - color: lightColors ? "white" : "black" + color: _fgColor visible: yAxisThrottle height: ScreenTools.defaultFontPixelHeight width: height @@ -121,7 +145,7 @@ Item { } QGCColoredImage { - color: lightColors ? "white" : "black" + color: _fgColor visible: yAxisThrottle height: ScreenTools.defaultFontPixelHeight width: height @@ -135,7 +159,7 @@ Item { } QGCColoredImage { - color: lightColors ? "white" : "black" + color: _fgColor visible: yAxisThrottle height: ScreenTools.defaultFontPixelHeight width: height @@ -149,31 +173,14 @@ Item { } Rectangle { - anchors.margins: parent.width / 4 - anchors.fill: parent - radius: width / 2 - border.color: mapPal.thumbJoystick - border.width: 2 - color: Qt.rgba(0,0,0,0) - } - - Rectangle { - anchors.fill: parent - radius: width / 2 - border.color: mapPal.thumbJoystick - border.width: 2 - color: Qt.rgba(0,0,0,0) - } - - Rectangle { - width: hatWidth - height: hatWidth - radius: hatWidthHalf - border.color: lightColors ? "white" : "black" - border.width: 1 - color: mapPal.thumbJoystick - x: stickPositionX - hatWidthHalf - y: stickPositionY - hatWidthHalf + width: hatWidth + height: hatWidth + radius: hatWidthHalf + border.color: _fgColor + border.width: 1 + color: Qt.rgba(_fgColor.r, _fgColor.g, _fgColor.b, 0.5) + x: stickPositionX - hatWidthHalf + y: stickPositionY - hatWidthHalf readonly property real hatWidth: ScreenTools.defaultFontPixelHeight readonly property real hatWidthHalf: ScreenTools.defaultFontPixelHeight / 2 diff --git a/src/QmlControls/QGCControlDebug.qml b/src/QmlControls/QGCControlDebug.qml index 5e665613f..35f95fd6a 100644 --- a/src/QmlControls/QGCControlDebug.qml +++ b/src/QmlControls/QGCControlDebug.qml @@ -12,6 +12,8 @@ import QtQuick 2.12 Item { property string name: "control" + Component.onCompleted: console.log("QGCControlDebug.onCompleted name,x,y,width,height,visible,z,parent", name, x, y, width, height, visible, z, parent) + Connections { target: parent onXChanged: console.log(name, "xChanged", parent.x) diff --git a/src/QmlControls/QGCPipOverlay.qml b/src/QmlControls/QGCPipOverlay.qml index cf435c3d3..46cd2f76b 100644 --- a/src/QmlControls/QGCPipOverlay.qml +++ b/src/QmlControls/QGCPipOverlay.qml @@ -20,13 +20,14 @@ Item { width: _pipSize height: _pipSize * (9/16) z: pipZOrder + 1 - visible: item2 && item2.pipState !== item2.pipState.window + visible: item2 && item2.pipState !== item2.pipState.window && show property var item1: null // Required property var item2: null // Optional, may come and go property string item1IsFullSettingsKey // Settings key to save whether item1 was saved in full mode property real fullZOrder: 0 // zOrder for items in full mode property real pipZOrder: 1 // zOrder for items in pip mode + property bool show: true readonly property string _pipExpandedSettingsKey: "IsPIPVisible" @@ -44,6 +45,12 @@ Item { _componentComplete = true } + onShowChanged: { + if (_pipOrWindowItem && _pipOrWindowItem.pipState.state !== _pipOrWindowItem.pipState.windowState) { + _pipOrWindowItem.visible = show + } + } + onItem2Changed: _initForItems() function showWindow() { @@ -101,6 +108,7 @@ Item { item.pipState.windowAboutToClose() item.pipState.state = item.pipState.windowClosingState item.pipState.state = item.pipState.pipState + item.visible = _root.show } } diff --git a/src/QmlControls/QGCToolInsets.qml b/src/QmlControls/QGCToolInsets.qml new file mode 100644 index 000000000..3639a2a28 --- /dev/null +++ b/src/QmlControls/QGCToolInsets.qml @@ -0,0 +1,40 @@ +/**************************************************************************** + * + * (c) 2009-2020 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.12 + +QtObject { + property real leftEdgeCenterInset: 0 + property real leftEdgeTopInset: 0 + property real leftEdgeBottomInset: 0 + property real rightEdgeCenterInset: 0 + property real rightEdgeTopInset: 0 + property real rightEdgeBottomInset: 0 + property real topEdgeCenterInset: 0 + property real topEdgeLeftInset: 0 + property real topEdgeRightInset: 0 + property real bottomEdgeCenterInset: 0 + property real bottomEdgeLeftInset: 0 + property real bottomEdgeRightInset: 0 + + signal insetsChanged + + onLeftEdgeBottomInsetChanged: insetsChanged() + onLeftEdgeTopInsetChanged: insetsChanged() + onLeftEdgeCenterInsetChanged: insetsChanged() + onRightEdgeBottomInsetChanged: insetsChanged() + onRightEdgeCenterInsetChanged: insetsChanged() + onRightEdgeTopInsetChanged: insetsChanged() + onBottomEdgeLeftInsetChanged: insetsChanged() + onBottomEdgeRightInsetChanged: insetsChanged() + onBottomEdgeCenterInsetChanged: insetsChanged() + onTopEdgeLeftInsetChanged: insetsChanged() + onTopEdgeRightInsetChanged: insetsChanged() + onTopEdgeCenterInsetChanged: insetsChanged() +} diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir index 444ec0580..4406652e3 100644 --- a/src/QmlControls/QGroundControl/Controls/qmldir +++ b/src/QmlControls/QGroundControl/Controls/qmldir @@ -5,6 +5,7 @@ AppMessages 1.0 AppMessages.qml AxisMonitor 1.0 AxisMonitor.qml CameraCalcCamera 1.0 CameraCalcCamera.qml CameraCalcGrid 1.0 CameraCalcGrid.qml +ContentAreaCalc 1.0 ContentAreaCalc.qml APMSubMotorDisplay 1.0 APMSubMotorDisplay.qml CameraSection 1.0 CameraSection.qml ClickableColor 1.0 ClickableColor.qml @@ -78,6 +79,7 @@ QGCTabBar 1.0 QGCTabBar.qml QGCTabButton 1.0 QGCTabButton.qml QGCTextField 1.0 QGCTextField.qml QGCToolBarButton 1.0 QGCToolBarButton.qml +QGCToolInsets 1.0 QGCToolInsets.qml QGCViewDialog 1.0 QGCViewDialog.qml QGCViewDialogContainer 1.0 QGCViewDialogContainer.qml QGCViewMessage 1.0 QGCViewMessage.qml diff --git a/src/QmlControls/QGroundControl/FlightDisplay/qmldir b/src/QmlControls/QGroundControl/FlightDisplay/qmldir index 13b819eca..073474cb8 100644 --- a/src/QmlControls/QGroundControl/FlightDisplay/qmldir +++ b/src/QmlControls/QGroundControl/FlightDisplay/qmldir @@ -1,13 +1,16 @@ Module QGroundControl.FlightDisplay -FlightDisplayView 1.0 FlightDisplayView.qml -FlightDisplayViewMap 1.0 FlightDisplayViewMap.qml -FlightDisplayViewVideo 1.0 FlightDisplayViewVideo.qml FlightDisplayViewWidgets 1.0 FlightDisplayViewWidgets.qml FlyViewAirspaceIndicator 1.0 FlyViewAirspaceIndicator.qml +FlyView 1.0 FlyView.qml +FlyViewCustomLayer 1.0 FlyViewCustomLayer.qml +FlyViewInstrumentPanel 1.0 FlyViewInstrumentPanel.qml +FlyViewMap 1.0 FlyViewMap.qml FlyViewMissionCompleteDialog 1.0 FlyViewMissionCompleteDialog.qml FlyViewPreFlightChecklistPopup 1.0 FlyViewPreFlightChecklistPopup.qml FlyViewToolStrip 1.0 FlyViewToolStrip.qml +FlyViewVideo 1.0 FlyViewVideo.qml +FlyViewWidgetLayer 1.0 FlyViewWidgetLayer.qml GuidedActionConfirm 1.0 GuidedActionConfirm.qml GuidedActionList 1.0 GuidedActionList.qml GuidedActionsController 1.0 GuidedActionsController.qml @@ -20,3 +23,4 @@ PreFlightRCCheck 1.0 PreFlightRCCheck.qml PreFlightSensorsHealthCheck 1.0 PreFlightSensorsHealthCheck.qml PreFlightSoundCheck 1.0 PreFlightSoundCheck.qml TerrainProgress 1.0 TerrainProgress.qml +VehicleWarnings 1.0 VehicleWarnings.qml diff --git a/src/QmlControls/ToolStrip.qml b/src/QmlControls/ToolStrip.qml index 9e10e79dc..249d7318f 100644 --- a/src/QmlControls/ToolStrip.qml +++ b/src/QmlControls/ToolStrip.qml @@ -68,6 +68,7 @@ Rectangle { height: parent.height contentHeight: toolStripColumn.height flickableDirection: Flickable.VerticalFlick + clip: true Column { id: toolStripColumn @@ -113,7 +114,7 @@ Rectangle { _root.clicked(index, checked) } else if (checked) { var panelEdgeTopPoint = mapToItem(_root, width, 0) - dropPanel.show(panelEdgeTopPoint, height, modelData.dropPanelComponent) + dropPanel.show(panelEdgeTopPoint, modelData.dropPanelComponent) _root.dropped(index) } if(_root && buttonTemplate) diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc index 0d0948547..ebc95de52 100644 --- a/src/api/QGCCorePlugin.cc +++ b/src/api/QGCCorePlugin.cc @@ -122,15 +122,18 @@ QGCCorePlugin::QGCCorePlugin(QGCApplication *app, QGCToolbox* toolbox) , _showTouchAreas(false) , _showAdvancedUI(true) { + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); _p = new QGCCorePlugin_p; } void QGCCorePlugin::setToolbox(QGCToolbox *toolbox) { QGCTool::setToolbox(toolbox); - QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); - qmlRegisterUncreatableType("QGroundControl.QGCCorePlugin", 1, 0, "QGCCorePlugin", "Reference only"); - qmlRegisterUncreatableType("QGroundControl.QGCOptions", 1, 0, "QGCOptions", "Reference only"); + + qmlRegisterUncreatableType ("QGroundControl", 1, 0, "QGCCorePlugin", "Reference only"); + qmlRegisterUncreatableType ("QGroundControl", 1, 0, "QGCOptions", "Reference only"); + qmlRegisterUncreatableType ("QGroundControl", 1, 0, "QGCFlyViewOptions", "Reference only"); + //-- Handle Camera and Video Changes connect(toolbox->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &QGCCorePlugin::_activeVehicleChanged); } @@ -319,8 +322,8 @@ int QGCCorePlugin::defaultSettings() QGCOptions* QGCCorePlugin::options() { - if(!_p->defaultOptions) { - _p->defaultOptions = new QGCOptions(); + if (!_p->defaultOptions) { + _p->defaultOptions = new QGCOptions(this); } return _p->defaultOptions; } diff --git a/src/api/QGCOptions.cc b/src/api/QGCOptions.cc index 508226772..56ed43fc3 100644 --- a/src/api/QGCOptions.cc +++ b/src/api/QGCOptions.cc @@ -8,6 +8,7 @@ ****************************************************************************/ #include "QGCOptions.h" + #include /// @file @@ -16,53 +17,46 @@ QGCOptions::QGCOptions(QObject* parent) : QObject(parent) - , _defaultInstrumentWidget(nullptr) { - qmlRegisterUncreatableType("QGroundControl", 1, 0, "CustomInstrumentWidget", "Reference only"); -} - -CustomInstrumentWidget* -QGCOptions::instrumentWidget() -{ - if(!_defaultInstrumentWidget) { - _defaultInstrumentWidget = new CustomInstrumentWidget(this); - } - return _defaultInstrumentWidget; + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); } -QUrl -QGCOptions::mainToolbarUrl() const +QUrl QGCOptions::mainToolbarUrl() const { return QUrl(QStringLiteral("qrc:/toolbar/MainToolBar.qml")); } -QUrl -QGCOptions::planToolbarUrl() const +QUrl QGCOptions::planToolbarUrl() const { return QUrl(QStringLiteral("qrc:/qml/PlanToolBar.qml")); } -QColor -QGCOptions::toolbarBackgroundLight() const +QColor QGCOptions::toolbarBackgroundLight() const { return QColor(255,255,255,204); } -QColor -QGCOptions::toolbarBackgroundDark() const +QColor QGCOptions::toolbarBackgroundDark() const { return QColor(0,0,0,192); } -QUrl -QGCOptions::planToolbarIndicatorsUrl() const +QUrl QGCOptions::planToolbarIndicatorsUrl() const { return QUrl(QStringLiteral("PlanToolBar.qml")); } - -CustomInstrumentWidget::CustomInstrumentWidget(QObject* parent) - : QObject(parent) +QGCFlyViewOptions* QGCOptions::flyViewOptions(void) { + if (!_defaultFlyViewOptions) { + _defaultFlyViewOptions = new QGCFlyViewOptions(this); + } + return _defaultFlyViewOptions; } +QGCFlyViewOptions::QGCFlyViewOptions(QGCOptions* options, QObject* parent) + : QObject (parent) + , _options (options) +{ + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); +} diff --git a/src/api/QGCOptions.h b/src/api/QGCOptions.h index 0b1b60db8..f559123de 100644 --- a/src/api/QGCOptions.h +++ b/src/api/QGCOptions.h @@ -14,11 +14,37 @@ #include #include -/// @file -/// @brief Core Plugin Interface for QGroundControl - Application Options -/// @author Gus Grubba +class QGCOptions; + +class QGCFlyViewOptions : public QObject +{ + Q_OBJECT +public: + QGCFlyViewOptions(QGCOptions* options, QObject* parent = nullptr); + + Q_PROPERTY(bool showMultiVehicleList READ showMultiVehicleList CONSTANT) + Q_PROPERTY(bool showInstrumentPanel READ showInstrumentPanel CONSTANT) + Q_PROPERTY(bool showMapScale READ showMapScale CONSTANT) + Q_PROPERTY(bool guidedBarShowEmergencyStop READ guidedBarShowEmergencyStop NOTIFY guidedBarShowEmergencyStopChanged) + Q_PROPERTY(bool guidedBarShowOrbit READ guidedBarShowOrbit NOTIFY guidedBarShowOrbitChanged) + Q_PROPERTY(bool guidedBarShowROI READ guidedBarShowROI NOTIFY guidedBarShowROIChanged) + +protected: + virtual bool showMultiVehicleList () const { return true; } + virtual bool showMapScale () const { return true; } + virtual bool showInstrumentPanel () const { return true; } + virtual bool guidedBarShowEmergencyStop () const { return true; } + virtual bool guidedBarShowOrbit () const { return true; } + virtual bool guidedBarShowROI () const { return true; } + + QGCOptions* _options; + +signals: + void guidedBarShowEmergencyStopChanged (bool show); + void guidedBarShowOrbitChanged (bool show); + void guidedBarShowROIChanged (bool show); +}; -class CustomInstrumentWidget; class QGCOptions : public QObject { Q_OBJECT @@ -28,15 +54,11 @@ public: Q_PROPERTY(bool combineSettingsAndSetup READ combineSettingsAndSetup CONSTANT) Q_PROPERTY(double toolbarHeightMultiplier READ toolbarHeightMultiplier CONSTANT) Q_PROPERTY(bool enablePlanViewSelector READ enablePlanViewSelector CONSTANT) - Q_PROPERTY(CustomInstrumentWidget* instrumentWidget READ instrumentWidget CONSTANT) - Q_PROPERTY(QUrl flyViewOverlay READ flyViewOverlay CONSTANT) Q_PROPERTY(QUrl preFlightChecklistUrl READ preFlightChecklistUrl CONSTANT) - Q_PROPERTY(QUrl mainToolbarUrl READ mainToolbarUrl CONSTANT) Q_PROPERTY(QUrl planToolbarUrl READ planToolbarUrl CONSTANT) Q_PROPERTY(QColor toolbarBackgroundLight READ toolbarBackgroundLight CONSTANT) Q_PROPERTY(QColor toolbarBackgroundDark READ toolbarBackgroundDark CONSTANT) - Q_PROPERTY(QUrl planToolbarIndicatorsUrl READ planToolbarIndicatorsUrl CONSTANT) Q_PROPERTY(bool showSensorCalibrationCompass READ showSensorCalibrationCompass NOTIFY showSensorCalibrationCompassChanged) Q_PROPERTY(bool showSensorCalibrationGyro READ showSensorCalibrationGyro NOTIFY showSensorCalibrationGyroChanged) @@ -47,9 +69,6 @@ public: Q_PROPERTY(bool wifiReliableForCalibration READ wifiReliableForCalibration CONSTANT) Q_PROPERTY(bool showFirmwareUpgrade READ showFirmwareUpgrade NOTIFY showFirmwareUpgradeChanged) Q_PROPERTY(QString firmwareUpgradeSingleURL READ firmwareUpgradeSingleURL CONSTANT) - Q_PROPERTY(bool guidedBarShowEmergencyStop READ guidedBarShowEmergencyStop NOTIFY guidedBarShowEmergencyStopChanged) - Q_PROPERTY(bool guidedBarShowOrbit READ guidedBarShowOrbit NOTIFY guidedBarShowOrbitChanged) - Q_PROPERTY(bool guidedBarShowROI READ guidedBarShowROI NOTIFY guidedBarShowROIChanged) Q_PROPERTY(bool missionWaypointsOnly READ missionWaypointsOnly NOTIFY missionWaypointsOnlyChanged) Q_PROPERTY(bool multiVehicleEnabled READ multiVehicleEnabled NOTIFY multiVehicleEnabledChanged) Q_PROPERTY(bool showOfflineMapExport READ showOfflineMapExport NOTIFY showOfflineMapExportChanged) @@ -64,11 +83,11 @@ public: Q_PROPERTY(float devicePixelDensity READ devicePixelDensity NOTIFY devicePixelDensityChanged) Q_PROPERTY(bool checkFirmwareVersion READ checkFirmwareVersion CONSTANT) Q_PROPERTY(bool showMavlinkLogOptions READ showMavlinkLogOptions CONSTANT) - Q_PROPERTY(bool enableMultiVehicleList READ enableMultiVehicleList CONSTANT) - Q_PROPERTY(bool enableMapScale READ enableMapScale CONSTANT) Q_PROPERTY(bool enableSaveMainWindowPosition READ enableSaveMainWindowPosition CONSTANT) Q_PROPERTY(QStringList surveyBuiltInPresetNames READ surveyBuiltInPresetNames CONSTANT) + Q_PROPERTY(QGCFlyViewOptions* flyView READ flyViewOptions CONSTANT) + /// Should QGC hide its settings menu and colapse it into one single menu (Settings and Vehicle Setup)? /// @return true if QGC should consolidate both menus into one. virtual bool combineSettingsAndSetup () { return false; } @@ -81,17 +100,10 @@ public: /// @return True or false virtual bool enablePlanViewSelector () { return true; } - /// Provides an alternate instrument widget for the Fly View - /// @return An alternate widget (see QGCInstrumentWidget.qml, the default widget) - virtual CustomInstrumentWidget* instrumentWidget(); - /// Should the mission status indicator (Plan View) be shown? /// @return Yes or no virtual bool showMissionStatus () { return true; } - /// Allows access to the full fly view window - virtual QUrl flyViewOverlay () const { return QUrl(); } - /// Provides an optional, custom preflight checklist virtual QUrl preFlightChecklistUrl () const { return QUrl::fromUserInput("qrc:/qml/PreFlightCheckList.qml"); } @@ -114,9 +126,6 @@ public: virtual bool wifiReliableForCalibration () const { return false; } virtual bool sensorsHaveFixedOrientation () const { return false; } virtual bool showFirmwareUpgrade () const { return true; } - virtual bool guidedBarShowEmergencyStop () const { return true; } - virtual bool guidedBarShowOrbit () const { return true; } - virtual bool guidedBarShowROI () const { return true; } virtual bool missionWaypointsOnly () const { return false; } ///< true: Only allow waypoints and complex items in Plan virtual bool multiVehicleEnabled () const { return true; } ///< false: multi vehicle support is disabled virtual bool guidedActionsRequireRCRSSI () const { return false; } ///< true: Guided actions will be disabled is there is no RC RSSI @@ -127,8 +136,6 @@ public: virtual bool disableVehicleConnection () const { return false; } ///< true: vehicle connection is disabled virtual bool checkFirmwareVersion () const { return true; } virtual bool showMavlinkLogOptions () const { return true; } - virtual bool enableMultiVehicleList () const { return true; } - virtual bool enableMapScale () const { return true; } /// Desktop builds save the main application size and position on close (and restore it on open) virtual bool enableSaveMainWindowPosition () const { return true; } virtual QStringList surveyBuiltInPresetNames () const { return QStringList(); } // Built in presets cannot be deleted @@ -148,6 +155,8 @@ public: virtual float devicePixelRatio () const { return 0.0f; } virtual float devicePixelDensity () const { return 0.0f; } + virtual QGCFlyViewOptions* flyViewOptions (); + signals: void showSensorCalibrationCompassChanged (bool show); void showSensorCalibrationGyroChanged (bool show); @@ -155,9 +164,6 @@ signals: void showSensorCalibrationLevelChanged (bool show); void showSensorCalibrationAirspeedChanged (bool show); void showFirmwareUpgradeChanged (bool show); - void guidedBarShowEmergencyStopChanged (bool show); - void guidedBarShowOrbitChanged (bool show); - void guidedBarShowROIChanged (bool show); void missionWaypointsOnlyChanged (bool missionWaypointsOnly); void multiVehicleEnabledChanged (bool multiVehicleEnabled); void showOfflineMapExportChanged (); @@ -167,30 +173,6 @@ signals: void devicePixelRatioChanged (); void devicePixelDensityChanged (); -private: - CustomInstrumentWidget* _defaultInstrumentWidget; -}; - -//----------------------------------------------------------------------------- -class CustomInstrumentWidget : public QObject -{ - Q_OBJECT -public: - //-- Widget Position - enum Pos { - POS_TOP_RIGHT, - POS_CENTER_RIGHT, - POS_BOTTOM_RIGHT, - POS_TOP_LEFT, - POS_CENTER_LEFT, - POS_BOTTOM_LEFT - }; - Q_ENUM(Pos) - CustomInstrumentWidget(QObject* parent = nullptr); - Q_PROPERTY(QUrl source READ source CONSTANT) - Q_PROPERTY(Pos widgetPosition READ widgetPosition NOTIFY widgetPositionChanged) - virtual QUrl source () { return QUrl(); } - virtual Pos widgetPosition () { return POS_TOP_RIGHT; } -signals: - void widgetPositionChanged (); +protected: + QGCFlyViewOptions* _defaultFlyViewOptions = nullptr; }; diff --git a/src/ui/MainRootWindow.qml b/src/ui/MainRootWindow.qml index 862caa331..40cd099f6 100644 --- a/src/ui/MainRootWindow.qml +++ b/src/ui/MainRootWindow.qml @@ -58,20 +58,20 @@ ApplicationWindow { //-- Global Scope Variables /// Current active Vehicle - property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle /// Indicates communication with vehicle is list (no heartbeats) - property bool communicationLost: activeVehicle ? activeVehicle.connectionLost : false - property string formatedMessage: activeVehicle ? activeVehicle.formatedMessage : "" + property bool communicationLost: activeVehicle ? activeVehicle.connectionLost : false + property string formatedMessage: activeVehicle ? activeVehicle.formatedMessage : "" /// Indicates usable height between toolbar and footer - property real availableHeight: mainWindow.height - mainWindow.header.height - mainWindow.footer.height + property real availableHeight: mainWindow.height - mainWindow.header.height - mainWindow.footer.height - property var currentPlanMissionItem: planMasterControllerPlan ? planMasterControllerPlan.missionController.currentPlanViewItem : null - property var planMasterControllerPlan: null - property var planMasterControllerView: null + property var currentPlanMissionItem: planMasterControllerPlanView ? planMasterControllerPlanView.missionController.currentPlanViewItem : null + property var planMasterControllerPlanView: null + property var planMasterControllerFlyView: null - readonly property string navButtonWidth: ScreenTools.defaultFontPixelWidth * 24 - readonly property real defaultTextHeight: ScreenTools.defaultFontPixelHeight - readonly property real defaultTextWidth: ScreenTools.defaultFontPixelWidth + readonly property string navButtonWidth: ScreenTools.defaultFontPixelWidth * 24 + readonly property real defaultTextHeight: ScreenTools.defaultFontPixelHeight + readonly property real defaultTextWidth: ScreenTools.defaultFontPixelWidth /// Default color palette used throughout the UI QGCPalette { id: qgcPal; colorGroupEnabled: true } @@ -268,7 +268,7 @@ ApplicationWindow { visible: false onYes: pendingParameterWritesCloseDialog.check() function check() { - if (planMasterControllerPlan && planMasterControllerPlan.dirty) { + if (planMasterControllerPlanView && planMasterControllerPlanView.dirty) { unsavedMissionCloseDialog.open() } else { pendingParameterWritesCloseDialog.check() @@ -352,16 +352,9 @@ ApplicationWindow { //------------------------------------------------------------------------- /// Fly View - FlightDisplayView { + FlyView { id: flightView anchors.fill: parent - //----------------------------------------------------------------- - //-- Loader helper for any child, no matter how deep, to display - // elements on top of the fly (video) window. - Loader { - id: rootVideoLoader - anchors.centerIn: parent - } } //------------------------------------------------------------------------- -- 2.22.0