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
    property real   _toolsMargin:                   ScreenTools.defaultFontPixelWidth * 0.75
58

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

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

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

Gus Grubba's avatar
Gus Grubba committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118
    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;
    }

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

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

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

148 149 150 151 152 153 154 155
    // 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))
156 157 158

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

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

    Component {
177 178 179
        id: missionCompleteDialogComponent

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

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

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

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

204 205 206 207 208 209 210
                    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()
211
                        }
212
                    }
213

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

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

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

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

243 244 245 246 247
                        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
248 249
                    }

250
                    QGCLabel {
Don Gagne's avatar
Don Gagne committed
251
                        Layout.fillWidth:   true
252 253 254 255
                        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
256
                    }
257
                }
258 259 260 261
            }
        }
    }

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

        Item {
            id:             videoItem
            anchors.fill:   parent
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

662 663 664 665
            }
        }

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

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

679 680 681 682 683 684
            onShowContinueMissionChanged: {
                if (showContinueMission) {
                    confirmAction(actionContinueMission)
                }
            }

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

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

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

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

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

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

778
    //-- Checklist GUI
779 780 781 782
    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
783 784
        height:         checkList.height
        width:          checkList.width
785 786 787 788
        modal:          true
        focus:          true
        closePolicy:    Popup.CloseOnEscape | Popup.CloseOnPressOutside
        background: Rectangle {
789 790 791
            anchors.fill:  parent
            color:      Qt.rgba(0,0,0,0)
            clip:       true
792
        }
793 794 795
        Loader {
            id:         checkList
            anchors.centerIn: parent
796
        }
797
    }
798

799
}