diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 77f6c15ab138e63d67e694b1593a3f5af8879819..170838fd8e5ff7d5c2c1ffbff276ae3fd418d40e 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -390,12 +390,12 @@ FORMS += \ HEADERS += \ src/api/QGCCorePlugin.h \ src/api/QGCOptions.h \ - src/api/QmlPageInfo.h \ + src/api/QmlComponentInfo.h \ SOURCES += \ src/api/QGCCorePlugin.cc \ src/api/QGCOptions.cc \ - src/api/QmlPageInfo.cc \ + src/api/QmlComponentInfo.cc \ # # Unit Test specific configuration goes here (requires full debug build with all plugins) diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index a8306f2dddeced69445eff363e9eeb1f80f41a4f..adc4f7795d9deb24189bc3ee4eee36099592eff2 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -145,6 +145,7 @@ src/FlightMap/Widgets/CenterMapDropButton.qml src/FlightMap/Widgets/CenterMapDropPanel.qml src/FlightMap/Widgets/CompassRing.qml + src/FlightMap/MapItems/CustomMapItems.qml src/FlightMap/Widgets/MapFitFunctions.qml src/FlightMap/FlightMap.qml src/FlightMap/Widgets/InstrumentSwipeView.qml diff --git a/src/FlightDisplay/FlightDisplayViewMap.qml b/src/FlightDisplay/FlightDisplayViewMap.qml index 4c08b002f7d7fa778069f79121a4954d06fd53c5..77a22c88574041533d175c37846d911eedd1b3fc 100644 --- a/src/FlightDisplay/FlightDisplayViewMap.qml +++ b/src/FlightDisplay/FlightDisplayViewMap.qml @@ -226,6 +226,12 @@ FlightMap { } } + // Allow custom builds to add map items + CustomMapItems { + map: flightMap + largeMapView: _mainIsMap + } + GeoFenceMapVisuals { map: flightMap myGeoFenceController: _geoFenceController diff --git a/src/FlightMap/MapItems/CustomMapItems.qml b/src/FlightMap/MapItems/CustomMapItems.qml new file mode 100644 index 0000000000000000000000000000000000000000..1c00c1e00b938e9a00ef8c58ba445647c0c0e0c7 --- /dev/null +++ b/src/FlightMap/MapItems/CustomMapItems.qml @@ -0,0 +1,52 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.3 +import QtLocation 5.3 +import QtPositioning 5.3 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.Vehicle 1.0 + +// Allow custom builds to add visual items associated with the Flight Plan to the map +Item { + property var map ///< Map control to show items on + property bool largeMapView ///< true: map takes up entire view, false: map is in small window + + Instantiator { + model: QGroundControl.corePlugin.customMapItems + + Item { + property var _customObject + + Component.onCompleted: { + var controlUrl = object.url + if (controlUrl != "") { + var component = Qt.createComponent(controlUrl); + if (component.status == Component.Ready) { + _customObject = _customComponent.createObject(map, { "vehicle": vehicle }); + if (_customObject) { + map.addMapItem(_customObject) + } + } else { + console.log("Component creation failed", component.errorString()) + } + } + } + + Component.onDestruction: { + if (_customObject) { + _customObject.destroy() + } + } + } + } +} diff --git a/src/FlightMap/qmldir b/src/FlightMap/qmldir index 02dcde2206cf804bd831acdb26b57352a8c3706c..d7b3ba36b4badb4963e6926fa6f40149c974facf 100644 --- a/src/FlightMap/qmldir +++ b/src/FlightMap/qmldir @@ -19,6 +19,7 @@ QGCPitchIndicator 1.0 QGCPitchIndicator.qml # Map items CameraTriggerIndicator 1.0 CameraTriggerIndicator.qml +CustomMapItems 1.0 CustomMapItems.qml MissionItemIndicator 1.0 MissionItemIndicator.qml MissionItemIndicatorDrag 1.0 MissionItemIndicatorDrag.qml MissionItemView 1.0 MissionItemView.qml diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc index 88f6e8940e9c50adbe4e8cd6d4a6130b9810e9fc..de2d76d00ee6a22dde0e3298ee74223b646c46a2 100644 --- a/src/api/QGCCorePlugin.cc +++ b/src/api/QGCCorePlugin.cc @@ -10,10 +10,11 @@ #include "QGCApplication.h" #include "QGCCorePlugin.h" #include "QGCOptions.h" -#include "QmlPageInfo.h" +#include "QmlComponentInfo.h" #include "FactMetaData.h" #include "SettingsManager.h" #include "AppMessages.h" +#include "QmlObjectListModel.h" #include #include @@ -65,23 +66,25 @@ public: delete defaultOptions; } - QmlPageInfo* pGeneral; - QmlPageInfo* pCommLinks; - QmlPageInfo* pOfflineMaps; - QmlPageInfo* pMAVLink; - QmlPageInfo* pConsole; + QmlComponentInfo* pGeneral; + QmlComponentInfo* pCommLinks; + QmlComponentInfo* pOfflineMaps; + QmlComponentInfo* pMAVLink; + QmlComponentInfo* pConsole; #if defined(QT_DEBUG) - QmlPageInfo* pMockLink; - QmlPageInfo* pDebug; + QmlComponentInfo* pMockLink; + QmlComponentInfo* pDebug; #endif QVariantList settingsList; QGCOptions* defaultOptions; - QmlPageInfo* valuesPageWidgetInfo; - QmlPageInfo* cameraPageWidgetInfo; - QmlPageInfo* healthPageWidgetInfo; - QmlPageInfo* vibrationPageWidgetInfo; - QVariantList instrumentPageWidgetList; + QmlComponentInfo* valuesPageWidgetInfo; + QmlComponentInfo* cameraPageWidgetInfo; + QmlComponentInfo* healthPageWidgetInfo; + QmlComponentInfo* vibrationPageWidgetInfo; + QVariantList instrumentPageWidgetList; + + QmlObjectListModel _emptyCustomMapItems; }; QGCCorePlugin::~QGCCorePlugin() @@ -110,33 +113,33 @@ void QGCCorePlugin::setToolbox(QGCToolbox *toolbox) QVariantList &QGCCorePlugin::settingsPages() { if(!_p->pGeneral) { - _p->pGeneral = new QmlPageInfo(tr("General"), + _p->pGeneral = new QmlComponentInfo(tr("General"), QUrl::fromUserInput("qrc:/qml/GeneralSettings.qml"), QUrl::fromUserInput("qrc:/res/gear-white.svg")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pGeneral)); - _p->pCommLinks = new QmlPageInfo(tr("Comm Links"), + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pGeneral)); + _p->pCommLinks = new QmlComponentInfo(tr("Comm Links"), QUrl::fromUserInput("qrc:/qml/LinkSettings.qml"), QUrl::fromUserInput("qrc:/res/waves.svg")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pCommLinks)); - _p->pOfflineMaps = new QmlPageInfo(tr("Offline Maps"), + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pCommLinks)); + _p->pOfflineMaps = new QmlComponentInfo(tr("Offline Maps"), QUrl::fromUserInput("qrc:/qml/OfflineMap.qml"), QUrl::fromUserInput("qrc:/res/waves.svg")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pOfflineMaps)); - _p->pMAVLink = new QmlPageInfo(tr("MAVLink"), + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pOfflineMaps)); + _p->pMAVLink = new QmlComponentInfo(tr("MAVLink"), QUrl::fromUserInput("qrc:/qml/MavlinkSettings.qml"), QUrl::fromUserInput("qrc:/res/waves.svg")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pMAVLink)); - _p->pConsole = new QmlPageInfo(tr("Console"), + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pMAVLink)); + _p->pConsole = new QmlComponentInfo(tr("Console"), QUrl::fromUserInput("qrc:/qml/QGroundControl/Controls/AppMessages.qml")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pConsole)); + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pConsole)); #if defined(QT_DEBUG) //-- These are always present on Debug builds - _p->pMockLink = new QmlPageInfo(tr("Mock Link"), + _p->pMockLink = new QmlComponentInfo(tr("Mock Link"), QUrl::fromUserInput("qrc:/qml/MockLink.qml")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pMockLink)); - _p->pDebug = new QmlPageInfo(tr("Debug"), + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pMockLink)); + _p->pDebug = new QmlComponentInfo(tr("Debug"), QUrl::fromUserInput("qrc:/qml/DebugWindow.qml")); - _p->settingsList.append(QVariant::fromValue((QmlPageInfo*)_p->pDebug)); + _p->settingsList.append(QVariant::fromValue((QmlComponentInfo*)_p->pDebug)); #endif } return _p->settingsList; @@ -145,10 +148,10 @@ QVariantList &QGCCorePlugin::settingsPages() QVariantList& QGCCorePlugin::instrumentPages(void) { if (!_p->valuesPageWidgetInfo) { - _p->valuesPageWidgetInfo = new QmlPageInfo(tr("Values"), QUrl::fromUserInput("qrc:/qml/ValuePageWidget.qml")); - _p->cameraPageWidgetInfo = new QmlPageInfo(tr("Camera"), QUrl::fromUserInput("qrc:/qml/CameraPageWidget.qml")); - _p->healthPageWidgetInfo = new QmlPageInfo(tr("Health"), QUrl::fromUserInput("qrc:/qml/HealthPageWidget.qml")); - _p->vibrationPageWidgetInfo = new QmlPageInfo(tr("Vibration"), QUrl::fromUserInput("qrc:/qml/VibrationPageWidget.qml")); + _p->valuesPageWidgetInfo = new QmlComponentInfo(tr("Values"), QUrl::fromUserInput("qrc:/qml/ValuePageWidget.qml")); + _p->cameraPageWidgetInfo = new QmlComponentInfo(tr("Camera"), QUrl::fromUserInput("qrc:/qml/CameraPageWidget.qml")); + _p->healthPageWidgetInfo = new QmlComponentInfo(tr("Health"), QUrl::fromUserInput("qrc:/qml/HealthPageWidget.qml")); + _p->vibrationPageWidgetInfo = new QmlComponentInfo(tr("Vibration"), QUrl::fromUserInput("qrc:/qml/VibrationPageWidget.qml")); _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->valuesPageWidgetInfo)); _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->cameraPageWidgetInfo)); @@ -265,3 +268,8 @@ bool QGCCorePlugin::mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlin return true; } + +QmlObjectListModel* QGCCorePlugin::customMapItems(void) +{ + return &_p->_emptyCustomMapItems; +} diff --git a/src/api/QGCCorePlugin.h b/src/api/QGCCorePlugin.h index 16e2c8d0003fb68229ef7bd54f45f83c21149c60..193253cc560b126aa95175861044562d852ca396 100644 --- a/src/api/QGCCorePlugin.h +++ b/src/api/QGCCorePlugin.h @@ -12,6 +12,7 @@ #include "QGCToolbox.h" #include "QGCPalette.h" #include "QGCMAVLink.h" +#include "QmlObjectListModel.h" #include #include @@ -31,7 +32,7 @@ class QGeoPositionInfoSource; class QQmlApplicationEngine; class Vehicle; class LinkInterface; - +class QmlObjectListModel; class QGCCorePlugin : public QGCTool { Q_OBJECT @@ -39,17 +40,16 @@ public: QGCCorePlugin(QGCApplication* app, QGCToolbox* toolbox); ~QGCCorePlugin(); - Q_PROPERTY(QVariantList settingsPages READ settingsPages NOTIFY settingsPagesChanged) - Q_PROPERTY(QVariantList instrumentPages READ instrumentPages NOTIFY instrumentPagesChanged) - Q_PROPERTY(int defaultSettings READ defaultSettings CONSTANT) - Q_PROPERTY(QGCOptions* options READ options CONSTANT) - - Q_PROPERTY(bool showTouchAreas READ showTouchAreas WRITE setShowTouchAreas NOTIFY showTouchAreasChanged) - Q_PROPERTY(bool showAdvancedUI READ showAdvancedUI WRITE setShowAdvancedUI NOTIFY showAdvancedUIChanged) - Q_PROPERTY(QString showAdvancedUIMessage READ showAdvancedUIMessage CONSTANT) - - Q_PROPERTY(QString brandImageIndoor READ brandImageIndoor CONSTANT) - Q_PROPERTY(QString brandImageOutdoor READ brandImageOutdoor CONSTANT) + Q_PROPERTY(QVariantList settingsPages READ settingsPages NOTIFY settingsPagesChanged) + Q_PROPERTY(QVariantList instrumentPages READ instrumentPages NOTIFY instrumentPagesChanged) + Q_PROPERTY(int defaultSettings READ defaultSettings CONSTANT) + Q_PROPERTY(QGCOptions* options READ options CONSTANT) + Q_PROPERTY(bool showTouchAreas READ showTouchAreas WRITE setShowTouchAreas NOTIFY showTouchAreasChanged) + Q_PROPERTY(bool showAdvancedUI READ showAdvancedUI WRITE setShowAdvancedUI NOTIFY showAdvancedUIChanged) + Q_PROPERTY(QString showAdvancedUIMessage READ showAdvancedUIMessage CONSTANT) + Q_PROPERTY(QString brandImageIndoor READ brandImageIndoor CONSTANT) + Q_PROPERTY(QString brandImageOutdoor READ brandImageOutdoor CONSTANT) + Q_PROPERTY(QmlObjectListModel* customMapItems READ customMapItems CONSTANT) /// The list of settings under the Settings Menu /// @return A list of QGCSettings @@ -102,6 +102,10 @@ public: /// @return true: Allow vehicle to continue processing, false: Vehicle should not process message virtual bool mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message); + /// Allows custom builds to add custom items to the FlightMap. Objects put into QmlObjectListModel + /// should derive from QmlComponentInfo and set the url property. + virtual QmlObjectListModel* customMapItems(void); + bool showTouchAreas(void) const { return _showTouchAreas; } bool showAdvancedUI(void) const { return _showAdvancedUI; } void setShowTouchAreas(bool show); diff --git a/src/api/QmlPageInfo.cc b/src/api/QmlComponentInfo.cc similarity index 79% rename from src/api/QmlPageInfo.cc rename to src/api/QmlComponentInfo.cc index 645a27dc0dca1b4e2d54776db6a981980479e039..a44931578619aa6dc2b066d01f1bd483f44f6f27 100644 --- a/src/api/QmlPageInfo.cc +++ b/src/api/QmlComponentInfo.cc @@ -7,9 +7,9 @@ * ****************************************************************************/ -#include "QmlPageInfo.h" +#include "QmlComponentInfo.h" -QmlPageInfo::QmlPageInfo(QString title, QUrl url, QUrl icon, QObject* parent) +QmlComponentInfo::QmlComponentInfo(QString title, QUrl url, QUrl icon, QObject* parent) : QObject (parent) , _title (title) , _url (url) diff --git a/src/api/QmlPageInfo.h b/src/api/QmlComponentInfo.h similarity index 81% rename from src/api/QmlPageInfo.h rename to src/api/QmlComponentInfo.h index d206915988a4b30ae503f7a14d9567779d8bf0fc..a0d354e3a853eae20e7e78f8e4e5b126d033bcc1 100644 --- a/src/api/QmlPageInfo.h +++ b/src/api/QmlComponentInfo.h @@ -12,13 +12,13 @@ #include #include -/// Represents a -class QmlPageInfo : public QObject +/// Represents a Qml component which can be loaded from a resource. +class QmlComponentInfo : public QObject { Q_OBJECT public: - QmlPageInfo(QString title, QUrl url, QUrl icon = QUrl(), QObject* parent = NULL); + QmlComponentInfo(QString title, QUrl url, QUrl icon = QUrl(), QObject* parent = NULL); Q_PROPERTY(QString title READ title CONSTANT) ///< Title for page Q_PROPERTY(QUrl url READ url CONSTANT) ///< Qml source code