diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index cb4b1510eda8127024132e3df0491efab192d7ce..d02a006c57c6afd930e5840bbb79b556605b07de 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -36,7 +36,6 @@ src/AnalyzeView/AnalyzeView.qml src/ui/AppSettings.qml src/ui/preferences/BluetoothSettings.qml - src/FlightMap/Widgets/CameraPageWidget.qml src/PlanView/CorridorScanEditor.qml src/ui/preferences/DebugWindow.qml src/AutoPilotPlugins/Common/ESP8266Component.qml @@ -117,7 +116,6 @@ src/QmlControls/ModeSwitchDisplay.qml src/QmlControls/MultiRotorMotorDisplay.qml src/QmlControls/OfflineMapButton.qml - src/QmlControls/PageView.qml src/QmlControls/ParameterEditor.qml src/QmlControls/ParameterEditorDialog.qml src/QmlControls/PIDTuning.qml @@ -222,7 +220,6 @@ src/FlightDisplay/GuidedAltitudeSlider.qml src/FlightDisplay/GuidedToolStripAction.qml src/FlightDisplay/MultiVehicleList.qml - src/FlightDisplay/MultiVehiclePanel.qml src/FlightDisplay/PreFlightBatteryCheck.qml src/FlightDisplay/PreFlightGPSCheck.qml src/FlightDisplay/PreFlightRCCheck.qml @@ -246,6 +243,7 @@ src/FlightMap/MapItems/MissionItemIndicatorDrag.qml src/FlightMap/MapItems/MissionItemView.qml src/FlightMap/MapItems/MissionLineView.qml + src/FlightMap/Widgets/PhotoVideoControl.qml src/FlightMap/MapItems/PlanMapItems.qml src/FlightMap/MapItems/PolygonEditor.qml src/FlightMap/Widgets/QGCArtificialHorizon.qml @@ -271,10 +269,8 @@ src/ui/preferences/TcpSettings.qml src/test.qml src/ui/preferences/UdpSettings.qml - src/FlightMap/Widgets/ValuePageWidget.qml src/VehicleSetup/VehicleSummary.qml src/AnalyzeView/VibrationPage.qml - src/FlightMap/Widgets/VideoPageWidget.qml src/FlightDisplay/VirtualJoystick.qml src/PlanView/VTOLLandingPatternEditor.qml diff --git a/src/AutoPilotPlugins/PX4/CameraComponent.qml b/src/AutoPilotPlugins/PX4/CameraComponent.qml index 75a12a0b0c972f57b2880a681d337fe754252ecc..118dc06d6f475753c76c6dd51fffd4ca938c8203 100644 --- a/src/AutoPilotPlugins/PX4/CameraComponent.qml +++ b/src/AutoPilotPlugins/PX4/CameraComponent.qml @@ -300,17 +300,6 @@ SetupPage { } } } // QGCGroupBox - Hardware Settings - - QGCGroupBox { - title: qsTr("Camera Test") - Layout.fillWidth: true - - QGCButton { - anchors.horizontalCenter: parent.horizontalCenter - text: qsTr("Trigger Camera") - onClicked: controller.vehicle.triggerCamera() - } - } } } } diff --git a/src/Camera/QGCCameraControl.cc b/src/Camera/QGCCameraControl.cc index 74071605a0bcbe7eed2e0353ba0f270dccf192f7..f661b1f19e7fb0b1ac8d91a45466a9496b434949 100644 --- a/src/Camera/QGCCameraControl.cc +++ b/src/Camera/QGCCameraControl.cc @@ -1590,7 +1590,7 @@ QGCCameraControl::handleVideoInfo(const mavlink_video_stream_information_t* vi) qCDebug(CameraControlLog) << "All stream handlers done"; _streamInfoTimer.stop(); emit autoStreamChanged(); - emit _vehicle->dynamicCameras()->streamChanged(); + emit _vehicle->cameraManager()->streamChanged(); } } @@ -1636,7 +1636,7 @@ QGCCameraControl::setCurrentStream(int stream) _requestStreamStatus(static_cast(pInfo->streamID())); } emit currentStreamChanged(); - emit _vehicle->dynamicCameras()->streamChanged(); + emit _vehicle->cameraManager()->streamChanged(); } } } @@ -1786,7 +1786,7 @@ QGCCameraControl::_streamTimeout() //-- If we have at least one stream, work with what we have. if(_streams.count()) { emit autoStreamChanged(); - emit _vehicle->dynamicCameras()->streamChanged(); + emit _vehicle->cameraManager()->streamChanged(); } return; } @@ -2140,7 +2140,7 @@ QGCCameraControl::wb() Fact* QGCCameraControl::mode() { - return _paramComplete ? getFact(kCAM_MODE) : nullptr; + return _paramComplete && factExists(kCAM_MODE) ? getFact(kCAM_MODE) : nullptr; } //----------------------------------------------------------------------------- diff --git a/src/FactSystem/FactGroup.cc b/src/FactSystem/FactGroup.cc index c98c5ca828b0ab33312f6c6eeac1420a0c0a2df8..985dea5b0ce9f209ffdc698a66c94a51f165a405 100644 --- a/src/FactSystem/FactGroup.cc +++ b/src/FactSystem/FactGroup.cc @@ -53,6 +53,29 @@ void FactGroup::_setupTimer() } } +bool FactGroup::factExists(const QString& name) +{ + if (name.contains(".")) { + QStringList parts = name.split("."); + if (parts.count() != 2) { + qWarning() << "Only single level of hierarchy supported"; + return false; + } + + FactGroup * factGroup = getFactGroup(parts[0]); + if (!factGroup) { + qWarning() << "Unknown FactGroup" << parts[0]; + return false; + } + + return factGroup->factExists(parts[1]); + } + + QString camelCaseName = _ignoreCamelCase ? name : _camelCase(name); + + return _nameToFactMap.contains(camelCaseName); +} + Fact* FactGroup::getFact(const QString& name) { if (name.contains(".")) { diff --git a/src/FactSystem/FactGroup.h b/src/FactSystem/FactGroup.h index fd1852b780c865272ea7d9449412af3be73feb4a..00614a8cab21889565090554fb3a627dee71fe87 100644 --- a/src/FactSystem/FactGroup.h +++ b/src/FactSystem/FactGroup.h @@ -32,10 +32,15 @@ public: Q_PROPERTY(QStringList factNames READ factNames CONSTANT) Q_PROPERTY(QStringList factGroupNames READ factGroupNames CONSTANT) + /// @ return true: if the fact exists in the group + Q_INVOKABLE bool factExists(const QString& name); + /// @return Fact for specified name, NULL if not found + /// Note: Requesting a fact which doesn't exists is considered an internal error and will spit out a qWarning Q_INVOKABLE Fact* getFact(const QString& name); /// @return FactGroup for specified name, NULL if not found + /// Note: Requesting a fact group which doesn't exists is considered an internal error and will spit out a qWarning Q_INVOKABLE FactGroup* getFactGroup(const QString& name); /// Turning on live updates will allow value changes to flow through as they are received. diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml index 47bb7209194083b76d92b04a036274c28a26cec3..037550e2da83c7f12cf54199b128f3885127037f 100644 --- a/src/FlightDisplay/FlightDisplayViewVideo.qml +++ b/src/FlightDisplay/FlightDisplayViewVideo.qml @@ -28,7 +28,7 @@ Item { property double _ar: QGroundControl.videoManager.aspectRatio property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0 - property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null + property var _dynamicCameras: activeVehicle ? activeVehicle.cameraManager : null property bool _connected: activeVehicle ? !activeVehicle.connectionLost : false property int _curCameraIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0 property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false diff --git a/src/FlightDisplay/FlightDisplayViewWidgets.qml b/src/FlightDisplay/FlightDisplayViewWidgets.qml index cf316ea60fd86a573ffa4e0a798f7c77738d049d..19e92a76672b9330e3f36ad78999d756b5fca472 100644 --- a/src/FlightDisplay/FlightDisplayViewWidgets.qml +++ b/src/FlightDisplay/FlightDisplayViewWidgets.qml @@ -26,15 +26,11 @@ Column { id: _root spacing: ScreenTools.defaultFontPixelHeight * 0.25 - property var missionController - property real availableHeight + property var missionController Loader { - width: parent.width + width: parent.width source: QGroundControl.settingsManager.flyViewSettings.alternateInstrumentPanel.rawValue ? "qrc:/qml/QGCInstrumentWidgetAlternate.qml" : "qrc:/qml/QGCInstrumentWidget.qml" - - property real maxHeight: availableHeight - y - property bool showValues: !QGroundControl.airspaceManager.airspaceVisible } } diff --git a/src/FlightDisplay/FlyViewInstrumentPanel.qml b/src/FlightDisplay/FlyViewInstrumentPanel.qml index 735330d06ebefdf92591ea537ad26eb9f1c66432..38b8ab5bbba1d3a21dc4c2cac9edad9177d844d8 100644 --- a/src/FlightDisplay/FlyViewInstrumentPanel.qml +++ b/src/FlightDisplay/FlyViewInstrumentPanel.qml @@ -23,12 +23,6 @@ Column { property real availableHeight - MultiVehiclePanel { - id: multiVehiclePanel - width: parent.width - availableHeight: parent.height - y - } - AirspaceControl { id: airspaceControl width: parent.width @@ -40,7 +34,5 @@ Column { id: flightDisplayViewWidgets width: parent.width missionController: _missionController - availableHeight: _root.availableHeight - y - visible: multiVehiclePanel.singleVehiclePanel } } diff --git a/src/FlightDisplay/FlyViewWidgetLayer.qml b/src/FlightDisplay/FlyViewWidgetLayer.qml index 4228d2a5c68fa28d5f77d28474cb2c37f3fefdf0..8541583b9af4130d248900dfd0826db0340bc358 100644 --- a/src/FlightDisplay/FlyViewWidgetLayer.qml +++ b/src/FlightDisplay/FlyViewWidgetLayer.qml @@ -71,20 +71,61 @@ Item { rallyPointController: _rallyPointController } + Row { + id: multiVehiclePanelSelector + anchors.margins: _toolsMargin + anchors.top: parent.top + anchors.right: parent.right + width: _rightPanelWidth + spacing: ScreenTools.defaultFontPixelWidth + visible: QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.flyView.showMultiVehicleList + + property bool showSingleVehiclePanel: !visible || singleVehicleRadio.checked + + QGCMapPalette { id: mapPal; lightColors: true } + + QGCRadioButton { + id: singleVehicleRadio + text: qsTr("Single") + checked: true + textColor: mapPal.text + } + + QGCRadioButton { + text: qsTr("Multi-Vehicle") + textColor: mapPal.text + } + } + + MultiVehicleList { + anchors.margins: _toolsMargin + anchors.top: multiVehiclePanelSelector.bottom + anchors.right: parent.right + width: _rightPanelWidth + height: parent.height - y - _toolsMargin + visible: !multiVehiclePanelSelector.showSingleVehiclePanel + } + FlyViewInstrumentPanel { id: instrumentPanel anchors.margins: _toolsMargin - anchors.top: parent.top - anchors.bottom: parent.bottom + anchors.top: multiVehiclePanelSelector.visible ? multiVehiclePanelSelector.bottom : parent.top anchors.right: parent.right width: _rightPanelWidth spacing: _toolsMargin - visible: QGroundControl.corePlugin.options.flyView.showInstrumentPanel + visible: QGroundControl.corePlugin.options.flyView.showInstrumentPanel && multiVehiclePanelSelector.showSingleVehiclePanel availableHeight: parent.height - y - _toolsMargin property real rightInset: visible ? parent.width - x : 0 } + PhotoVideoControl { + anchors.margins: _toolsMargin + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + width: _rightPanelWidth + } + TelemetryValuesBar { id: telemetryPanel x: recalcXPosition() diff --git a/src/FlightDisplay/MultiVehiclePanel.qml b/src/FlightDisplay/MultiVehiclePanel.qml deleted file mode 100644 index 7e657cab99cf1ab908682dff8a2fc02d7f7e0b1c..0000000000000000000000000000000000000000 --- a/src/FlightDisplay/MultiVehiclePanel.qml +++ /dev/null @@ -1,55 +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.Layouts 1.12 - -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 - height: singleVehiclePanel ? selectorRow.height : availableHeight - visible: QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.flyView.showMultiVehicleList - - property alias singleVehiclePanel: singleVehicleView.checked - property real availableHeight - - QGCMapPalette { id: mapPal; lightColors: true } - - Row { - id: selectorRow - spacing: ScreenTools.defaultFontPixelWidth - - QGCRadioButton { - id: singleVehicleView - text: qsTr("Single") - checked: true - textColor: mapPal.text - } - - QGCRadioButton { - text: qsTr("Multi-Vehicle") - textColor: mapPal.text - } - } - - MultiVehicleList { - anchors.topMargin: ScreenTools.defaultFontPixelHeight / 2 - anchors.top: selectorRow.bottom - anchors.bottom: parent.bottom - width: parent.width - visible: !singleVehiclePanel && !QGroundControl.videoManager.fullScreen && QGroundControl.corePlugin.options.showMultiVehicleList - } -} diff --git a/src/FlightMap/Widgets/CameraPageWidget.qml b/src/FlightMap/Widgets/CameraPageWidget.qml deleted file mode 100644 index 8499d7151928c8b9a9d10f43a0b2755f8accd6eb..0000000000000000000000000000000000000000 --- a/src/FlightMap/Widgets/CameraPageWidget.qml +++ /dev/null @@ -1,506 +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.4 -import QtPositioning 5.2 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 -import QtGraphicalEffects 1.0 - -import QGroundControl 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.Vehicle 1.0 -import QGroundControl.Controllers 1.0 -import QGroundControl.FactSystem 1.0 -import QGroundControl.FactControls 1.0 - -/// Camera page for Instrument Panel PageView -Column { - width: pageWidth - spacing: ScreenTools.defaultFontPixelHeight * 0.25 - - property bool showSettingsIcon: _camera !== null - - property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null - property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false - property int _curCameraIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0 - property var _camera: _isCamera ? (_dynamicCameras.cameras.get(_curCameraIndex) && _dynamicCameras.cameras.get(_curCameraIndex).paramComplete ? _dynamicCameras.cameras.get(_curCameraIndex) : null) : null - property bool _cameraModeUndefined: _camera ? _camera.cameraMode === QGCCameraControl.CAM_MODE_UNDEFINED : true - property bool _cameraVideoMode: _camera ? _camera.cameraMode === QGCCameraControl.CAM_MODE_VIDEO : false - property bool _cameraPhotoMode: _camera ? _camera.cameraMode === QGCCameraControl.CAM_MODE_PHOTO : false - property bool _cameraElapsedMode: _camera && _camera.cameraMode === QGCCameraControl.CAM_MODE_PHOTO && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE - property real _spacers: ScreenTools.defaultFontPixelHeight * 0.5 - property real _labelFieldWidth: ScreenTools.defaultFontPixelWidth * 30 - property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 - property bool _communicationLost: activeVehicle ? activeVehicle.connectionLost : false - property bool _streamingEnabled: false //TODO: determine what it should be, VideoPageWidget.qml does QGroundControl.settingsManager.videoSettings.streamConfigured - property bool _hasModes: _camera && _camera.hasModes - property bool _videoRecording: _camera && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING - property bool _photoIdle: _camera && (_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_IDLE || _camera.photoStatus >= QGCCameraControl.PHOTO_CAPTURE_LAST) - property bool _storageReady: _camera && _camera.storageStatus === QGCCameraControl.STORAGE_READY - property bool _batteryReady: _camera && _camera.batteryRemaining >= 0 - property bool _storageIgnored: _camera && _camera.storageStatus === QGCCameraControl.STORAGE_NOT_SUPPORTED - property bool _canShoot: !_cameraModeUndefined && ((_storageReady && _camera.storageFree > 0) || _storageIgnored) - property bool _isShooting: (_cameraVideoMode && _videoRecording) || (_cameraPhotoMode && !_photoIdle) - - function showSettings() { - mainWindow.showComponentDialog(cameraSettings, _cameraVideoMode ? qsTr("Video Settings") : qsTr("Camera Settings"), 70, StandardButton.Ok) - } - - //-- Dumb camera trigger if no actual camera interface exists - QGCButton { - anchors.horizontalCenter: parent.horizontalCenter - text: qsTr("Trigger Camera") - visible: !_camera - onClicked: activeVehicle.triggerCamera() - enabled: activeVehicle - } - Item { width: 1; height: ScreenTools.defaultFontPixelHeight; visible: _camera; } - //-- Actual controller - QGCLabel { - id: cameraLabel - text: _camera ? _camera.modelName : qsTr("Camera") - visible: _camera - font.pointSize: ScreenTools.defaultFontPointSize - anchors.horizontalCenter: parent.horizontalCenter - } - QGCLabel { - text: _camera ? qsTr("Free Space: ") + _camera.storageFreeStr : "" - font.pointSize: ScreenTools.defaultFontPointSize - anchors.horizontalCenter: parent.horizontalCenter - visible: _storageReady - } - QGCLabel { - text: _camera ? qsTr("Battery: ") + _camera.batteryRemainingStr : "" - font.pointSize: ScreenTools.defaultFontPointSize - anchors.horizontalCenter: parent.horizontalCenter - visible: _batteryReady - } - //-- Camera Mode (visible only if camera has modes) - Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 0.75; visible: camMode.visible; } - Rectangle { - id: camMode - width: _hasModes ? ScreenTools.defaultFontPixelWidth * 8 : 0 - height: _hasModes ? ScreenTools.defaultFontPixelWidth * 4 : 0 - color: qgcPal.windowShadeLight - radius: height * 0.5 - visible: _hasModes - anchors.horizontalCenter: parent.horizontalCenter - //-- Video Mode - Rectangle { - width: parent.height - height: parent.height - color: _cameraVideoMode ? qgcPal.window : qgcPal.windowShadeLight - radius: height * 0.5 - anchors.left: parent.left - border.color: qgcPal.text - border.width: _cameraVideoMode ? 1 : 0 - anchors.verticalCenter: parent.verticalCenter - QGCColoredImage { - height: parent.height * 0.5 - width: height - anchors.centerIn: parent - source: "/qmlimages/camera_video.svg" - fillMode: Image.PreserveAspectFit - sourceSize.height: height - color: _cameraVideoMode ? qgcPal.colorGreen : qgcPal.text - MouseArea { - anchors.fill: parent - enabled: _cameraPhotoMode && !_isShooting - onClicked: { - _camera.setVideoMode() - } - } - } - } - //-- Photo Mode - Rectangle { - width: parent.height - height: parent.height - color: _cameraPhotoMode ? qgcPal.window : qgcPal.windowShadeLight - radius: height * 0.5 - anchors.right: parent.right - border.color: qgcPal.text - border.width: _cameraPhotoMode ? 1 : 0 - anchors.verticalCenter: parent.verticalCenter - QGCColoredImage { - height: parent.height * 0.5 - width: height - anchors.centerIn: parent - source: "/qmlimages/camera_photo.svg" - fillMode: Image.PreserveAspectFit - sourceSize.height: height - color: _cameraPhotoMode ? qgcPal.colorGreen : qgcPal.text - MouseArea { - anchors.fill: parent - enabled: _cameraVideoMode && !_isShooting - onClicked: { - _camera.setPhotoMode() - } - } - } - } - } - //-- Shutter - Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 0.75; visible: camShutter.visible; } - Rectangle { - id: camShutter - color: Qt.rgba(0,0,0,0) - width: ScreenTools.defaultFontPixelWidth * 6 - height: width - radius: width * 0.5 - visible: _camera - border.color: qgcPal.buttonText - border.width: 3 - anchors.horizontalCenter: parent.horizontalCenter - Rectangle { - width: parent.width * (_isShooting ? 0.5 : 0.75) - height: width - radius: _isShooting ? 0 : width * 0.5 - color: _canShoot ? qgcPal.colorRed : qgcPal.colorGrey - anchors.centerIn: parent - } - MouseArea { - anchors.fill: parent - enabled: _canShoot - onClicked: { - if(_cameraVideoMode) { - _camera.toggleVideo() - } else { - if(_cameraPhotoMode && !_photoIdle && _cameraElapsedMode) { - _camera.stopTakePhoto() - } else { - _camera.takePhoto() - } - } - } - } - } - //-- Timer/Counter - Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 0.75; visible: _camera; } - QGCLabel { - text: (_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) ? _camera.recordTimeStr : "00:00:00" - font.pointSize: ScreenTools.defaultFontPointSize - visible: _cameraVideoMode - anchors.horizontalCenter: parent.horizontalCenter - } - QGCLabel { - text: activeVehicle && _cameraPhotoMode ? ('00000' + activeVehicle.cameraTriggerPoints.count).slice(-5) : "00000" - font.pointSize: ScreenTools.defaultFontPointSize - visible: _cameraPhotoMode - anchors.horizontalCenter: parent.horizontalCenter - } - //-- Settings - Item { width: 1; height: ScreenTools.defaultFontPixelHeight; visible: _camera; } - Component { - id: cameraSettings - QGCViewDialog { - id: _cameraSettingsDialog - QGCFlickable { - anchors.fill: parent - contentHeight: camSettingsCol.height - flickableDirection: Flickable.VerticalFlick - clip: true - Column { - id: camSettingsCol - anchors.left: parent.left - anchors.right: parent.right - spacing: _margins - //------------------------------------------- - //-- Camera Selector - Row { - spacing: ScreenTools.defaultFontPixelWidth - visible: _isCamera && _dynamicCameras.cameraLabels.length > 1 - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: qsTr("Camera Selector:") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: cameraSelector - model: _isCamera ? _dynamicCameras.cameraLabels : [] - width: _editFieldWidth - onActivated: _dynamicCameras.currentCamera = index - currentIndex: _dynamicCameras.currentCamera - } - } - //------------------------------------------- - //-- Stream Selector - Row { - spacing: ScreenTools.defaultFontPixelWidth - visible: _camera && _camera.streamLabels.length > 1 - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: qsTr("Stream Selector:") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - model: _camera ? _camera.streamLabels : [] - width: _editFieldWidth - onActivated: _camera.currentStream = index - currentIndex: _camera ? _camera.currentStream : 0 - } - } - //------------------------------------------- - //-- Thermal Modes - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - visible: QGroundControl.videoManager.hasThermal - property var thermalModes: [qsTr("Off"), qsTr("Blend"), qsTr("Full"), qsTr("Picture In Picture")] - QGCLabel { - text: qsTr("Thermal View Mode") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - width: _editFieldWidth - model: parent.thermalModes - currentIndex: _camera ? _camera.thermalMode : 0 - onActivated: _camera.thermalMode = index - } - } - //------------------------------------------- - //-- Thermal Video Opacity - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - visible: QGroundControl.videoManager.hasThermal && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND - QGCLabel { - text: qsTr("Blend Opacity") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - Slider { - width: _editFieldWidth - maximumValue: 100 - minimumValue: 0 - value: _camera ? _camera.thermalOpacity : 0 - updateValueWhileDragging: true - onValueChanged: { - _camera.thermalOpacity = value - } - } - } - //------------------------------------------- - //-- Camera Settings - Repeater { - model: _camera ? _camera.activeSettings : [] - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - property var _fact: _camera.getFact(modelData) - property bool _isBool: _fact.typeIsBool - property bool _isCombo: !_isBool && _fact.enumStrings.length > 0 - property bool _isSlider: _fact && !isNaN(_fact.increment) - property bool _isEdit: !_isBool && !_isSlider && _fact.enumStrings.length < 1 - QGCLabel { - text: parent._fact.shortDescription - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - FactComboBox { - width: parent._isCombo ? _editFieldWidth : 0 - fact: parent._fact - indexModel: false - visible: parent._isCombo - anchors.verticalCenter: parent.verticalCenter - } - FactTextField { - width: parent._isEdit ? _editFieldWidth : 0 - fact: parent._fact - visible: parent._isEdit - } - QGCSlider { - width: parent._isSlider ? _editFieldWidth : 0 - maximumValue: parent._fact.max - minimumValue: parent._fact.min - stepSize: parent._fact.increment - visible: parent._isSlider - updateValueWhileDragging: false - anchors.verticalCenter: parent.verticalCenter - Component.onCompleted: { - value = parent._fact.value - } - onValueChanged: { - parent._fact.value = value - } - } - Item { - width: parent._isBool ? _editFieldWidth : 0 - height: factSwitch.height - visible: parent._isBool - anchors.verticalCenter: parent.verticalCenter - property var _fact: parent._fact - Switch { - id: factSwitch - anchors.left: parent.left - checked: parent._fact ? parent._fact.value : false - onClicked: parent._fact.value = checked ? 1 : 0 - } - } - } - } - //------------------------------------------- - //-- Time Lapse - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - visible: _cameraPhotoMode - property var photoModes: [qsTr("Single"), qsTr("Time Lapse")] - QGCLabel { - text: qsTr("Photo Mode") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: photoModeCombo - width: _editFieldWidth - model: parent.photoModes - currentIndex: _camera ? _camera.photoMode : 0 - onActivated: _camera.photoMode = index - } - } - //------------------------------------------- - //-- Time Lapse Interval - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - visible: _cameraPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE - QGCLabel { - text: qsTr("Photo Interval (seconds)") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - Item { - height: photoModeCombo.height - width: _editFieldWidth - QGCSlider { - maximumValue: 60 - minimumValue: 1 - stepSize: 1 - value: _camera ? _camera.photoLapse : 5 - displayValue: true - updateValueWhileDragging: true - anchors.fill: parent - onValueChanged: { - _camera.photoLapse = value - } - } - } - } - //------------------------------------------- - // Grid Lines - Row { - visible: _camera && _camera.autoStream - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: qsTr("Grid Lines") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCSwitch { - enabled: _streamingEnabled && activeVehicle - checked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue - width: _editFieldWidth - anchors.verticalCenter: parent.verticalCenter - onClicked: { - if(checked) { - QGroundControl.settingsManager.videoSettings.gridLines.rawValue = 1 - } else { - QGroundControl.settingsManager.videoSettings.gridLines.rawValue = 0 - } - } - } - } - //------------------------------------------- - //-- Video Fit - Row { - visible: _camera && _camera.autoStream - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: qsTr("Video Screen Fit") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - FactComboBox { - fact: QGroundControl.settingsManager.videoSettings.videoFit - indexModel: false - width: _editFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - } - //------------------------------------------- - //-- Reset Camera - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: qsTr("Reset Camera Defaults") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCButton { - text: qsTr("Reset") - onClicked: resetPrompt.open() - width: _editFieldWidth - anchors.verticalCenter: parent.verticalCenter - MessageDialog { - id: resetPrompt - title: qsTr("Reset Camera to Factory Settings") - text: qsTr("Confirm resetting all settings?") - standardButtons: StandardButton.Yes | StandardButton.No - onNo: resetPrompt.close() - onYes: { - _camera.resetSettings() - resetPrompt.close() - } - } - } - } - //------------------------------------------- - //-- Format Storage - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.horizontalCenter: parent.horizontalCenter - QGCLabel { - text: qsTr("Storage") - width: _labelFieldWidth - anchors.verticalCenter: parent.verticalCenter - } - QGCButton { - text: qsTr("Format") - onClicked: formatPrompt.open() - width: _editFieldWidth - anchors.verticalCenter: parent.verticalCenter - MessageDialog { - id: formatPrompt - title: qsTr("Format Camera Storage") - text: qsTr("Confirm erasing all files?") - standardButtons: StandardButton.Yes | StandardButton.No - onNo: formatPrompt.close() - onYes: { - _camera.formatCard() - formatPrompt.close() - } - } - } - } - } - } - } - } -} diff --git a/src/FlightMap/Widgets/PhotoVideoControl.qml b/src/FlightMap/Widgets/PhotoVideoControl.qml new file mode 100644 index 0000000000000000000000000000000000000000..7e853940c8ad1e59b19afc2ad034a289b81cda6f --- /dev/null +++ b/src/FlightMap/Widgets/PhotoVideoControl.qml @@ -0,0 +1,486 @@ +/**************************************************************************** + * + * (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.4 +import QtPositioning 5.2 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 +import QtGraphicalEffects 1.0 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Vehicle 1.0 +import QGroundControl.Controllers 1.0 +import QGroundControl.FactSystem 1.0 +import QGroundControl.FactControls 1.0 + +Rectangle { + height: mainLayout.height + (_margins * 2) + color: "#80000000" + radius: _margins + visible: !QGroundControl.settingsManager.flyViewSettings.alternateInstrumentPanel.rawValue && (_camera || _anyVideoStreamAvailable) && multiVehiclePanelSelector.showSingleVehiclePanel + + property real _margins: ScreenTools.defaultFontPixelHeight / 2 + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property var _cameraManager: _activeVehicle ? _activeVehicle.cameraManager : null + property var _videoManager: QGroundControl.videoManager + property bool _noCameras: _cameraManager ? _cameraManager.cameras.count === 0 : true + property bool _multipleCameras: _cameraManager ? _cameraManager.cameras.count > 1 : false + property bool _noMavlinkCameraStreams: _camera ? _camera.streamLabels.length : true + property bool _multipleMavlinkCameraStreams: _camera ? _camera.streamLabels.length > 1 : false + property bool _anyVideoStreamAvailable: _videoManager.hasVideo + property int _curCameraIndex: _cameraManager ? _cameraManager.currentCamera : -1 + property int _curStreamIndex: _camera ? _camera.currentStream : -1 + property var _camera: !_noCameras ? (_cameraManager.cameras.get(_curCameraIndex) && _cameraManager.cameras.get(_curCameraIndex).paramComplete ? _cameraManager.cameras.get(_curCameraIndex) : null) : null + property string _cameraName: _camera ? (_multipleCameras ? _camera.modelName : "") : qsTr("Video Stream") + property bool _hasThermalVideoStream: _camera ? _camera.thermalStreamInstance : false + property bool _cameraModeUndefined: _camera ? _camera.cameraMode === QGCCameraControl.CAM_MODE_UNDEFINED : true + property bool _cameraInVideoMode: _camera ? _camera.cameraMode === QGCCameraControl.CAM_MODE_VIDEO : false + property bool _cameraInPhotoMode: _camera ? _camera.cameraMode === QGCCameraControl.CAM_MODE_PHOTO : false + property bool _cameraElapsedMode: _camera && _camera.cameraMode === QGCCameraControl.CAM_MODE_PHOTO && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE + property real _spacers: ScreenTools.defaultFontPixelHeight * 0.5 + property real _labelFieldWidth: ScreenTools.defaultFontPixelWidth * 30 + property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 + property bool _communicationLost: _activeVehicle ? _activeVehicle.connectionLost : false + property bool _hasModes: _camera && _camera.hasModes + property bool _videoRecording: _camera && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING + property bool _photoIdle: _camera && (_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_IDLE || _camera.photoStatus >= QGCCameraControl.PHOTO_CAPTURE_LAST) + property bool _storageReady: _camera && _camera.storageStatus === QGCCameraControl.STORAGE_READY + property bool _batteryReady: _camera && _camera.batteryRemaining >= 0 + property bool _storageSupported: _camera && _camera.storageStatus === QGCCameraControl.STORAGE_NOT_SUPPORTED + property bool _canShoot: (!_cameraModeUndefined && ((_storageReady && _camera.storageFree > 0) || _storageSupported)) || _videoManager.streaming + property bool _isShooting: ((_cameraInVideoMode && _videoRecording) || (_cameraInPhotoMode && !_photoIdle)) || _videoManager.recording + property var _videoSettings: QGroundControl.settingsManager.videoSettings + + QGCPalette { id: qgcPal; colorGroupEnabled: enabled } + + QGCColoredImage { + anchors.margins: _margins + anchors.top: parent.top + anchors.right: parent.right + source: "/res/gear-black.svg" + mipmap: true + height: ScreenTools.defaultFontPixelHeight + width: height + sourceSize.height: height + color: qgcPal.text + fillMode: Image.PreserveAspectFit + + QGCMouseArea { + fillItem: parent + onClicked: mainWindow.showPopupDialogFromComponent(settingsDialogComponent) + } + } + + ColumnLayout { + id: mainLayout + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + spacing: ScreenTools.defaultFontPixelHeight / 2 + + //-- Photo/Video Mode Selector (Mavlink Cameras only) + Rectangle { + id: camMode + Layout.alignment: Qt.AlignHCenter + width: _hasModes ? ScreenTools.defaultFontPixelWidth * 10 : 0 + height: _hasModes ? width / 2 : 0 + color: qgcPal.windowShadeLight + radius: height * 0.5 + visible: _hasModes + + //-- Video Mode + Rectangle { + width: parent.height + height: parent.height + color: _cameraInVideoMode ? qgcPal.window : qgcPal.windowShadeLight + radius: height * 0.5 + anchors.left: parent.left + border.color: qgcPal.text + border.width: _cameraInVideoMode ? 1 : 0 + anchors.verticalCenter: parent.verticalCenter + QGCColoredImage { + height: parent.height * 0.5 + width: height + anchors.centerIn: parent + source: "/qmlimages/camera_video.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + color: _cameraInVideoMode ? qgcPal.colorGreen : qgcPal.text + MouseArea { + anchors.fill: parent + enabled: _cameraInPhotoMode && !_isShooting + onClicked: { + _camera.setVideoMode() + } + } + } + } + //-- Photo Mode + Rectangle { + width: parent.height + height: parent.height + color: _cameraInPhotoMode ? qgcPal.window : qgcPal.windowShadeLight + radius: height * 0.5 + anchors.right: parent.right + border.color: qgcPal.text + border.width: _cameraInPhotoMode ? 1 : 0 + anchors.verticalCenter: parent.verticalCenter + QGCColoredImage { + height: parent.height * 0.5 + width: height + anchors.centerIn: parent + source: "/qmlimages/camera_photo.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + color: _cameraInPhotoMode ? qgcPal.colorGreen : qgcPal.text + MouseArea { + anchors.fill: parent + enabled: _cameraInVideoMode && !_isShooting + onClicked: { + _camera.setPhotoMode() + } + } + } + } + } + + // Take Photo, Start/Stop Video button + Rectangle { + Layout.alignment: Qt.AlignHCenter + color: Qt.rgba(0,0,0,0) + width: ScreenTools.defaultFontPixelWidth * 6 + height: width + radius: width * 0.5 + visible: _camera || _anyVideoStreamAvailable + border.color: qgcPal.buttonText + border.width: 3 + + Rectangle { + anchors.centerIn: parent + width: parent.width * (_isShooting ? 0.5 : 0.75) + height: width + radius: _isShooting ? 0 : width * 0.5 + color: _canShoot ? qgcPal.colorRed : qgcPal.colorGrey + } + + MouseArea { + anchors.fill: parent + enabled: _canShoot + onClicked: { + if (_camera) { + if(_cameraInVideoMode) { + _camera.toggleVideo() + } else { + if(_cameraInPhotoMode && !_photoIdle && _cameraElapsedMode) { + _camera.stopTakePhoto() + } else { + _camera.takePhoto() + } + } + } else { + if (_videoManager.recording) { + _videoManager.stopRecording() + } else { + _videoManager.startRecording() + } + } + } + } + } + + //-- Status Information + ColumnLayout { + Layout.alignment: Qt.AlignHCenter + spacing: 0 + + QGCLabel { + Layout.alignment: Qt.AlignHCenter + text: _cameraName + visible: _cameraName !== "" + } + QGCLabel { + Layout.alignment: Qt.AlignHCenter + text: (_cameraInVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) ? _camera.recordTimeStr : "00:00:00" + font.pointSize: ScreenTools.largeFontPointSize + visible: _cameraInVideoMode + } + QGCLabel { + Layout.alignment: Qt.AlignHCenter + text: _activeVehicle && _cameraInPhotoMode ? ('00000' + _activeVehicle.cameraTriggerPoints.count).slice(-5) : "0000_cameraPhotoMode0" + font.pointSize: ScreenTools.largeFontPointSize + visible: _cameraInPhotoMode + } + QGCLabel { + Layout.alignment: Qt.AlignHCenter + text: _camera ? qsTr("Free Space: ") + _camera.storageFreeStr : "" + font.pointSize: ScreenTools.defaultFontPointSize + visible: _storageReady + } + QGCLabel { + Layout.alignment: Qt.AlignHCenter + text: _camera ? qsTr("Battery: ") + _camera.batteryRemainingStr : "" + font.pointSize: ScreenTools.defaultFontPointSize + visible: _batteryReady + } + } + } + + Component { + id: settingsDialogComponent + + QGCPopupDialog { + title: qsTr("Settings") + buttons: StandardButton.Close + + ColumnLayout { + spacing: _margins + + GridLayout { + id: gridLayout + flow: GridLayout.TopToBottom + rows: dynamicRows + (_camera ? _camera.activeSettings.length : 0) + + property int dynamicRows: 10 + + // First column + QGCLabel { + text: qsTr("Camera") + visible: _multipleCameras + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Video Stream") + visible: _multipleMavlinkCameraStreams + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Thermal View Mode") + visible: _hasThermalVideoStream + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Blend Opacity") + visible: _hasThermalVideoStream && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + // Mavlink Camera Protocol active settings + Repeater { + model: _camera ? _camera.activeSettings : [] + + QGCLabel { + text: _camera.getFact(modelData).shortDescription + } + } + + QGCLabel { + text: qsTr("Photo Mode") + visible: _hasModes + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Photo Interval (seconds)") + width: _labelFieldWidth + visible: _cameraInPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Video Grid Lines") + visible: _anyVideoStreamAvailable + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Video Screen Fit") + visible: _anyVideoStreamAvailable + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Reset Camera Defaults") + visible: _camera + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + QGCLabel { + text: qsTr("Storage") + visible: _storageSupported + onVisibleChanged: gridLayout.dynamicRows += visible ? 1 : -1 + } + + // Second column + QGCComboBox { + Layout.fillWidth: true + sizeToContents: true + model: _cameraManager ? _cameraManager.cameraLabels : [] + currentIndex: _curCameraIndex + visible: _multipleCameras + onActivated: _cameraManager.currentCamera = index + } + + QGCComboBox { + Layout.fillWidth: true + sizeToContents: true + model: _camera ? _camera.streamLabels : [] + currentIndex: _curStreamIndex + visible: _multipleMavlinkCameraStreams + onActivated: _camera.currentStream = index + } + + QGCComboBox { + Layout.fillWidth: true + sizeToContents: true + model: [ qsTr("Off"), qsTr("Blend"), qsTr("Full"), qsTr("Picture In Picture") ] + currentIndex: _camera ? _camera.thermalMode : -1 + visible: _hasThermalVideoStream + onActivated: _camera.thermalMode = index + } + + QGCSlider { + Layout.fillWidth: true + maximumValue: 100 + minimumValue: 0 + value: _camera ? _camera.thermalOpacity : 0 + updateValueWhileDragging: true + visible: _hasThermalVideoStream && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND + onValueChanged: _camera.thermalOpacity = value + } + + // Mavlink Camera Protocol active settings + Repeater { + model: _camera ? _camera.activeSettings : [] + + RowLayout { + Layout.fillWidth: true + spacing: ScreenTools.defaultFontPixelWidth + + property var _fact: _camera.getFact(modelData) + property bool _isBool: _fact.typeIsBool + property bool _isCombo: !_isBool && _fact.enumStrings.length > 0 + property bool _isSlider: _fact && !isNaN(_fact.increment) + property bool _isEdit: !_isBool && !_isSlider && _fact.enumStrings.length < 1 + + FactComboBox { + Layout.fillWidth: true + sizeToContents: true + fact: parent._fact + indexModel: false + visible: parent._isCombo + } + FactTextField { + Layout.fillWidth: true + fact: parent._fact + visible: parent._isEdit + } + QGCSlider { + Layout.fillWidth: true + maximumValue: parent._fact.max + minimumValue: parent._fact.min + stepSize: parent._fact.increment + visible: parent._isSlider + updateValueWhileDragging: false + onValueChanged: parent._fact.value = value + Component.onCompleted: value = parent._fact.value + } + QGCSwitch { + checked: parent._fact ? parent._fact.value : false + visible: parent._isBool + onClicked: parent._fact.value = checked ? 1 : 0 + } + } + } + + QGCComboBox { + Layout.fillWidth: true + sizeToContents: true + model: [ qsTr("Single"), qsTr("Time Lapse") ] + currentIndex: _camera ? _camera.photoMode : 0 + visible: _hasModes + onActivated: _camera.photoMode = index + } + + QGCSlider { + Layout.fillWidth: true + maximumValue: 60 + minimumValue: 1 + stepSize: 1 + value: _camera ? _camera.photoLapse : 5 + displayValue: true + updateValueWhileDragging: true + visible: _cameraInPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE + onValueChanged: { + if (_camera) { + _camera.photoLapse = value + } + } + } + + QGCSwitch { + checked: _videoSettings.gridLines.rawValue + visible: _anyVideoStreamAvailable + onClicked: _videoSettings.gridLines.rawValue = checked ? 1 : 0 + } + + FactComboBox { + Layout.fillWidth: true + sizeToContents: true + fact: _videoSettings.videoFit + indexModel: false + visible: _anyVideoStreamAvailable + } + + QGCButton { + Layout.fillWidth: true + text: qsTr("Reset") + visible: _camera + onClicked: resetPrompt.open() + MessageDialog { + id: resetPrompt + title: qsTr("Reset Camera to Factory Settings") + text: qsTr("Confirm resetting all settings?") + standardButtons: StandardButton.Yes | StandardButton.No + onNo: resetPrompt.close() + onYes: { + _camera.resetSettings() + resetPrompt.close() + } + } + } + + QGCButton { + Layout.fillWidth: true + text: qsTr("Format") + visible: _storageSupported + onClicked: formatPrompt.open() + MessageDialog { + id: formatPrompt + title: qsTr("Format Camera Storage") + text: qsTr("Confirm erasing all files?") + standardButtons: StandardButton.Yes | StandardButton.No + onNo: formatPrompt.close() + onYes: { + _camera.formatCard() + formatPrompt.close() + } + } + } + } + } + } + } +} diff --git a/src/FlightMap/Widgets/QGCInstrumentWidget.qml b/src/FlightMap/Widgets/QGCInstrumentWidget.qml index a21b457b3ff9118794ac4a94e0ba29e060265a7a..76885eda4fd32dd99f7af727cac941d5a1b9975a 100644 --- a/src/FlightMap/Widgets/QGCInstrumentWidget.qml +++ b/src/FlightMap/Widgets/QGCInstrumentWidget.qml @@ -22,15 +22,10 @@ ColumnLayout { id: root 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 _spacing: ScreenTools.defaultFontPixelHeight * 0.33 property real _topBottomMargin: (width * 0.05) / 2 - property real _availableValueHeight: maxHeight - _valuesItem.y QGCPalette { id: qgcPal } @@ -65,26 +60,4 @@ ColumnLayout { TerrainProgress { Layout.fillWidth: true } - - Item { - id: _valuesItem - Layout.fillWidth: true - height: _valuesWidget.height - visible: showValues - - DeadMouseArea { anchors.fill: parent } - - Rectangle { - anchors.fill: _valuesWidget - color: qgcPal.window - } - - PageView { - id: _valuesWidget - anchors.margins: 1 - anchors.left: parent.left - anchors.right: parent.right - maxHeight: _availableValueHeight - } - } } diff --git a/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml b/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml index 7123619ed1d4127d1f0ebb137fba56d48f73d48e..bd551b9a7ab2404928ee4de85219999c55adb5b5 100644 --- a/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml +++ b/src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml @@ -27,11 +27,9 @@ Rectangle { // 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 _spacing: ScreenTools.defaultFontPixelHeight * 0.33 - property real _topBottomMargin: (width * 0.05) / 2 - property real _availableValueHeight: maxHeight - (attitude.height + compass.height) + property real _innerRadius: (width - (_topBottomMargin * 2)) / 2 + property real _outerRadius: _innerRadius + _topBottomMargin * 2 + property real _margins: (width * 0.05) / 2 // Prevent all clicks from going through to lower layers DeadMouseArea { @@ -41,51 +39,20 @@ Rectangle { QGCPalette { id: qgcPal } QGCAttitudeWidget { - id: attitude - anchors.topMargin : _topBottomMargin - anchors.bottomMargin: _topBottomMargin - anchors.top: parent.top - size: _innerRadius * 2 - vehicle: activeVehicle - anchors.horizontalCenter: parent.horizontalCenter - } - - Item { - id: _valuesItem - anchors.topMargin: ScreenTools.defaultFontPixelHeight / 4 - anchors.bottomMargin: ScreenTools.defaultFontPixelHeight / 4 - anchors.top: attitude.bottom - anchors.bottom: compass.top - width: parent.width - height: _valuesWidget.height - visible: showValues - - // Prevent all clicks from going through to lower layers - DeadMouseArea { - anchors.fill: parent - } - - Rectangle { - anchors.fill: _valuesWidget - color: qgcPal.window - } - - PageView { - id: _valuesWidget - anchors.margins: 1 - anchors.left: parent.left - anchors.right: parent.right - maxHeight: _availableValueHeight - } + id: attitude + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins : _margins + anchors.top: parent.top + size: _innerRadius * 2 + vehicle: activeVehicle } QGCCompassWidget { id: compass - anchors.bottom : parent.bottom - anchors.bottomMargin: _topBottomMargin - anchors.topMargin: _topBottomMargin + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: _margins + anchors.top: attitude.bottom size: _innerRadius * 2 vehicle: activeVehicle - anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/src/FlightMap/Widgets/ValuePageWidget.qml b/src/FlightMap/Widgets/ValuePageWidget.qml deleted file mode 100644 index 7c8c30d4cd8bc482153aa409f92fcdd0ddf32058..0000000000000000000000000000000000000000 --- a/src/FlightMap/Widgets/ValuePageWidget.qml +++ /dev/null @@ -1,38 +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.Dialogs 1.3 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.5 -import QtQml 2.12 - -import QGroundControl.Controls 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.FactSystem 1.0 -import QGroundControl.FactControls 1.0 -import QGroundControl.Controllers 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.FlightMap 1.0 -import QGroundControl 1.0 - -/// Value page for InstrumentPanel PageView -VerticalFactValueGrid { - id: _root - width: pageWidth - userSettingsGroup: valuePageUserSettingsGroup - defaultSettingsGroup: valuePageDefaultSettingsGroup - - property bool showSettingsIcon: true - property bool showLockIcon: true - - function showSettings(settingsUnlocked) { - _root.settingsUnlocked = settingsUnlocked - } -} diff --git a/src/FlightMap/Widgets/VideoPageWidget.qml b/src/FlightMap/Widgets/VideoPageWidget.qml deleted file mode 100644 index af06ab0ebec362a41876cdeaf788e27a9ab8b90a..0000000000000000000000000000000000000000 --- a/src/FlightMap/Widgets/VideoPageWidget.qml +++ /dev/null @@ -1,183 +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.11 -import QtPositioning 5.2 -import QtQuick.Layouts 1.2 -import QtQuick.Controls 2.4 -import QtQuick.Dialogs 1.2 -import QtGraphicalEffects 1.0 - -import QGroundControl 1.0 -import QGroundControl.ScreenTools 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.Vehicle 1.0 -import QGroundControl.Controllers 1.0 -import QGroundControl.FactSystem 1.0 -import QGroundControl.FactControls 1.0 - -/// Video streaming page for Instrument Panel PageView -Item { - width: pageWidth - height: videoGrid.y + videoGrid.height + _margins - anchors.margins: ScreenTools.defaultFontPixelWidth * 2 - anchors.centerIn: parent - - property bool _communicationLost: activeVehicle ? activeVehicle.connectionLost : false - property bool _recordingVideo: QGroundControl.videoManager.recording - property bool _decodingVideo: QGroundControl.videoManager.decoding - property bool _streamingEnabled: QGroundControl.settingsManager.videoSettings.streamConfigured - property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null - property int _curCameraIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0 - property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false - property var _camera: _isCamera ? (_dynamicCameras.cameras.get(_curCameraIndex) && _dynamicCameras.cameras.get(_curCameraIndex).paramComplete ? _dynamicCameras.cameras.get(_curCameraIndex) : null) : null - property real _margins: ScreenTools.defaultFontPixelWidth / 2 - - QGCPalette { id:qgcPal; colorGroupEnabled: true } - - GridLayout { - id: videoGrid - anchors.margins: _margins - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - columns: 2 - columnSpacing: _margins - rowSpacing: ScreenTools.defaultFontPixelHeight - Connections { - // For some reason, the normal signal is not reflected in the control below - target: QGroundControl.settingsManager.videoSettings.streamEnabled - onRawValueChanged: { - enableSwitch.checked = QGroundControl.settingsManager.videoSettings.streamEnabled.rawValue - } - } - // Enable/Disable Video Streaming - QGCLabel { - text: qsTr("Enable") - font.pointSize: ScreenTools.smallFontPointSize - visible: !_camera || !_camera.autoStream - } - QGCSwitch { - id: enableSwitch - visible: !_camera || !_camera.autoStream - enabled: _streamingEnabled - checked: QGroundControl.settingsManager.videoSettings.streamEnabled.rawValue - Layout.alignment: Qt.AlignHCenter - onClicked: { - if(checked) { - QGroundControl.settingsManager.videoSettings.streamEnabled.rawValue = 1 - QGroundControl.videoManager.startVideo() - } else { - QGroundControl.settingsManager.videoSettings.streamEnabled.rawValue = 0 - QGroundControl.videoManager.stopVideo() - } - } - } - // Grid Lines - QGCLabel { - text: qsTr("Grid Lines") - font.pointSize: ScreenTools.smallFontPointSize - visible: QGroundControl.videoManager.isGStreamer && QGroundControl.settingsManager.videoSettings.gridLines.visible - } - QGCSwitch { - enabled: _streamingEnabled && activeVehicle - checked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue - visible: QGroundControl.videoManager.isGStreamer && QGroundControl.settingsManager.videoSettings.gridLines.visible - Layout.alignment: Qt.AlignHCenter - onClicked: { - if(checked) { - QGroundControl.settingsManager.videoSettings.gridLines.rawValue = 1 - } else { - QGroundControl.settingsManager.videoSettings.gridLines.rawValue = 0 - } - } - } - //-- Video Fit - QGCLabel { - text: qsTr("Video Fit") - visible: QGroundControl.videoManager.isGStreamer - font.pointSize: ScreenTools.smallFontPointSize - } - FactComboBox { - fact: QGroundControl.settingsManager.videoSettings.videoFit - visible: QGroundControl.videoManager.isGStreamer - indexModel: false - Layout.alignment: Qt.AlignHCenter - } - QGCLabel { - text: qsTr("File Name"); - font.pointSize: ScreenTools.smallFontPointSize - visible: QGroundControl.videoManager.isGStreamer - } - QGCTextField { - id: videoFileName - Layout.fillWidth: true - visible: QGroundControl.videoManager.isGStreamer - } - //-- Video Recording - QGCLabel { - text: _recordingVideo ? qsTr("Stop Recording") : qsTr("Record Stream") - font.pointSize: ScreenTools.smallFontPointSize - visible: QGroundControl.videoManager.isGStreamer - } - // Button to start/stop video recording - Item { - anchors.margins: ScreenTools.defaultFontPixelHeight / 2 - height: ScreenTools.defaultFontPixelHeight * 2 - width: height - Layout.alignment: Qt.AlignHCenter - visible: QGroundControl.videoManager.isGStreamer - Rectangle { - id: recordBtnBackground - anchors.top: parent.top - anchors.bottom: parent.bottom - width: height - radius: _recordingVideo ? 0 : height - color: (_decodingVideo && _streamingEnabled) ? "red" : "gray" - SequentialAnimation on opacity { - running: _recordingVideo - loops: Animation.Infinite - PropertyAnimation { to: 0.5; duration: 500 } - PropertyAnimation { to: 1.0; duration: 500 } - } - } - QGCColoredImage { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - width: height * 0.625 - sourceSize.width: width - source: "/qmlimages/CameraIcon.svg" - visible: recordBtnBackground.visible - fillMode: Image.PreserveAspectFit - color: "white" - } - MouseArea { - anchors.fill: parent - enabled: _decodingVideo && _streamingEnabled - onClicked: { - if (_recordingVideo) { - QGroundControl.videoManager.stopRecording() - // reset blinking animation - recordBtnBackground.opacity = 1 - } else { - QGroundControl.videoManager.startRecording(videoFileName.text) - } - } - } - } - QGCLabel { - text: qsTr("Video Streaming Not Configured") - font.pointSize: ScreenTools.smallFontPointSize - visible: !_streamingEnabled - Layout.columnSpan: 2 - } - } -} diff --git a/src/QGCLoggingCategory.h b/src/QGCLoggingCategory.h index 79a3e19e622eca97e5bddfd02abe4ee7694a32e5..9aee851293fedabd598524195f2f4831aa16bb00 100644 --- a/src/QGCLoggingCategory.h +++ b/src/QGCLoggingCategory.h @@ -7,12 +7,7 @@ * ****************************************************************************/ - -/// @file -/// @author Don Gagne - -#ifndef QGC_LOGGING_CATEGORY_H -#define QGC_LOGGING_CATEGORY_H +#pragma once #include #include @@ -73,5 +68,3 @@ class QGCLoggingCategory public: QGCLoggingCategory(const char* category) { QGCLoggingCategoryRegister::instance()->registerCategory(category); } }; - -#endif diff --git a/src/QmlControls/PageView.qml b/src/QmlControls/PageView.qml deleted file mode 100644 index 3cff0b39c74fdf9702024130f7b19b66652a4957..0000000000000000000000000000000000000000 --- a/src/QmlControls/PageView.qml +++ /dev/null @@ -1,81 +0,0 @@ -import QtQuick 2.3 -import QtQuick.Controls 1.2 -import QtQuick.Layouts 1.2 - -import QGroundControl 1.0 -import QGroundControl.Palette 1.0 -import QGroundControl.ScreenTools 1.0 - -Rectangle { - id: _root - height: pageFlickable.y + pageFlickable.height + _margins - color: qgcPal.window - radius: ScreenTools.defaultFontPixelWidth * 0.5 - - property real maxHeight ///< Maximum height that should be taken, smaller than this is ok - - property real _margins: ScreenTools.defaultFontPixelWidth / 2 - property real _pageWidth: _root.width - property var _instrumentPages: QGroundControl.corePlugin.instrumentPages - property bool _settingsUnlocked: false - - QGCPalette { id:qgcPal; colorGroupEnabled: parent.enabled } - - QGCComboBox { - id: pageCombo - anchors.left: parent.left - anchors.right: parent.right - model: _instrumentPages - textRole: "title" - centeredLabel: true - font.pointSize: ScreenTools.smallFontPointSize - - onCurrentIndexChanged: _settingsUnlocked = false - - QGCColoredImage { - anchors.leftMargin: _margins - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - source: pageWidgetLoader.item.showLockIcon ? (_settingsUnlocked ? "/res/LockOpen.svg" : "/res/LockClosed.svg") : "/res/gear-black.svg" - mipmap: true - height: parent.height * 0.7 - width: height - sourceSize.height: height - color: qgcPal.text - fillMode: Image.PreserveAspectFit - visible: pageWidgetLoader.item ? (pageWidgetLoader.item.showSettingsIcon ? pageWidgetLoader.item.showSettingsIcon : false) : false - - QGCMouseArea { - fillItem: parent - onClicked: { - if (pageWidgetLoader.item.showLockIcon) { - _settingsUnlocked = !_settingsUnlocked - pageWidgetLoader.item.showSettings(_settingsUnlocked) - } else { - pageWidgetLoader.item.showSettings() - } - } - } - } - } - - QGCFlickable { - id: pageFlickable - anchors.margins: _margins - anchors.top: pageCombo.bottom - anchors.left: parent.left - anchors.right: parent.right - height: Math.min(_maxHeight, pageWidgetLoader.height) - contentHeight: pageWidgetLoader.height - flickableDirection: Flickable.VerticalFlick - clip: true - - property real _maxHeight: maxHeight - y - _margins - - Loader { - id: pageWidgetLoader - source: _instrumentPages[pageCombo.currentIndex].url - property real pageWidth: parent.width - } - } -} diff --git a/src/QmlControls/QGCControlDebug.qml b/src/QmlControls/QGCControlDebug.qml index 32e47d9666920de7b98e49549dc5347b84fc11ab..8ba76d665c7962d9f0fa77b09cd8fc227c55298d 100644 --- a/src/QmlControls/QGCControlDebug.qml +++ b/src/QmlControls/QGCControlDebug.qml @@ -11,7 +11,7 @@ import QtQuick 2.12 Rectangle { id: _root - border.width: borderColor === undefined ? 0 : 1 + border.width: 1 border.color: borderColor color: "transparent" diff --git a/src/QmlControls/QGCPopupDialogContainer.qml b/src/QmlControls/QGCPopupDialogContainer.qml index 828c7eff00d11b9607292e83dc00b4817575c8c6..b5f7e5e31d2bbc4b540ecd24e635eeb27c14d637 100644 --- a/src/QmlControls/QGCPopupDialogContainer.qml +++ b/src/QmlControls/QGCPopupDialogContainer.qml @@ -179,7 +179,7 @@ Popup { Layout.leftMargin: ScreenTools.defaultFontPixelWidth Layout.fillWidth: true text: _dialogTitle - height: parent.height + font.pointSize: ScreenTools.mediumFontPointSize verticalAlignment: Text.AlignVCenter } diff --git a/src/QmlControls/QGCSlider.qml b/src/QmlControls/QGCSlider.qml index 74344176c7dc846188565fa29024644d7d408c63..34f4fc8f909fc1b1f72d3844bd1ad9fd9ef48baf 100644 --- a/src/QmlControls/QGCSlider.qml +++ b/src/QmlControls/QGCSlider.qml @@ -26,8 +26,8 @@ Slider { style: SliderStyle { groove: Item { anchors.verticalCenter: parent.verticalCenter - implicitWidth: Math.round(ScreenTools.defaultFontPixelHeight * 4.5) - implicitHeight: Math.round(ScreenTools.defaultFontPixelHeight * 0.3) + implicitWidth: Math.round(ScreenTools.defaultFontPixelHeight * 4.5) + implicitHeight: Math.round(ScreenTools.defaultFontPixelHeight * 0.3) Rectangle { radius: height / 2 @@ -66,7 +66,9 @@ Slider { implicitWidth: _radius * 2 implicitHeight: _radius * 2 radius: _radius - property real _radius: Math.round(ScreenTools.defaultFontPixelHeight * 0.75) + + property real _radius: Math.round(_root.implicitHeight / 2) + Label { text: _root.value.toFixed( _root.maximumValue <= 1 ? 1 : 0) visible: _root.displayValue diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir index 90e2d8ba69e8b48e8d84d47b913fc46a519ae0c1..695b7f61ffe9ace139595cfab8eec624a47c4eea 100644 --- a/src/QmlControls/QGroundControl/Controls/qmldir +++ b/src/QmlControls/QGroundControl/Controls/qmldir @@ -43,7 +43,6 @@ MissionItemStatus 1.0 MissionItemStatus.qml ModeSwitchDisplay 1.0 ModeSwitchDisplay.qml MultiRotorMotorDisplay 1.0 MultiRotorMotorDisplay.qml OfflineMapButton 1.0 OfflineMapButton.qml -PageView 1.0 PageView.qml ParameterEditor 1.0 ParameterEditor.qml ParameterEditorDialog 1.0 ParameterEditorDialog.qml PIDTuning 1.0 PIDTuning.qml diff --git a/src/QmlControls/QGroundControl/FlightDisplay/qmldir b/src/QmlControls/QGroundControl/FlightDisplay/qmldir index e5ea5bff5fc6e625b5d6fb82104afdfab526ccd6..5cf441110e21c00531949447d7be84df5b3ae859 100644 --- a/src/QmlControls/QGroundControl/FlightDisplay/qmldir +++ b/src/QmlControls/QGroundControl/FlightDisplay/qmldir @@ -23,7 +23,6 @@ GuidedAltitudeSlider 1.0 GuidedAltitudeSlider.qml GuidedActionTakeoff 1.0 GuidedActionTakeoff.qml GuidedToolStripAction 1.0 GuidedToolStripAction.qml MultiVehicleList 1.0 MultiVehicleList.qml -MultiVehiclePanel 1.0 MultiVehiclePanel.qml PreFlightBatteryCheck 1.0 PreFlightBatteryCheck.qml PreFlightGPSCheck 1.0 PreFlightGPSCheck.qml PreFlightRCCheck 1.0 PreFlightRCCheck.qml diff --git a/src/QmlControls/QGroundControl/FlightMap/qmldir b/src/QmlControls/QGroundControl/FlightMap/qmldir index 543a52608c82e8033afed39efbcc0e0c7183ec7e..1d863ace4ecc8ae367ba40bc369e403aaf1f4d48 100644 --- a/src/QmlControls/QGroundControl/FlightMap/qmldir +++ b/src/QmlControls/QGroundControl/FlightMap/qmldir @@ -12,6 +12,7 @@ InstrumentSwipeView 1.0 InstrumentSwipeView.qml MapFitFunctions 1.0 MapFitFunctions.qml MapLineArrow 1.0 MapLineArrow.qml MapScale 1.0 MapScale.qml +PhotoVideoControl 1.0 PhotoVideoControl.qml QGCArtificialHorizon 1.0 QGCArtificialHorizon.qml QGCAttitudeHUD 1.0 QGCAttitudeHUD.qml QGCAttitudeWidget 1.0 QGCAttitudeWidget.qml diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 349ba3700cfefbafa0399dd94833e62f142a28e7..e3083c13ad3565de942c964010301423fa2ed738 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -149,7 +149,6 @@ Vehicle::Vehicle(LinkInterface* link, , _telemetryRNoise(0) , _highLatencyLink(false) , _receivingAttitudeQuaternion(false) - , _cameras(nullptr) , _connectionLost(false) , _connectionLostEnabled(true) , _initialPlanRequestComplete(false) @@ -282,8 +281,8 @@ Vehicle::Vehicle(LinkInterface* link, connect(&_orbitTelemetryTimer, &QTimer::timeout, this, &Vehicle::_orbitTelemetryTimeout); // Create camera manager instance - _cameras = _firmwarePlugin->createCameraManager(this); - emit dynamicCamerasChanged(); + _cameraManager = _firmwarePlugin->createCameraManager(this); + emit cameraManagerChanged(); // Start csv logger connect(&_csvLogTimer, &QTimer::timeout, this, &Vehicle::_writeCsvLine); @@ -338,7 +337,7 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType, , _capabilityBits(MAV_PROTOCOL_CAPABILITY_MISSION_FENCE | MAV_PROTOCOL_CAPABILITY_MISSION_RALLY) , _highLatencyLink(false) , _receivingAttitudeQuaternion(false) - , _cameras(nullptr) + , _cameraManager(nullptr) , _connectionLost(false) , _connectionLostEnabled(true) , _initialPlanRequestComplete(false) @@ -573,13 +572,13 @@ Vehicle::~Vehicle() void Vehicle::prepareDelete() { - if(_cameras) { - // because of _cameras QML bindings check for nullptr won't work in the binding pipeline + if(_cameraManager) { + // because of _cameraManager QML bindings check for nullptr won't work in the binding pipeline // the dangling pointer access will cause a runtime fault - auto tmpCameras = _cameras; - _cameras = nullptr; + auto tmpCameras = _cameraManager; + _cameraManager = nullptr; delete tmpCameras; - emit dynamicCamerasChanged(); + emit cameraManagerChanged(); qApp->processEvents(); } } @@ -3616,17 +3615,6 @@ void Vehicle::setOfflineEditingDefaultComponentId(int defaultComponentId) } } -void Vehicle::triggerCamera() -{ - sendMavCommand(_defaultComponentId, - MAV_CMD_DO_DIGICAM_CONTROL, - true, // show errors - 0.0, 0.0, 0.0, 0.0, // param 1-4 unused - 1.0, // trigger camera - 0.0, // param 6 unused - 1.0); // test shot flag -} - void Vehicle::setVtolInFwdFlight(bool vtolInFwdFlight) { if (_vtolInFwdFlight != vtolInFwdFlight) { diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index a0efc616d236140737912dd496628a434165396c..9044fcdf7aac28ab53c0418d7d3c90e92d7149da 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -625,7 +625,7 @@ public: Q_PROPERTY(QVariantList modeIndicators READ modeIndicators NOTIFY modeIndicatorsChanged) Q_PROPERTY(bool initialPlanRequestComplete READ initialPlanRequestComplete NOTIFY initialPlanRequestCompleteChanged) Q_PROPERTY(QVariantList staticCameraList READ staticCameraList CONSTANT) - Q_PROPERTY(QGCCameraManager* dynamicCameras READ dynamicCameras NOTIFY dynamicCamerasChanged) + Q_PROPERTY(QGCCameraManager* cameraManager READ cameraManager NOTIFY cameraManagerChanged) Q_PROPERTY(QString hobbsMeter READ hobbsMeter NOTIFY hobbsMeterChanged) Q_PROPERTY(bool vtolInFwdFlight READ vtolInFwdFlight WRITE setVtolInFwdFlight NOTIFY vtolInFwdFlightChanged) Q_PROPERTY(bool highLatencyLink READ highLatencyLink NOTIFY highLatencyLinkChanged) @@ -771,7 +771,6 @@ public: /// Clear Messages Q_INVOKABLE void clearMessages(); - Q_INVOKABLE void triggerCamera(); Q_INVOKABLE void sendPlan(QString planFile); /// Used to check if running current version is equal or higher than the one being compared. @@ -1130,7 +1129,7 @@ public: bool capabilitiesKnown () const { return _capabilityBitsKnown; } uint64_t capabilityBits () const { return _capabilityBits; } // Change signalled by capabilityBitsChanged - QGCCameraManager* dynamicCameras () { return _cameras; } + QGCCameraManager* cameraManager () { return _cameraManager; } QString hobbsMeter (); /// The vehicle is responsible for making the initial request for the Plan. @@ -1190,7 +1189,7 @@ signals: void defaultHoverSpeedChanged (double hoverSpeed); void firmwareTypeChanged (); void vehicleTypeChanged (); - void dynamicCamerasChanged (); + void cameraManagerChanged (); void hobbsMeterChanged (); void capabilitiesKnownChanged (bool capabilitiesKnown); void initialPlanRequestCompleteChanged(bool initialPlanRequestComplete); @@ -1457,7 +1456,7 @@ private: SysStatusSensorInfo _sysStatusSensorInfo; - QGCCameraManager* _cameras; + QGCCameraManager* _cameraManager = nullptr; QString _prearmError; QTimer _prearmErrorTimer; diff --git a/src/VideoManager/VideoManager.cc b/src/VideoManager/VideoManager.cc index ebefed5e7f83d6a31abcbbb4bec449b5aa3fe6c2..296d5d57ede4216d1d296b1aaf6fead8371308e8 100644 --- a/src/VideoManager/VideoManager.cc +++ b/src/VideoManager/VideoManager.cc @@ -363,8 +363,8 @@ VideoManager::grabImage(const QString& imageFile) //----------------------------------------------------------------------------- double VideoManager::aspectRatio() { - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->currentStreamInstance(); if(pInfo) { qCDebug(VideoManagerLog) << "Primary AR: " << pInfo->aspectRatio(); return pInfo->aspectRatio(); @@ -377,8 +377,8 @@ double VideoManager::aspectRatio() //----------------------------------------------------------------------------- double VideoManager::thermalAspectRatio() { - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->thermalStreamInstance(); if(pInfo) { qCDebug(VideoManagerLog) << "Thermal AR: " << pInfo->aspectRatio(); return pInfo->aspectRatio(); @@ -390,8 +390,8 @@ double VideoManager::thermalAspectRatio() //----------------------------------------------------------------------------- double VideoManager::hfov() { - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->currentStreamInstance(); if(pInfo) { return pInfo->hfov(); } @@ -402,8 +402,8 @@ double VideoManager::hfov() //----------------------------------------------------------------------------- double VideoManager::thermalHfov() { - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->thermalStreamInstance(); if(pInfo) { return pInfo->aspectRatio(); } @@ -415,8 +415,8 @@ double VideoManager::thermalHfov() bool VideoManager::hasThermal() { - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->thermalStreamInstance(); if(pInfo) { return true; } @@ -436,8 +436,8 @@ bool VideoManager::autoStreamConfigured() { #if defined(QGC_GST_STREAMING) - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->currentStreamInstance(); if(pInfo) { return !pInfo->uri().isEmpty(); } @@ -614,8 +614,8 @@ VideoManager::_updateSettings(unsigned id) //-- Auto discovery - if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + if(_activeVehicle && _activeVehicle->cameraManager()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->cameraManager()->currentStreamInstance(); if(pInfo) { if (id == 0) { qCDebug(VideoManagerLog) << "Configure primary stream:" << pInfo->uri(); @@ -646,7 +646,7 @@ VideoManager::_updateSettings(unsigned id) } } else if (id == 1) { //-- Thermal stream (if any) - QGCVideoStreamInfo* pTinfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + QGCVideoStreamInfo* pTinfo = _activeVehicle->cameraManager()->thermalStreamInstance(); if (pTinfo) { qCDebug(VideoManagerLog) << "Configure secondary stream:" << pTinfo->uri(); switch(pTinfo->type()) { @@ -788,20 +788,20 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle) { if(_activeVehicle) { disconnect(_activeVehicle, &Vehicle::connectionLostChanged, this, &VideoManager::_connectionLostChanged); - if(_activeVehicle->dynamicCameras()) { - QGCCameraControl* pCamera = _activeVehicle->dynamicCameras()->currentCameraInstance(); + if(_activeVehicle->cameraManager()) { + QGCCameraControl* pCamera = _activeVehicle->cameraManager()->currentCameraInstance(); if(pCamera) { pCamera->stopStream(); } - disconnect(_activeVehicle->dynamicCameras(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartAllVideos); + disconnect(_activeVehicle->cameraManager(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartAllVideos); } } _activeVehicle = vehicle; if(_activeVehicle) { connect(_activeVehicle, &Vehicle::connectionLostChanged, this, &VideoManager::_connectionLostChanged); - if(_activeVehicle->dynamicCameras()) { - connect(_activeVehicle->dynamicCameras(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartAllVideos); - QGCCameraControl* pCamera = _activeVehicle->dynamicCameras()->currentCameraInstance(); + if(_activeVehicle->cameraManager()) { + connect(_activeVehicle->cameraManager(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartAllVideos); + QGCCameraControl* pCamera = _activeVehicle->cameraManager()->currentCameraInstance(); if(pCamera) { pCamera->resumeStream(); } diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc index 33f5a6934f8f80050187e096178bd53fca9512a1..2954d7e1d2e8d05b77e99d8b5cca85feffb88d00 100644 --- a/src/api/QGCCorePlugin.cc +++ b/src/api/QGCCorePlugin.cc @@ -97,14 +97,9 @@ public: QmlComponentInfo* pQmlTest = nullptr; #endif - QmlComponentInfo* cameraPageWidgetInfo = nullptr; - QmlComponentInfo* videoPageWidgetInfo = nullptr; - QmlComponentInfo* vibrationPageWidgetInfo = nullptr; - QGCOptions* defaultOptions = nullptr; QVariantList settingsList; QVariantList analyzeList; - QVariantList instrumentPageWidgetList; QmlObjectListModel _emptyCustomMapItems; }; @@ -132,79 +127,6 @@ void QGCCorePlugin::setToolbox(QGCToolbox *toolbox) 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); -} - -void QGCCorePlugin::_activeVehicleChanged(Vehicle* activeVehicle) -{ - if(activeVehicle != _activeVehicle) { - if(_activeVehicle) { - disconnect(_activeVehicle, &Vehicle::dynamicCamerasChanged, this, &QGCCorePlugin::_dynamicCamerasChanged); - } - if(_dynamicCameras) { - disconnect(_dynamicCameras, &QGCCameraManager::currentCameraChanged, this, &QGCCorePlugin::_currentCameraChanged); - _dynamicCameras = nullptr; - } - _activeVehicle = activeVehicle; - if(_activeVehicle) { - connect(_activeVehicle, &Vehicle::dynamicCamerasChanged, this, &QGCCorePlugin::_dynamicCamerasChanged); - } - } -} - -void QGCCorePlugin::_dynamicCamerasChanged() -{ - if(_currentCamera) { - disconnect(_currentCamera, &QGCCameraControl::autoStreamChanged, this, &QGCCorePlugin::_autoStreamChanged); - _currentCamera = nullptr; - } - if(_activeVehicle) { - _dynamicCameras = _activeVehicle->dynamicCameras(); - if(_dynamicCameras) { - connect(_dynamicCameras, &QGCCameraManager::currentCameraChanged, this, &QGCCorePlugin::_currentCameraChanged); - } - } -} - -void QGCCorePlugin::_currentCameraChanged() -{ - if(_dynamicCameras) { - QGCCameraControl* cp = _dynamicCameras->currentCameraInstance(); - if(_currentCamera) { - disconnect(_currentCamera, &QGCCameraControl::autoStreamChanged, this, &QGCCorePlugin::_autoStreamChanged); - } - if(_currentCamera != cp) { - _currentCamera = cp; - connect(_currentCamera, &QGCCameraControl::autoStreamChanged, this, &QGCCorePlugin::_autoStreamChanged); - } - } -} - -void QGCCorePlugin::_autoStreamChanged() -{ - _resetInstrumentPages(); - emit instrumentPagesChanged(); -} - -void QGCCorePlugin::_resetInstrumentPages() -{ - if(_p->cameraPageWidgetInfo) { - _p->cameraPageWidgetInfo->deleteLater(); - _p->cameraPageWidgetInfo = nullptr; - } -#if defined(QGC_GST_STREAMING) - if(_p->videoPageWidgetInfo) { - _p->videoPageWidgetInfo->deleteLater(); - _p->videoPageWidgetInfo = nullptr; - } -#endif - if(_p->vibrationPageWidgetInfo) { - _p->vibrationPageWidgetInfo->deleteLater(); - _p->vibrationPageWidgetInfo = nullptr; - } - _p->instrumentPageWidgetList.clear(); } QVariantList &QGCCorePlugin::settingsPages() @@ -266,26 +188,6 @@ QVariantList &QGCCorePlugin::settingsPages() return _p->settingsList; } -QVariantList& QGCCorePlugin::instrumentPages() -{ - if (!_p->cameraPageWidgetInfo) { - _p->cameraPageWidgetInfo = new QmlComponentInfo(tr("Camera"), QUrl::fromUserInput("qrc:/qml/CameraPageWidget.qml")); -#if defined(QGC_GST_STREAMING) - if(!_currentCamera || !_currentCamera->autoStream()) { - //-- Video Page Widget only available if using manual video streaming - _p->videoPageWidgetInfo = new QmlComponentInfo(tr("Video Stream"), QUrl::fromUserInput("qrc:/qml/VideoPageWidget.qml")); - } -#endif - - _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->cameraPageWidgetInfo)); -#if defined(QGC_GST_STREAMING) - _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->videoPageWidgetInfo)); -#endif - _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->vibrationPageWidgetInfo)); - } - return _p->instrumentPageWidgetList; -} - QVariantList& QGCCorePlugin::analyzePages() { if (!_p->analyzeList.count()) { diff --git a/src/api/QGCCorePlugin.h b/src/api/QGCCorePlugin.h index ed92b158fd13ba8ab1d2044de49db9edc8e19b09..a6c64ddbdc7ce0f08b5e40d4646c6e5c92d1a33a 100644 --- a/src/api/QGCCorePlugin.h +++ b/src/api/QGCCorePlugin.h @@ -48,7 +48,6 @@ public: Q_PROPERTY(QVariantList settingsPages READ settingsPages NOTIFY settingsPagesChanged) Q_PROPERTY(QVariantList analyzePages READ analyzePages NOTIFY analyzePagesChanged) - Q_PROPERTY(QVariantList instrumentPages READ instrumentPages NOTIFY instrumentPagesChanged) Q_PROPERTY(int defaultSettings READ defaultSettings CONSTANT) Q_PROPERTY(QGCOptions* options READ options CONSTANT) Q_PROPERTY(bool showTouchAreas READ showTouchAreas WRITE setShowTouchAreas NOTIFY showTouchAreasChanged) @@ -71,10 +70,6 @@ public: /// @return A list of QmlPageInfo virtual QVariantList& analyzePages(); - /// The list of PageWidget pages shown in the instrument panel - /// @return A list of QmlPageInfo - virtual QVariantList& instrumentPages(); - /// The default settings panel to show /// @return The settings index virtual int defaultSettings(); @@ -205,25 +200,15 @@ public: signals: void settingsPagesChanged (); void analyzePagesChanged (); - void instrumentPagesChanged (); void showTouchAreasChanged (bool showTouchAreas); void showAdvancedUIChanged (bool showAdvancedUI); void toolBarIndicatorsChanged (); -protected slots: - void _activeVehicleChanged (Vehicle* activeVehicle); - void _dynamicCamerasChanged (); - void _currentCameraChanged (); - void _autoStreamChanged (); - -protected: - void _resetInstrumentPages (); - protected: bool _showTouchAreas; bool _showAdvancedUI; Vehicle* _activeVehicle = nullptr; - QGCCameraManager* _dynamicCameras = nullptr; + QGCCameraManager* _cameraManager = nullptr; QGCCameraControl* _currentCamera = nullptr; QVariantList _toolBarIndicatorList;