CustomCameraControl.qml 52.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/****************************************************************************
 *
 * (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

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
31
import Custom.Camera                    1.0
32 33

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

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

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

    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
61
    property Fact   _irPaletteFact:         _camera ? _camera.irPalette : null
62 63 64 65
    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
66 67 68 69 70 71 72 73 74 75 76 77 78
    Connections {
        target: QGroundControl.multiVehicleManager.activeVehicle
        onConnectionLostChanged: {
            if(_communicationLost && cameraSettings.visible) {
                cameraSettings.close()
            }
        }
    }

    DeadMouseArea {
        anchors.fill:   parent
    }

79 80 81 82
    //-------------------------------------------------------------------------
    //-- Main Column
    Column {
        id:             mainColumn
83
        spacing:        _spacers
84 85 86
        anchors.centerIn: parent
        //---------------------------------------------------------------------
        //-- Quick Thermal Modes
87
        Item {
88 89 90
            id:             backgroundRect
            width:          buttonsRow.width  + (ScreenTools.defaultFontPixelWidth  * 4)
            height:         buttonsRow.height + (ScreenTools.defaultFontPixelHeight)
91
            visible:        _irPaletteFact && QGroundControl.videoManager.hasThermal || _camera.vendor === "NextVision"
92
            anchors.horizontalCenter: parent.horizontalCenter
93 94 95 96 97 98 99 100 101 102
            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
                }
            }
103 104 105 106
            ButtonGroup {
                id:         buttonGroup
                exclusive:  true
                buttons:    buttonsRow.children
107
            }
108 109
            Row {
                id:                     buttonsRow
110
                spacing:                ScreenTools.defaultFontPixelWidth * 0.5
111 112
                anchors.centerIn:       parent
                //-- Standard
113 114
                CustomQuickButton {
                    id:                 standardMode
115
                    width:              buttonSize
116 117
                    height:             buttonSize
                    iconSource:        "/custom/img/thermal-standard.svg"
118 119
                    onClicked:  {
                        _camera.thermalMode = QGCCameraControl.THERMAL_OFF
120 121
                    }
                }
122
                //-- PIP
123 124
                CustomQuickButton {
                    id:                 thermalPip
125
                    width:              buttonSize
126 127 128 129 130
                    height:             buttonSize
                    visible:            _camera.vendor !== "NextVision"
                    iconSource:        "/custom/img/thermal-pip.svg"
                    onClicked:  {
                        _camera.thermalMode = QGCCameraControl.THERMAL_PIP
131 132
                    }
                }
133 134 135
                // Thermal
                CustomQuickButton {
                    id:                 thermalFull
136
                    width:              buttonSize
137 138 139 140
                    height:             buttonSize
                    iconSource:         "/custom/img/thermal-brightness.svg"
                    onClicked:  {
                        _camera.thermalMode = QGCCameraControl.THERMAL_FULL
141 142
                    }
                }
143 144 145 146
                // Thermal palette options
                CustomQuickButton {
                    checkable:          false
                    enabled:            thermalFull.checked || thermalPip.checked
147
                    width:              buttonSize
148 149 150
                    height:             buttonSize
                    iconSource:        "/custom/img/thermal-palette.svg"
                    onClicked:  {
151
                        if(_irPaletteFact) {
152
                            thermalPalettes.open()
153
                        }
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 404 405 406 407 408 409
            }
            //-- Gimbal Indicator
            Rectangle {
                width:                  _hasGimbal ? ScreenTools.defaultFontPixelWidth * 6 : 0
                height:                 _hasGimbal ? (gimbalCol.height + (ScreenTools.defaultFontPixelHeight * 2)) : 0
                visible:                _hasGimbal
                color:                  Qt.rgba(0,0,0,0.5)
                radius:                 ScreenTools.defaultFontPixelWidth * 0.5
                anchors.verticalCenter: cameraRect.verticalCenter
410
                Column {
411 412 413 414 415 416 417 418 419 420 421 422 423
                    id:                 gimbalCol
                    spacing:            ScreenTools.defaultFontPixelHeight * 0.75
                    anchors.centerIn:   parent
                    Image {
                        source:         "/custom/img/gimbal_icon.svg"
                        width:          ScreenTools.defaultFontPixelWidth * 2
                        height:         width
                        smooth:         true
                        mipmap:         true
                        antialiasing:   true
                        fillMode:       Image.PreserveAspectFit
                        sourceSize.width: width
                        anchors.horizontalCenter: parent.horizontalCenter
424
                    }
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
                    Image {
                        id:                 pitchScale
                        height:             cameraRect.height * 0.65
                        source:             "/custom/img/gimbal_pitch.svg"
                        fillMode:           Image.PreserveAspectFit
                        sourceSize.height:  height
                        smooth:             true
                        mipmap:             true
                        antialiasing:       true
                        anchors.horizontalCenter: parent.horizontalCenter
                        Image {
                            id:                 yawIndicator
                            width:              ScreenTools.defaultFontPixelWidth * 4
                            source:             "/custom/img/gimbal_position.svg"
                            fillMode:           Image.PreserveAspectFit
                            sourceSize.width:   width
                            y:                  (parent.height * _pitch / 105)
                            smooth:             true
                            mipmap:             true
                            anchors.horizontalCenter: parent.horizontalCenter
                            transform: Rotation {
                                origin.x:       yawIndicator.width  / 2
                                origin.y:       yawIndicator.height / 2
                                angle:          _gimbalYaw
                            }
                            property real _pitch: _gimbalPitch < -15 ? -15  : (_gimbalPitch > 90 ? 90 : _gimbalPitch)
451
                        }
452 453 454 455 456 457
                    }
                    QGCLabel {
                        id:             gimbalLabel
                        text:           _gimbalPitch ? _gimbalPitch.toFixed(0) : 0
                        color:          "#FFF"
                        font.pointSize:  ScreenTools.smallFontPointSize
458
                        anchors.horizontalCenter: parent.horizontalCenter
459 460 461 462
                    }
                }
            }
        }
463 464 465 466
        //-- Zoom Buttons
        ZoomControl {
            id:             zoomControl
            visible:        _hasZoom
467
            mainColor:      qgcPal.window
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
            contentColor:   qgcPal.text
            fontPointSize:  ScreenTools.defaultFontPointSize * 1.25
            zoomLevelVisible: false
            zoomLevel:      _hasZoom ? _camera.zoomLevel : NaN
            anchors.horizontalCenter: parent.horizontalCenter
            onZoomIn: {
                _camera.stepZoom(1)
            }
            onZoomOut: {
                _camera.stepZoom(-1)
            }
            onContinuousZoomStart: {
                _camera.startZoom(zoomIn ? 1 : -1)
            }
            onContinuousZoomStop: {
                _camera.stopZoom()
            }
        }
486 487 488 489 490 491 492 493 494 495 496 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
    }
    //-------------------------------------------------------------------------
    //-- 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
537
                    spacing:            _spacers
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
                    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
554
                            height:         _editFieldHeight
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
                            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
579
                            height:         _editFieldHeight
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
                            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
604
                            height:         _editFieldHeight
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
                            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
629
                            height:         _editFieldHeight
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
                            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
654
                                spacing:            _spacers
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
                                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
670 671
                                        width:      parent._isCombo ? _editFieldWidth  : 0
                                        height:     parent._isCombo ? _editFieldHeight : 0
672 673 674 675 676 677 678
                                        fact:       parent.parent._fact
                                        indexModel: false
                                        visible:    parent._isCombo
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                    QGCButton {
                                        visible:    parent._isEdit
Gus Grubba's avatar
Gus Grubba committed
679 680
                                        width:      parent._isEdit ? _editFieldWidth  : 0
                                        height:     parent._isEdit ? _editFieldHeight : 0
681 682 683 684 685 686
                                        text:       parent.parent._fact.valueString
                                        onClicked: {
                                            showEditFact(parent.parent._fact)
                                        }
                                    }
                                    QGCSlider {
Gus Grubba's avatar
Gus Grubba committed
687 688
                                        width:          parent._isSlider ? _editFieldWidth  : 0
                                        height:         parent._isSlider ? _editFieldHeight : 0
689 690 691 692 693 694 695 696 697 698 699 700 701 702
                                        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
703 704
                                        width:      parent._isBool ? _editFieldWidth  : 0
                                        height:     parent._isBool ? _editFieldHeight : 0
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
                                        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
733
                            height:         _editFieldHeight
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
                            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
758
                            height:         _editFieldHeight
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
                            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
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
                    //-- 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
                    }
                    //-------------------------------------------
804 805 806 807 808 809 810 811 812 813 814 815 816
                    //-- 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
817
                            height:     _editFieldHeight
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
                            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
841
                            height:     _editFieldHeight
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
                            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
867
                            height:     _editFieldHeight
868 869 870 871 872 873 874 875 876 877 878 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
                            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()
                            }
                        }
                    }
                }
            }
        }
    }
939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
    //-------------------------------------------------------------------------
    //-- Thermal Palettes
    Popup {
        id:                     thermalPalettes
        width:                  Math.min(mainWindow.width * 0.666, ScreenTools.defaultFontPixelWidth * 40)
        height:                 mainWindow.height * 0.5
        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
        property int selectedIndex: 0
        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
            QGCFlickable {
                clip:               true
                anchors.fill:       parent
                width:              comboListCol.width + (ScreenTools.defaultFontPixelWidth * 2)
                contentHeight:      comboListCol.height
                contentWidth:       comboListCol.width
                anchors.horizontalCenter: parent.horizontalCenter
                Column {
                    id:                 comboListCol
                    spacing:            ScreenTools.defaultFontPixelHeight
                    anchors.margins:    ScreenTools.defaultFontPixelHeight
                    anchors.horizontalCenter: parent.horizontalCenter
                    Repeater {
                        model:          _irPaletteFact ? _irPaletteFact.enumStrings : []
                        QGCButton {
                            text:       modelData
                            width:      ScreenTools.defaultFontPixelWidth  * 30
                            height:     ScreenTools.defaultFontPixelHeight * 2
                            checked:    index === _irPaletteFact.value
                            anchors.horizontalCenter: parent.horizontalCenter
                            onClicked: {
                                _irPaletteFact.value = index
                                thermalPalettes.close()
                            }
                        }
                    }
                }
            }
        }
    }
991 992
}