CustomCameraControl.qml 54.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/****************************************************************************
 *
 * (c) 2009-2019 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.
 *
 * @file
 *   @author Gus Grubba <gus@auterion.com>
 */

import QtQuick                  2.11
import QtQuick.Controls         2.4
import QtQuick.Layouts          1.11
import QtQuick.Dialogs          1.3
16
import QtGraphicalEffects       1.0
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

import QtMultimedia             5.9
import QtPositioning            5.2

import QGroundControl                   1.0
import QGroundControl.Controls          1.0
import QGroundControl.FactControls      1.0
import QGroundControl.FactSystem        1.0
import QGroundControl.FlightMap         1.0
import QGroundControl.Palette           1.0
import QGroundControl.ScreenTools       1.0
import QGroundControl.Vehicle           1.0

import CustomQuickInterface             1.0
import Custom.Widgets                   1.0
32
import Custom.Camera                    1.0
33 34

Item {
35
    id:             _root
36 37
    height:         mainColumn.height
    width:          mainColumn.width + (ScreenTools.defaultFontPixelWidth * 2)
38 39
    visible:        !QGroundControl.videoManager.fullScreen

40
    readonly property string _commLostStr:  qsTr("NO CAMERA")
41
    readonly property real   buttonSize:    ScreenTools.defaultFontPixelWidth * 5
42

43
    property real   _spacers:               ScreenTools.defaultFontPixelHeight * 0.5
Gus Grubba's avatar
Gus Grubba committed
44 45 46
    property real   _labelFieldWidth:       ScreenTools.defaultFontPixelWidth  * 28
    property real   _editFieldWidth:        ScreenTools.defaultFontPixelWidth  * 30
    property real   _editFieldHeight:       ScreenTools.defaultFontPixelHeight * 2
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

    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) : null
    property bool   _communicationLost:     activeVehicle ? activeVehicle.connectionLost : false
    property bool   _noSdCard:              _camera && _camera.storageTotal === 0
    property bool   _fullSD:                _camera && _camera.storageTotal !== 0 && _camera.storageFree > 0 && _camera.storageFree < 250 // We get kiB from the camera
    property bool   _cameraVideoMode:       !_communicationLost && (_noSdCard ? false : _camera && _camera.cameraMode   === QGCCameraControl.CAM_MODE_VIDEO)
    property bool   _cameraPhotoMode:       !_communicationLost && (_noSdCard ? false : _camera && (_camera.cameraMode  === QGCCameraControl.CAM_MODE_PHOTO || _camera.cameraMode === QGCCameraControl.CAM_MODE_SURVEY))
    property bool   _cameraPhotoIdle:       !_communicationLost && (_noSdCard ? false : _camera && _camera.photoStatus  === QGCCameraControl.PHOTO_CAPTURE_IDLE)
    property bool   _cameraElapsedMode:     !_communicationLost && (_noSdCard ? false : _camera && _camera.cameraMode   === QGCCameraControl.CAM_MODE_PHOTO && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE)
    property bool   _cameraModeUndefined:   !_cameraPhotoMode && !_cameraVideoMode
    property bool   _recordingVideo:        _cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING
    property bool   _settingsEnabled:       !_communicationLost && _camera && _camera.cameraMode !== QGCCameraControl.CAM_MODE_UNDEFINED && _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_IDLE && !_recordingVideo
    property bool   _hasZoom:               _camera && _camera.hasZoom
63
    property Fact   _irPaletteFact:         _camera ? _camera.irPalette : null
64 65 66 67
    property bool   _isShortScreen:         mainWindow.height / ScreenTools.realPixelDensity < 120
    property real   _gimbalPitch:           activeVehicle ? -activeVehicle.gimbalPitch : 0
    property real   _gimbalYaw:             activeVehicle ? activeVehicle.gimbalYaw : 0
    property bool   _hasGimbal:             activeVehicle && activeVehicle.gimbalData
68 69 70 71 72 73 74 75 76 77 78 79 80
    Connections {
        target: QGroundControl.multiVehicleManager.activeVehicle
        onConnectionLostChanged: {
            if(_communicationLost && cameraSettings.visible) {
                cameraSettings.close()
            }
        }
    }

    DeadMouseArea {
        anchors.fill:   parent
    }

81 82 83 84
    //-------------------------------------------------------------------------
    //-- Main Column
    Column {
        id:             mainColumn
85
        spacing:        _spacers
86 87 88
        anchors.centerIn: parent
        //---------------------------------------------------------------------
        //-- Quick Thermal Modes
89
        Item {
90
            id:             thermalBackgroundRect
91 92
            width:          buttonsRow.width  + (ScreenTools.defaultFontPixelWidth  * 4)
            height:         buttonsRow.height + (ScreenTools.defaultFontPixelHeight)
93
            visible:        _irPaletteFact && (QGroundControl.videoManager.hasThermal || _camera.vendor === "NextVision")
94
            anchors.horizontalCenter: parent.horizontalCenter
95 96 97 98 99 100 101 102 103 104
            Component.onCompleted: {
                if(_irPaletteFact && QGroundControl.videoManager.hasThermal) {
                    if(_camera.thermalMode === QGCCameraControl.THERMAL_OFF)
                        standardMode.checked = true
                    if(_camera.thermalMode === QGCCameraControl.THERMAL_PIP)
                        thermalPip.checked = true
                    if(_camera.thermalMode === QGCCameraControl.THERMAL_FULL)
                        thermalFull.checked = true
                }
            }
105 106 107 108
            ButtonGroup {
                id:         buttonGroup
                exclusive:  true
                buttons:    buttonsRow.children
109
            }
110 111
            Row {
                id:                     buttonsRow
112
                spacing:                ScreenTools.defaultFontPixelWidth * 0.5
113 114
                anchors.centerIn:       parent
                //-- Standard
115 116
                CustomQuickButton {
                    id:                 standardMode
117
                    width:              buttonSize
118 119
                    height:             buttonSize
                    iconSource:        "/custom/img/thermal-standard.svg"
120 121
                    onClicked:  {
                        _camera.thermalMode = QGCCameraControl.THERMAL_OFF
122 123
                    }
                }
124
                //-- PIP
125 126
                CustomQuickButton {
                    id:                 thermalPip
127
                    width:              buttonSize
128 129 130 131 132
                    height:             buttonSize
                    visible:            _camera.vendor !== "NextVision"
                    iconSource:        "/custom/img/thermal-pip.svg"
                    onClicked:  {
                        _camera.thermalMode = QGCCameraControl.THERMAL_PIP
133 134
                    }
                }
135 136 137
                // Thermal
                CustomQuickButton {
                    id:                 thermalFull
138
                    width:              buttonSize
139 140 141 142
                    height:             buttonSize
                    iconSource:         "/custom/img/thermal-brightness.svg"
                    onClicked:  {
                        _camera.thermalMode = QGCCameraControl.THERMAL_FULL
143 144
                    }
                }
145 146 147
                // Thermal palette options
                CustomQuickButton {
                    checkable:          false
148
                    width:              buttonSize
149
                    height:             buttonSize
150
                    visible:            _irPaletteFact
151 152
                    iconSource:        "/custom/img/thermal-palette.svg"
                    onClicked:  {
153
                        thermalPalettes.open()
154 155 156 157 158 159
                    }
                }
            }
        }
        //---------------------------------------------------------------------
        //-- Main Camera Control
160 161
        Row {
            spacing:            ScreenTools.defaultFontPixelWidth * 0.5
162
            anchors.horizontalCenter: parent.horizontalCenter
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
            Rectangle {
                id:             cameraRect
                height:         cameraCol.height
                width:          cameraCol.width + (ScreenTools.defaultFontPixelWidth * 4)
                color:          qgcPal.window
                radius:         ScreenTools.defaultFontPixelWidth * 0.5
                Column {
                    id:         cameraCol
                    spacing:    _spacers
                    anchors.centerIn: parent
                    Item {
                        height:     1
                        width:      1
                    }
                    //-----------------------------------------------------------------
                    //-- Camera Name
                    QGCLabel {
                        text:                   activeVehicle ? (_camera && _camera.modelName !== "" ? _camera.modelName : _commLostStr) : _commLostStr
                        font.pointSize:         ScreenTools.smallFontPointSize
                        anchors.horizontalCenter: parent.horizontalCenter
183
                    }
184 185 186 187 188
                    QGCLabel {
                        text: {
                            if(_noSdCard)   return qsTr("NONE")
                            if(_fullSD)     return qsTr("FULL")
                            return _camera ? _camera.storageFreeStr : ""
189
                        }
190 191 192 193
                        visible:                _isShortScreen
                        color:                  (_noSdCard || _fullSD) ? qgcPal.colorOrange : qgcPal.text
                        font.pointSize:         ScreenTools.smallFontPointSize
                        anchors.horizontalCenter: parent.horizontalCenter
194
                    }
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
                    //-----------------------------------------------------------------
                    //-- Camera Mode
                    Item {
                        width:                  modeCol.width
                        height:                 modeCol.height
                        anchors.horizontalCenter: parent.horizontalCenter
                        Column {
                            id:                 modeCol
                            spacing:            _spacers
                            QGCColoredImage {
                                height:         ScreenTools.defaultFontPixelHeight * 1.25
                                width:          height
                                source:         (_cameraModeUndefined || _cameraPhotoMode) ? "/custom/img/camera_photo.svg" : "/custom/img/camera_video.svg"
                                color:          qgcPal.text
                                fillMode:       Image.PreserveAspectFit
                                sourceSize.height:  height
                                anchors.horizontalCenter: parent.horizontalCenter
212
                            }
213 214 215 216
                            QGCLabel {
                                text:           _cameraVideoMode ? qsTr("Video") : qsTr("Photo")
                                font.pointSize: ScreenTools.smallFontPointSize
                                anchors.horizontalCenter: parent.horizontalCenter
217 218
                            }
                        }
219 220 221 222 223 224
                        MouseArea {
                            anchors.fill:       parent
                            enabled:            !_cameraModeUndefined && _camera && _camera.videoStatus !== QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING && _cameraPhotoIdle
                            onClicked: {
                                _camera.toggleMode()
                            }
225 226
                        }
                    }
227 228
                    //-----------------------------------------------------------------
                    //-- Shutter
229
                    Rectangle {
230 231 232 233 234
                        color:                  Qt.rgba(0,0,0,0)
                        width:                  height
                        height:                 ScreenTools.defaultFontPixelHeight * 4
                        radius:                 width * 0.5
                        border.color:           qgcPal.buttonText
Yasen's avatar
Yasen committed
235
                        border.width:           1
236 237
                        anchors.horizontalCenter: parent.horizontalCenter
                        Rectangle {
Yasen's avatar
Yasen committed
238
                            width:              parent.width * 0.85
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 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
                            height:             width
                            radius:             width * 0.5
                            color:              _cameraModeUndefined ? qgcPal.colorGrey : ( _cameraVideoMode ? qgcPal.colorRed : qgcPal.text )
                            visible:            !pauseVideo.visible
                            anchors.centerIn:   parent
                            QGCColoredImage {
                                id:                 busyIndicator
                                height:             parent.height * 0.75
                                width:              height
                                source:             "/qmlimages/MapSync.svg"
                                sourceSize.height:  height
                                fillMode:           Image.PreserveAspectFit
                                mipmap:             true
                                smooth:             true
                                color:              qgcPal.window
                                visible: {
                                    if(_cameraPhotoMode && !_cameraPhotoIdle && !_cameraElapsedMode) {
                                        return true
                                    }
                                    return false
                                }
                                anchors.centerIn:   parent
                                RotationAnimation on rotation {
                                    loops:          Animation.Infinite
                                    from:           360
                                    to:             0
                                    duration:       740
                                    running:        busyIndicator.visible
                                }
                            }
                            QGCLabel {
                                text:               _camera ? _camera.photoLapse.toFixed(0) + 's' : qsTr('N/A')
                                font.family:        ScreenTools.demiboldFontFamily
                                color:              qgcPal.colorBlue
                                visible:            _cameraElapsedMode
                                anchors.centerIn:   parent
                            }
                        }
                        Rectangle {
                            id:         pauseVideo
                            width:      parent.width * 0.5
                            height:     width
                            color:      _cameraModeUndefined ? qgcPal.colorGrey : qgcPal.colorRed
                            visible: {
                               if(_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) {
284 285
                                   return true
                               }
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
                               if(_cameraPhotoMode) {
                                   if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) {
                                       return true
                                   }
                               }
                               return false
                            }
                            anchors.centerIn:   parent
                        }
                        MouseArea {
                            anchors.fill:   parent
                            enabled:        !_noSdCard
                            onClicked: {
                                if(_cameraVideoMode) {
                                    if(_camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) {
                                        _camera.stopVideo()
                                    } else {
                                        if(!_fullSD) {
                                            _camera.startVideo()
                                        }
306 307
                                    }
                                } else {
308 309 310 311 312 313
                                    if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) {
                                        _camera.stopTakePhoto()
                                    } else {
                                        if(!_fullSD) {
                                            _camera.takePhoto()
                                        }
314
                                    }
315 316 317 318
                                }
                            }
                        }
                    }
319 320 321 322 323
                    //-----------------------------------------------------------------
                    //-- Settings
                    Item {
                        width:                  settingsCol.width
                        height:                 settingsCol.height
324
                        anchors.horizontalCenter: parent.horizontalCenter
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 356 357 358
                        Column {
                            id:                 settingsCol
                            spacing:            _spacers
                            anchors.horizontalCenter: parent.horizontalCenter
                            QGCColoredImage {
                                width:                      ScreenTools.defaultFontPixelHeight * 1.25
                                height:                     width
                                sourceSize.width:           width
                                source:                     "qrc:/custom/img/camera_settings.svg"
                                color:                      qgcPal.text
                                fillMode:                   Image.PreserveAspectFit
                                opacity:                    _settingsEnabled ? 1 : 0.5
                                anchors.horizontalCenter:   parent.horizontalCenter
                            }
                            QGCLabel {
                                text:                       qsTr("Settings")
                                font.pointSize:             ScreenTools.smallFontPointSize
                                anchors.horizontalCenter:   parent.horizontalCenter
                            }
                        }
                        MouseArea {
                            anchors.fill:       parent
                            enabled:            _settingsEnabled
                            onClicked: {
                                cameraSettings.open()
                            }
                        }
                    }
                    //-----------------------------------------------------------------
                    //-- microSD Card
                    Column {
                        spacing:                        _spacers
                        visible:                        !_isShortScreen
                        anchors.horizontalCenter:       parent.horizontalCenter
359 360 361 362
                        QGCColoredImage {
                            width:                      ScreenTools.defaultFontPixelHeight * 1.25
                            height:                     width
                            sourceSize.width:           width
363
                            source:                     "qrc:/custom/img/microSD.svg"
364 365 366 367 368 369
                            color:                      qgcPal.text
                            fillMode:                   Image.PreserveAspectFit
                            opacity:                    _settingsEnabled ? 1 : 0.5
                            anchors.horizontalCenter:   parent.horizontalCenter
                        }
                        QGCLabel {
370 371 372 373 374 375 376 377
                            text: {
                                if(_noSdCard)   return qsTr("NONE")
                                if(_fullSD)     return qsTr("FULL")
                                return _camera ? _camera.storageFreeStr : ""
                            }
                            color:          (_noSdCard || _fullSD) ? qgcPal.colorOrange : qgcPal.text
                            font.pointSize: ScreenTools.smallFontPointSize
                            anchors.horizontalCenter: parent.horizontalCenter
378 379
                        }
                    }
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
                    /*
                    //-----------------------------------------------------------------
                    //-- Recording Time / Images Captured
                    CustomLabel {
                        text:               (_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) ? _camera.recordTimeStr : "00:00:00"
                        visible:            _cameraVideoMode
                        pointSize:          ScreenTools.smallFontPointSize
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    CustomLabel {
                        text:               activeVehicle && _cameraPhotoMode ? ('00000' + activeVehicle.cameraTriggerPoints.count).slice(-5) : "00000"
                        visible:            _cameraPhotoMode
                        pointSize:          ScreenTools.smallFontPointSize
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    */
                    Item {
                        height:     1
                        width:      1
399 400
                    }
                }
401 402 403
            }
            //-- Gimbal Indicator
            Rectangle {
404
                id: gimbalBackground
405 406 407
                width:                  _hasGimbal ? ScreenTools.defaultFontPixelWidth * 6 : 0
                height:                 _hasGimbal ? (gimbalCol.height + (ScreenTools.defaultFontPixelHeight * 2)) : 0
                visible:                _hasGimbal
408
                color:                  Qt.rgba(qgcPal.window.r, qgcPal.window.g, qgcPal.window.b, 0.75)
409 410
                radius:                 ScreenTools.defaultFontPixelWidth * 0.5
                anchors.verticalCenter: cameraRect.verticalCenter
411
                Column {
412 413 414
                    id:                 gimbalCol
                    spacing:            ScreenTools.defaultFontPixelHeight * 0.75
                    anchors.centerIn:   parent
415
                    QGCColoredImage {
416
                        id:             gimbalIcon
417
                        source:         "/custom/img/gimbal_icon.svg"
418
                        color:          qgcPal.text
419 420 421 422 423 424 425 426
                        width:          ScreenTools.defaultFontPixelWidth * 2
                        height:         width
                        smooth:         true
                        mipmap:         true
                        antialiasing:   true
                        fillMode:       Image.PreserveAspectFit
                        sourceSize.width: width
                        anchors.horizontalCenter: parent.horizontalCenter
427
                    }
428 429 430
                    Image {
                        id:                 pitchScale
                        height:             cameraRect.height * 0.65
431
                        source:             qgcPal.globalTheme === QGCPalette.Light ? "/custom/img/gimbal_pitch_indoors.svg" : "/custom/img/gimbal_pitch_outdoors.svg"
432 433 434 435 436
                        fillMode:           Image.PreserveAspectFit
                        sourceSize.height:  height
                        smooth:             true
                        mipmap:             true
                        antialiasing:       true
437

438 439 440 441 442 443
                        Image {
                            id:                 yawIndicator
                            width:              ScreenTools.defaultFontPixelWidth * 4
                            source:             "/custom/img/gimbal_position.svg"
                            fillMode:           Image.PreserveAspectFit
                            sourceSize.width:   width
444 445
                            x:                  pitchScale.width/2
                            y:                  (pitchScale.height * pitchScale.scaleRatio) + (pitchScale._pitch / pitchScale.rangeValue) * pitchScale.height
446 447
                            smooth:             true
                            mipmap:             true
448 449 450 451 452 453 454 455 456
                            transform: [
                                Translate {
                                    x: -yawIndicator.width / 2
                                    y: -yawIndicator.height / 2
                                },
                                Rotation {
                                    angle: _gimbalYaw
                                }
                            ]
457
                        }
458 459 460 461 462 463
                        readonly property real minValue: -15
                        readonly property real centerValue: 0
                        readonly property real maxValue: 90
                        readonly property real rangeValue: maxValue - minValue
                        readonly property real scaleRatio: 1/7
                        property real          _pitch: _gimbalPitch < minValue ? minValue  : (_gimbalPitch > maxValue ? maxValue : _gimbalPitch)
464 465 466
                    }
                    QGCLabel {
                        id:             gimbalLabel
467
                        color:          qgcPal.text
468
                        font.pointSize:  ScreenTools.smallFontPointSize
469 470
                    }
                }
471
            } // Gimbal Indicator
472
        }
473 474 475 476
        //-- Zoom Buttons
        ZoomControl {
            id:             zoomControl
            visible:        _hasZoom
477
            mainColor:      qgcPal.window
478
            contentColor:   qgcPal.text
479
            fontPointSize:  ScreenTools.defaultFontPointSize * 1.75
480 481 482
            zoomLevelVisible: false
            zoomLevel:      _hasZoom ? _camera.zoomLevel : NaN
            anchors.horizontalCenter: parent.horizontalCenter
483
            onlyContinousZoom: true
484 485 486 487 488 489 490 491 492 493 494 495 496
            onZoomIn: {
                _camera.stepZoom(1)
            }
            onZoomOut: {
                _camera.stepZoom(-1)
            }
            onContinuousZoomStart: {
                _camera.startZoom(zoomIn ? 1 : -1)
            }
            onContinuousZoomStop: {
                _camera.stopZoom()
            }
        }
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
    }
    //-------------------------------------------------------------------------
    //-- Camera Settings
    Popup {
        id:                 cameraSettings
        width:              Math.min(mainWindow.width  * 0.666, ScreenTools.defaultFontPixelWidth * 80)
        height:             mainWindow.height * 0.666
        modal:              true
        focus:              true
        parent:             Overlay.overlay
        x:                  Math.round((mainWindow.width  - width)  * 0.5)
        y:                  Math.round((mainWindow.height - height) * 0.5)
        closePolicy:        Popup.CloseOnEscape | Popup.CloseOnPressOutside
        background: Rectangle {
            anchors.fill:   parent
            color:          qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
            border.color:   qgcPal.text
            radius:         ScreenTools.defaultFontPixelWidth
        }
        Item {
            anchors.fill:       parent
            anchors.margins:    ScreenTools.defaultFontPixelHeight
            function showEditFact(fact) {
                factEditor.text = fact.valueString
                factEdit.fact = fact
                factEdit.visible = true
            }
            function hideEditFact() {
                factEdit.visible = false
                factEdit.fact = null
            }
            QGCLabel {
                id:                 cameraSettingsLabel
                text:               _noSdCard ? qsTr("Settings") : (_cameraVideoMode ? qsTr("Video Settings") : qsTr("Photo Settings"))
                font.family:        ScreenTools.demiboldFontFamily
                font.pointSize:     ScreenTools.mediumFontPointSize
                anchors.margins:    ScreenTools.defaultFontPixelWidth
                anchors.top:        parent.top
                anchors.left:       parent.left
            }
            QGCFlickable {
                clip:               true
                anchors.top:        cameraSettingsLabel.bottom
                anchors.bottom:     parent.bottom
                anchors.margins:    ScreenTools.defaultFontPixelWidth
                width:              cameraSettingsCol.width + (ScreenTools.defaultFontPixelWidth * 2)
                contentHeight:      cameraSettingsCol.height
                contentWidth:       cameraSettingsCol.width
                anchors.horizontalCenter: parent.horizontalCenter
                Column {
                    id:                 cameraSettingsCol
548
                    spacing:            _spacers
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
                    anchors.margins:    ScreenTools.defaultFontPixelHeight
                    anchors.horizontalCenter: parent.horizontalCenter
                    //-------------------------------------------
                    //-- 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 {
                            model:          _isCamera ? _dynamicCameras.cameraLabels : []
                            width:          _editFieldWidth
Gus Grubba's avatar
Gus Grubba committed
565
                            height:         _editFieldHeight
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
                            onActivated:    _dynamicCameras.currentCamera = index
                            currentIndex:   _dynamicCameras ? _dynamicCameras.currentCamera : 0
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _isCamera && _dynamicCameras.cameraLabels.length > 1
                    }
                    //-------------------------------------------
                    //-- Stream Selector
                    Row {
                        spacing:        ScreenTools.defaultFontPixelWidth
                        visible:        _isCamera && _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
Gus Grubba's avatar
Gus Grubba committed
590
                            height:         _editFieldHeight
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
                            onActivated:    _camera.currentStream = index
                            currentIndex:   _camera ? _camera.currentStream : 0
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _isCamera && _camera.streamLabels.length > 1
                    }
                    //-------------------------------------------
                    //-- 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
Gus Grubba's avatar
Gus Grubba committed
615
                            height:         _editFieldHeight
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
                            model:          parent.thermalModes
                            currentIndex:   _camera ? _camera.thermalMode : 0
                            onActivated:    _camera.thermalMode = index
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:            QGroundControl.videoManager.hasThermal
                    }
                    //-------------------------------------------
                    //-- 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
Gus Grubba's avatar
Gus Grubba committed
640
                            height:         _editFieldHeight
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
                            to:             100
                            from:           0
                            value:          _camera ? _camera.thermalOpacity : 0
                            live:           true
                            onValueChanged: {
                                _camera.thermalOpacity = value
                            }
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:            QGroundControl.videoManager.hasThermal && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND
                    }
                    //-------------------------------------------
                    //-- Settings from Camera Definition File
                    Repeater {
                        model:      _camera ? _camera.activeSettings : []
                        Item {
                            width:   repCol.width
                            height:  repCol.height
                            Column {
                                id:                 repCol
665
                                spacing:            _spacers
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
                                property var _fact: _camera.getFact(modelData)
                                Row {
                                    height:         visible ? undefined : 0
                                    spacing:        ScreenTools.defaultFontPixelWidth
                                    anchors.horizontalCenter: parent.horizontalCenter
                                    property bool   _isBool:    parent._fact.typeIsBool
                                    property bool   _isCombo:   !_isBool && parent._fact.enumStrings.length > 0
                                    property bool   _isSlider:  parent._fact && !isNaN(parent._fact.increment)
                                    property bool   _isEdit:    !_isBool && !_isSlider && parent._fact.enumStrings.length < 1
                                    QGCLabel {
                                        text:       parent.parent._fact.shortDescription
                                        width:      _labelFieldWidth
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    FactComboBox {
Gus Grubba's avatar
Gus Grubba committed
681 682
                                        width:      parent._isCombo ? _editFieldWidth  : 0
                                        height:     parent._isCombo ? _editFieldHeight : 0
683 684 685 686 687 688 689
                                        fact:       parent.parent._fact
                                        indexModel: false
                                        visible:    parent._isCombo
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    QGCButton {
                                        visible:    parent._isEdit
Gus Grubba's avatar
Gus Grubba committed
690 691
                                        width:      parent._isEdit ? _editFieldWidth  : 0
                                        height:     parent._isEdit ? _editFieldHeight : 0
692 693 694 695 696 697
                                        text:       parent.parent._fact.valueString
                                        onClicked: {
                                            showEditFact(parent.parent._fact)
                                        }
                                    }
                                    QGCSlider {
Gus Grubba's avatar
Gus Grubba committed
698 699
                                        width:          parent._isSlider ? _editFieldWidth  : 0
                                        height:         parent._isSlider ? _editFieldHeight : 0
700 701 702 703 704 705 706 707 708 709 710 711 712 713
                                        maximumValue:   parent.parent._fact.max
                                        minimumValue:   parent.parent._fact.min
                                        stepSize:       parent.parent._fact.increment
                                        visible:        parent._isSlider
                                        updateValueWhileDragging:   false
                                        anchors.verticalCenter:     parent.verticalCenter
                                        Component.onCompleted: {
                                            value = parent.parent._fact.value
                                        }
                                        onValueChanged: {
                                            parent.parent._fact.value = value
                                        }
                                    }
                                    CustomOnOffSwitch {
Gus Grubba's avatar
Gus Grubba committed
714 715
                                        width:      parent._isBool ? _editFieldWidth  : 0
                                        height:     parent._isBool ? _editFieldHeight : 0
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
                                        checked:    parent.parent._fact ? parent.parent._fact.value : false
                                        onClicked:  parent.parent._fact.value = checked ? 1 : 0
                                        visible:    parent._isBool
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                }
                                Rectangle {
                                    color:      qgcPal.button
                                    height:     1
                                    width:      cameraSettingsCol.width
                                }
                            }
                        }
                    }
                    //-------------------------------------------
                    //-- Time Lapse
                    Row {
                        spacing:        ScreenTools.defaultFontPixelWidth
                        anchors.horizontalCenter: parent.horizontalCenter
                        visible:        _cameraPhotoMode && !_noSdCard
                        property var photoModes: [qsTr("Single"), qsTr("Time Lapse")]
                        QGCLabel {
                            text:       qsTr("Photo Mode")
                            width:      _labelFieldWidth
                            anchors.verticalCenter: parent.verticalCenter
                        }
                        QGCComboBox {
                            width:          _editFieldWidth
Gus Grubba's avatar
Gus Grubba committed
744
                            height:         _editFieldHeight
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
                            model:          parent.photoModes
                            currentIndex:   _camera ? _camera.photoMode : 0
                            onActivated:    _camera.photoMode = index
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _cameraPhotoMode && !_noSdCard
                    }
                    //-------------------------------------------
                    //-- Time Lapse Interval
                    Row {
                        spacing:        ScreenTools.defaultFontPixelWidth
                        anchors.horizontalCenter: parent.horizontalCenter
                        visible:        _cameraPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE && !_noSdCard
                        QGCLabel {
                            text:       qsTr("Photo Interval (seconds)")
                            width:      _labelFieldWidth
                            anchors.verticalCenter: parent.verticalCenter
                        }
                        QGCSlider {
                            width:          _editFieldWidth
Gus Grubba's avatar
Gus Grubba committed
769
                            height:         _editFieldHeight
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789
                            maximumValue:   60
                            minimumValue:   _camera ? (_camera.isE90 ? 3 : 5) : 5
                            stepSize:       1
                            value:          _camera ? _camera.photoLapse : 5
                            updateValueWhileDragging:   true
                            anchors.verticalCenter:     parent.verticalCenter
                            onValueChanged: {
                                if(_camera) {
                                    _camera.photoLapse = value
                                }
                            }
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _cameraPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE && !_noSdCard
                    }
                    //-------------------------------------------
Gus Grubba's avatar
Gus Grubba committed
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
                    //-- Gimbal Control
                    Row {
                        spacing:        ScreenTools.defaultFontPixelWidth
                        visible:        _camera && !_camera.isThermal
                        anchors.horizontalCenter: parent.horizontalCenter
                        QGCLabel {
                            text:       qsTr("Show Gimbal Control")
                            width:      _labelFieldWidth
                            anchors.verticalCenter: parent.verticalCenter
                        }
                        CustomOnOffSwitch {
                            checked:    CustomQuickInterface.showGimbalControl
                            width:      _editFieldWidth
                            height:     _editFieldHeight
                            anchors.verticalCenter: parent.verticalCenter
                            onClicked:  CustomQuickInterface.showGimbalControl = checked
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _camera && !_camera.isThermal
                    }
                    //-------------------------------------------
815 816 817 818 819 820 821 822 823 824 825 826 827
                    //-- Screen Grid
                    Row {
                        spacing:        ScreenTools.defaultFontPixelWidth
                        visible:        _camera && !_camera.isThermal
                        anchors.horizontalCenter: parent.horizontalCenter
                        QGCLabel {
                            text:       qsTr("Screen Grid")
                            width:      _labelFieldWidth
                            anchors.verticalCenter: parent.verticalCenter
                        }
                        CustomOnOffSwitch {
                            checked:     QGroundControl.settingsManager.videoSettings.gridLines.rawValue
                            width:      _editFieldWidth
Gus Grubba's avatar
Gus Grubba committed
828
                            height:     _editFieldHeight
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
                            anchors.verticalCenter: parent.verticalCenter
                            onClicked:  QGroundControl.settingsManager.videoSettings.gridLines.rawValue = checked
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _camera && !_camera.isThermal
                    }
                    //-------------------------------------------
                    //-- Video Fit
                    Row {
                        spacing:        ScreenTools.defaultFontPixelWidth
                        visible:        _camera
                        anchors.horizontalCenter: parent.horizontalCenter
                        QGCLabel {
                            text:       qsTr("Video Screen Fit")
                            width:      _labelFieldWidth
                            anchors.verticalCenter: parent.verticalCenter
                        }
                        FactComboBox {
                            width:      _editFieldWidth
Gus Grubba's avatar
Gus Grubba committed
852
                            height:     _editFieldHeight
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
                            fact:       QGroundControl.settingsManager.videoSettings.videoFit
                            indexModel: false
                            anchors.verticalCenter: parent.verticalCenter
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                        visible:    _camera && !_camera.isThermal
                    }
                    //-------------------------------------------
                    //-- 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
Gus Grubba's avatar
Gus Grubba committed
878
                            height:     _editFieldHeight
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949
                            enabled:    !_recordingVideo
                            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()
                                    QGroundControl.settingsManager.videoSettings.gridLines.rawValue = false
                                    _camera.photoMode = QGCCameraControl.PHOTO_CAPTURE_SINGLE
                                    _camera.photoLapse = 5.0
                                    _camera.photoLapseCount = 0
                                    resetPrompt.close()
                                }
                            }
                        }
                    }
                    Rectangle {
                        color:      qgcPal.button
                        height:     1
                        width:      cameraSettingsCol.width
                    }
                }
            }
            Rectangle {
                id:             factEdit
                visible:        false
                color:          qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.5) : Qt.rgba(0,0,0,0.5)
                anchors.fill:   parent
                property var fact: null
                DeadMouseArea {
                    anchors.fill:   parent
                }
                Rectangle {
                    width:      factEditCol.width  * 1.25
                    height:     factEditCol.height * 1.25
                    color:      qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
                    border.width:       1
                    border.color:       qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.35) : Qt.rgba(1,1,1,0.35)
                    anchors.top:        parent.top
                    anchors.topMargin:  ScreenTools.defaultFontPixelHeight * 8
                    anchors.horizontalCenter: parent.horizontalCenter
                    Column {
                        id:             factEditCol
                        spacing:        ScreenTools.defaultFontPixelHeight
                        anchors.centerIn: parent
                        QGCLabel {
                            text:       factEdit.fact ? factEdit.fact.shortDescription : ""
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        FactTextField {
                            id:         factEditor
                            width:      _editFieldWidth
                            fact:       factEdit.fact
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        QGCButton {
                            text: qsTr("Close")
                            anchors.horizontalCenter: parent.horizontalCenter
                            onClicked: {
                                factEditor.completeEditing()
                                hideEditFact()
                            }
                        }
                    }
                }
            }
        }
    }
950 951 952 953 954 955
    //-------------------------------------------------------------------------
    //-- Thermal Palettes
    Popup {
        id:                     thermalPalettes
        width:                  Math.min(mainWindow.width * 0.666, ScreenTools.defaultFontPixelWidth * 40)
        height:                 mainWindow.height * 0.5
956
        modal:                  true
957 958 959 960 961
        focus:                  true
        parent:                 Overlay.overlay
        x:                      Math.round((mainWindow.width  - width)  * 0.5)
        y:                      Math.round((mainWindow.height - height) * 0.5)
        closePolicy:            Popup.CloseOnEscape | Popup.CloseOnPressOutside
962

963 964 965 966
        background: Rectangle {
            anchors.fill:       parent
            color:              qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
            border.color:       qgcPal.text
967
            radius:             ScreenTools.defaultFontPixelWidth * 0.5
968 969 970 971 972 973 974 975 976 977 978
        }
        Item {
            anchors.fill:       parent
            anchors.margins:    ScreenTools.defaultFontPixelHeight
            QGCFlickable {
                clip:               true
                anchors.fill:       parent
                width:              comboListCol.width + (ScreenTools.defaultFontPixelWidth * 2)
                contentHeight:      comboListCol.height
                contentWidth:       comboListCol.width
                anchors.horizontalCenter: parent.horizontalCenter
Gus Grubba's avatar
Gus Grubba committed
979
                ColumnLayout {
980 981 982 983
                    id:                 comboListCol
                    spacing:            ScreenTools.defaultFontPixelHeight
                    anchors.margins:    ScreenTools.defaultFontPixelHeight
                    anchors.horizontalCenter: parent.horizontalCenter
984
                    QGCLabel {
Gus Grubba's avatar
Gus Grubba committed
985 986
                        text:           qsTr("Thermal Palettes")
                        Layout.alignment: Qt.AlignHCenter
987
                    }
988 989 990
                    Repeater {
                        model:          _irPaletteFact ? _irPaletteFact.enumStrings : []
                        QGCButton {
Gus Grubba's avatar
Gus Grubba committed
991 992 993 994 995 996 997
                            text:                   modelData
                            Layout.minimumHeight:   ScreenTools.defaultFontPixelHeight * 3
                            Layout.minimumWidth:    ScreenTools.defaultFontPixelWidth  * 30
                            Layout.fillHeight:      true
                            Layout.fillWidth:       true
                            Layout.alignment:       Qt.AlignHCenter
                            checked:                index === _irPaletteFact.value
998 999
                            onClicked: {
                                _irPaletteFact.value = index
1000 1001 1002
                                if(thermalBackgroundRect.visible) {
                                    if(_camera.thermalMode !== QGCCameraControl.THERMAL_PIP && _camera.thermalMode !== QGCCameraControl.THERMAL_FULL) {
                                        _camera.thermalMode = QGCCameraControl.THERMAL_FULL
1003
                                        thermalFull.checked = true
1004 1005 1006
                                    }
                                }

1007 1008 1009 1010 1011 1012 1013 1014
                                thermalPalettes.close()
                            }
                        }
                    }
                }
            }
        }
    }
1015 1016
}