MissionEditor.qml 43 KB
Newer Older
Don Gagne's avatar
Don Gagne committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

Don Gagne's avatar
Don Gagne committed
24 25 26 27 28
import QtQuick          2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs  1.2
import QtLocation       5.3
import QtPositioning    5.3
Don Gagne's avatar
Don Gagne committed
29

30
import QGroundControl               1.0
Don Gagne's avatar
Don Gagne committed
31 32 33 34
import QGroundControl.FlightMap     1.0
import QGroundControl.ScreenTools   1.0
import QGroundControl.Controls      1.0
import QGroundControl.Palette       1.0
Don Gagne's avatar
Don Gagne committed
35
import QGroundControl.Mavlink       1.0
36
import QGroundControl.Controllers   1.0
Don Gagne's avatar
Don Gagne committed
37 38

/// Mission Editor
Don Gagne's avatar
Don Gagne committed
39

Don Gagne's avatar
Don Gagne committed
40 41
QGCView {
    viewPanel: panel
Don Gagne's avatar
Don Gagne committed
42

43 44 45
    // zOrder comes from the Loader in MainWindow.qml
    z: zOrder

Don Gagne's avatar
Don Gagne committed
46
    readonly property int   _decimalPlaces:     7
Don Gagne's avatar
Don Gagne committed
47
    readonly property real  _horizontalMargin:  ScreenTools.defaultFontPixelWidth / 2
48
    readonly property real  _margin:            ScreenTools.defaultFontPixelHeight / 2
Don Gagne's avatar
Don Gagne committed
49
    readonly property var   _activeVehicle:     multiVehicleManager.activeVehicle
50
    readonly property real  _editFieldWidth:    ScreenTools.defaultFontPixelWidth * 16
51 52 53 54
    readonly property real  _rightPanelWidth:   ScreenTools.defaultFontPixelWidth * 30
    readonly property real  _rightPanelOpacity: 0.8
    readonly property int   _toolButtonCount:   6
    readonly property int   _addMissionItemsButtonAutoOffTimeout:   10000
Don Gagne's avatar
Don Gagne committed
55

56
    property var    _missionItems:              _controller.missionItems
57 58 59

    property var    _homePositionManager:       QGroundControl.homePositionManager
    property string _homePositionName:          _homePositionManager.homePositions.get(0).name
60 61

    property var    offlineHomePosition:        _homePositionManager.homePositions.get(0).coordinate
62 63
    property var    liveHomePosition:           _controller.liveHomePosition
    property var    liveHomePositionAvailable:  _controller.liveHomePositionAvailable
64
    property var    homePosition:               offlineHomePosition // live or offline depending on state
65

66 67
    property bool _syncNeeded:                  _controller.missionItems.dirty

68 69
    MissionEditorController { id: _controller }

70
    QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
Don Gagne's avatar
Don Gagne committed
71

72 73 74 75 76 77
    ExclusiveGroup {
        id: _mapTypeButtonsExclusiveGroup
    }

    ExclusiveGroup {
        id: _dropButtonsExclusiveGroup
78 79
    }

80 81 82 83 84 85
    function setCurrentItem(index) {
        for (var i=0; i<_missionItems.count; i++) {
            _missionItems.get(i).isCurrentItem = (i == index)
        }
    }

86 87
    function updateHomePosition() {
        homePosition = liveHomePositionAvailable ? liveHomePosition : offlineHomePosition
Don Gagne's avatar
Don Gagne committed
88 89
        // Changing the coordinate will set the dirty bit, so we save and reset it
        var dirtyBit = _missionItems.dirty
90
        _missionItems.get(0).coordinate = homePosition
Don Gagne's avatar
Don Gagne committed
91 92 93
        _missionItems.dirty = dirtyBit
    }

94 95 96 97
    Component.onCompleted:              updateHomePosition()
    onOfflineHomePositionChanged:       updateHomePosition()
    onLiveHomePositionAvailableChanged: updateHomePosition()
    onLiveHomePositionChanged:          updateHomePosition()
Don Gagne's avatar
Don Gagne committed
98 99

    Connections {
100
        target: _controller
Don Gagne's avatar
Don Gagne committed
101

102 103
        // When the mission items change _missionsItems[0] changes as well so we need to reset it to home
        onMissionItemsChanged: updateHomePosition
Don Gagne's avatar
Don Gagne committed
104 105
    }

Don Gagne's avatar
Don Gagne committed
106 107 108
    QGCViewPanel {
        id:             panel
        anchors.fill:   parent
Don Gagne's avatar
Don Gagne committed
109

Don Gagne's avatar
Don Gagne committed
110
        Item {
Don Gagne's avatar
Don Gagne committed
111 112
            anchors.fill: parent

Don Gagne's avatar
Don Gagne committed
113 114
            FlightMap {
                id:             editorMap
115
                anchors.fill:   parent
Don Gagne's avatar
Don Gagne committed
116
                mapName:        "MissionEditor"
117 118

                Component.onCompleted: {
119 120
                    latitude = homePosition.latitude
                    longitude = homePosition.longitude
121
                }
Don Gagne's avatar
Don Gagne committed
122

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
                readonly property real animationDuration: 500

                Behavior on zoomLevel {
                    NumberAnimation {
                        duration:       editorMap.animationDuration
                        easing.type:    Easing.InOutQuad
                    }
                }

                Behavior on latitude {
                    NumberAnimation {
                        duration:       editorMap.animationDuration
                        easing.type:    Easing.InOutQuad
                    }
                }

                Behavior on longitude {
                    NumberAnimation {
                        duration:       editorMap.animationDuration
                        easing.type:    Easing.InOutQuad
                    }
                }

Don Gagne's avatar
Don Gagne committed
146 147 148 149 150 151 152
                MouseArea {
                    anchors.fill: parent

                    onClicked: {
                        var coordinate = editorMap.toCoordinate(Qt.point(mouse.x, mouse.y))
                        coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces)
                        coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces)
153
                        coordinate.altitude = coordinate.altitude.toFixed(_decimalPlaces)
154
                        if (homePositionManagerButton.checked) {
155
                            offlineHomePosition = coordinate
156
                        } else if (addMissionItemsButton.checked) {
157
                            var index = _controller.addMissionItem(coordinate)
158
                            addMissionItemsButtonAutoOffTimer.start()
159
                            setCurrentItem(index)
160 161
                        } else {
                            editorMap.zoomLevel = editorMap.maxZoomLevel - 2
162
                        }
Don Gagne's avatar
Don Gagne committed
163
                    }
Don Gagne's avatar
Don Gagne committed
164
                }
Don Gagne's avatar
Don Gagne committed
165

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
                // We use this item to support dragging since dragging a MapQuickItem just doesn't seem to work
                Item {
                    id:         itemEditor
                    x:          missionItemIndicator ? (missionItemIndicator.x + missionItemIndicator.anchorPoint.x - (itemEditor.width / 2)) : 100
                    y:          missionItemIndicator ? (missionItemIndicator.y + missionItemIndicator.anchorPoint.y - (itemEditor.height / 2)) : 100
                    width:      ScreenTools.defaultFontPixelHeight * 7
                    height:     ScreenTools.defaultFontPixelHeight * 7
                    visible:    false
                    z:          editorMap.zOrderMapItems + 1    // Above item icons

                    property var    missionItem
                    property var    missionItemIndicator
                    property real   heading: missionItem ? missionItem.heading : 0

                    Drag.active:    itemDrag.drag.active
                    Drag.hotSpot.x: width  / 2
                    Drag.hotSpot.y: height / 2

                    MissionItemIndexLabel {
                        x:              (itemEditor.width / 2) - (width / 2)
                        y:              (itemEditor.height / 2) - (height / 2)
                        label:          itemEditor.missionItemIndicator ? itemEditor.missionItemIndicator.label : ""
                        isCurrentItem:  true
189
                    }
190

191 192 193 194
                    MouseArea {
                        id:             itemDrag
                        anchors.fill:   parent
                        drag.target:    parent
195

196
                        property bool dragActive: drag.active
197

198 199 200 201
                        onDragActiveChanged: {
                            if (!drag.active) {
                                var point = Qt.point(itemEditor.x + (itemEditor.width  / 2), itemEditor.y + (itemEditor.height / 2))
                                itemEditor.missionItem.coordinate = editorMap.toCoordinate(point)
Don Gagne's avatar
Don Gagne committed
202 203 204
                            }
                        }
                    }
205
                }
206

Don Gagne's avatar
Don Gagne committed
207 208
                // Add the mission items to the map
                MapItemView {
209
                    model: _controller.missionItems
210

Don Gagne's avatar
Don Gagne committed
211 212
                    delegate:
                        MissionItemIndicator {
Don Gagne's avatar
Don Gagne committed
213
                            id:             itemIndicator
214 215
                            label:          object.sequenceNumber == 0 ? (liveHomePositionAvailable ? "H" : "F") : object.sequenceNumber
                            isCurrentItem:  !homePositionManagerButton.checked && object.isCurrentItem
Don Gagne's avatar
Don Gagne committed
216
                            coordinate:     object.coordinate
217
                            z:              editorMap.zOrderMapItems
Don Gagne's avatar
Don Gagne committed
218
                            visible:        object.specifiesCoordinate
Don Gagne's avatar
Don Gagne committed
219

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
                            onClicked: setCurrentItem(object.sequenceNumber)

                            Connections {
                                target: object

                                onIsCurrentItemChanged: {
                                    if (isCurrentItem) {
                                        // Setup our drag item
                                        if (object.sequenceNumber != 0) {
                                            itemEditor.visible = true
                                            itemEditor.missionItem = Qt.binding(function() { return object })
                                            itemEditor.missionItemIndicator = Qt.binding(function() { return itemIndicator })
                                        } else {
                                            itemEditor.visible = false
                                            itemEditor.missionItem = undefined
                                            itemEditor.missionItemIndicator = undefined
                                        }

                                        // Zoom the map and move to the new position
                                        editorMap.zoomLevel = editorMap.maxZoomLevel
                                        editorMap.latitude = object.coordinate.latitude
                                        editorMap.longitude = object.coordinate.longitude
                                    }
                                }
Don Gagne's avatar
Don Gagne committed
244
                            }
245

246
                            // These are the non-coordinate child mission items attached to this item
Don Gagne's avatar
Don Gagne committed
247 248 249
                            Row {
                                anchors.top:    parent.top
                                anchors.left:   parent.right
250

Don Gagne's avatar
Don Gagne committed
251 252
                                Repeater {
                                    model: object.childItems
253

Don Gagne's avatar
Don Gagne committed
254 255 256
                                    delegate:
                                        MissionItemIndexLabel {
                                            label:          object.sequenceNumber
257
                                            isCurrentItem:  !homePositionManagerButton.checked && object.isCurrentItem
Don Gagne's avatar
Don Gagne committed
258
                                            z:              2
259

Don Gagne's avatar
Don Gagne committed
260 261
                                            onClicked: {
                                                setCurrentItem(object.sequenceNumber)
262
                                                missionItemEditorButton.checked
Don Gagne's avatar
Don Gagne committed
263
                                            }
264

Don Gagne's avatar
Don Gagne committed
265 266 267 268
                                        }
                                }
                            }
                        }
269 270 271 272
                }

                // Add lines between waypoints
                MapItemView {
273
                    model: _controller.waypointLines
274 275 276 277

                    delegate:
                        MapPolyline {
                            line.width: 3
278 279
                            line.color: qgcPal.mapButtonHighlight
                            z:          editorMap.zOrderMapItems - 1 // Under item indicators
280 281 282 283 284

                            path: [
                                { latitude: object.coordinate1.latitude, longitude: object.coordinate1.longitude },
                                { latitude: object.coordinate2.latitude, longitude: object.coordinate2.longitude },
                            ]
Don Gagne's avatar
Don Gagne committed
285 286 287
                        }
                }

288
                // Mission Item Editor
Don Gagne's avatar
Don Gagne committed
289
                Item {
290 291 292 293 294 295 296 297 298 299 300
                    id:             missionItemEditor
                    anchors.top:    parent.top
                    anchors.bottom: parent.bottom
                    anchors.right:  parent.right
                    width:          _rightPanelWidth
                    visible:        !helpButton.checked && !homePositionManagerButton.checked && _missionItems.count > 1
                    opacity:        _rightPanelOpacity
                    z:              editorMap.zOrderTopMost

                    ListView {
                        id:             missionItemSummaryList
301
                        anchors.fill:   parent
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
                        spacing:        _margin / 2
                        orientation:    ListView.Vertical
                        model:          _controller.canEdit ? _controller.missionItems : 0

                        property real _maxItemHeight: 0

                        delegate:
                            MissionItemEditor {
                            missionItem:    object
                            width:          parent.width
                            readOnly:       object.sequenceNumber == 0 && liveHomePositionAvailable

                            onClicked:  setCurrentItem(object.sequenceNumber)

                            onRemove: {
                                var newCurrentItem = object.sequenceNumber - 1
                                _controller.removeMissionItem(object.sequenceNumber)
                                if (_missionItems.count > 1) {
                                    newCurrentItem = Math.min(_missionItems.count - 1, newCurrentItem)
                                    setCurrentItem(newCurrentItem)
322
                                }
323
                            }
324
                        }
325
                    } // ListView
Don Gagne's avatar
Don Gagne committed
326

327
                    QGCLabel {
328
                        anchors.fill:   parent
329 330 331 332 333 334
                        visible:        !_controller.canEdit
                        wrapMode:       Text.WordWrap
                        text:           "The set of mission items you have loaded cannot be edited by QGroundControl. " +
                                        "You will only be able to save these to a file, or send them to a vehicle."
                    }
                } // Item - Mission Item editor
335

336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
                // Home Position Manager
                Rectangle {
                    id:             homePositionManager
                    anchors.top:    parent.top
                    anchors.bottom: parent.bottom
                    anchors.right:  parent.right
                    width:          _rightPanelWidth
                    visible:        homePositionManagerButton.checked
                    color:          qgcPal.window
                    opacity:        _rightPanelOpacity
                    z:              editorMap.zOrderTopMost

                    Column {
                        anchors.margins:    _margin
                        anchors.fill:       parent
                        visible:            !liveHomePositionAvailable
352

353 354 355 356
                        QGCLabel {
                            font.pixelSize: ScreenTools.mediumFontPixelSize
                            text:           "Flying Field Manager"
                        }
357

358 359 360 361
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight
                        }
362

363 364 365 366 367
                        QGCLabel {
                            width:      parent.width
                            wrapMode:   Text.WordWrap
                            text:       "This is used to save locations associated with your flying field for use while creating missions with no vehicle connection."
                        }
368

369 370 371 372
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight
                        }
373

374 375 376
                        QGCLabel {
                            text:       "Select field to use:"
                        }
377

378 379 380 381 382 383 384 385 386 387 388 389 390
                        QGCComboBox {
                            id:         homePosCombo
                            width:      parent.width
                            textRole:   "text"
                            model:      _homePositionManager.homePositions

                            onCurrentIndexChanged: {
                                if (currentIndex != -1) {
                                    var homePos = _homePositionManager.homePositions.get(currentIndex)
                                    _homePositionName = homePos.name
                                    offlineHomePosition = homePos.coordinate
                                    editorMap.latitude = offlineHomePosition.latitude
                                    editorMap.longitude = offlineHomePosition.longitude
391 392
                                }
                            }
393
                        }
394

395 396 397 398
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight
                        }
399

400 401 402 403 404 405 406 407
                        QGCLabel {
                            width:      parent.width
                            wrapMode:   Text.WordWrap
                            text:       "To add a new flying field, click on the Map to set the position. " +
                                        "Then give it a new name and click Add/Update. " +
                                        "To change the current field position, click on the Map to set the new position. " +
                                        "Then click Add/Update without changing the name."
                        }
408

409 410 411 412
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight / 3
                        }
413

414 415 416
                        Item {
                            width:  parent.width
                            height: nameField.height
417

418 419 420
                            QGCLabel {
                                anchors.baseline:   nameField.baseline
                                text:               "Name:"
421 422
                            }

423 424 425 426 427
                            QGCTextField {
                                id:             nameField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           _homePositionName
428
                            }
429
                        }
430

431 432 433 434
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight / 3
                        }
435

436 437 438
                        Item {
                            width:  parent.width
                            height: offlineLatitudeField.height
439

440 441 442
                            QGCLabel {
                                anchors.baseline:   offlineLatitudeField.baseline
                                text:               "Lat:"
443 444
                            }

445 446 447 448 449
                            QGCTextField {
                                id:             offlineLatitudeField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           offlineHomePosition.latitude
450
                            }
451
                        }
452

453 454 455 456
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight / 3
                        }
457

458 459 460
                        Item {
                            width:  parent.width
                            height: offlineLongitudeField.height
461

462 463 464
                            QGCLabel {
                                anchors.baseline:   offlineLongitudeField.baseline
                                text:               "Lon:"
465 466
                            }

467 468 469 470 471
                            QGCTextField {
                                id:             offlineLongitudeField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           offlineHomePosition.longitude
472
                            }
473
                        }
474

475 476 477 478
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight / 3
                        }
479

480 481 482
                        Item {
                            width:  parent.width
                            height: offlineAltitudeField.height
483

484 485 486
                            QGCLabel {
                                anchors.baseline:   offlineAltitudeField.baseline
                                text:               "Alt:"
487 488
                            }

489 490 491 492 493
                            QGCTextField {
                                id:             offlineAltitudeField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           offlineHomePosition.altitude
494
                            }
495
                        }
496

497 498 499 500
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight
                        }
501

502 503
                        Row {
                            spacing: ScreenTools.defaultFontPixelWidth
504

505 506
                            QGCButton {
                                text: "Add/Update"
507

508 509 510 511
                                onClicked: {
                                    offlineHomePosition = QtPositioning.coordinate(latitudeField.text, longitudeField.text, altitudeField.text)
                                    _homePositionManager.updateHomePosition(nameField.text, offlineHomePosition)
                                    homePosCombo.currentIndex = homePosCombo.find(nameField.text)
512 513
                                }
                            }
514

515 516
                            QGCButton {
                                text: "Delete"
517

518 519 520 521 522 523 524 525
                                onClicked: {
                                    homePosCombo.currentIndex = -1
                                    _homePositionManager.deleteHomePosition(nameField.text)
                                    homePosCombo.currentIndex = 0
                                    var homePos = _homePositionManager.homePositions.get(0)
                                    _homePositionName = homePos.name
                                    offlineHomePosition = homePos.coordinate
                                }
526
                            }
527 528
                        }
                    } // Column - Offline view
529

530 531 532 533
                    Column {
                        anchors.margins:    _margin
                        anchors.fill:       parent
                        visible:            liveHomePositionAvailable
534

535 536 537 538
                        QGCLabel {
                            font.pixelSize: ScreenTools.mediumFontPixelSize
                            text:           "Vehicle Home Position"
                        }
539

540 541 542 543
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight
                        }
544

545 546 547 548 549 550 551
                        Item {
                            width:  parent.width
                            height: liveLatitudeField.height

                            QGCLabel {
                                anchors.baseline:   liveLatitudeField.baseline
                                text:               "Lat:"
552 553
                            }

554 555 556 557 558
                            QGCLabel {
                                id:             liveLatitudeField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           liveHomePosition.latitude
559
                            }
560
                        }
561

562 563 564 565
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight / 3
                        }
566

567 568 569
                        Item {
                            width:  parent.width
                            height: liveLongitudeField.height
570

571 572 573
                            QGCLabel {
                                anchors.baseline:   liveLongitudeField.baseline
                                text:               "Lon:"
574 575
                            }

576 577 578 579 580
                            QGCLabel {
                                id:             liveLongitudeField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           liveHomePosition.longitude
581
                            }
582
                        }
583

584 585 586 587
                        Item {
                            width: 10
                            height: ScreenTools.defaultFontPixelHeight / 3
                        }
588

589 590 591
                        Item {
                            width:  parent.width
                            height: liveAltitudeField.height
592

593 594 595
                            QGCLabel {
                                anchors.baseline:   liveAltitudeField.baseline
                                text:               "Alt:"
596 597
                            }

598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
                            QGCLabel {
                                id:             liveAltitudeField
                                anchors.right:  parent.right
                                width:          _editFieldWidth
                                text:           liveHomePosition.altitude
                            }
                        }
                    } // Column - Online view
                } // Item - Home Position Manager

                // Help Panel
                Rectangle {
                    id:             helpPanel
                    anchors.top:    parent.top
                    anchors.bottom: parent.bottom
                    anchors.right:  parent.right
                    width:          _rightPanelWidth
                    visible:        !homePositionManagerButton.checked && (_missionItems.count == 1 || helpButton.checked)
                    color:          qgcPal.window
                    opacity:        _rightPanelOpacity
                    z:              editorMap.zOrderTopMost
619

620
                    Item {
621 622
                        anchors.margins:    _margin
                        anchors.fill:       parent
623 624 625 626 627 628 629 630 631 632 633 634 635

                        QGCLabel {
                            id:             helpTitle
                            font.pixelSize: ScreenTools.mediumFontPixelSize
                            text:           "Mission Planner"
                        }

                        QGCLabel {
                            id:                 helpIconLabel
                            anchors.topMargin:  ScreenTools.defaultFontPixelHeight
                            anchors.top:        helpTitle.bottom
                            width:              parent.width
                            wrapMode:           Text.WordWrap
dogmaphobic's avatar
dogmaphobic committed
636
                            text:               "Mission Planner tool buttons:"
637 638
                        }

dogmaphobic's avatar
dogmaphobic committed
639 640 641 642 643 644 645 646 647
                        Image {
                            id:                 addMissionItemsHelpIcon
                            anchors.topMargin:  ScreenTools.defaultFontPixelHeight
                            anchors.top:        helpIconLabel.bottom
                            width:              ScreenTools.defaultFontPixelHeight * 3
                            fillMode:           Image.PreserveAspectFit
                            mipmap:             true
                            smooth:             true
                            source:             "/qmlimages/MapAddMission.svg"
648 649 650 651 652 653 654 655 656
                        }

                        QGCLabel {
                            id:                 addMissionItemsHelpText
                            anchors.leftMargin: ScreenTools.defaultFontPixelHeight
                            anchors.left:       mapTypeHelpIcon.right
                            anchors.right:      parent.right
                            anchors.top:        addMissionItemsHelpIcon.top
                            wrapMode:           Text.WordWrap
dogmaphobic's avatar
dogmaphobic committed
657 658
                            text:               "<b>Add Mission Items</b><br>" +
                                                "When enabled, add mission items by clicking on the map."
659 660
                        }

dogmaphobic's avatar
dogmaphobic committed
661 662 663 664 665 666 667 668 669
                        Image {
                            id:                 homePositionManagerHelpIcon
                            anchors.topMargin:  ScreenTools.defaultFontPixelHeight
                            anchors.top:        addMissionItemsHelpText.bottom
                            width:              ScreenTools.defaultFontPixelHeight * 3
                            fillMode:           Image.PreserveAspectFit
                            mipmap:             true
                            smooth:             true
                            source:             "/qmlimages/MapHome.svg"
670 671 672 673 674 675 676 677 678
                        }

                        QGCLabel {
                            id:                 homePositionManagerHelpText
                            anchors.leftMargin: ScreenTools.defaultFontPixelHeight
                            anchors.left:       mapTypeHelpIcon.right
                            anchors.right:      parent.right
                            anchors.top:        homePositionManagerHelpIcon.top
                            wrapMode:           Text.WordWrap
679 680 681
                            text:               "<b>Flying Field Manager</b><br>" +
                                                "When enabled, allows you to select/add/update flying field locations. " +
                                                "You can save multiple flying field locations for use while creating missions while you are not connected to your vehicle."
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
                        }

                        Image {
                            id:                 mapCenterHelpIcon
                            anchors.topMargin:  ScreenTools.defaultFontPixelHeight
                            anchors.top:        homePositionManagerHelpText.bottom
                            width:              ScreenTools.defaultFontPixelHeight * 3
                            fillMode:           Image.PreserveAspectFit
                            mipmap:             true
                            smooth:             true
                            source:             "/qmlimages/MapCenter.svg"
                        }

                        QGCLabel {
                            id:                 mapCenterHelpText
                            anchors.leftMargin: ScreenTools.defaultFontPixelHeight
                            anchors.left:       mapTypeHelpIcon.right
                            anchors.right:      parent.right
                            anchors.top:        mapCenterHelpIcon.top
                            wrapMode:           Text.WordWrap
dogmaphobic's avatar
dogmaphobic committed
702 703
                            text:               "<b>Map Center</b><br>" +
                                                "Options for centering the map."
704 705 706 707 708 709 710 711 712 713
                        }

                        Image {
                            id:                 syncHelpIcon
                            anchors.topMargin:  ScreenTools.defaultFontPixelHeight
                            anchors.top:        mapCenterHelpText.bottom
                            width:              ScreenTools.defaultFontPixelHeight * 3
                            fillMode:           Image.PreserveAspectFit
                            mipmap:             true
                            smooth:             true
dogmaphobic's avatar
dogmaphobic committed
714
                            source:             "/qmlimages/MapSync.svg"
715 716 717 718 719 720 721 722 723
                        }

                        QGCLabel {
                            id:                 syncHelpText
                            anchors.leftMargin: ScreenTools.defaultFontPixelHeight
                            anchors.left:       mapTypeHelpIcon.right
                            anchors.right:      parent.right
                            anchors.top:        syncHelpIcon.top
                            wrapMode:           Text.WordWrap
dogmaphobic's avatar
dogmaphobic committed
724 725
                            text:               "<b>Sync</b><br>" +
                                                "Options for saving/loading mission items."
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
                        }

                        Image {
                            id:                 mapTypeHelpIcon
                            anchors.topMargin:  ScreenTools.defaultFontPixelHeight
                            anchors.top:        syncHelpText.bottom
                            width:              ScreenTools.defaultFontPixelHeight * 3
                            fillMode:           Image.PreserveAspectFit
                            mipmap:             true
                            smooth:             true
                            source:             "/qmlimages/MapType.svg"
                        }

                        QGCLabel {
                            id:                 mapTypeHelpText
                            anchors.leftMargin: ScreenTools.defaultFontPixelHeight
                            anchors.left:       mapTypeHelpIcon.right
                            anchors.right:      parent.right
                            anchors.top:        mapTypeHelpIcon.top
                            wrapMode:           Text.WordWrap
dogmaphobic's avatar
dogmaphobic committed
746 747
                            text:               "<b>Map Type</b><br>" +
                                                "Map type options."
748
                        }
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952
                    } // Item - margin
                } // Item - Help Panel

                RoundButton {
                    id:                     addMissionItemsButton
                    anchors.margins:        _margin
                    anchors.left:           parent.left
                    y:                      (parent.height - (_toolButtonCount * height) - ((_toolButtonCount - 1) * _margin)) / 2
                    buttonImage:            "/qmlimages/MapAddMission.svg"
                    exclusiveGroup:         _dropButtonsExclusiveGroup

                    onCheckedChanged: {
                        if (checked) {
                            addMissionItemsButtonAutoOffTimer.start()
                        } else {
                            addMissionItemsButtonAutoOffTimer.stop()
                        }
                    }

                    Timer {
                        id:         addMissionItemsButtonAutoOffTimer
                        interval:   _addMissionItemsButtonAutoOffTimeout
                        repeat:     false

                        onTriggered: addMissionItemsButton.checked = false
                    }
                }

                RoundButton {
                    id:                 homePositionManagerButton
                    anchors.margins:    _margin
                    anchors.left:       parent.left
                    anchors.top:        addMissionItemsButton.bottom
                    buttonImage:        "/qmlimages/MapHome.svg"
                    exclusiveGroup:     _dropButtonsExclusiveGroup
                    z:                  editorMap.zOrderWidgets
                }

                DropButton {
                    id:                 centerMapButton
                    anchors.margins:    _margin
                    anchors.left:       parent.left
                    anchors.top:        homePositionManagerButton.bottom
                    dropDirection:      dropRight
                    buttonImage:        "/qmlimages/MapCenter.svg"
                    viewportMargins:    ScreenTools.defaultFontPixelWidth / 2
                    exclusiveGroup:     _dropButtonsExclusiveGroup
                    z:                  editorMap.zOrderWidgets

                    dropDownComponent: Component {
                        Column {
                            QGCLabel { text: "Center map:" }

                            Row {
                                spacing: ScreenTools.defaultFontPixelWidth

                                QGCButton {
                                    text: "Home"

                                    onClicked: {
                                        centerMapButton.hideDropDown()
                                        editorMap.center = QtPositioning.coordinate(homePosition.latitude, homePosition.longitude)
                                    }
                                }

                                QGCButton {
                                    text:       "Vehicle"
                                    enabled:    activeVehicle && activeVehicle.latitude != 0 && activeVehicle.longitude != 0

                                    property var activeVehicle: multiVehicleManager.activeVehicle

                                    onClicked: {
                                        centerMapButton.hideDropDown()
                                        editorMap.latitude = activeVehicle.latitude
                                        editorMap.longitude = activeVehicle.longitude
                                    }
                                }
                            }
                        }
                    }
                }

                DropButton {
                    id:                 syncButton
                    anchors.margins:    _margin
                    anchors.left:       parent.left
                    anchors.top:        centerMapButton.bottom
                    dropDirection:      dropRight
                    buttonImage:        _syncNeeded ? "/qmlimages/MapSyncChanged.svg" : "/qmlimages/MapSync.svg"
                    viewportMargins:    ScreenTools.defaultFontPixelWidth / 2
                    exclusiveGroup:     _dropButtonsExclusiveGroup
                    z:                  editorMap.zOrderWidgets

                    dropDownComponent: Component {
                        Column {
                            id:         columnHolder
                            spacing:    _margin

                            QGCLabel {
                                width:      columnHolder.width
                                wrapMode:   Text.WordWrap
                                text:       _syncNeeded ?
                                                "You have unsaved changed to you mission. You should send to your vehicle, or save to a file:" :
                                                "Sync:"
                            }

                            Row {
                                spacing: ScreenTools.defaultFontPixelWidth

                                QGCButton {
                                    text:       "Send to vehicle"
                                    enabled:    _activeVehicle && !_activeVehicle.missionManager.inProgress

                                    onClicked: {
                                        syncButton.hideDropDown()
                                        _controller.setMissionItems()
                                    }
                                }

                                QGCButton {
                                    text:       "Load from vehicle"
                                    enabled:    _activeVehicle && !_activeVehicle.missionManager.inProgress

                                    onClicked: {
                                        syncButton.hideDropDown()
                                        _controller.getMissionItems()
                                    }
                                }
                            }

                            Row {
                                spacing: ScreenTools.defaultFontPixelWidth

                                QGCButton {
                                    text:       "Save to file..."

                                    onClicked: {
                                        syncButton.hideDropDown()
                                        _controller.saveMissionToFile()
                                    }
                                }

                                QGCButton {
                                    text:       "Load from file..."

                                    onClicked: {
                                        syncButton.hideDropDown()
                                        _controller.loadMissionFromFile()
                                    }
                                }
                            }
                        }
                    }
                }

                DropButton {
                    id:                 mapTypeButton
                    anchors.margins:    _margin
                    anchors.left:       parent.left
                    anchors.top:        syncButton.bottom
                    dropDirection:      dropRight
                    buttonImage:        "/qmlimages/MapType.svg"
                    viewportMargins:    ScreenTools.defaultFontPixelWidth / 2
                    exclusiveGroup:     _dropButtonsExclusiveGroup
                    z:                  editorMap.zOrderWidgets

                    dropDownComponent: Component {
                        Column {
                            QGCLabel { text: "Map type:" }

                            Row {
                                spacing: ScreenTools.defaultFontPixelWidth

                                Repeater {
                                    model: QGroundControl.flightMapSettings.mapTypes

                                    QGCButton {
                                        checkable:      true
                                        checked:        editorMap.mapType == text
                                        text:           modelData
                                        exclusiveGroup: _mapTypeButtonsExclusiveGroup

                                        onClicked: {
                                            editorMap.mapType = text
                                            checked = true
                                            mapTypeButton.hideDropDown()
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                RoundButton {
                    id:                 helpButton
                    anchors.margins:    _margin
                    anchors.left:       parent.left
                    anchors.top:        mapTypeButton.bottom
                    buttonImage:        "/qmlimages/Help.svg"
                    exclusiveGroup:     _dropButtonsExclusiveGroup
                    z:                  editorMap.zOrderWidgets
                }
            } // FlightMap
Don Gagne's avatar
Don Gagne committed
953 954 955
        } // Item - split view container
    } // QGCViewPanel
} // QGCVIew