FlightDisplayView.qml 35.3 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *
 *   (c) 2009-2016 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.
 *
 ****************************************************************************/
9

10 11 12 13
import QtQuick                  2.11
import QtQuick.Controls         2.4
import QtQuick.Dialogs          1.3
import QtQuick.Layouts          1.11
14

15 16
import QtLocation               5.3
import QtPositioning            5.3
Patrick José Pereira's avatar
Patrick José Pereira committed
17
import QtQuick.Window           2.2
18
import QtQml.Models             2.1
19

20
import QGroundControl               1.0
21 22 23 24
import QGroundControl.Airspace      1.0
import QGroundControl.Controllers   1.0
import QGroundControl.Controls      1.0
import QGroundControl.FactSystem    1.0
Don Gagne's avatar
Don Gagne committed
25
import QGroundControl.FlightDisplay 1.0
26 27
import QGroundControl.FlightMap     1.0
import QGroundControl.Palette       1.0
28
import QGroundControl.ScreenTools   1.0
29
import QGroundControl.Vehicle       1.0
30 31

/// Flight Display View
32
Item {
33

Gus Grubba's avatar
Gus Grubba committed
34
    PlanMasterController {
Gus Grubba's avatar
Gus Grubba committed
35 36 37 38 39
        id: _planController
        Component.onCompleted: {
            start(true /* flyView */)
            mainWindow.planMasterControllerView = _planController
        }
Gus Grubba's avatar
Gus Grubba committed
40 41
    }

42 43 44 45 46 47 48 49 50
    property alias  guidedController:              guidedActionsController
    property bool   activeVehicleJoystickEnabled:  activeVehicle ? activeVehicle.joystickEnabled : false
    property bool   mainIsMap:                     QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey,  true) : true
    property bool   isBackgroundDark:              mainIsMap ? (mainWindow.flightDisplayMap ? mainWindow.flightDisplayMap.isSatelliteMap : true) : true

    property var    _missionController:             _planController.missionController
    property var    _geoFenceController:            _planController.geoFenceController
    property var    _rallyPointController:          _planController.rallyPointController
    property bool   _isPipVisible:                  QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false
51
    property bool   _useChecklist:                  QGroundControl.settingsManager.appSettings.useChecklist.rawValue && QGroundControl.corePlugin.options.preFlightChecklistUrl.toString().length
52 53 54 55 56
    property real   _savedZoomLevel:                0
    property real   _margins:                       ScreenTools.defaultFontPixelWidth / 2
    property real   _pipSize:                       mainWindow.width * 0.2
    property alias  _guidedController:              guidedActionsController
    property alias  _altitudeSlider:                altitudeSlider
57

Gus Grubba's avatar
Gus Grubba committed
58
    readonly property var       _dynamicCameras:        activeVehicle ? activeVehicle.dynamicCameras : null
59
    readonly property bool      _isCamera:              _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false
Don Gagne's avatar
Don Gagne committed
60 61 62 63 64 65 66 67 68 69 70
    readonly property real      _defaultRoll:           0
    readonly property real      _defaultPitch:          0
    readonly property real      _defaultHeading:        0
    readonly property real      _defaultAltitudeAMSL:   0
    readonly property real      _defaultGroundSpeed:    0
    readonly property real      _defaultAirSpeed:       0
    readonly property string    _mapName:               "FlightDisplayView"
    readonly property string    _showMapBackgroundKey:  "/showMapBackground"
    readonly property string    _mainIsMapKey:          "MainFlyWindowIsMap"
    readonly property string    _PIPVisibleKey:         "IsPIPVisible"

71
    function setStates() {
72 73
        QGroundControl.saveBoolGlobalSetting(_mainIsMapKey, mainIsMap)
        if(mainIsMap) {
74 75 76 77
            //-- Adjust Margins
            _flightMapContainer.state   = "fullMode"
            _flightVideo.state          = "pipMode"
            //-- Save/Restore Map Zoom Level
78 79 80 81 82 83 84 85 86
            if(_savedZoomLevel != 0) {
                if(mainWindow.flightDisplayMap) {
                    mainWindow.flightDisplayMap.zoomLevel = _savedZoomLevel
                }
            } else {
                if(mainWindow.flightDisplayMap) {
                    _savedZoomLevel = mainWindow.flightDisplayMap.zoomLevel
                }
            }
87
        } else {
88 89 90 91
            //-- Adjust Margins
            _flightMapContainer.state   = "pipMode"
            _flightVideo.state          = "fullMode"
            //-- Set Map Zoom Level
92 93 94 95
            if(mainWindow.flightDisplayMap) {
                _savedZoomLevel = mainWindow.flightDisplayMap.zoomLevel
                mainWindow.flightDisplayMap.zoomLevel = _savedZoomLevel - 3
            }
96
        }
Don Gagne's avatar
Don Gagne committed
97 98
    }

99 100 101
    function setPipVisibility(state) {
        _isPipVisible = state;
        QGroundControl.saveBoolGlobalSetting(_PIPVisibleKey, state)
102 103
    }

Gus Grubba's avatar
Gus Grubba committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117
    function isInstrumentRight() {
        if(QGroundControl.corePlugin.options.instrumentWidget) {
            if(QGroundControl.corePlugin.options.instrumentWidget.source.toString().length) {
                switch(QGroundControl.corePlugin.options.instrumentWidget.widgetPosition) {
                case CustomInstrumentWidget.POS_TOP_LEFT:
                case CustomInstrumentWidget.POS_BOTTOM_LEFT:
                case CustomInstrumentWidget.POS_CENTER_LEFT:
                    return false;
                }
            }
        }
        return true;
    }

118
    Connections {
119 120
        target:                     _missionController
        onResumeMissionUploadFail:  guidedActionsController.confirmAction(guidedActionsController.actionResumeMissionUploadFail)
121 122
    }

123 124 125 126 127 128 129 130 131 132 133 134
    Connections {
        target:                 mainWindow
        onArmVehicle:           guidedController.confirmAction(guidedController.actionArm)
        onDisarmVehicle: {
            if (guidedController.showEmergenyStop) {
                guidedController.confirmAction(guidedController.actionEmergencyStop)
            } else {
                guidedController.confirmAction(guidedController.actionDisarm)
            }
        }
        onVtolTransitionToFwdFlight:    guidedController.confirmAction(guidedController.actionVtolTransitionToFwdFlight)
        onVtolTransitionToMRFlight:     guidedController.confirmAction(guidedController.actionVtolTransitionToMRFlight)
135
        onFlightDisplayMapChanged:      setStates()
136 137
    }

138
    Component.onCompleted: {
139 140 141
        if(QGroundControl.corePlugin.options.flyViewOverlay.toString().length) {
            flyViewOverlay.source = QGroundControl.corePlugin.options.flyViewOverlay
        }
142 143 144
        if(QGroundControl.corePlugin.options.preFlightChecklistUrl.toString().length) {
            checkList.source = QGroundControl.corePlugin.options.preFlightChecklistUrl
        }
145
    }
dogmaphobic's avatar
dogmaphobic committed
146

147 148 149 150 151 152 153 154
    // The following code is used to track vehicle states for showing the mission complete dialog
    property bool vehicleArmed:                     activeVehicle ? activeVehicle.armed : true // true here prevents pop up from showing during shutdown
    property bool vehicleWasArmed:                  false
    property bool vehicleInMissionFlightMode:       activeVehicle ? (activeVehicle.flightMode === activeVehicle.missionFlightMode) : false
    property bool vehicleWasInMissionFlightMode:    false
    property bool showMissionCompleteDialog:        vehicleWasArmed && vehicleWasInMissionFlightMode &&
                                                        (_missionController.containsItems || _geoFenceController.containsItems || _rallyPointController.containsItems ||
                                                        (activeVehicle ? activeVehicle.cameraTriggerPoints.count !== 0 : false))
155 156 157

    onVehicleArmedChanged: {
        if (vehicleArmed) {
158 159
            vehicleWasArmed = true
            vehicleWasInMissionFlightMode = vehicleInMissionFlightMode
160
        } else {
161 162
            if (showMissionCompleteDialog) {
                mainWindow.showComponentDialog(missionCompleteDialogComponent, qsTr("Flight Plan complete"), mainWindow.showDialogDefaultWidth, StandardButton.Close)
163
            }
164 165
            vehicleWasArmed = false
            vehicleWasInMissionFlightMode = false
166 167 168 169
        }
    }

    onVehicleInMissionFlightModeChanged: {
170 171
        if (vehicleInMissionFlightMode && vehicleArmed) {
            vehicleWasInMissionFlightMode = true
172 173 174 175
        }
    }

    Component {
176 177 178
        id: missionCompleteDialogComponent

        QGCViewDialog {
Gus Grubba's avatar
Gus Grubba committed
179
            property var activeVehicleCopy: activeVehicle
180 181 182 183 184
            onActiveVehicleCopyChanged:
                if (!activeVehicleCopy) {
                    hideDialog()
                }

185 186 187 188
            QGCFlickable {
                anchors.fill:   parent
                contentHeight:  column.height

189
                ColumnLayout {
190 191 192 193
                    id:                 column
                    anchors.margins:    _margins
                    anchors.left:       parent.left
                    anchors.right:      parent.right
194
                    spacing:            ScreenTools.defaultFontPixelHeight
195

196 197 198 199 200 201
                    QGCLabel {
                        Layout.fillWidth:       true
                        text:                   qsTr("%1 Images Taken").arg(activeVehicle.cameraTriggerPoints.count)
                        horizontalAlignment:    Text.AlignHCenter
                        visible:                activeVehicle.cameraTriggerPoints.count !== 0
                    }
202

203 204 205 206 207 208 209
                    QGCButton {
                        Layout.fillWidth:   true
                        text:               qsTr("Remove plan from vehicle")
                        visible:            !activeVehicle.connectionLost// && !activeVehicle.apmFirmware  // ArduPilot has a bug somewhere with mission clear
                        onClicked: {
                            _planController.removeAllFromVehicle()
                            hideDialog()
210
                        }
211
                    }
212

213 214 215 216 217 218
                    QGCButton {
                        Layout.fillWidth:   true
                        Layout.alignment:   Qt.AlignHCenter
                        text:               qsTr("Leave plan on vehicle")
                        onClicked:          hideDialog()
                    }
Don Gagne's avatar
Don Gagne committed
219

220 221 222 223 224
                    Rectangle {
                        Layout.fillWidth:   true
                        color:              qgcPal.text
                        height:             1
                    }
Don Gagne's avatar
Don Gagne committed
225

226 227 228 229
                    ColumnLayout {
                        Layout.fillWidth:   true
                        spacing:            ScreenTools.defaultFontPixelHeight
                        visible:            !activeVehicle.connectionLost && _guidedController.showResumeMission
Don Gagne's avatar
Don Gagne committed
230

231 232 233 234 235 236 237 238 239
                        QGCButton {
                            Layout.fillWidth:   true
                            Layout.alignment:   Qt.AlignHCenter
                            text:               qsTr("Resume Mission From Waypoint %1").arg(_guidedController._resumeMissionIndex)

                            onClicked: {
                                guidedController.executeAction(_guidedController.actionResumeMission, null, null)
                                hideDialog()
                            }
Don Gagne's avatar
Don Gagne committed
240 241
                        }

242 243 244 245 246
                        QGCLabel {
                            Layout.fillWidth:   true
                            wrapMode:           Text.WordWrap
                            text:               qsTr("Resume Mission will rebuild the current mission from the last flown waypoint and upload it to the vehicle for the next flight.")
                        }
Don Gagne's avatar
Don Gagne committed
247 248
                    }

249
                    QGCLabel {
Don Gagne's avatar
Don Gagne committed
250
                        Layout.fillWidth:   true
251 252 253 254
                        wrapMode:           Text.WordWrap
                        color:              qgcPal.warningText
                        text:               qsTr("If you are changing batteries for Resume Mission do not disconnect from the vehicle.")
                        visible:            _guidedController.showResumeMission
Don Gagne's avatar
Don Gagne committed
255
                    }
256
                }
257 258 259 260
            }
        }
    }

Patrick José Pereira's avatar
Patrick José Pereira committed
261 262
    Window {
        id:             videoWindow
263 264
        width:          !mainIsMap ? _mapAndVideo.width  : _pipSize
        height:         !mainIsMap ? _mapAndVideo.height : _pipSize * (9/16)
Patrick José Pereira's avatar
Patrick José Pereira committed
265 266 267 268 269 270 271 272 273 274 275
        visible:        false

        Item {
            id:             videoItem
            anchors.fill:   parent
        }

        onClosing: {
            _flightVideo.state = "unpopup"
            videoWindow.visible = false
        }
276
    }
Patrick José Pereira's avatar
Patrick José Pereira committed
277

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
    /* This timer will startVideo again after the popup window appears and is loaded.
     * Such approach was the only one to avoid a crash for windows users
     */
    Timer {
      id: videoPopUpTimer
      interval: 2000;
      running: false;
      repeat: false
      onTriggered: {
          // If state is popup, the next one will be popup-finished
          if (_flightVideo.state ==  "popup") {
            _flightVideo.state = "popup-finished"
          }
          QGroundControl.videoManager.startVideo()
      }
Patrick José Pereira's avatar
Patrick José Pereira committed
293 294
    }

295
    QGCMapPalette { id: mapPal; lightColors: mainIsMap ? mainWindow.flightDisplayMap.isSatelliteMap : true }
296

297
    Item {
298
        id:             _mapAndVideo
299
        anchors.fill:   parent
300 301 302 303

        //-- Map View
        Item {
            id: _flightMapContainer
304
            z:  mainIsMap ? _mapAndVideo.z + 1 : _mapAndVideo.z + 2
305 306
            anchors.left:   _mapAndVideo.left
            anchors.bottom: _mapAndVideo.bottom
307 308 309
            visible:        mainIsMap || _isPipVisible && !QGroundControl.videoManager.fullScreen
            width:          mainIsMap ? _mapAndVideo.width  : _pipSize
            height:         mainIsMap ? _mapAndVideo.height : _pipSize * (9/16)
310 311 312 313 314 315 316 317 318 319 320 321 322 323
            states: [
                State {
                    name:   "pipMode"
                    PropertyChanges {
                        target:             _flightMapContainer
                        anchors.margins:    ScreenTools.defaultFontPixelHeight
                    }
                },
                State {
                    name:   "fullMode"
                    PropertyChanges {
                        target:             _flightMapContainer
                        anchors.margins:    0
                    }
324
                }
325 326
            ]
            FlightDisplayViewMap {
327
                id:                         _fMap
328 329
                anchors.fill:               parent
                guidedActionsController:    _guidedController
Gus Grubba's avatar
Gus Grubba committed
330
                missionController:          _planController
331 332
                flightWidgets:              flightDisplayViewWidgets
                rightPanelWidth:            ScreenTools.defaultFontPixelHeight * 9
333
                multiVehicleView:           !singleVehicleView.checked
334
                scaleState:                 (mainIsMap && flyViewOverlay.item) ? (flyViewOverlay.item.scaleState ? flyViewOverlay.item.scaleState : "bottomMode") : "bottomMode"
335 336 337
                Component.onCompleted: {
                    mainWindow.flightDisplayMap = _fMap
                }
338
            }
339
        }
340

341
        //-- Video View
342
        Item {
343
            id:             _flightVideo
344 345 346
            z:              mainIsMap ? _mapAndVideo.z + 2 : _mapAndVideo.z + 1
            width:          !mainIsMap ? _mapAndVideo.width  : _pipSize
            height:         !mainIsMap ? _mapAndVideo.height : _pipSize * (9/16)
347 348
            anchors.left:   _mapAndVideo.left
            anchors.bottom: _mapAndVideo.bottom
349
            visible:        QGroundControl.videoManager.hasVideo && (!mainIsMap || _isPipVisible)
350 351 352 353 354 355

            onParentChanged: {
                /* If video comes back from popup
                 * correct anchors.
                 * Such thing is not possible with ParentChange.
                 */
356
                if(parent == _mapAndVideo) {
357
                    // Do anchors again after popup
358 359
                    anchors.left =       _mapAndVideo.left
                    anchors.bottom =     _mapAndVideo.bottom
360 361 362 363
                    anchors.margins =    ScreenTools.defaultFontPixelHeight
                }
            }

364 365 366 367 368
            states: [
                State {
                    name:   "pipMode"
                    PropertyChanges {
                        target: _flightVideo
Patrick José Pereira's avatar
Patrick José Pereira committed
369 370 371 372 373
                        anchors.margins: ScreenTools.defaultFontPixelHeight
                    }
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: false
374 375 376 377 378 379 380 381
                    }
                },
                State {
                    name:   "fullMode"
                    PropertyChanges {
                        target: _flightVideo
                        anchors.margins:    0
                    }
Patrick José Pereira's avatar
Patrick José Pereira committed
382 383 384 385 386 387 388 389
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: false
                    }
                },
                State {
                    name: "popup"
                    StateChangeScript {
390 391 392 393 394 395
                        script: {
                            // Stop video, restart it again with Timer
                            // Avoiding crashs if ParentChange is not yet done
                            QGroundControl.videoManager.stopVideo()
                            videoPopUpTimer.running = true
                        }
Patrick José Pereira's avatar
Patrick José Pereira committed
396
                    }
397 398 399 400 401 402 403
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: true
                    }
                },
                State {
                    name: "popup-finished"
Patrick José Pereira's avatar
Patrick José Pereira committed
404 405 406 407 408
                    ParentChange {
                        target: _flightVideo
                        parent: videoItem
                        x: 0
                        y: 0
409 410
                        width: videoItem.width
                        height: videoItem.height
Patrick José Pereira's avatar
Patrick José Pereira committed
411 412 413 414 415
                    }
                },
                State {
                    name: "unpopup"
                    StateChangeScript {
416 417 418 419
                        script: {
                            QGroundControl.videoManager.stopVideo()
                            videoPopUpTimer.running = true
                        }
Patrick José Pereira's avatar
Patrick José Pereira committed
420 421 422
                    }
                    ParentChange {
                        target: _flightVideo
423
                        parent: _mapAndVideo
Patrick José Pereira's avatar
Patrick José Pereira committed
424 425 426 427 428
                    }
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: false
                    }
429
                }
430
            ]
431
            //-- Video Streaming
432
            FlightDisplayViewVideo {
Patrick José Pereira's avatar
Patrick José Pereira committed
433
                id:             videoStreaming
434 435 436 437
                anchors.fill:   parent
                visible:        QGroundControl.videoManager.isGStreamer
            }
            //-- UVC Video (USB Camera or Video Device)
438 439
            Loader {
                id:             cameraLoader
440 441
                anchors.fill:   parent
                visible:        !QGroundControl.videoManager.isGStreamer
442
                source:         QGroundControl.videoManager.uvcEnabled ? "qrc:/qml/FlightDisplayViewUVC.qml" : "qrc:/qml/FlightDisplayViewDummy.qml"
443
            }
dogmaphobic's avatar
dogmaphobic committed
444
        }
445 446 447 448

        QGCPipable {
            id:                 _flightVideoPipControl
            z:                  _flightVideo.z + 3
449 450
            width:              _pipSize
            height:             _pipSize * (9/16)
451 452
            anchors.left:       _mapAndVideo.left
            anchors.bottom:     _mapAndVideo.bottom
453
            anchors.margins:    ScreenTools.defaultFontPixelHeight
454
            visible:            QGroundControl.videoManager.hasVideo && !QGroundControl.videoManager.fullScreen && _flightVideo.state != "popup"
455 456
            isHidden:           !_isPipVisible
            isDark:             isBackgroundDark
457
            enablePopup:        mainIsMap
458
            onActivated: {
459
                mainIsMap = !mainIsMap
460 461 462 463 464
                setStates()
            }
            onHideIt: {
                setPipVisibility(!state)
            }
Patrick José Pereira's avatar
Patrick José Pereira committed
465 466 467 468
            onPopup: {
                videoWindow.visible = true
                _flightVideo.state = "popup"
            }
469 470
            onNewWidth: {
                _pipSize = newWidth
Jacob Walser's avatar
Jacob Walser committed
471
            }
dogmaphobic's avatar
dogmaphobic committed
472
        }
Don Gagne's avatar
Don Gagne committed
473

474 475 476 477 478 479
        Row {
            id:                     singleMultiSelector
            anchors.topMargin:      ScreenTools.toolbarHeight + _margins
            anchors.rightMargin:    _margins
            anchors.right:          parent.right
            spacing:                ScreenTools.defaultFontPixelWidth
480
            z:                      _mapAndVideo.z + 4
481
            visible:                QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.enableMultiVehicleList
482 483 484 485 486

            QGCRadioButton {
                id:             singleVehicleView
                text:           qsTr("Single")
                checked:        true
487
                textColor:      mapPal.text
488 489 490
            }

            QGCRadioButton {
491
                text:           qsTr("Multi-Vehicle")
492
                textColor:      mapPal.text
493 494 495
            }
        }

496
        FlightDisplayViewWidgets {
497
            id:                 flightDisplayViewWidgets
498 499
            z:                  _mapAndVideo.z + 4
            height:             availableHeight - (singleMultiSelector.visible ? singleMultiSelector.height + _margins : 0) - (ScreenTools.defaultFontPixelHeight * 0.5)
500
            anchors.left:       parent.left
501
            anchors.right:      altitudeSlider.visible ? altitudeSlider.left : parent.right
502
            anchors.bottom:     parent.bottom
503
            anchors.top:        singleMultiSelector.visible? singleMultiSelector.bottom : undefined
504
            useLightColors:     isBackgroundDark
505
            missionController:  _missionController
506
            visible:            singleVehicleView.checked && !QGroundControl.videoManager.fullScreen
507 508
        }

509 510 511 512 513
        //-------------------------------------------------------------------------
        //-- Loader helper for plugins to overlay elements over the fly view
        Loader {
            id:                 flyViewOverlay
            z:                  flightDisplayViewWidgets.z + 1
514
            visible:            !QGroundControl.videoManager.fullScreen
515
            height:             mainWindow.height - mainWindow.header.height
516 517 518 519 520
            anchors.left:       parent.left
            anchors.right:      altitudeSlider.visible ? altitudeSlider.left : parent.right
            anchors.bottom:     parent.bottom
        }

521
        MultiVehicleList {
522 523 524 525 526
            anchors.margins:            _margins
            anchors.top:                singleMultiSelector.bottom
            anchors.right:              parent.right
            anchors.bottom:             parent.bottom
            width:                      ScreenTools.defaultFontPixelWidth * 30
527
            visible:                    !singleVehicleView.checked && !QGroundControl.videoManager.fullScreen && QGroundControl.corePlugin.options.enableMultiVehicleList
528
            z:                          _mapAndVideo.z + 4
529
            guidedActionsController:    _guidedController
530
        }
dogmaphobic's avatar
dogmaphobic committed
531

532
        //-- Virtual Joystick
533
        Loader {
534
            id:                         virtualJoystickMultiTouch
535
            z:                          _mapAndVideo.z + 5
536
            width:                      parent.width  - (_flightVideoPipControl.width / 2)
537
            height:                     Math.min(mainWindow.height * 0.25, ScreenTools.defaultFontPixelWidth * 16)
Gus Grubba's avatar
Gus Grubba committed
538
            visible:                    (_virtualJoystick ? _virtualJoystick.value : false) && !QGroundControl.videoManager.fullScreen && !(activeVehicle ? activeVehicle.highLatencyLink : false)
539 540
            anchors.bottom:             _flightVideoPipControl.top
            anchors.bottomMargin:       ScreenTools.defaultFontPixelHeight * 2
541
            anchors.horizontalCenter:   flightDisplayViewWidgets.horizontalCenter
542
            source:                     "qrc:/qml/VirtualJoystick.qml"
Gus Grubba's avatar
Gus Grubba committed
543
            active:                     (_virtualJoystick ? _virtualJoystick.value : false) && !(activeVehicle ? activeVehicle.highLatencyLink : false)
Don Gagne's avatar
Don Gagne committed
544

545
            property bool useLightColors: isBackgroundDark
546 547
            // The default behaviour is not centralized throttle
            property bool centralizeThrottle: _virtualJoystickCentralized ? _virtualJoystickCentralized.value : false
548 549

            property Fact _virtualJoystick: QGroundControl.settingsManager.appSettings.virtualJoystick
550
            property Fact _virtualJoystickCentralized: QGroundControl.settingsManager.appSettings.virtualJoystickCentralized
Don Gagne's avatar
Don Gagne committed
551
        }
552 553

        ToolStrip {
Gus Grubba's avatar
Gus Grubba committed
554
            visible:            (activeVehicle ? activeVehicle.guidedModeSupported : true) && !QGroundControl.videoManager.fullScreen
555
            id:                 toolStrip
556 557

            anchors.leftMargin: isInstrumentRight() ? ScreenTools.defaultFontPixelWidth * 2 : undefined
558
            anchors.left:       isInstrumentRight() ? _mapAndVideo.left : undefined
Gus Grubba's avatar
Gus Grubba committed
559
            anchors.rightMargin:isInstrumentRight() ? undefined : ScreenTools.defaultFontPixelWidth
560
            anchors.right:      isInstrumentRight() ? undefined : _mapAndVideo.right
Don Gagne's avatar
Don Gagne committed
561
            anchors.topMargin:  ScreenTools.defaultFontPixelHeight * 0.5
562
            anchors.top:        parent.top
563
            z:                  _mapAndVideo.z + 4
564
            maxHeight:          (_flightVideo.visible ? _flightVideo.y : parent.height) - toolStrip.y
565

566
            property bool _anyActionAvailable: _guidedController.showStartMission || _guidedController.showResumeMission || _guidedController.showChangeAlt || _guidedController.showLandAbort
567 568
            property var _actionModel: [
                {
569 570 571 572
                    title:      _guidedController.startMissionTitle,
                    text:       _guidedController.startMissionMessage,
                    action:     _guidedController.actionStartMission,
                    visible:    _guidedController.showStartMission
573
                },
Don Gagne's avatar
Don Gagne committed
574 575 576 577 578 579
                {
                    title:      _guidedController.continueMissionTitle,
                    text:       _guidedController.continueMissionMessage,
                    action:     _guidedController.actionContinueMission,
                    visible:    _guidedController.showContinueMission
                },
580
                {
581 582 583 584
                    title:      _guidedController.changeAltTitle,
                    text:       _guidedController.changeAltMessage,
                    action:     _guidedController.actionChangeAlt,
                    visible:    _guidedController.showChangeAlt
585 586
                },
                {
587 588 589 590
                    title:      _guidedController.landAbortTitle,
                    text:       _guidedController.landAbortMessage,
                    action:     _guidedController.actionLandAbort,
                    visible:    _guidedController.showLandAbort
591 592 593 594
                }
            ]

            model: [
595
                {
596 597
                    name:               "Plan",
                    iconSource:         "/qmlimages/Plan.svg",
Gus Grubba's avatar
Gus Grubba committed
598 599
                    buttonVisible:      true,
                    buttonEnabled:      true,
600 601 602 603
                },
                {
                    name:               "Checklist",
                    iconSource:         "/qmlimages/check.svg",
Gus Grubba's avatar
Gus Grubba committed
604 605
                    buttonVisible:      _useChecklist,
                    buttonEnabled:      _useChecklist && activeVehicle && !activeVehicle.armed,
606
                },
607
                {
Gus Grubba's avatar
Gus Grubba committed
608 609 610 611 612
                    name:               _guidedController.takeoffTitle,
                    iconSource:         "/res/takeoff.svg",
                    buttonVisible:      _guidedController.showTakeoff || !_guidedController.showLand,
                    buttonEnabled:      _guidedController.showTakeoff,
                    action:             _guidedController.actionTakeoff
613 614
                },
                {
Gus Grubba's avatar
Gus Grubba committed
615 616 617 618 619
                    name:               _guidedController.landTitle,
                    iconSource:         "/res/land.svg",
                    buttonVisible:      _guidedController.showLand && !_guidedController.showTakeoff,
                    buttonEnabled:      _guidedController.showLand,
                    action:             _guidedController.actionLand
620 621
                },
                {
Gus Grubba's avatar
Gus Grubba committed
622 623 624 625 626
                    name:               _guidedController.rtlTitle,
                    iconSource:         "/res/rtl.svg",
                    buttonVisible:      true,
                    buttonEnabled:      _guidedController.showRTL,
                    action:             _guidedController.actionRTL
627 628
                },
                {
Gus Grubba's avatar
Gus Grubba committed
629 630 631 632 633
                    name:               _guidedController.pauseTitle,
                    iconSource:         "/res/pause-mission.svg",
                    buttonVisible:      _guidedController.showPause,
                    buttonEnabled:      _guidedController.showPause,
                    action:             _guidedController.actionPause
634 635
                },
                {
Gus Grubba's avatar
Gus Grubba committed
636 637 638 639 640
                    name:               qsTr("Action"),
                    iconSource:         "/res/action.svg",
                    buttonVisible:      !_guidedController.showPause,
                    buttonEnabled:      _anyActionAvailable,
                    action:             -1
DonLakeFlyer's avatar
DonLakeFlyer committed
641
                }
642 643 644
            ]

            onClicked: {
645
                guidedActionsController.closeAll()
646 647
                if(index === 0) {
                    mainWindow.showPlanView()
648 649
                } else if(index === 1) {
                    checklistDropPanel.open()
650
                } else {
651 652 653 654 655 656 657
                    var action = model[index].action
                    if (action === -1) {
                        guidedActionList.model   = _actionModel
                        guidedActionList.visible = true
                    } else {
                        _guidedController.confirmAction(action)
                    }
658
                }
659

660 661 662 663
            }
        }

        GuidedActionsController {
664
            id:                 guidedActionsController
665
            missionController:  _missionController
666
            confirmDialog:      guidedActionConfirm
DonLakeFlyer's avatar
DonLakeFlyer committed
667
            actionList:         guidedActionList
Don Gagne's avatar
Don Gagne committed
668
            altitudeSlider:     _altitudeSlider
669 670
            z:                  _flightVideoPipControl.z + 1

671
            onShowStartMissionChanged: {
Don Gagne's avatar
Don Gagne committed
672
                if (showStartMission) {
673 674 675 676
                    confirmAction(actionStartMission)
                }
            }

677 678 679 680 681 682
            onShowContinueMissionChanged: {
                if (showContinueMission) {
                    confirmAction(actionContinueMission)
                }
            }

683 684 685 686 687
            onShowLandAbortChanged: {
                if (showLandAbort) {
                    confirmAction(actionLandAbort)
                }
            }
688 689 690 691 692 693 694

            /// Close all dialogs
            function closeAll() {
                guidedActionConfirm.visible = false
                guidedActionList.visible    = false
                altitudeSlider.visible      = false
            }
695 696
        }

697
        GuidedActionConfirm {
698 699 700 701
            id:                         guidedActionConfirm
            anchors.margins:            _margins
            anchors.bottom:             parent.bottom
            anchors.horizontalCenter:   parent.horizontalCenter
702 703
            guidedController:           _guidedController
            altitudeSlider:             _altitudeSlider
704 705
        }

706
        GuidedActionList {
707 708 709 710
            id:                         guidedActionList
            anchors.margins:            _margins
            anchors.bottom:             parent.bottom
            anchors.horizontalCenter:   parent.horizontalCenter
711
            guidedController:           _guidedController
712 713 714
        }

        //-- Altitude slider
DonLakeFlyer's avatar
DonLakeFlyer committed
715
        GuidedAltitudeSlider {
716 717 718 719 720 721
            id:                 altitudeSlider
            anchors.margins:    _margins
            anchors.right:      parent.right
            anchors.topMargin:  ScreenTools.toolbarHeight + _margins
            anchors.top:        parent.top
            anchors.bottom:     parent.bottom
722
            z:                  _guidedController.z
723 724 725 726 727
            radius:             ScreenTools.defaultFontPixelWidth / 2
            width:              ScreenTools.defaultFontPixelWidth * 10
            color:              qgcPal.window
            visible:            false
        }
Don Gagne's avatar
Don Gagne committed
728
    }
729

730
    //-- Airspace Indicator
731
    Rectangle {
732 733 734
        id:             airspaceIndicator
        width:          airspaceRow.width + (ScreenTools.defaultFontPixelWidth * 3)
        height:         airspaceRow.height * 1.25
735
        color:          qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
736
        visible:        QGroundControl.airmapSupported && mainIsMap && flightPermit && flightPermit !== AirspaceFlightPlanProvider.PermitNone
737 738 739 740 741 742 743
        radius:         3
        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.toolbarHeight + (ScreenTools.defaultFontPixelHeight * 0.25)
        anchors.horizontalCenter: parent.horizontalCenter
        Row {
744
            id: airspaceRow
745 746
            spacing: ScreenTools.defaultFontPixelWidth
            anchors.centerIn: parent
747
            QGCLabel { text: airspaceIndicator.providerName+":"; anchors.verticalCenter: parent.verticalCenter; }
748 749
            QGCLabel {
                text: {
750
                    if(airspaceIndicator.flightPermit) {
Gus Grubba's avatar
Gus Grubba committed
751
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitPending)
752
                            return qsTr("Approval Pending")
753
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitAccepted || airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitNotRequired)
754
                            return qsTr("Flight Approved")
Gus Grubba's avatar
Gus Grubba committed
755
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitRejected)
756
                            return qsTr("Flight Rejected")
757 758 759 760
                    }
                    return ""
                }
                color: {
761
                    if(airspaceIndicator.flightPermit) {
Gus Grubba's avatar
Gus Grubba committed
762
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitPending)
763
                            return qgcPal.colorOrange
764
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitAccepted || airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitNotRequired)
765 766 767 768 769 770 771
                            return qgcPal.colorGreen
                    }
                    return qgcPal.colorRed
                }
                anchors.verticalCenter: parent.verticalCenter;
            }
        }
Gus Grubba's avatar
Gus Grubba committed
772
        property var  flightPermit: QGroundControl.airmapSupported ? QGroundControl.airspaceManager.flightPlan.flightPermitStatus : null
773
        property string  providerName: QGroundControl.airspaceManager.providerName
774 775
    }

776
    //-- Checklist GUI
777 778 779 780
    Popup {
        id:             checklistDropPanel
        x:              Math.round((mainWindow.width  - width)  * 0.5)
        y:              Math.round((mainWindow.height - height) * 0.5)
Gus Grubba's avatar
Gus Grubba committed
781 782
        height:         checkList.height
        width:          checkList.width
783 784 785 786
        modal:          true
        focus:          true
        closePolicy:    Popup.CloseOnEscape | Popup.CloseOnPressOutside
        background: Rectangle {
787 788 789
            anchors.fill:  parent
            color:      Qt.rgba(0,0,0,0)
            clip:       true
790
        }
791 792 793
        Loader {
            id:         checkList
            anchors.centerIn: parent
794
        }
795
    }
796

797
}