diff --git a/src/FlightMap/MapItems/MissionItemIndicator.qml b/src/FlightMap/MapItems/MissionItemIndicator.qml index 8036cb1151120a28b8bbe08fc39300ee2c26ac05..d67bdbeb992431a778c1c968bf646b4b3752e077 100644 --- a/src/FlightMap/MapItems/MissionItemIndicator.qml +++ b/src/FlightMap/MapItems/MissionItemIndicator.qml @@ -30,14 +30,20 @@ import QGroundControl.Vehicle 1.0 /// Marker for displaying a mission item on the map MapQuickItem { + id: _item + property alias label: _label.label property alias isCurrentItem: _label.isCurrentItem + signal clicked + anchorPoint.x: sourceItem.width / 2 anchorPoint.y: sourceItem.height / 2 sourceItem: MissionItemIndexLabel { id: _label + + onClicked: _item.clicked() } } diff --git a/src/MissionEditor/MissionEditor.cc b/src/MissionEditor/MissionEditor.cc index c998c59c8b49ab62dcbbad81797c1a652368e754..c385d8416f1cc2d785f76665ef012f37c8ef700c 100644 --- a/src/MissionEditor/MissionEditor.cc +++ b/src/MissionEditor/MissionEditor.cc @@ -36,16 +36,11 @@ MissionEditor::MissionEditor(QWidget *parent) : QGCQmlWidgetHolder(parent) , _missionItems(NULL) { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); // Get rid of layout default margins QLayout* pl = layout(); if(pl) { pl->setContentsMargins(0,0,0,0); } -#ifndef __android__ - setMinimumWidth( 31 * ScreenToolsController::defaultFontPixelSize_s()); - setMinimumHeight(33 * ScreenToolsController::defaultFontPixelSize_s()); -#endif Vehicle* activeVehicle = MultiVehicleManager::instance()->activeVehicle(); if (activeVehicle) { @@ -72,6 +67,8 @@ void MissionEditor::_newMissionItemsAvailable(void) } _missionItems = MultiVehicleManager::instance()->activeVehicle()->missionManager()->copyMissionItems(); + _reSequence(); + emit missionItemsChanged(); } @@ -93,30 +90,63 @@ void MissionEditor::setMissionItems(void) } } -void MissionEditor::saveSetting(const QString &name, const QString& value) +int MissionEditor::addMissionItem(QGeoCoordinate coordinate) { - QSettings settings; - - settings.beginGroup(_settingsGroup); + MissionItem * newItem = new MissionItem(this, _missionItems->count(), coordinate); + if (_missionItems->count() == 0) { + newItem->setCommand(MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF); + } + qDebug() << "MissionItem" << newItem->coordinate(); + _missionItems->append(newItem); - settings.setValue(name, value); + return _missionItems->count() - 1; } -QString MissionEditor::loadSetting(const QString &name, const QString& defaultValue) +void MissionEditor::_reSequence(void) { - QSettings settings; + for (int i=0; i<_missionItems->count(); i++) { + qobject_cast(_missionItems->get(i))->setSequenceNumber(i); + } +} + +void MissionEditor::removeMissionItem(int index) +{ + _missionItems->removeAt(index); + _reSequence(); +} + +void MissionEditor::moveUp(int index) +{ + if (_missionItems->count() < 2 || index <= 0 || index >= _missionItems->count()) { + return; + } + + MissionItem item1 = *qobject_cast(_missionItems->get(index - 1)); + MissionItem item2 = *qobject_cast(_missionItems->get(index)); + + _missionItems->removeAt(index - 1); + _missionItems->removeAt(index - 1); - settings.beginGroup(_settingsGroup); + _missionItems->insert(index - 1, new MissionItem(item2, _missionItems)); + _missionItems->insert(index, new MissionItem(item1, _missionItems)); - return settings.value(name, defaultValue).toString(); + _reSequence(); } -void MissionEditor::addMissionItem(QGeoCoordinate coordinate) +void MissionEditor::moveDown(int index) { - MissionItem * newItem = new MissionItem(this, _missionItems->count(), coordinate); - if (_missionItems->count() == 0) { - newItem->setCommand(MavlinkQmlSingleton::MAV_CMD_NAV_TAKEOFF); + if (_missionItems->count() < 2 || index >= _missionItems->count() - 1) { + return; } - qDebug() << "MissionItem" << newItem->coordinate(); - _missionItems->append(newItem); + + MissionItem item1 = *qobject_cast(_missionItems->get(index)); + MissionItem item2 = *qobject_cast(_missionItems->get(index + 1)); + + _missionItems->removeAt(index); + _missionItems->removeAt(index); + + _missionItems->insert(index, new MissionItem(item2, _missionItems)); + _missionItems->insert(index + 1, new MissionItem(item1, _missionItems)); + + _reSequence(); } diff --git a/src/MissionEditor/MissionEditor.h b/src/MissionEditor/MissionEditor.h index ceea6e8cb55c61bd730125cbc3965f22b1411c8d..57786c00213b70aaab9d1ea608e1b6d0d3b52277 100644 --- a/src/MissionEditor/MissionEditor.h +++ b/src/MissionEditor/MissionEditor.h @@ -37,12 +37,12 @@ public: Q_PROPERTY(QmlObjectListModel* missionItems READ missionItemsModel NOTIFY missionItemsChanged) - Q_INVOKABLE void addMissionItem(QGeoCoordinate coordinate); + Q_INVOKABLE int addMissionItem(QGeoCoordinate coordinate); Q_INVOKABLE void getMissionItems(void); Q_INVOKABLE void setMissionItems(void); - - Q_INVOKABLE void saveSetting (const QString &key, const QString& value); - Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue); + Q_INVOKABLE void removeMissionItem(int index); + Q_INVOKABLE void moveUp(int index); + Q_INVOKABLE void moveDown(int index); // Property accessors @@ -54,6 +54,9 @@ signals: private slots: void _newMissionItemsAvailable(); +private: + void _reSequence(void); + private: QmlObjectListModel* _missionItems; diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml index e27ebe721947ebc36e6bccaec1500e95d7efa5cd..d5a29965ed0cf542a347c055631dce736cf0e90b 100644 --- a/src/MissionEditor/MissionEditor.qml +++ b/src/MissionEditor/MissionEditor.qml @@ -44,8 +44,16 @@ QGCView { readonly property real _verticalMargin: ScreenTools.defaultFontPixelHeight / 2 readonly property var _activeVehicle: multiVehicleManager.activeVehicle + property var _missionItems: controller.missionItems + QGCPalette { id: _qgcPal; colorGroupEnabled: enabled } + function setCurrentItem(index) { + for (var i=0; i<_missionItems.count; i++) { + _missionItems.get(i).isCurrentItem = (i == index) + } + } + QGCViewPanel { id: panel anchors.fill: parent @@ -76,7 +84,8 @@ QGCView { coordinate.latitude = coordinate.latitude.toFixed(_decimalPlaces) coordinate.longitude = coordinate.longitude.toFixed(_decimalPlaces) coordinate.altitude = 0 - controller.addMissionItem(coordinate) + var index = controller.addMissionItem(coordinate) + setCurrentItem(index) } } @@ -90,6 +99,8 @@ QGCView { isCurrentItem: object.isCurrentItem coordinate: object.coordinate + onClicked: setCurrentItem(object.sequenceNumber) + Component.onCompleted: console.log("Indicator", object.coordinate) } } @@ -171,6 +182,20 @@ QGCView { MissionItemEditor { missionItem: object width: parent.width + + onClicked: setCurrentItem(object.sequenceNumber) + + onRemove: { + var newCurrentItem = object.sequenceNumber - 1 + controller.removeMissionItem(object.sequenceNumber) + if (_missionItems.count) { + newCurrentItem = Math.min(_missionItems.count - 1, newCurrentItem) + setCurrentItem(newCurrentItem) + } + } + + onMoveUp: controller.moveUp(object.sequenceNumber) + onMoveDown: controller.moveDown(object.sequenceNumber) } } // ListView } // Item diff --git a/src/QmlControls/MissionItemEditor.qml b/src/QmlControls/MissionItemEditor.qml index e9aa869175e0c7169271b47df3716df3809684cc..44e6af5e1d4f38dee2d0f49197d74adc46e4d3dc 100644 --- a/src/QmlControls/MissionItemEditor.qml +++ b/src/QmlControls/MissionItemEditor.qml @@ -11,11 +11,20 @@ import QGroundControl.Palette 1.0 /// Mission item edit control Rectangle { + id: _root + property var missionItem - height: ((missionItem.factCount + 3) * (latitudeField.height + _margin)) + commandPicker.height + (_margin * 5) - color: missionItem.isCurrentItem ? qgcPal.buttonHighlight : qgcPal.windowShade + signal clicked + signal remove + signal moveUp + signal moveDown +// FIXME: THis doesn't work right for RTL + height: missionItem.isCurrentItem ? + ((missionItem.factCount + (missionItem.specifiesCoordinate ? 3 : 0)) * (latitudeField.height + _margin)) + commandPicker.height + deleteButton.height + (_margin * 6) : + commandPicker.height + (_margin * 2) + color: missionItem.isCurrentItem ? qgcPal.buttonHighlight : qgcPal.windowShade readonly property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 13 readonly property real _margin: ScreenTools.defaultFontPixelWidth / 3 @@ -30,14 +39,23 @@ Rectangle { anchors.fill: parent MissionItemIndexLabel { - id: label - isCurrentItem: missionItem.isCurrentItem - label: missionItem.sequenceNumber + id: label + anchors.verticalCenter: commandPicker.verticalCenter + isCurrentItem: missionItem.isCurrentItem + label: missionItem.sequenceNumber + } + + MouseArea { + anchors.fill: parent + visible: !missionItem.isCurrentItem + + onClicked: _root.clicked() } + QGCComboBox { id: commandPicker - anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 4 + anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 10 anchors.left: label.right anchors.right: parent.right currentIndex: missionItem.commandByIndex @@ -53,6 +71,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right color: qgcPal.windowShadeDark + visible: missionItem.isCurrentItem Item { anchors.margins: _margin @@ -120,7 +139,7 @@ Rectangle { anchors.topMargin: _margin anchors.left: parent.left anchors.right: parent.right - anchors.top: missionItem.specifiesCoordinate ? altitudeField.bottom : commandPicker.bottom + anchors.top: missionItem.specifiesCoordinate ? altitudeField.bottom : parent.top spacing: _margin Repeater { @@ -145,6 +164,38 @@ Rectangle { } } } // Column - Values column + + Row { + anchors.topMargin: _margin + anchors.top: valueColumn.bottom + + width: parent.width + spacing: _margin + + readonly property real buttonWidth: (width - (_margin * 2)) / 3 + + QGCButton { + id: deleteButton + width: parent.buttonWidth + text: "Delete" + + onClicked: _root.remove() + } + + QGCButton { + width: parent.buttonWidth + text: "Up" + + onClicked: _root.moveUp() + } + + QGCButton { + width: parent.buttonWidth + text: "Down" + + onClicked: _root.moveDown() + } + } } // Item } // Rectangle } // Item diff --git a/src/QmlControls/MissionItemIndexLabel.qml b/src/QmlControls/MissionItemIndexLabel.qml index a5f9b87f024811f3560f7a4308d652974cb5ca6d..630b76479caa359a08d9024849e84e6ea828e976 100644 --- a/src/QmlControls/MissionItemIndexLabel.qml +++ b/src/QmlControls/MissionItemIndexLabel.qml @@ -8,6 +8,8 @@ Rectangle { property alias label: _label.text property bool isCurrentItem: false + signal clicked + width: ScreenTools.defaultFontPixelHeight * 1.5 height: width radius: width / 2 @@ -15,6 +17,12 @@ Rectangle { border.color: "white" color: isCurrentItem ? "green" : "orange" + MouseArea { + anchors.fill: parent + + onClicked: parent.clicked() + } + QGCLabel { id: _label anchors.fill: parent diff --git a/src/QmlControls/QmlObjectListModel.cc b/src/QmlControls/QmlObjectListModel.cc index 6d89c0a45aab1dc2c4e5827790ead0567ba5342d..a3647ff792d098cfe76531614dec0ddc2d1050fc 100644 --- a/src/QmlControls/QmlObjectListModel.cc +++ b/src/QmlControls/QmlObjectListModel.cc @@ -89,6 +89,10 @@ bool QmlObjectListModel::insertRows(int position, int rows, const QModelIndex& p { Q_UNUSED(parent); + if (position < 0 || position > _objectList.count() + 1) { + qWarning() << "Invalid position position:count" << position << _objectList.count(); + } + beginInsertRows(QModelIndex(), position, position + rows - 1); endInsertRows(); @@ -101,10 +105,18 @@ bool QmlObjectListModel::removeRows(int position, int rows, const QModelIndex& p { Q_UNUSED(parent); + if (position < 0 || position >= _objectList.count()) { + qWarning() << "Invalid position position:count" << position << _objectList.count(); + } else if (position + rows > _objectList.count()) { + qWarning() << "Invalid rows position:rows:count" << position << rows << _objectList.count(); + } + beginRemoveRows(QModelIndex(), position, position + rows - 1); for (int row=0; rowdeleteLater(); _objectList.removeAt(position); } + qDebug() << _objectList; endRemoveRows(); emit countChanged(count()); @@ -134,10 +146,19 @@ void QmlObjectListModel::removeAt(int i) removeRows(i, 1); } +void QmlObjectListModel::insert(int i, QObject* object) +{ + if (i < 0 || i > _objectList.count()) { + qWarning() << "Invalid index index:count" << i << _objectList.count(); + } + + _objectList.insert(i, object); + insertRows(i, 1); +} + void QmlObjectListModel::append(QObject* object) { - _objectList += object; - insertRows(_objectList.count() - 1, 1); + insert(_objectList.count(), object); } int QmlObjectListModel::count(void) const diff --git a/src/QmlControls/QmlObjectListModel.h b/src/QmlControls/QmlObjectListModel.h index 8f6cd946e6129e23784530d8a75af99bbfe78426..effedeace8584ba498d2b5056487ba5889ed685c 100644 --- a/src/QmlControls/QmlObjectListModel.h +++ b/src/QmlControls/QmlObjectListModel.h @@ -42,6 +42,7 @@ public: void append(QObject* object); void clear(void); void removeAt(int i); + void insert(int i, QObject* object); QObject* operator[](int i); const QObject* operator[](int i) const;