Newer
Older
/****************************************************************************
*
* (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
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")
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
QGCLabel {
text: _camera ? qsTr("Battery: ") + _camera.batteryRemainingStr : ""
font.pointSize: ScreenTools.defaultFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
//-- Camera Mode (visible only if camera has modes)
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 0.75; visible: camMode.visible; }
width: _hasModes ? ScreenTools.defaultFontPixelWidth * 8 : 0
height: _hasModes ? ScreenTools.defaultFontPixelWidth * 4 : 0
radius: height * 0.5
visible: _hasModes
anchors.horizontalCenter: parent.horizontalCenter
//-- Video Mode
Rectangle {
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
onClicked: {
_camera.setVideoMode()
}
}
}
}
//-- Photo Mode
Rectangle {
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
onClicked: {
_camera.setPhotoMode()
}
}
}
}
}
//-- Shutter
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 0.75; visible: camShutter.visible; }
color: Qt.rgba(0,0,0,0)
width: ScreenTools.defaultFontPixelWidth * 6
height: width
radius: width * 0.5
border.color: qgcPal.buttonText
border.width: 3
anchors.horizontalCenter: parent.horizontalCenter
Rectangle {
color: _canShoot ? qgcPal.colorRed : qgcPal.colorGrey
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
if(_cameraVideoMode) {
if(_cameraPhotoMode && !_photoIdle && _cameraElapsedMode) {
_camera.stopTakePhoto()
} else {
_camera.takePhoto()
}
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
}
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
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
}
}
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
//-------------------------------------------
//-- 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
}
}
}
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
//-------------------------------------------
//-- 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
}
}
}
}
//-------------------------------------------
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
//-- 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
}
}
}
}
//-------------------------------------------
Gus Grubba
committed
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
// 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 {
Gus Grubba
committed
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: {
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
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: {
formatPrompt.close()
}
}
}
}
}
}
}
}