FlightDisplayView.qml 35.4 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 51 52 53 54 55 56
    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
    property bool   _useChecklist:                  QGroundControl.settingsManager.appSettings.useChecklist.rawValue
    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
    BuiltInPreFlightCheckModel {
119
        id: preFlightCheckModel
120 121
    }

122
    Connections {
123 124
        target:                     _missionController
        onResumeMissionUploadFail:  guidedActionsController.confirmAction(guidedActionsController.actionResumeMissionUploadFail)
125 126
    }

127 128 129 130 131 132 133 134 135 136 137 138
    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)
139
        onFlightDisplayMapChanged:      setStates()
140 141
    }

142
    Component.onCompleted: {
143 144 145
        if(QGroundControl.corePlugin.options.flyViewOverlay.toString().length) {
            flyViewOverlay.source = QGroundControl.corePlugin.options.flyViewOverlay
        }
146
    }
dogmaphobic's avatar
dogmaphobic committed
147

148 149
    // The following code is used to track vehicle states such that we prompt to remove mission from vehicle when mission completes

Gus Grubba's avatar
Gus Grubba committed
150
    property bool vehicleArmed:                 activeVehicle ? activeVehicle.armed : true // true here prevents pop up from showing during shutdown
151
    property bool vehicleWasArmed:              false
Gus Grubba's avatar
Gus Grubba committed
152
    property bool vehicleInMissionFlightMode:   activeVehicle ? (activeVehicle.flightMode === activeVehicle.missionFlightMode) : false
153 154 155 156 157 158 159 160 161
    property bool promptForMissionRemove:       false

    onVehicleArmedChanged: {
        if (vehicleArmed) {
            if (!promptForMissionRemove) {
                promptForMissionRemove = vehicleInMissionFlightMode
                vehicleWasArmed = true
            }
        } else {
162
            if (promptForMissionRemove && (_missionController.containsItems || _geoFenceController.containsItems || _rallyPointController.containsItems)) {
163
                // ArduPilot has a strange bug which prevents mission clear from working at certain times, so we can't show this dialog
Gus Grubba's avatar
Gus Grubba committed
164
                if (!activeVehicle.apmFirmware) {
165
                    mainWindow.showDialog(missionCompleteDialogComponent, qsTr("Flight Plan complete"), mainWindow.showDialogDefaultWidth, StandardButton.Close)
166
                }
167 168 169 170 171 172 173 174 175 176 177 178
            }
            promptForMissionRemove = false
        }
    }

    onVehicleInMissionFlightModeChanged: {
        if (!promptForMissionRemove && vehicleArmed) {
            promptForMissionRemove = true
        }
    }

    Component {
179 180 181
        id: missionCompleteDialogComponent

        QGCViewDialog {
Gus Grubba's avatar
Gus Grubba committed
182
            property var activeVehicleCopy: activeVehicle
183 184 185 186 187
            onActiveVehicleCopyChanged:
                if (!activeVehicleCopy) {
                    hideDialog()
                }

188 189 190 191
            QGCFlickable {
                anchors.fill:   parent
                contentHeight:  column.height

192
                ColumnLayout {
193 194 195 196 197
                    id:                 column
                    anchors.margins:    _margins
                    anchors.left:       parent.left
                    anchors.right:      parent.right

198
                    ColumnLayout {
199
                        Layout.fillWidth:   true
200
                        spacing:            ScreenTools.defaultFontPixelHeight
Gus Grubba's avatar
Gus Grubba committed
201
                        visible:            !activeVehicle.connectionLost || !_guidedController.showResumeMission
202 203 204

                        QGCLabel {
                            Layout.fillWidth:       true
Gus Grubba's avatar
Gus Grubba committed
205
                            text:                   qsTr("%1 Images Taken").arg(activeVehicle.cameraTriggerPoints.count)
206
                            horizontalAlignment:    Text.AlignHCenter
Gus Grubba's avatar
Gus Grubba committed
207
                            visible:                activeVehicle.cameraTriggerPoints.count !== 0
208
                        }
209

210 211 212 213
                        QGCButton {
                            Layout.fillWidth:   true
                            text:               qsTr("Remove plan from vehicle")
                            onClicked: {
Gus Grubba's avatar
Gus Grubba committed
214
                                _planController.removeAllFromVehicle()
215 216 217
                                hideDialog()
                            }
                        }
Don Gagne's avatar
Don Gagne committed
218

219 220 221 222 223 224
                        QGCButton {
                            Layout.fillWidth:   true
                            Layout.alignment:   Qt.AlignHCenter
                            text:               qsTr("Leave plan on vehicle")
                            onClicked:          hideDialog()
                        }
Don Gagne's avatar
Don Gagne committed
225

226 227 228 229 230
                        Rectangle {
                            Layout.fillWidth:   true
                            color:              qgcPal.text
                            height:             1
                        }
Don Gagne's avatar
Don Gagne committed
231

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

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

244 245 246 247 248 249 250 251 252 253 254 255 256 257
                        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.")
                            visible:            _guidedController.showResumeMission
                        }

                        QGCLabel {
                            Layout.fillWidth:   true
                            wrapMode:           Text.WordWrap
                            color:              qgcPal.warningText
                            text:               qsTr("If you are changing batteries for Resume Mission do not disconnect from the vehicle when communication is lost.")
                            visible:            _guidedController.showResumeMission
                        }
Don Gagne's avatar
Don Gagne committed
258 259
                    }

260
                    ColumnLayout {
Don Gagne's avatar
Don Gagne committed
261
                        Layout.fillWidth:   true
262
                        spacing:            ScreenTools.defaultFontPixelHeight
Gus Grubba's avatar
Gus Grubba committed
263
                        visible:            activeVehicle.connectionLost && _guidedController.showResumeMission
264 265 266 267 268 269 270

                        QGCLabel {
                            Layout.fillWidth:   true
                            wrapMode:           Text.WordWrap
                            color:              qgcPal.warningText
                            text:               qsTr("If you are changing batteries for Resume Mission do not disconnect from the vehicle.")
                        }
Don Gagne's avatar
Don Gagne committed
271
                    }
272
                }
273 274 275 276
            }
        }
    }

Patrick José Pereira's avatar
Patrick José Pereira committed
277 278
    Window {
        id:             videoWindow
279 280
        width:          !mainIsMap ? _mapAndVideo.width  : _pipSize
        height:         !mainIsMap ? _mapAndVideo.height : _pipSize * (9/16)
Patrick José Pereira's avatar
Patrick José Pereira committed
281 282 283 284 285 286 287 288 289 290 291
        visible:        false

        Item {
            id:             videoItem
            anchors.fill:   parent
        }

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

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
    /* 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
309 310
    }

311
    QGCMapPalette { id: mapPal; lightColors: mainIsMap ? mainWindow.flightDisplayMap.isSatelliteMap : true }
312

313
    Item {
314
        id:             _mapAndVideo
315 316 317 318
        anchors.left:   parent.left
        anchors.right:  parent.right
        anchors.top:    parent.top
        anchors.bottom: logReplayStatusBar.top
319 320 321 322

        //-- Map View
        Item {
            id: _flightMapContainer
323
            z:  mainIsMap ? _mapAndVideo.z + 1 : _mapAndVideo.z + 2
324 325
            anchors.left:   _mapAndVideo.left
            anchors.bottom: _mapAndVideo.bottom
326 327 328
            visible:        mainIsMap || _isPipVisible && !QGroundControl.videoManager.fullScreen
            width:          mainIsMap ? _mapAndVideo.width  : _pipSize
            height:         mainIsMap ? _mapAndVideo.height : _pipSize * (9/16)
329 330 331 332 333 334 335 336 337 338 339 340 341 342
            states: [
                State {
                    name:   "pipMode"
                    PropertyChanges {
                        target:             _flightMapContainer
                        anchors.margins:    ScreenTools.defaultFontPixelHeight
                    }
                },
                State {
                    name:   "fullMode"
                    PropertyChanges {
                        target:             _flightMapContainer
                        anchors.margins:    0
                    }
343
                }
344 345
            ]
            FlightDisplayViewMap {
346
                id:                         _fMap
347 348
                anchors.fill:               parent
                guidedActionsController:    _guidedController
Gus Grubba's avatar
Gus Grubba committed
349
                missionController:          _planController
350 351
                flightWidgets:              flightDisplayViewWidgets
                rightPanelWidth:            ScreenTools.defaultFontPixelHeight * 9
352
                multiVehicleView:           !singleVehicleView.checked
353
                scaleState:                 (mainIsMap && flyViewOverlay.item) ? (flyViewOverlay.item.scaleState ? flyViewOverlay.item.scaleState : "bottomMode") : "bottomMode"
354 355 356
                Component.onCompleted: {
                    mainWindow.flightDisplayMap = _fMap
                }
357
            }
358
        }
359

360
        //-- Video View
361
        Item {
362
            id:             _flightVideo
363 364 365
            z:              mainIsMap ? _mapAndVideo.z + 2 : _mapAndVideo.z + 1
            width:          !mainIsMap ? _mapAndVideo.width  : _pipSize
            height:         !mainIsMap ? _mapAndVideo.height : _pipSize * (9/16)
366 367
            anchors.left:   _mapAndVideo.left
            anchors.bottom: _mapAndVideo.bottom
368
            visible:        QGroundControl.videoManager.hasVideo && (!mainIsMap || _isPipVisible)
369 370 371 372 373 374

            onParentChanged: {
                /* If video comes back from popup
                 * correct anchors.
                 * Such thing is not possible with ParentChange.
                 */
375
                if(parent == _mapAndVideo) {
376
                    // Do anchors again after popup
377 378
                    anchors.left =       _mapAndVideo.left
                    anchors.bottom =     _mapAndVideo.bottom
379 380 381 382
                    anchors.margins =    ScreenTools.defaultFontPixelHeight
                }
            }

383 384 385 386 387
            states: [
                State {
                    name:   "pipMode"
                    PropertyChanges {
                        target: _flightVideo
Patrick José Pereira's avatar
Patrick José Pereira committed
388 389 390 391 392
                        anchors.margins: ScreenTools.defaultFontPixelHeight
                    }
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: false
393 394 395 396 397 398 399 400
                    }
                },
                State {
                    name:   "fullMode"
                    PropertyChanges {
                        target: _flightVideo
                        anchors.margins:    0
                    }
Patrick José Pereira's avatar
Patrick José Pereira committed
401 402 403 404 405 406 407 408
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: false
                    }
                },
                State {
                    name: "popup"
                    StateChangeScript {
409 410 411 412 413 414
                        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
415
                    }
416 417 418 419 420 421 422
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: true
                    }
                },
                State {
                    name: "popup-finished"
Patrick José Pereira's avatar
Patrick José Pereira committed
423 424 425 426 427
                    ParentChange {
                        target: _flightVideo
                        parent: videoItem
                        x: 0
                        y: 0
428 429
                        width: videoItem.width
                        height: videoItem.height
Patrick José Pereira's avatar
Patrick José Pereira committed
430 431 432 433 434
                    }
                },
                State {
                    name: "unpopup"
                    StateChangeScript {
435 436 437 438
                        script: {
                            QGroundControl.videoManager.stopVideo()
                            videoPopUpTimer.running = true
                        }
Patrick José Pereira's avatar
Patrick José Pereira committed
439 440 441
                    }
                    ParentChange {
                        target: _flightVideo
442
                        parent: _mapAndVideo
Patrick José Pereira's avatar
Patrick José Pereira committed
443 444 445 446 447
                    }
                    PropertyChanges {
                        target: _flightVideoPipControl
                        inPopup: false
                    }
448
                }
449
            ]
450
            //-- Video Streaming
451
            FlightDisplayViewVideo {
Patrick José Pereira's avatar
Patrick José Pereira committed
452
                id:             videoStreaming
453 454 455 456
                anchors.fill:   parent
                visible:        QGroundControl.videoManager.isGStreamer
            }
            //-- UVC Video (USB Camera or Video Device)
457 458
            Loader {
                id:             cameraLoader
459 460
                anchors.fill:   parent
                visible:        !QGroundControl.videoManager.isGStreamer
461
                source:         QGroundControl.videoManager.uvcEnabled ? "qrc:/qml/FlightDisplayViewUVC.qml" : "qrc:/qml/FlightDisplayViewDummy.qml"
462
            }
dogmaphobic's avatar
dogmaphobic committed
463
        }
464 465 466 467

        QGCPipable {
            id:                 _flightVideoPipControl
            z:                  _flightVideo.z + 3
468 469
            width:              _pipSize
            height:             _pipSize * (9/16)
470 471
            anchors.left:       _mapAndVideo.left
            anchors.bottom:     _mapAndVideo.bottom
472
            anchors.margins:    ScreenTools.defaultFontPixelHeight
473
            visible:            QGroundControl.videoManager.hasVideo && !QGroundControl.videoManager.fullScreen && _flightVideo.state != "popup"
474 475
            isHidden:           !_isPipVisible
            isDark:             isBackgroundDark
476
            enablePopup:        mainIsMap
477
            onActivated: {
478
                mainIsMap = !mainIsMap
479 480 481 482 483
                setStates()
            }
            onHideIt: {
                setPipVisibility(!state)
            }
Patrick José Pereira's avatar
Patrick José Pereira committed
484 485 486 487
            onPopup: {
                videoWindow.visible = true
                _flightVideo.state = "popup"
            }
488 489
            onNewWidth: {
                _pipSize = newWidth
Jacob Walser's avatar
Jacob Walser committed
490
            }
dogmaphobic's avatar
dogmaphobic committed
491
        }
Don Gagne's avatar
Don Gagne committed
492

493 494 495 496 497 498 499
        Row {
            id:                     singleMultiSelector
            anchors.topMargin:      ScreenTools.toolbarHeight + _margins
            anchors.rightMargin:    _margins
            anchors.right:          parent.right
            anchors.top:            parent.top
            spacing:                ScreenTools.defaultFontPixelWidth
500
            z:                      _mapAndVideo.z + 4
501
            visible:                QGroundControl.multiVehicleManager.vehicles.count > 1 && QGroundControl.corePlugin.options.enableMultiVehicleList
502 503 504 505 506

            QGCRadioButton {
                id:             singleVehicleView
                text:           qsTr("Single")
                checked:        true
507
                textColor:      mapPal.text
508 509 510
            }

            QGCRadioButton {
511
                text:           qsTr("Multi-Vehicle")
512
                textColor:      mapPal.text
513 514 515
            }
        }

516
        FlightDisplayViewWidgets {
517
            id:                 flightDisplayViewWidgets
518 519
            z:                  _mapAndVideo.z + 4
            height:             availableHeight - (singleMultiSelector.visible ? singleMultiSelector.height + _margins : 0) - (ScreenTools.defaultFontPixelHeight * 0.5)
520
            anchors.left:       parent.left
521
            anchors.right:      altitudeSlider.visible ? altitudeSlider.left : parent.right
522
            anchors.bottom:     parent.bottom
523
            useLightColors:     isBackgroundDark
524
            missionController:  _missionController
525
            visible:            singleVehicleView.checked && !QGroundControl.videoManager.fullScreen
526 527
        }

528 529 530 531 532
        //-------------------------------------------------------------------------
        //-- Loader helper for plugins to overlay elements over the fly view
        Loader {
            id:                 flyViewOverlay
            z:                  flightDisplayViewWidgets.z + 1
533
            visible:            !QGroundControl.videoManager.fullScreen
534
            height:             mainWindow.height - mainWindow.header.height
535 536 537 538 539
            anchors.left:       parent.left
            anchors.right:      altitudeSlider.visible ? altitudeSlider.left : parent.right
            anchors.bottom:     parent.bottom
        }

540
        MultiVehicleList {
541 542 543 544 545
            anchors.margins:            _margins
            anchors.top:                singleMultiSelector.bottom
            anchors.right:              parent.right
            anchors.bottom:             parent.bottom
            width:                      ScreenTools.defaultFontPixelWidth * 30
546
            visible:                    !singleVehicleView.checked && !QGroundControl.videoManager.fullScreen && QGroundControl.corePlugin.options.enableMultiVehicleList
547
            z:                          _mapAndVideo.z + 4
548
            guidedActionsController:    _guidedController
549
        }
dogmaphobic's avatar
dogmaphobic committed
550

551
        //-- Virtual Joystick
552
        Loader {
553
            id:                         virtualJoystickMultiTouch
554
            z:                          _mapAndVideo.z + 5
555
            width:                      parent.width  - (_flightVideoPipControl.width / 2)
556
            height:                     Math.min(mainWindow.height * 0.25, ScreenTools.defaultFontPixelWidth * 16)
Gus Grubba's avatar
Gus Grubba committed
557
            visible:                    (_virtualJoystick ? _virtualJoystick.value : false) && !QGroundControl.videoManager.fullScreen && !(activeVehicle ? activeVehicle.highLatencyLink : false)
558 559
            anchors.bottom:             _flightVideoPipControl.top
            anchors.bottomMargin:       ScreenTools.defaultFontPixelHeight * 2
560
            anchors.horizontalCenter:   flightDisplayViewWidgets.horizontalCenter
561
            source:                     "qrc:/qml/VirtualJoystick.qml"
Gus Grubba's avatar
Gus Grubba committed
562
            active:                     (_virtualJoystick ? _virtualJoystick.value : false) && !(activeVehicle ? activeVehicle.highLatencyLink : false)
Don Gagne's avatar
Don Gagne committed
563

564
            property bool useLightColors: isBackgroundDark
565 566
            // The default behaviour is not centralized throttle
            property bool centralizeThrottle: _virtualJoystickCentralized ? _virtualJoystickCentralized.value : false
567 568

            property Fact _virtualJoystick: QGroundControl.settingsManager.appSettings.virtualJoystick
569
            property Fact _virtualJoystickCentralized: QGroundControl.settingsManager.appSettings.virtualJoystickCentralized
Don Gagne's avatar
Don Gagne committed
570
        }
571 572

        ToolStrip {
Gus Grubba's avatar
Gus Grubba committed
573
            visible:            (activeVehicle ? activeVehicle.guidedModeSupported : true) && !QGroundControl.videoManager.fullScreen
574
            id:                 toolStrip
575 576

            anchors.leftMargin: isInstrumentRight() ? ScreenTools.defaultFontPixelWidth * 2 : undefined
577
            anchors.left:       isInstrumentRight() ? _mapAndVideo.left : undefined
Gus Grubba's avatar
Gus Grubba committed
578
            anchors.rightMargin:isInstrumentRight() ? undefined : ScreenTools.defaultFontPixelWidth
579
            anchors.right:      isInstrumentRight() ? undefined : _mapAndVideo.right
580 581
            anchors.topMargin:  mainWindow.header.height + (ScreenTools.defaultFontPixelHeight * 0.5)
            anchors.top:        parent.top
582
            z:                  _mapAndVideo.z + 4
583
            maxHeight:          (_flightVideo.visible ? _flightVideo.y : parent.height) - toolStrip.y
584 585 586

            buttonVisible:      [true, _useChecklist, _guidedController.showTakeoff || !_guidedController.showLand, _guidedController.showLand && !_guidedController.showTakeoff, true, _guidedController.showPause, !_guidedController.showPause ]
            buttonEnabled:      [true, _useChecklist && activeVehicle, _guidedController.showTakeoff, _guidedController.showLand, _guidedController.showRTL, _guidedController.showPause, _anyActionAvailable ]
587

588
            property bool _anyActionAvailable: _guidedController.showStartMission || _guidedController.showResumeMission || _guidedController.showChangeAlt || _guidedController.showLandAbort
589 590
            property var _actionModel: [
                {
591 592 593 594
                    title:      _guidedController.startMissionTitle,
                    text:       _guidedController.startMissionMessage,
                    action:     _guidedController.actionStartMission,
                    visible:    _guidedController.showStartMission
595
                },
Don Gagne's avatar
Don Gagne committed
596 597 598 599 600 601
                {
                    title:      _guidedController.continueMissionTitle,
                    text:       _guidedController.continueMissionMessage,
                    action:     _guidedController.actionContinueMission,
                    visible:    _guidedController.showContinueMission
                },
602
                {
603 604 605 606
                    title:      _guidedController.resumeMissionTitle,
                    text:       _guidedController.resumeMissionMessage,
                    action:     _guidedController.actionResumeMission,
                    visible:    _guidedController.showResumeMission
607 608
                },
                {
609 610 611 612
                    title:      _guidedController.changeAltTitle,
                    text:       _guidedController.changeAltMessage,
                    action:     _guidedController.actionChangeAlt,
                    visible:    _guidedController.showChangeAlt
613 614
                },
                {
615 616 617 618
                    title:      _guidedController.landAbortTitle,
                    text:       _guidedController.landAbortMessage,
                    action:     _guidedController.actionLandAbort,
                    visible:    _guidedController.showLandAbort
619 620 621 622
                }
            ]

            model: [
623
                {
624 625 626 627 628 629
                    name:               "Plan",
                    iconSource:         "/qmlimages/Plan.svg",
                },
                {
                    name:               "Checklist",
                    iconSource:         "/qmlimages/check.svg",
630 631
                    dropPanelComponent: checklistDropPanel
                },
632
                {
633
                    name:       _guidedController.takeoffTitle,
634
                    iconSource: "/res/takeoff.svg",
635
                    action:     _guidedController.actionTakeoff
636 637
                },
                {
638
                    name:       _guidedController.landTitle,
639
                    iconSource: "/res/land.svg",
640
                    action:     _guidedController.actionLand
641 642
                },
                {
643
                    name:       _guidedController.rtlTitle,
644
                    iconSource: "/res/rtl.svg",
645
                    action:     _guidedController.actionRTL
646 647
                },
                {
648
                    name:       _guidedController.pauseTitle,
Gus Grubba's avatar
Gus Grubba committed
649
                    iconSource: "/res/pause-mission.svg",
650
                    action:     _guidedController.actionPause
651 652 653
                },
                {
                    name:       qsTr("Action"),
Gus Grubba's avatar
Gus Grubba committed
654
                    iconSource: "/res/action.svg",
655
                    action:     -1
DonLakeFlyer's avatar
DonLakeFlyer committed
656
                }
657 658 659
            ]

            onClicked: {
660
                guidedActionsController.closeAll()
661 662
                if(index === 0) {
                    mainWindow.showPlanView()
663
                } else {
664 665 666 667 668 669 670
                    var action = model[index].action
                    if (action === -1) {
                        guidedActionList.model   = _actionModel
                        guidedActionList.visible = true
                    } else {
                        _guidedController.confirmAction(action)
                    }
671
                }
672

673 674 675 676
            }
        }

        GuidedActionsController {
677
            id:                 guidedActionsController
678
            missionController:  _missionController
679
            confirmDialog:      guidedActionConfirm
DonLakeFlyer's avatar
DonLakeFlyer committed
680
            actionList:         guidedActionList
Don Gagne's avatar
Don Gagne committed
681
            altitudeSlider:     _altitudeSlider
682 683
            z:                  _flightVideoPipControl.z + 1

684
            onShowStartMissionChanged: {
Don Gagne's avatar
Don Gagne committed
685
                if (showStartMission) {
686 687 688 689
                    confirmAction(actionStartMission)
                }
            }

690 691 692 693 694 695
            onShowContinueMissionChanged: {
                if (showContinueMission) {
                    confirmAction(actionContinueMission)
                }
            }

696 697 698 699 700
            onShowLandAbortChanged: {
                if (showLandAbort) {
                    confirmAction(actionLandAbort)
                }
            }
701 702 703 704 705 706 707

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

710
        GuidedActionConfirm {
711 712 713 714
            id:                         guidedActionConfirm
            anchors.margins:            _margins
            anchors.bottom:             parent.bottom
            anchors.horizontalCenter:   parent.horizontalCenter
715 716
            guidedController:           _guidedController
            altitudeSlider:             _altitudeSlider
717 718
        }

719
        GuidedActionList {
720 721 722 723
            id:                         guidedActionList
            anchors.margins:            _margins
            anchors.bottom:             parent.bottom
            anchors.horizontalCenter:   parent.horizontalCenter
724
            guidedController:           _guidedController
725 726 727
        }

        //-- Altitude slider
DonLakeFlyer's avatar
DonLakeFlyer committed
728
        GuidedAltitudeSlider {
729 730 731 732 733 734
            id:                 altitudeSlider
            anchors.margins:    _margins
            anchors.right:      parent.right
            anchors.topMargin:  ScreenTools.toolbarHeight + _margins
            anchors.top:        parent.top
            anchors.bottom:     parent.bottom
735
            z:                  _guidedController.z
736 737 738 739 740
            radius:             ScreenTools.defaultFontPixelWidth / 2
            width:              ScreenTools.defaultFontPixelWidth * 10
            color:              qgcPal.window
            visible:            false
        }
Don Gagne's avatar
Don Gagne committed
741
    }
742

743 744 745 746 747 748 749 750
    LogReplayStatusBar {
        id:                 logReplayStatusBar
        anchors.left:       parent.left
        anchors.right:      parent.right
        anchors.bottom:     parent.bottom
        visible:            QGroundControl.settingsManager.flyViewSettings.showLogReplayStatusBar.rawValue &&_flightMapContainer.state === "fullMode"
    }

751
    //-- Airspace Indicator
752
    Rectangle {
753 754 755
        id:             airspaceIndicator
        width:          airspaceRow.width + (ScreenTools.defaultFontPixelWidth * 3)
        height:         airspaceRow.height * 1.25
756
        color:          qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
757
        visible:        QGroundControl.airmapSupported && mainIsMap && flightPermit && flightPermit !== AirspaceFlightPlanProvider.PermitNone
758 759 760 761 762 763 764
        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 {
765
            id: airspaceRow
766 767
            spacing: ScreenTools.defaultFontPixelWidth
            anchors.centerIn: parent
768
            QGCLabel { text: airspaceIndicator.providerName+":"; anchors.verticalCenter: parent.verticalCenter; }
769 770
            QGCLabel {
                text: {
771
                    if(airspaceIndicator.flightPermit) {
Gus Grubba's avatar
Gus Grubba committed
772
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitPending)
773
                            return qsTr("Approval Pending")
774
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitAccepted || airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitNotRequired)
775
                            return qsTr("Flight Approved")
Gus Grubba's avatar
Gus Grubba committed
776
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitRejected)
777
                            return qsTr("Flight Rejected")
778 779 780 781
                    }
                    return ""
                }
                color: {
782
                    if(airspaceIndicator.flightPermit) {
Gus Grubba's avatar
Gus Grubba committed
783
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitPending)
784
                            return qgcPal.colorOrange
785
                        if(airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitAccepted || airspaceIndicator.flightPermit === AirspaceFlightPlanProvider.PermitNotRequired)
786 787 788 789 790 791 792
                            return qgcPal.colorGreen
                    }
                    return qgcPal.colorRed
                }
                anchors.verticalCenter: parent.verticalCenter;
            }
        }
Gus Grubba's avatar
Gus Grubba committed
793
        property var  flightPermit: QGroundControl.airmapSupported ? QGroundControl.airspaceManager.flightPlan.flightPermitStatus : null
794
        property string  providerName: QGroundControl.airspaceManager.providerName
795 796
    }

797
    //-- Checklist GUI
798 799
    Component {
        id: checklistDropPanel
800 801 802
        PreFlightCheckList {
            model: preFlightCheckModel
        }
803
    }
804
}