PlanToolBar.qml 15.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import QtQuick          2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts  1.2
import QtQuick.Dialogs  1.2

import QGroundControl                   1.0
import QGroundControl.ScreenTools       1.0
import QGroundControl.Controls          1.0
import QGroundControl.FactControls      1.0
import QGroundControl.Palette           1.0

// Toolbar for Plan View
Rectangle {
    id:                 _root
    height:             ScreenTools.toolbarHeight
    anchors.left:       parent.left
    anchors.right:      parent.right
    anchors.top:        parent.top
    z:                  toolBar.z + 1
Gus Grubba's avatar
Gus Grubba committed
20
    color:              qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.8) : Qt.rgba(0,0,0,0.75)
21
    visible:            false
22
    anchors.bottomMargin: 1
23 24 25

    signal showFlyView

26
    property var    planMasterController
27 28
    property var    currentMissionItem          ///< Mission item to display status for

29 30 31 32 33
    property var    missionItems:               _controllerValid ? planMasterController.missionController.visualItems : undefined
    property real   missionDistance:            _controllerValid ? planMasterController.missionController.missionDistance : NaN
    property real   missionTime:                _controllerValid ? planMasterController.missionController.missionTime : NaN
    property real   missionMaxTelemetry:        _controllerValid ? planMasterController.missionController.missionMaxTelemetry : NaN
    property bool   missionDirty:               _controllerValid ? planMasterController.missionController.dirty : false
34

35
    property bool   _controllerValid:           planMasterController !== undefined
DonLakeFlyer's avatar
DonLakeFlyer committed
36 37 38
    property bool   _controllerOffline:         _controllerValid ? planMasterController.offline : true
    property var    _controllerDirty:           _controllerValid ? planMasterController.dirty : false
    property var    _controllerSyncInProgress:  _controllerValid ? planMasterController.syncInProgress : false
39

40 41
    property bool   _statusValid:               currentMissionItem !== undefined
    property bool   _missionValid:              missionItems !== undefined
42

43
    property real   _dataFontSize:              ScreenTools.defaultFontPointSize
44
    property real   _largeValueWidth:           ScreenTools.defaultFontPixelWidth * 8
45 46
    property real   _mediumValueWidth:          ScreenTools.defaultFontPixelWidth * 4
    property real   _smallValueWidth:           ScreenTools.defaultFontPixelWidth * 3
47
    property real   _labelToValueSpacing:       ScreenTools.defaultFontPixelWidth
48
    property real   _rowSpacing:                ScreenTools.isMobile ? 1 : 0
49 50 51
    property real   _distance:                  _statusValid && currentMissionItem ? currentMissionItem.distance : NaN
    property real   _altDifference:             _statusValid && currentMissionItem ? currentMissionItem.altDifference : NaN
    property real   _gradient:                  _statusValid && currentMissionItem && currentMissionItem.distance > 0 ? Math.atan(currentMissionItem.altDifference / currentMissionItem.distance) : NaN
52
    property real   _gradientPercent:           isNaN(_gradient) ? NaN : _gradient * 100
53 54
    property real   _azimuth:                   _statusValid && currentMissionItem ? currentMissionItem.azimuth : NaN
    property real   _heading:                   _statusValid && currentMissionItem ? currentMissionItem.missionVehicleYaw : NaN
55 56 57
    property real   _missionDistance:           _missionValid ? missionDistance : NaN
    property real   _missionMaxTelemetry:       _missionValid ? missionMaxTelemetry : NaN
    property real   _missionTime:               _missionValid ? missionTime : NaN
58 59
    property int    _batteryChangePoint:        _controllerValid ? planMasterController.missionController.batteryChangePoint : -1
    property int    _batteriesRequired:         _controllerValid ? planMasterController.missionController.batteriesRequired : -1
60
    property bool   _batteryInfoAvailable:      _batteryChangePoint >= 0 || _batteriesRequired >= 0
61 62
    property real   _controllerProgressPct:     _controllerValid ? planMasterController.missionController.progressPct : 0
    property bool   _syncInProgress:            _controllerValid ? planMasterController.missionController.syncInProgress : false
63 64 65

    property string _distanceText:              isNaN(_distance) ?              "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_distance).toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString
    property string _altDifferenceText:         isNaN(_altDifference) ?         "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_altDifference).toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString
66
    property string _gradientText:              isNaN(_gradient) ?              "-.-" : _gradientPercent.toFixed(0) + " %"
67 68
    property string _azimuthText:               isNaN(_azimuth) ?               "-.-" : Math.round(_azimuth) % 360
    property string _headingText:               isNaN(_azimuth) ?               "-.-" : Math.round(_heading) % 360
69 70
    property string _missionDistanceText:       isNaN(_missionDistance) ?       "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_missionDistance).toFixed(0) + " " + QGroundControl.appSettingsDistanceUnitsString
    property string _missionMaxTelemetryText:   isNaN(_missionMaxTelemetry) ?   "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_missionMaxTelemetry).toFixed(0) + " " + QGroundControl.appSettingsDistanceUnitsString
71 72
    property string _batteryChangePointText:    _batteryChangePoint < 0 ?       "N/A" : _batteryChangePoint
    property string _batteriesRequiredText:     _batteriesRequired < 0 ?        "N/A" : _batteriesRequired
73

Donald Gagne's avatar
Donald Gagne committed
74
    readonly property real _margins: ScreenTools.defaultFontPixelWidth
75 76 77

    QGCPalette { id: qgcPal }

78 79 80 81 82 83 84 85
    function getMissionTime() {
        if(isNaN(_missionTime)) {
            return "00:00:00"
        }
        var t = new Date(0, 0, 0, 0, 0, Number(_missionTime))
        return Qt.formatTime(t, 'hh:mm:ss')
    }

Gus Grubba's avatar
Gus Grubba committed
86
    //-- Eat mouse events, preventing them from reaching toolbar, which is underneath us.
87 88
    DeadMouseArea {
        anchors.fill: parent
Gus Grubba's avatar
Gus Grubba committed
89 90
    }

91 92
    //-- The reason for this Row to be here is so the Logo (Home) button is in the same
    //   location as the one in the main toolbar.
93
    Row {
94
        id:                     logoRow
95 96 97 98
        anchors.bottomMargin:   1
        anchors.left:           parent.left
        anchors.top:            parent.top
        anchors.bottom:         parent.bottom
99 100 101 102 103 104 105 106 107
        QGCToolBarButton {
            id:                 settingsButton
            anchors.top:        parent.top
            anchors.bottom:     parent.bottom
            source:             "/qmlimages/PaperPlane.svg"
            logo:               true
            checked:            false
            onClicked: {
                checked = false
108
                showFlyView()
109 110
            }
        }
111 112
    }

113 114 115 116
    // Progress bar

    on_ControllerProgressPctChanged: {
        if (_controllerProgressPct === 1) {
117 118
            missionStats.visible = false
            uploadCompleteText.visible = true
119
            progressBar.visible = false
120 121 122 123 124 125 126 127
            resetProgressTimer.start()
        } else if (_controllerProgressPct > 0) {
            progressBar.visible = true
        }
    }

    Timer {
        id:             resetProgressTimer
128 129 130 131 132
        interval:       5000
        onTriggered: {
            missionStats.visible = true
            uploadCompleteText.visible = false
        }
133 134
    }

135 136 137 138 139 140 141 142 143 144 145 146 147
    QGCLabel {
        id:                     uploadCompleteText
        anchors.top:            parent.top
        anchors.bottom:         parent.bottom
        anchors.left:           logoRow.right
        anchors.right:          uploadButton.left
        font.pointSize:         ScreenTools.largeFontPointSize
        horizontalAlignment:    Text.AlignHCenter
        verticalAlignment:      Text.AlignVCenter
        text:                   "Done"
        visible:                false
    }

148
    GridLayout {
149 150 151
        id:                     missionStats
        anchors.top:            parent.top
        anchors.bottom:         parent.bottom
152 153
        anchors.leftMargin:     _margins
        anchors.rightMargin:    _margins
154 155
        anchors.left:           logoRow.right
        anchors.right:          uploadButton.visible ? uploadButton.left : parent.right
156 157
        columnSpacing:          0
        columns:                3
158 159

        GridLayout {
160
            columns:                8
161
            rowSpacing:             _rowSpacing
162
            columnSpacing:          _labelToValueSpacing
163
            Layout.alignment:       Qt.AlignVCenter | Qt.AlignHCenter
164 165

            QGCLabel {
166
                text:               qsTr("Selected Waypoint")
167
                Layout.columnSpan:  8
Donald Gagne's avatar
Donald Gagne committed
168
                font.pointSize:     ScreenTools.smallFontPointSize
169 170
            }

171
            QGCLabel { text: qsTr("Alt diff:"); font.pointSize: _dataFontSize; }
172
            QGCLabel {
173
                text:                   _altDifferenceText
174
                font.pointSize:         _dataFontSize
175
                Layout.minimumWidth:    _mediumValueWidth
176
            }
177

Donald Gagne's avatar
Donald Gagne committed
178 179
            Item { width: 1; height: 1 }

180
            QGCLabel { text: qsTr("Azimuth:"); font.pointSize: _dataFontSize; }
181
            QGCLabel {
182
                text:                   _azimuthText
183
                font.pointSize:         _dataFontSize
184 185
                Layout.minimumWidth:    _smallValueWidth
            }
186

187 188 189
            Item { width: 1; height: 1 }

            QGCLabel { text: qsTr("Distance:"); font.pointSize: _dataFontSize; }
190
            QGCLabel {
191
                text:                   _distanceText
192
                font.pointSize:         _dataFontSize
193
                Layout.minimumWidth:    _largeValueWidth
194 195 196 197 198 199 200
            }

            QGCLabel { text: qsTr("Gradient:"); font.pointSize: _dataFontSize; }
            QGCLabel {
                text:                   _gradientText
                font.pointSize:         _dataFontSize
                Layout.minimumWidth:    _mediumValueWidth
201
            }
202

Donald Gagne's avatar
Donald Gagne committed
203 204
            Item { width: 1; height: 1 }

205
            QGCLabel { text: qsTr("Heading:"); font.pointSize: _dataFontSize; }
206
            QGCLabel {
207
                text:                   _headingText
208
                font.pointSize:         _dataFontSize
209 210
                Layout.minimumWidth:    _smallValueWidth
            }
211 212 213
        }

        GridLayout {
214
            columns:                5
215
            rowSpacing:             _rowSpacing
216
            columnSpacing:          _labelToValueSpacing
217
            Layout.alignment:       Qt.AlignVCenter | Qt.AlignHCenter
218 219

            QGCLabel {
220
                text:               qsTr("Total Mission")
Donald Gagne's avatar
Donald Gagne committed
221 222
                Layout.columnSpan:  5
                font.pointSize:     ScreenTools.smallFontPointSize
223 224
            }

225
            QGCLabel { text: qsTr("Distance:"); font.pointSize: _dataFontSize; }
226 227
            QGCLabel {
                text:                   _missionDistanceText
228
                font.pointSize:         _dataFontSize
229 230
                Layout.minimumWidth:    _largeValueWidth
            }
231

Donald Gagne's avatar
Donald Gagne committed
232 233
            Item { width: 1; height: 1 }

234
            QGCLabel { text: qsTr("Max telem dist:"); font.pointSize: _dataFontSize; }
235 236
            QGCLabel {
                text:                   _missionMaxTelemetryText
237
                font.pointSize:         _dataFontSize
238 239
                Layout.minimumWidth:    _largeValueWidth
            }
240

241
            QGCLabel { text: qsTr("Time:"); font.pointSize: _dataFontSize; }
242
            QGCLabel {
243 244
                text:                   getMissionTime()
                font.pointSize:         _dataFontSize
245 246
                Layout.minimumWidth:    _largeValueWidth
            }
247
        }
Donald Gagne's avatar
Donald Gagne committed
248 249

        GridLayout {
250
            columns:                3
251
            rowSpacing:             _rowSpacing
252
            columnSpacing:          _labelToValueSpacing
253
            Layout.alignment:       Qt.AlignVCenter | Qt.AlignHCenter
254
            visible:                _batteryInfoAvailable
Donald Gagne's avatar
Donald Gagne committed
255 256 257 258 259 260 261

            QGCLabel {
                text:               qsTr("Battery")
                Layout.columnSpan:  3
                font.pointSize:     ScreenTools.smallFontPointSize
            }

262
            QGCLabel { text: qsTr("Batteries required:"); font.pointSize: _dataFontSize; }
263 264
            QGCLabel {
                text:                   _batteriesRequiredText
265
                font.pointSize:         _dataFontSize
266
                Layout.minimumWidth:    _mediumValueWidth
267
            }
Donald Gagne's avatar
Donald Gagne committed
268 269

            Item { width: 1; height: 1 }
270 271
/*
            FIXME: Swap point display is currently hidden since the code which calcs it doesn't work correctly
272
            QGCLabel { text: qsTr("Swap waypoint:"); font.pointSize: _dataFontSize; }
273 274
            QGCLabel {
                text:                   _batteryChangePointText
275
                font.pointSize:         _dataFontSize
276
                Layout.minimumWidth:    _mediumValueWidth
277
            }
278
*/
Donald Gagne's avatar
Donald Gagne committed
279
        }
280
    }
281 282 283 284 285 286

    QGCButton {
        id:                     uploadButton
        anchors.rightMargin:    _margins
        anchors.right:          parent.right
        anchors.verticalCenter: parent.verticalCenter
Don Gagne's avatar
Don Gagne committed
287
        text:                   _controllerDirty ? qsTr("Upload Required") : qsTr("Upload")
288
        enabled:                !_controllerSyncInProgress
289 290
        visible:                !_controllerOffline && !_controllerSyncInProgress && !uploadCompleteText.visible
        primary:                _controllerDirty
291
        onClicked:              planMasterController.upload()
292 293 294 295 296 297

        PropertyAnimation on opacity {
            easing.type:    Easing.OutQuart
            from:           0.5
            to:             1
            loops:          Animation.Infinite
298
            running:        _controllerDirty && !_controllerSyncInProgress
299 300 301
            alwaysRunToEnd: true
            duration:       2000
        }
302
    }
303 304 305 306 307 308 309 310 311 312

    // Small mission download progress bar
    Rectangle {
        id:             progressBar
        anchors.left:   parent.left
        anchors.bottom: parent.bottom
        height:         4
        width:          _controllerProgressPct * parent.width
        color:          qgcPal.colorGreen
        visible:        false
313 314 315 316 317 318

        onVisibleChanged: {
            if (visible) {
                largeProgressBar._userHide = false
            }
        }
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
    }

    /*
    Rectangle {
        anchors.bottom: parent.bottom
        height:         toolBar.height * 0.05
        width:          _activeVehicle ? _activeVehicle.parameterManager.loadProgress * parent.width : 0
        color:          qgcPal.colorGreen
        visible:        !largeProgressBar.visible
    }
    */

    // Large mission download progress bar
    Rectangle {
        id:             largeProgressBar
        anchors.bottom: parent.bottom
        anchors.left:   parent.left
        anchors.right:  parent.right
        height:         parent.height
        color:          qgcPal.window
        visible:        _showLargeProgress

        property bool _userHide:                false
        property bool _showLargeProgress:       progressBar.visible && !_userHide && qgcPal.globalTheme === QGCPalette.Light

        Connections {
            target:                 QGroundControl.multiVehicleManager
            onActiveVehicleChanged: largeProgressBar._userHide = false
        }

        Rectangle {
            anchors.top:    parent.top
            anchors.bottom: parent.bottom
            width:          _controllerProgressPct * parent.width
            color:          qgcPal.colorGreen
        }

        QGCLabel {
            anchors.centerIn:   parent
            text:               qsTr("Syncing Mission")
            font.pointSize:     ScreenTools.largeFontPointSize
        }

        QGCLabel {
            anchors.margins:    _margin
            anchors.right:      parent.right
            anchors.bottom:     parent.bottom
            text:               qsTr("Click anywhere to hide")

            property real _margin: ScreenTools.defaultFontPixelWidth / 2
        }

        MouseArea {
            anchors.fill:   parent
            onClicked:      largeProgressBar._userHide = true
        }
    }
376 377
}