FlightDisplayView.qml 33.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
import QtQuick                  2.3
import QtQuick.Controls         1.2
13
import QtQuick.Controls.Styles  1.4
14
import QtQuick.Dialogs          1.2
15 16
import QtLocation               5.3
import QtPositioning            5.3
17
import QtQuick.Layouts          1.2
Patrick José Pereira's avatar
Patrick José Pereira committed
18
import QtQuick.Window           2.2
19
import QtQml.Models             2.1
20

21
import QGroundControl               1.0
22 23 24 25
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
26
import QGroundControl.FlightDisplay 1.0
27 28
import QGroundControl.FlightMap     1.0
import QGroundControl.Palette       1.0
29
import QGroundControl.ScreenTools   1.0
30
import QGroundControl.Vehicle       1.0
31 32

/// Flight Display View
33 34 35
QGCView {
    id:             root
    viewPanel:      _panel
36

37
    QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
38

Gus Grubba's avatar
Gus Grubba committed
39 40 41 42 43
    PlanMasterController {
        id:                     planMasterController
        Component.onCompleted:  start(true /* flyView */)
    }

Don Gagne's avatar
Don Gagne committed
44 45
    property alias  guidedController:   guidedActionsController

Gus Grubba's avatar
Gus Grubba committed
46
    property bool   activeVehicleJoystickEnabled: activeVehicle ? activeVehicle.joystickEnabled : false
47

Gus Grubba's avatar
Gus Grubba committed
48 49 50
    property var    _missionController:     planMasterController.missionController
    property var    _geoFenceController:    planMasterController.geoFenceController
    property var    _rallyPointController:  planMasterController.rallyPointController
51 52
    property bool   _mainIsMap:             QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey,  true) : true
    property bool   _isPipVisible:          QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false
53
    property bool   _useChecklist:          QGroundControl.settingsManager.appSettings.useChecklist.rawValue
54 55
    property real   _savedZoomLevel:        0
    property real   _margins:               ScreenTools.defaultFontPixelWidth / 2
56
    property real   _pipSize:               flightView.width * 0.2
57 58
    property alias  _guidedController:      guidedActionsController
    property alias  _altitudeSlider:        altitudeSlider
59

Gus Grubba's avatar
Gus Grubba committed
60
    readonly property var       _dynamicCameras:        activeVehicle ? activeVehicle.dynamicCameras : null
61
    readonly property bool      _isCamera:              _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false
Don Gagne's avatar
Don Gagne committed
62 63 64 65 66 67 68 69 70 71 72 73
    readonly property bool      isBackgroundDark:       _mainIsMap ? (_flightMap ? _flightMap.isSatelliteMap : true) : true
    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"

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

95 96 97
    function setPipVisibility(state) {
        _isPipVisible = state;
        QGroundControl.saveBoolGlobalSetting(_PIPVisibleKey, state)
98 99
    }

Gus Grubba's avatar
Gus Grubba committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113
    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;
    }

114
    PlanMasterController {
115
        id:                     masterController
116
        Component.onCompleted:  start(true /* flyView */)
117 118
    }

119
    BuiltInPreFlightCheckModel {
120
        id: preFlightCheckModel
121 122
    }

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

128 129
    Component.onCompleted: {
        setStates()
130 131 132
        if(QGroundControl.corePlugin.options.flyViewOverlay.toString().length) {
            flyViewOverlay.source = QGroundControl.corePlugin.options.flyViewOverlay
        }
133
    }
dogmaphobic's avatar
dogmaphobic committed
134

135 136
    // 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
137
    property bool vehicleArmed:                 activeVehicle ? activeVehicle.armed : true // true here prevents pop up from showing during shutdown
138
    property bool vehicleWasArmed:              false
Gus Grubba's avatar
Gus Grubba committed
139
    property bool vehicleInMissionFlightMode:   activeVehicle ? (activeVehicle.flightMode === activeVehicle.missionFlightMode) : false
140 141 142 143 144 145 146 147 148
    property bool promptForMissionRemove:       false

    onVehicleArmedChanged: {
        if (vehicleArmed) {
            if (!promptForMissionRemove) {
                promptForMissionRemove = vehicleInMissionFlightMode
                vehicleWasArmed = true
            }
        } else {
149
            if (promptForMissionRemove && (_missionController.containsItems || _geoFenceController.containsItems || _rallyPointController.containsItems)) {
150
                // 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
151
                if (!activeVehicle.apmFirmware) {
152 153
                    root.showDialog(missionCompleteDialogComponent, qsTr("Flight Plan complete"), showDialogDefaultWidth, StandardButton.Close)
                }
154 155 156 157 158 159 160 161 162 163 164 165
            }
            promptForMissionRemove = false
        }
    }

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

    Component {
166 167 168
        id: missionCompleteDialogComponent

        QGCViewDialog {
Gus Grubba's avatar
Gus Grubba committed
169
            property var activeVehicleCopy: activeVehicle
170 171 172 173 174
            onActiveVehicleCopyChanged:
                if (!activeVehicleCopy) {
                    hideDialog()
                }

175 176 177 178
            QGCFlickable {
                anchors.fill:   parent
                contentHeight:  column.height

179
                ColumnLayout {
180 181 182 183 184
                    id:                 column
                    anchors.margins:    _margins
                    anchors.left:       parent.left
                    anchors.right:      parent.right

185
                    ColumnLayout {
186
                        Layout.fillWidth:   true
187
                        spacing:            ScreenTools.defaultFontPixelHeight
Gus Grubba's avatar
Gus Grubba committed
188
                        visible:            !activeVehicle.connectionLost || !_guidedController.showResumeMission
189 190 191

                        QGCLabel {
                            Layout.fillWidth:       true
Gus Grubba's avatar
Gus Grubba committed
192
                            text:                   qsTr("%1 Images Taken").arg(activeVehicle.cameraTriggerPoints.count)
193
                            horizontalAlignment:    Text.AlignHCenter
Gus Grubba's avatar
Gus Grubba committed
194
                            visible:                activeVehicle.cameraTriggerPoints.count != 0
195
                        }
196

197 198 199 200
                        QGCButton {
                            Layout.fillWidth:   true
                            text:               qsTr("Remove plan from vehicle")
                            onClicked: {
Gus Grubba's avatar
Gus Grubba committed
201
                                planMasterController.removeAllFromVehicle()
202 203 204
                                hideDialog()
                            }
                        }
Don Gagne's avatar
Don Gagne committed
205

206 207 208 209 210 211
                        QGCButton {
                            Layout.fillWidth:   true
                            Layout.alignment:   Qt.AlignHCenter
                            text:               qsTr("Leave plan on vehicle")
                            onClicked:          hideDialog()
                        }
Don Gagne's avatar
Don Gagne committed
212

213 214 215 216 217
                        Rectangle {
                            Layout.fillWidth:   true
                            color:              qgcPal.text
                            height:             1
                        }
Don Gagne's avatar
Don Gagne committed
218

219 220 221 222 223 224 225 226 227 228
                        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
229 230
                        }

231 232 233 234 235 236 237 238 239 240 241 242 243 244
                        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
245 246
                    }

247
                    ColumnLayout {
Don Gagne's avatar
Don Gagne committed
248
                        Layout.fillWidth:   true
249
                        spacing:            ScreenTools.defaultFontPixelHeight
Gus Grubba's avatar
Gus Grubba committed
250
                        visible:            activeVehicle.connectionLost && _guidedController.showResumeMission
251 252 253 254 255 256 257

                        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
258
                    }
259
                }
260 261 262 263
            }
        }
    }

Patrick José Pereira's avatar
Patrick José Pereira committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
    Window {
        id:             videoWindow
        width:          !_mainIsMap ? _panel.width  : _pipSize
        height:         !_mainIsMap ? _panel.height : _pipSize * (9/16)
        visible:        false

        Item {
            id:             videoItem
            anchors.fill:   parent
        }

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

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
    /* 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
296 297
    }

298 299
    QGCMapPalette { id: mapPal; lightColors: _mainIsMap ? _flightMap.isSatelliteMap : true }

300 301 302 303 304 305 306 307 308 309 310 311
    QGCViewPanel {
        id:             _panel
        anchors.fill:   parent

        //-- Map View
        //   For whatever reason, if FlightDisplayViewMap is the _panel item, changing
        //   width/height has no effect.
        Item {
            id: _flightMapContainer
            z:  _mainIsMap ? _panel.z + 1 : _panel.z + 2
            anchors.left:   _panel.left
            anchors.bottom: _panel.bottom
312
            visible:        _mainIsMap || _isPipVisible && !QGroundControl.videoManager.fullScreen
313 314
            width:          _mainIsMap ? _panel.width  : _pipSize
            height:         _mainIsMap ? _panel.height : _pipSize * (9/16)
315 316 317 318 319 320 321 322 323 324 325 326 327 328
            states: [
                State {
                    name:   "pipMode"
                    PropertyChanges {
                        target:             _flightMapContainer
                        anchors.margins:    ScreenTools.defaultFontPixelHeight
                    }
                },
                State {
                    name:   "fullMode"
                    PropertyChanges {
                        target:             _flightMapContainer
                        anchors.margins:    0
                    }
329
                }
330 331
            ]
            FlightDisplayViewMap {
332 333 334 335 336 337
                id:                         _flightMap
                anchors.fill:               parent
                guidedActionsController:    _guidedController
                flightWidgets:              flightDisplayViewWidgets
                rightPanelWidth:            ScreenTools.defaultFontPixelHeight * 9
                qgcView:                    root
338
                multiVehicleView:           !singleVehicleView.checked
339
                scaleState:                 (_mainIsMap && flyViewOverlay.item) ? (flyViewOverlay.item.scaleState ? flyViewOverlay.item.scaleState : "bottomMode") : "bottomMode"
340
            }
341
        }
342

343
        //-- Video View
344
        Item {
345 346
            id:             _flightVideo
            z:              _mainIsMap ? _panel.z + 2 : _panel.z + 1
347 348
            width:          !_mainIsMap ? _panel.width  : _pipSize
            height:         !_mainIsMap ? _panel.height : _pipSize * (9/16)
349 350
            anchors.left:   _panel.left
            anchors.bottom: _panel.bottom
351
            visible:        QGroundControl.videoManager.hasVideo && (!_mainIsMap || _isPipVisible)
352 353 354 355 356 357 358 359 360 361 362 363 364 365

            onParentChanged: {
                /* If video comes back from popup
                 * correct anchors.
                 * Such thing is not possible with ParentChange.
                 */
                if(parent == _panel) {
                    // Do anchors again after popup
                    anchors.left =       _panel.left
                    anchors.bottom =     _panel.bottom
                    anchors.margins =    ScreenTools.defaultFontPixelHeight
                }
            }

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

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

476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
        Row {
            id:                     singleMultiSelector
            anchors.topMargin:      ScreenTools.toolbarHeight + _margins
            anchors.rightMargin:    _margins
            anchors.right:          parent.right
            anchors.top:            parent.top
            spacing:                ScreenTools.defaultFontPixelWidth
            z:                      _panel.z + 4
            visible:                QGroundControl.multiVehicleManager.vehicles.count > 1

            ExclusiveGroup { id: multiVehicleSelectorGroup }

            QGCRadioButton {
                id:             singleVehicleView
                exclusiveGroup: multiVehicleSelectorGroup
                text:           qsTr("Single")
                checked:        true
493
                textColor:      mapPal.text
494 495 496 497
            }

            QGCRadioButton {
                exclusiveGroup: multiVehicleSelectorGroup
498
                text:           qsTr("Multi-Vehicle")
499
                textColor:      mapPal.text
500 501 502
            }
        }

503
        FlightDisplayViewWidgets {
504 505
            id:                 flightDisplayViewWidgets
            z:                  _panel.z + 4
506
            height:             ScreenTools.availableHeight - (singleMultiSelector.visible ? singleMultiSelector.height + _margins : 0)
507
            anchors.left:       parent.left
508
            anchors.right:      altitudeSlider.visible ? altitudeSlider.left : parent.right
509 510
            anchors.bottom:     parent.bottom
            qgcView:            root
511
            useLightColors:     isBackgroundDark
512
            missionController:  _missionController
513
            visible:            singleVehicleView.checked && !QGroundControl.videoManager.fullScreen
514 515
        }

516 517 518 519 520
        //-------------------------------------------------------------------------
        //-- Loader helper for plugins to overlay elements over the fly view
        Loader {
            id:                 flyViewOverlay
            z:                  flightDisplayViewWidgets.z + 1
521
            visible:            !QGroundControl.videoManager.fullScreen
522 523 524 525
            height:             ScreenTools.availableHeight
            anchors.left:       parent.left
            anchors.right:      altitudeSlider.visible ? altitudeSlider.left : parent.right
            anchors.bottom:     parent.bottom
526 527

            property var qgcView: root
528 529
        }

530
        MultiVehicleList {
531 532 533 534 535 536 537 538
            anchors.margins:            _margins
            anchors.top:                singleMultiSelector.bottom
            anchors.right:              parent.right
            anchors.bottom:             parent.bottom
            width:                      ScreenTools.defaultFontPixelWidth * 30
            visible:                    !singleVehicleView.checked && !QGroundControl.videoManager.fullScreen
            z:                          _panel.z + 4
            guidedActionsController:    _guidedController
539
        }
dogmaphobic's avatar
dogmaphobic committed
540

541
        //-- Virtual Joystick
542
        Loader {
543
            id:                         virtualJoystickMultiTouch
544 545
            z:                          _panel.z + 5
            width:                      parent.width  - (_flightVideoPipControl.width / 2)
546
            height:                     Math.min(ScreenTools.availableHeight * 0.25, ScreenTools.defaultFontPixelWidth * 16)
Gus Grubba's avatar
Gus Grubba committed
547
            visible:                    (_virtualJoystick ? _virtualJoystick.value : false) && !QGroundControl.videoManager.fullScreen && !(activeVehicle ? activeVehicle.highLatencyLink : false)
548 549
            anchors.bottom:             _flightVideoPipControl.top
            anchors.bottomMargin:       ScreenTools.defaultFontPixelHeight * 2
550
            anchors.horizontalCenter:   flightDisplayViewWidgets.horizontalCenter
551
            source:                     "qrc:/qml/VirtualJoystick.qml"
Gus Grubba's avatar
Gus Grubba committed
552
            active:                     (_virtualJoystick ? _virtualJoystick.value : false) && !(activeVehicle ? activeVehicle.highLatencyLink : false)
Don Gagne's avatar
Don Gagne committed
553

554
            property bool useLightColors: isBackgroundDark
555 556

            property Fact _virtualJoystick: QGroundControl.settingsManager.appSettings.virtualJoystick
Don Gagne's avatar
Don Gagne committed
557
        }
558 559

        ToolStrip {
Gus Grubba's avatar
Gus Grubba committed
560
            visible:            (activeVehicle ? activeVehicle.guidedModeSupported : true) && !QGroundControl.videoManager.fullScreen
561
            id:                 toolStrip
Gus Grubba's avatar
Gus Grubba committed
562 563 564 565
            anchors.leftMargin: isInstrumentRight() ? ScreenTools.defaultFontPixelWidth : undefined
            anchors.left:       isInstrumentRight() ? _panel.left : undefined
            anchors.rightMargin:isInstrumentRight() ? undefined : ScreenTools.defaultFontPixelWidth
            anchors.right:      isInstrumentRight() ? undefined : _panel.right
566
            anchors.topMargin:  ScreenTools.toolbarHeight + (_margins * 2)
567 568 569 570
            anchors.top:        _panel.top
            z:                  _panel.z + 4
            title:              qsTr("Fly")
            maxHeight:          (_flightVideo.visible ? _flightVideo.y : parent.height) - toolStrip.y
DonLakeFlyer's avatar
DonLakeFlyer committed
571
            buttonVisible:      [ _useChecklist, _guidedController.showTakeoff || !_guidedController.showLand, _guidedController.showLand && !_guidedController.showTakeoff, true, true, true ]
Gus Grubba's avatar
Gus Grubba committed
572
            buttonEnabled:      [ _useChecklist && activeVehicle, _guidedController.showTakeoff, _guidedController.showLand, _guidedController.showRTL, _guidedController.showPause, _anyActionAvailable ]
573

574
            property bool _anyActionAvailable: _guidedController.showStartMission || _guidedController.showResumeMission || _guidedController.showChangeAlt || _guidedController.showLandAbort
575 576
            property var _actionModel: [
                {
577 578 579 580
                    title:      _guidedController.startMissionTitle,
                    text:       _guidedController.startMissionMessage,
                    action:     _guidedController.actionStartMission,
                    visible:    _guidedController.showStartMission
581
                },
Don Gagne's avatar
Don Gagne committed
582 583 584 585 586 587
                {
                    title:      _guidedController.continueMissionTitle,
                    text:       _guidedController.continueMissionMessage,
                    action:     _guidedController.actionContinueMission,
                    visible:    _guidedController.showContinueMission
                },
588
                {
589 590 591 592
                    title:      _guidedController.resumeMissionTitle,
                    text:       _guidedController.resumeMissionMessage,
                    action:     _guidedController.actionResumeMission,
                    visible:    _guidedController.showResumeMission
593 594
                },
                {
595 596 597 598
                    title:      _guidedController.changeAltTitle,
                    text:       _guidedController.changeAltMessage,
                    action:     _guidedController.actionChangeAlt,
                    visible:    _guidedController.showChangeAlt
599 600
                },
                {
601 602 603 604
                    title:      _guidedController.landAbortTitle,
                    text:       _guidedController.landAbortMessage,
                    action:     _guidedController.actionLandAbort,
                    visible:    _guidedController.showLandAbort
605 606 607 608
                }
            ]

            model: [
609 610 611 612 613
                {
                    name:               "Checklist",
                    iconSource:         "/qmlimages/check.svg",
                    dropPanelComponent: checklistDropPanel
                },
614
                {
615
                    name:       _guidedController.takeoffTitle,
616
                    iconSource: "/res/takeoff.svg",
617
                    action:     _guidedController.actionTakeoff
618 619
                },
                {
620
                    name:       _guidedController.landTitle,
621
                    iconSource: "/res/land.svg",
622
                    action:     _guidedController.actionLand
623 624
                },
                {
625
                    name:       _guidedController.rtlTitle,
626
                    iconSource: "/res/rtl.svg",
627
                    action:     _guidedController.actionRTL
628 629
                },
                {
630
                    name:       _guidedController.pauseTitle,
Gus Grubba's avatar
Gus Grubba committed
631
                    iconSource: "/res/pause-mission.svg",
632
                    action:     _guidedController.actionPause
633 634 635
                },
                {
                    name:       qsTr("Action"),
Gus Grubba's avatar
Gus Grubba committed
636
                    iconSource: "/res/action.svg",
637
                    action:     -1
DonLakeFlyer's avatar
DonLakeFlyer committed
638
                }
639 640 641
            ]

            onClicked: {
642
                guidedActionsController.closeAll()
643 644
                var action = model[index].action
                if (action === -1) {
DonLakeFlyer's avatar
DonLakeFlyer committed
645 646
                    guidedActionList.model   = _actionModel
                    guidedActionList.visible = true
647
                } else {
648
                    _guidedController.confirmAction(action)
649 650 651 652 653
                }
            }
        }

        GuidedActionsController {
654
            id:                 guidedActionsController
655
            missionController:  _missionController
656
            confirmDialog:      guidedActionConfirm
DonLakeFlyer's avatar
DonLakeFlyer committed
657
            actionList:         guidedActionList
Don Gagne's avatar
Don Gagne committed
658
            altitudeSlider:     _altitudeSlider
659 660
            z:                  _flightVideoPipControl.z + 1

661
            onShowStartMissionChanged: {
Don Gagne's avatar
Don Gagne committed
662
                if (showStartMission) {
663 664 665 666
                    confirmAction(actionStartMission)
                }
            }

667 668 669 670 671 672
            onShowContinueMissionChanged: {
                if (showContinueMission) {
                    confirmAction(actionContinueMission)
                }
            }

673 674 675 676 677
            onShowLandAbortChanged: {
                if (showLandAbort) {
                    confirmAction(actionLandAbort)
                }
            }
678 679 680

            /// Close all dialogs
            function closeAll() {
681
                mainWindow.enableToolbar()
682 683 684 685 686
                rootLoader.sourceComponent  = null
                guidedActionConfirm.visible = false
                guidedActionList.visible    = false
                altitudeSlider.visible      = false
            }
687 688
        }

689
        GuidedActionConfirm {
690 691 692 693
            id:                         guidedActionConfirm
            anchors.margins:            _margins
            anchors.bottom:             parent.bottom
            anchors.horizontalCenter:   parent.horizontalCenter
694 695
            guidedController:           _guidedController
            altitudeSlider:             _altitudeSlider
696 697
        }

698
        GuidedActionList {
699 700 701 702
            id:                         guidedActionList
            anchors.margins:            _margins
            anchors.bottom:             parent.bottom
            anchors.horizontalCenter:   parent.horizontalCenter
703
            guidedController:           _guidedController
704 705 706
        }

        //-- Altitude slider
DonLakeFlyer's avatar
DonLakeFlyer committed
707
        GuidedAltitudeSlider {
708 709 710 711 712 713
            id:                 altitudeSlider
            anchors.margins:    _margins
            anchors.right:      parent.right
            anchors.topMargin:  ScreenTools.toolbarHeight + _margins
            anchors.top:        parent.top
            anchors.bottom:     parent.bottom
714
            z:                  _guidedController.z
715 716 717 718 719
            radius:             ScreenTools.defaultFontPixelWidth / 2
            width:              ScreenTools.defaultFontPixelWidth * 10
            color:              qgcPal.window
            visible:            false
        }
Don Gagne's avatar
Don Gagne committed
720
    }
721

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

768
    //-- Checklist GUI
769 770
    Component {
        id: checklistDropPanel
771 772 773
        PreFlightCheckList {
            model: preFlightCheckModel
        }
774
    }
775
}