diff --git a/platform/qt/include/QQuickMapboxGLStyle b/platform/qt/include/QQuickMapboxGLStyle new file mode 100644 index 000000000..24fc0c04e --- /dev/null +++ b/platform/qt/include/QQuickMapboxGLStyle @@ -0,0 +1 @@ +#include "qquickmapboxglstyle.hpp" diff --git a/platform/qt/include/qquickmapboxgl.hpp b/platform/qt/include/qquickmapboxgl.hpp index 337360cac..c89a1683a 100644 --- a/platform/qt/include/qquickmapboxgl.hpp +++ b/platform/qt/include/qquickmapboxgl.hpp @@ -8,6 +8,8 @@ #include #include +#include + class QDeclarativeGeoServiceProvider; class QQuickItem; @@ -29,7 +31,7 @@ class Q_DECL_EXPORT QQuickMapboxGL : public QQuickFramebufferObject Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) // MapboxGL QML Type interface. - Q_PROPERTY(QString style READ style WRITE setStyle NOTIFY styleChanged) + Q_PROPERTY(QQuickMapboxGLStyle *style READ style WRITE setStyle NOTIFY styleChanged) Q_PROPERTY(qreal bearing READ bearing WRITE setBearing NOTIFY bearingChanged) Q_PROPERTY(qreal pitch READ pitch WRITE setPitch NOTIFY pitchChanged) @@ -73,8 +75,8 @@ public: QList& paintPropertyChanges() { return m_paintChanges; } // MapboxGL QML Type interface. - void setStyle(const QString &style); - QString style() const; + void setStyle(QQuickMapboxGLStyle *); + QQuickMapboxGLStyle* style() const; void setBearing(qreal bearing); qreal bearing() const; @@ -121,6 +123,7 @@ public slots: void setCenter(const QGeoCoordinate ¢er); private slots: + void onStyleChanged(); void onStylePropertyUpdated(const QVariantMap ¶ms); private: @@ -136,7 +139,7 @@ private: QList m_layoutChanges; QList m_paintChanges; - QString m_style; + QQuickMapboxGLStyle *m_style = 0; qreal m_bearing = 0; qreal m_pitch = 0; diff --git a/platform/qt/include/qquickmapboxglstyle.hpp b/platform/qt/include/qquickmapboxglstyle.hpp new file mode 100644 index 000000000..653984131 --- /dev/null +++ b/platform/qt/include/qquickmapboxglstyle.hpp @@ -0,0 +1,39 @@ +#ifndef QQUICKMAPBOXGLSTYLE_H +#define QQUICKMAPBOXGLSTYLE_H + +#include + +class Q_DECL_EXPORT QQuickMapboxGLStyle : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) + Q_PROPERTY(QString styleClass READ styleClass WRITE setStyleClass NOTIFY classChanged) + +public: + QQuickMapboxGLStyle(QQuickItem *parent = Q_NULLPTR); + virtual ~QQuickMapboxGLStyle() {} + + // QQuickItem implementation + virtual void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &); + + void setUrl(const QString &); + QString url() const; + + void setStyleClass(const QString &); + QString styleClass() const; + +signals: + void urlChanged(const QString &); + void classChanged(const QString &); + + void propertyUpdated(const QVariantMap &); + +private: + QString m_url; + QString m_class; +}; + +QML_DECLARE_TYPE(QQuickMapboxGLStyle) + +#endif // QQUICKMAPBOXGLSTYLE_H diff --git a/platform/qt/qmlapp/main.cpp b/platform/qt/qmlapp/main.cpp index 0a376c6bd..d5f7dc767 100644 --- a/platform/qt/qmlapp/main.cpp +++ b/platform/qt/qmlapp/main.cpp @@ -4,6 +4,7 @@ #include #include +#include #include int main(int argc, char *argv[]) @@ -15,6 +16,7 @@ int main(int argc, char *argv[]) #endif qmlRegisterType("QQuickMapboxGL", 1, 0, "MapboxMap"); + qmlRegisterType("QQuickMapboxGL", 1, 0, "MapboxStyle"); qmlRegisterType("QQuickMapboxGL", 1, 0, "MapboxLayoutStyleProperty"); qmlRegisterType("QQuickMapboxGL", 1, 0, "MapboxPaintStyleProperty"); diff --git a/platform/qt/qmlapp/main.qml b/platform/qt/qmlapp/main.qml index bee98bc8b..dcd0afa77 100644 --- a/platform/qt/qmlapp/main.qml +++ b/platform/qt/qmlapp/main.qml @@ -16,7 +16,7 @@ ApplicationWindow { ColorDialog { id: landColorDialog title: "Land color" - onCurrentColorChanged: { mapStreets.color = currentColor } + onCurrentColorChanged: { mapFront.color = currentColor } } ColorDialog { @@ -26,21 +26,21 @@ ApplicationWindow { } MapboxLayoutStyleProperty { - parent: mapStreets + parent: styleStreets layer: "road-label-large" property: "visibility" value: roadLabel.checked ? "visible" : "none" } MapboxLayoutStyleProperty { - parent: mapStreets + parent: styleStreets layer: "road-label-medium" property: "visibility" value: roadLabel.checked ? "visible" : "none" } MapboxLayoutStyleProperty { - parent: mapStreets + parent: styleStreets layer: "road-label-small" property: "visibility" value: roadLabel.checked ? "visible" : "none" @@ -70,12 +70,15 @@ ApplicationWindow { anchors.fill: parent MapboxMap { - id: mapStreets + id: mapFront anchors.fill: parent visible: false - style: "mapbox://styles/mapbox/streets-v9" + style: MapboxStyle { + id: styleStreets + url: "mapbox://styles/mapbox/streets-v9" + } center: QtPositioning.coordinate(60.170448, 24.942046) // Helsinki zoomLevel: 14 @@ -124,7 +127,7 @@ ApplicationWindow { OpacityMask { anchors.fill: maskStreets - source: mapStreets + source: mapFront maskSource: maskStreets } @@ -134,7 +137,7 @@ ApplicationWindow { property var lastX: 0 property var lastY: 0 - onWheel: mapStreets.zoomLevel += 0.2 * wheel.angleDelta.y / 120 + onWheel: mapFront.zoomLevel += 0.2 * wheel.angleDelta.y / 120 onPressed: { lastX = mouse.x @@ -142,7 +145,7 @@ ApplicationWindow { } onPositionChanged: { - mapStreets.pan(mouse.x - lastX, mouse.y - lastY) + mapFront.pan(mouse.x - lastX, mouse.y - lastY) lastX = mouse.x lastY = mouse.y @@ -154,20 +157,23 @@ ApplicationWindow { anchors.fill: parent MapboxMap { - id: mapSatellite + id: mapBack anchors.fill: parent visible: false - style: "mapbox://styles/mapbox/satellite-streets-v9" + style: MapboxStyle { + id: styleSatellite + url: "mapbox://styles/mapbox/satellite-streets-v9" + } - center: mapStreets.center - zoomLevel: mapStreets.zoomLevel - minimumZoomLevel: mapStreets.minimumZoomLevel - maximumZoomLevel: mapStreets.maximumZoomLevel + center: mapFront.center + zoomLevel: mapFront.zoomLevel + minimumZoomLevel: mapFront.minimumZoomLevel + maximumZoomLevel: mapFront.maximumZoomLevel - bearing: mapStreets.bearing - pitch: mapStreets.pitch + bearing: mapFront.bearing + pitch: mapFront.pitch Image { anchors.right: parent.right @@ -197,7 +203,7 @@ ApplicationWindow { OpacityMask { anchors.fill: maskSatellite - source: mapSatellite + source: mapBack maskSource: maskSatellite } @@ -207,7 +213,7 @@ ApplicationWindow { property var lastX: 0 property var lastY: 0 - onWheel: mapStreets.zoomLevel += 0.2 * wheel.angleDelta.y / 120 + onWheel: mapFront.zoomLevel += 0.2 * wheel.angleDelta.y / 120 onPressed: { lastX = mouse.x @@ -215,7 +221,7 @@ ApplicationWindow { } onPositionChanged: { - mapStreets.pan(mouse.x - lastX, mouse.y - lastY) + mapFront.pan(mouse.x - lastX, mouse.y - lastY) lastX = mouse.x lastY = mouse.y @@ -281,14 +287,14 @@ ApplicationWindow { anchors.left: parent.left anchors.right: parent.right text: "Light style" - onClicked: { mapStreets.style = "mapbox://styles/mapbox/light-v9" } + onClicked: { styleStreets.url = "mapbox://styles/mapbox/light-v9" } } Button { anchors.left: parent.left anchors.right: parent.right text: "Dark style" - onClicked: { mapStreets.style = "mapbox://styles/mapbox/dark-v9" } + onClicked: { styleStreets.url = "mapbox://styles/mapbox/dark-v9" } } CheckBox { diff --git a/platform/qt/qt5.cmake b/platform/qt/qt5.cmake index f19c02aec..95e35eaab 100644 --- a/platform/qt/qt5.cmake +++ b/platform/qt/qt5.cmake @@ -17,10 +17,12 @@ set(MBGL_QT_LIBRARIES add_library(qmapboxgl SHARED platform/qt/include/qquickmapboxgl.hpp + platform/qt/include/qquickmapboxglstyle.hpp platform/qt/include/qquickmapboxglstyleproperty.hpp platform/qt/src/qquickmapboxgl.cpp platform/qt/src/qquickmapboxglrenderer.cpp platform/qt/src/qquickmapboxglrenderer.hpp + platform/qt/src/qquickmapboxglstyle.cpp platform/qt/src/qquickmapboxglstyleproperty.cpp ) diff --git a/platform/qt/src/qquickmapboxgl.cpp b/platform/qt/src/qquickmapboxgl.cpp index b80b343d3..73241460c 100644 --- a/platform/qt/src/qquickmapboxgl.cpp +++ b/platform/qt/src/qquickmapboxgl.cpp @@ -182,13 +182,21 @@ void QQuickMapboxGL::pan(int dx, int dy) update(); } -void QQuickMapboxGL::setStyle(const QString &styleUrl) +void QQuickMapboxGL::setStyle(QQuickMapboxGLStyle *style) { - if (m_style == styleUrl) { + if (style == m_style) { return; } - m_style = styleUrl; + disconnect(style, SIGNAL(urlChanged(QString)), this, SLOT(onStyleChanged())); + disconnect(style, SIGNAL(propertyUpdated(QVariantMap)), this, SLOT(onStylePropertyUpdated(QVariantMap))); + delete m_style; + m_style = style; + if (style) { + style->setParentItem(this); + connect(style, SIGNAL(urlChanged(QString)), this, SLOT(onStyleChanged())); + connect(style, SIGNAL(propertyUpdated(QVariantMap)), this, SLOT(onStylePropertyUpdated(QVariantMap))); + } m_syncState |= StyleNeedsSync; update(); @@ -196,7 +204,7 @@ void QQuickMapboxGL::setStyle(const QString &styleUrl) emit styleChanged(); } -QString QQuickMapboxGL::style() const +QQuickMapboxGLStyle *QQuickMapboxGL::style() const { return m_style; } @@ -295,3 +303,11 @@ void QQuickMapboxGL::onStylePropertyUpdated(const QVariantMap ¶ms) update(); } + +void QQuickMapboxGL::onStyleChanged() +{ + m_syncState |= StyleNeedsSync; + update(); + + emit styleChanged(); +} diff --git a/platform/qt/src/qquickmapboxglrenderer.cpp b/platform/qt/src/qquickmapboxglrenderer.cpp index 1b9a983d5..54ea251b0 100644 --- a/platform/qt/src/qquickmapboxglrenderer.cpp +++ b/platform/qt/src/qquickmapboxglrenderer.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -83,8 +84,8 @@ void QQuickMapboxGLRenderer::synchronize(QQuickFramebufferObject *item) m_map->setCoordinateZoom({ center.latitude(), center.longitude() }, quickMap->zoomLevel()); } - if (syncStatus & QQuickMapboxGL::StyleNeedsSync) { - m_map->setStyleURL(quickMap->style()); + if (syncStatus & QQuickMapboxGL::StyleNeedsSync && quickMap->style()) { + m_map->setStyleURL(quickMap->style()->url()); m_styleLoaded = false; } diff --git a/platform/qt/src/qquickmapboxglstyle.cpp b/platform/qt/src/qquickmapboxglstyle.cpp new file mode 100644 index 000000000..1a8640928 --- /dev/null +++ b/platform/qt/src/qquickmapboxglstyle.cpp @@ -0,0 +1,59 @@ +#include +#include + +QQuickMapboxGLStyle::QQuickMapboxGLStyle(QQuickItem *parent) + : QQuickItem(parent) +{ +} + +void QQuickMapboxGLStyle::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + QQuickItem::itemChange(change, value); + + switch (change) { + case QQuickItem::ItemChildAddedChange: + if (QQuickMapboxGLStyleProperty *property = qobject_cast(value.item)) { + connect(property, SIGNAL(updated(QVariantMap)), this, SIGNAL(propertyUpdated(QVariantMap))); + connect(this, SIGNAL(urlChanged(QString)), property, SLOT(checkUpdated())); + } + break; + case QQuickItem::ItemChildRemovedChange: + if (QQuickMapboxGLStyleProperty *property = qobject_cast(value.item)) { + disconnect(property, SIGNAL(updated(QVariantMap)), this, SIGNAL(propertyUpdated(QVariantMap))); + disconnect(this, SIGNAL(urlChanged(QString)), property, SLOT(checkUpdated())); + } + break; + default: + break; + } +} + +void QQuickMapboxGLStyle::setUrl(const QString &url) +{ + if (url == m_url) { + return; + } + + m_url = url; + emit urlChanged(url); +} + +QString QQuickMapboxGLStyle::url() const +{ + return m_url; +} + +void QQuickMapboxGLStyle::setStyleClass(const QString &styleClass) +{ + if (styleClass == m_class) { + return; + } + + m_class = styleClass; + emit classChanged(styleClass); +} + +QString QQuickMapboxGLStyle::styleClass() const +{ + return m_class; +}