Browse Source
Unified photo/video control which works with mavlink cameras and and video streamQGC4.4
29 changed files with 621 additions and 1148 deletions
@ -1,55 +0,0 @@
@@ -1,55 +0,0 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 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 |
||||
} |
||||
} |
@ -1,506 +0,0 @@
@@ -1,506 +0,0 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 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() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,486 @@
@@ -0,0 +1,486 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 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() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 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 |
||||
} |
||||
} |
@ -1,183 +0,0 @@
@@ -1,183 +0,0 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 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 |
||||
} |
||||
} |
||||
} |
@ -1,81 +0,0 @@
@@ -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 |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue