diff options
31 files changed, 568 insertions, 369 deletions
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp index 9e96f3c6..eab0f214 100644 --- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp +++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp @@ -654,8 +654,7 @@ void QDeclarativePolygonMapItem::geometryChanged(const QRectF &newGeometry, cons MapPolygonNode::MapPolygonNode() : border_(new MapPolylineNode()), - geometry_(QSGGeometry::defaultAttributes_Point2D(), 0), - blocked_(true) + geometry_(QSGGeometry::defaultAttributes_Point2D(), 0) { geometry_.setDrawingMode(QSGGeometry::DrawTriangles); QSGGeometryNode::setMaterial(&fill_material_); @@ -671,14 +670,6 @@ MapPolygonNode::~MapPolygonNode() /*! \internal */ -bool MapPolygonNode::isSubtreeBlocked() const -{ - return blocked_; -} - -/*! - \internal -*/ void MapPolygonNode::update(const QColor &fillColor, const QColor &borderColor, const QGeoMapItemGeometry *fillShape, const QGeoMapItemGeometry *borderShape) @@ -692,13 +683,13 @@ void MapPolygonNode::update(const QColor &fillColor, const QColor &borderColor, * accuracy) */ if (fillShape->size() == 0) { if (borderShape->size() == 0) { - blocked_ = true; + setSubtreeBlocked(true); return; } else { - blocked_ = false; + setSubtreeBlocked(false); } } else { - blocked_ = false; + setSubtreeBlocked(false); } QSGGeometry *fill = QSGGeometryNode::geometry(); diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h index febeb751..83983651 100644 --- a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h +++ b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h @@ -137,24 +137,20 @@ private: ////////////////////////////////////////////////////////////////////// -class Q_LOCATION_PRIVATE_EXPORT MapPolygonNode : public QSGGeometryNode +class Q_LOCATION_PRIVATE_EXPORT MapPolygonNode : public MapItemGeometryNode { public: MapPolygonNode(); - ~MapPolygonNode(); + ~MapPolygonNode() override; void update(const QColor &fillColor, const QColor &borderColor, const QGeoMapItemGeometry *fillShape, const QGeoMapItemGeometry *borderShape); - - bool isSubtreeBlocked() const override; - private: QSGFlatColorMaterial fill_material_; MapPolylineNode *border_; QSGGeometry geometry_; - bool blocked_; }; QT_END_NAMESPACE diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp index dffec4d5..620ed14e 100644 --- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp +++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp @@ -1014,29 +1014,76 @@ QGeoMap::ItemType QDeclarativePolylineMapItem::itemType() const /*! \internal */ -MapPolylineNode::MapPolylineNode() : - geometry_(QSGGeometry::defaultAttributes_Point2D(),0), - blocked_(true) +VisibleNode::VisibleNode() : m_blocked{true}, m_visible{true} { - geometry_.setDrawingMode(QSGGeometry::DrawTriangleStrip); - QSGGeometryNode::setMaterial(&fill_material_); - QSGGeometryNode::setGeometry(&geometry_); + } +VisibleNode::~VisibleNode() +{ + +} /*! \internal */ -MapPolylineNode::~MapPolylineNode() +bool VisibleNode::subtreeBlocked() const +{ + return m_blocked || !m_visible; +} + +/*! + \internal +*/ +void VisibleNode::setSubtreeBlocked(bool blocked) +{ + m_blocked = blocked; +} + +bool VisibleNode::visible() const +{ + return m_visible; +} + +/*! + \internal +*/ +void VisibleNode::setVisible(bool visible) { + m_visible = visible; } /*! \internal */ -bool MapPolylineNode::isSubtreeBlocked() const +MapItemGeometryNode::~MapItemGeometryNode() +{ + +} + +bool MapItemGeometryNode::isSubtreeBlocked() const +{ + return subtreeBlocked(); +} + + +/*! + \internal +*/ +MapPolylineNode::MapPolylineNode() : + geometry_(QSGGeometry::defaultAttributes_Point2D(),0) +{ + geometry_.setDrawingMode(QSGGeometry::DrawTriangleStrip); + QSGGeometryNode::setMaterial(&fill_material_); + QSGGeometryNode::setGeometry(&geometry_); +} + + +/*! + \internal +*/ +MapPolylineNode::~MapPolylineNode() { - return blocked_; } /*! @@ -1046,10 +1093,10 @@ void MapPolylineNode::update(const QColor &fillColor, const QGeoMapItemGeometry *shape) { if (shape->size() == 0) { - blocked_ = true; + setSubtreeBlocked(true); return; } else { - blocked_ = false; + setSubtreeBlocked(false); } QSGGeometry *fill = QSGGeometryNode::geometry(); diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h index ca01de12..225f21d9 100644 --- a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h +++ b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h @@ -181,20 +181,39 @@ private: ////////////////////////////////////////////////////////////////////// -class Q_LOCATION_PRIVATE_EXPORT MapPolylineNode : public QSGGeometryNode +class Q_LOCATION_PRIVATE_EXPORT VisibleNode { +public: + VisibleNode(); + virtual ~VisibleNode(); + + bool subtreeBlocked() const; + void setSubtreeBlocked(bool blocked); + bool visible() const; + void setVisible(bool visible); + + bool m_blocked : 1; + bool m_visible : 1; +}; +class Q_LOCATION_PRIVATE_EXPORT MapItemGeometryNode : public QSGGeometryNode, public VisibleNode +{ +public: + ~MapItemGeometryNode() override; + bool isSubtreeBlocked() const override; +}; + +class Q_LOCATION_PRIVATE_EXPORT MapPolylineNode : public MapItemGeometryNode +{ public: MapPolylineNode(); - ~MapPolylineNode(); + ~MapPolylineNode() override; void update(const QColor &fillColor, const QGeoMapItemGeometry *shape); - bool isSubtreeBlocked() const override; private: QSGFlatColorMaterial fill_material_; QSGGeometry geometry_; - bool blocked_; }; QT_END_NAMESPACE diff --git a/src/location/declarativemaps/qgeomapobject.cpp b/src/location/declarativemaps/qgeomapobject.cpp index 391ac04c..9a2e37bd 100644 --- a/src/location/declarativemaps/qgeomapobject.cpp +++ b/src/location/declarativemaps/qgeomapobject.cpp @@ -198,8 +198,8 @@ void QGeoMapObject::setMap(QGeoMap *map) // old implementation gets destroyed if/when d_ptr gets replaced d_ptr->m_componentCompleted = oldCmponentCompleted; d_ptr->setVisible(oldVisible); + d_ptr->setMap(map); } - d_ptr->setMap(map); const QList<QGeoMapObject *> kids = geoMapObjectChildren(); for (auto kid : kids) @@ -207,7 +207,8 @@ void QGeoMapObject::setMap(QGeoMap *map) // Each subclass is in charge to do the equivalent of // if (!map) { - // // Map was set, now it has ben re-set to NULL + // // Map was set, now it has ben re-set to NULL, but not inside d_ptr. + // // so m_map inside d_ptr can still be used to remove itself, inside the destructor. // d_ptr = new QMapCircleObjectPrivateDefault(*d); // // Old pimpl deleted implicitly by QExplicitlySharedDataPointer // } diff --git a/src/location/labs/qgeotiledmaplabs.cpp b/src/location/labs/qgeotiledmaplabs.cpp index 2e4b2c16..22d582c0 100644 --- a/src/location/labs/qgeotiledmaplabs.cpp +++ b/src/location/labs/qgeotiledmaplabs.cpp @@ -42,26 +42,20 @@ #include <QtLocation/private/qmapcircleobjectqsg_p_p.h> #include <QtLocation/private/qmaprouteobjectqsg_p_p.h> #include <QtLocation/private/qmapiconobjectqsg_p_p.h> +#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> +#include <QtLocation/private/qgeomapobjectqsgsupport_p.h> QT_BEGIN_NAMESPACE -struct MapObject { - MapObject(QPointer<QGeoMapObject> &o, QQSGMapObject *sgo) - : object(o), sgObject(sgo) {} - QPointer<QGeoMapObject> object; - QQSGMapObject *sgObject = nullptr; -}; - class QGeoTiledMapLabsPrivate : public QGeoTiledMapPrivate { Q_DECLARE_PUBLIC(QGeoTiledMapLabs) public: - QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine); + QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine, QGeoTiledMapLabs *map); virtual ~QGeoTiledMapLabsPrivate(); QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj) override; virtual QList<QGeoMapObject *> mapObjects() const override; - static int findMapObject(QGeoMapObject *o, const QList<MapObject> &list); void removeMapObject(QGeoMapObject *obj); void updateMapObjects(QSGNode *root, QQuickWindow *window); @@ -72,14 +66,13 @@ protected: void changeCameraData(const QGeoCameraData &oldCameraData) override; void changeActiveMapType(const QGeoMapType mapType) override; - QList<MapObject> m_mapObjects; - QList<MapObject> m_pendingMapObjects; + QGeoMapObjectQSGSupport m_qsgSupport; }; -QGeoTiledMapLabsPrivate::QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine) +QGeoTiledMapLabsPrivate::QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine, QGeoTiledMapLabs *map) : QGeoTiledMapPrivate(engine) { - + m_qsgSupport.m_map = map; } QGeoTiledMapLabsPrivate::~QGeoTiledMapLabsPrivate() @@ -89,136 +82,27 @@ QGeoTiledMapLabsPrivate::~QGeoTiledMapLabsPrivate() QGeoMapObjectPrivate *QGeoTiledMapLabsPrivate::createMapObjectImplementation(QGeoMapObject *obj) { - switch (obj->type()) { - case QGeoMapObject::PolylineType: { - QMapPolylineObjectPrivate &oldImpl = static_cast<QMapPolylineObjectPrivate &>(*obj->implementation()); - QMapPolylineObjectPrivateQSG *pimpl = - new QMapPolylineObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::PolygonType: { - QMapPolygonObjectPrivate &oldImpl = static_cast<QMapPolygonObjectPrivate &>(*obj->implementation()); - QMapPolygonObjectPrivateQSG *pimpl = - new QMapPolygonObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::CircleType: { - QMapCircleObjectPrivate &oldImpl = static_cast<QMapCircleObjectPrivate &>(*obj->implementation()); - QMapCircleObjectPrivateQSG *pimpl = - new QMapCircleObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::RouteType: { - QMapRouteObjectPrivate &oldImpl = static_cast<QMapRouteObjectPrivate &>(*obj->implementation()); - QMapRouteObjectPrivateQSG *pimpl = - new QMapRouteObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::IconType: { - QMapIconObjectPrivate &oldImpl = static_cast<QMapIconObjectPrivate &>(*obj->implementation()); - QMapIconObjectPrivateQSG *pimpl = - new QMapIconObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - default: - qWarning() << "Unsupported object type: " << obj->type(); - break; - } - return nullptr; + return m_qsgSupport.createMapObjectImplementationPrivate(obj); } QList<QGeoMapObject *> QGeoTiledMapLabsPrivate::mapObjects() const { - return QList<QGeoMapObject *>(); -} - -int QGeoTiledMapLabsPrivate::findMapObject(QGeoMapObject *o, const QList<MapObject> &list) -{ - for (int i = 0; i < list.size(); ++i) - { - if (list.at(i).object.data() == o) - return i; - } - return -1; + return m_qsgSupport.mapObjects(); } void QGeoTiledMapLabsPrivate::removeMapObject(QGeoMapObject *obj) { - int idx = findMapObject(obj, m_mapObjects); - if (idx >= 0) { - m_mapObjects.removeAt(idx); - } else { - idx = findMapObject(obj, m_pendingMapObjects); - if (idx >= 0) { - m_pendingMapObjects.removeAt(idx); - } else { - // obj not here. - } - } + m_qsgSupport.removeMapObject(obj); } void QGeoTiledMapLabsPrivate::updateMapObjects(QSGNode *root, QQuickWindow *window) { - for (int i = 0; i < m_mapObjects.size(); ++i) { - // already added as node - if (!m_mapObjects.at(i).object) { - qWarning() << "m_mapObjects at "<<i<< " NULLed!!"; - continue; - } - - QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; - QSGNode *oldNode = sgo->node; - sgo->node = sgo->updateMapObjectNode(oldNode, root, window); - } - - QList<int> toRemove; - for (int i = 0; i < m_pendingMapObjects.size(); ++i) { - // already added as node - QQSGMapObject *sgo = m_pendingMapObjects.at(i).sgObject; - QSGNode *oldNode = sgo->node; - sgo->updateGeometry(); // or subtree will be blocked - sgo->node = sgo->updateMapObjectNode(oldNode, root, window); - if (sgo->node) { - m_mapObjects << m_pendingMapObjects.at(i); - toRemove.push_front(i); - } else { - // leave it to be processed - } - } - - for (int i: qAsConst(toRemove)) - m_pendingMapObjects.removeAt(i); + m_qsgSupport.updateMapObjects(root, window); } void QGeoTiledMapLabsPrivate::updateObjectsGeometry() { - Q_Q(QGeoTiledMapLabs); - for (int i = 0; i < m_mapObjects.size(); ++i) { - // already added as node - if (!m_mapObjects.at(i).object) { - qWarning() << "m_mapObjects at "<<i<< " NULLed!!"; - continue; - } - - QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; - sgo->updateGeometry(); - } - emit q->sgNodeChanged(); + m_qsgSupport.updateObjectsGeometry(); } void QGeoTiledMapLabsPrivate::changeViewportSize(const QSize &size) @@ -247,7 +131,7 @@ void QGeoTiledMapLabsPrivate::changeActiveMapType(const QGeoMapType mapType) QGeoTiledMapLabs::QGeoTiledMapLabs(QGeoTiledMappingManagerEngine *engine, QObject *parent) - : QGeoTiledMap(*new QGeoTiledMapLabsPrivate(engine), engine, parent) + : QGeoTiledMap(*new QGeoTiledMapLabsPrivate(engine, this), engine, parent) { } @@ -260,15 +144,7 @@ QGeoTiledMapLabs::~QGeoTiledMapLabs() bool QGeoTiledMapLabs::createMapObjectImplementation(QGeoMapObject *obj) { Q_D(QGeoTiledMapLabs); - QExplicitlySharedDataPointer<QGeoMapObjectPrivate> pimpl = - QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(d->createMapObjectImplementation(obj)); - if (pimpl.constData()) { - bool res = obj->setImplementation(pimpl); - if (res) - emit sgNodeChanged(); - return res; - } - return false; + return d->m_qsgSupport.createMapObjectImplementation(obj, d); } QSGNode *QGeoTiledMapLabs::updateSceneGraph(QSGNode *node, QQuickWindow *window) diff --git a/src/location/labs/qgeotiledmaplabs_p.h b/src/location/labs/qgeotiledmaplabs_p.h index f6499784..4f179028 100644 --- a/src/location/labs/qgeotiledmaplabs_p.h +++ b/src/location/labs/qgeotiledmaplabs_p.h @@ -71,10 +71,10 @@ public: virtual ~QGeoTiledMapLabs(); bool createMapObjectImplementation(QGeoMapObject *obj) override; + void removeMapObject(QGeoMapObject *obj) override; protected: QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override; - void removeMapObject(QGeoMapObject *obj) override; QSGClipNode *m_clip = nullptr; QSGSimpleRectNode *m_simpleRectNode = nullptr; diff --git a/src/location/labs/qmapcircleobject.cpp b/src/location/labs/qmapcircleobject.cpp index 735ece5c..d7f1d58f 100644 --- a/src/location/labs/qmapcircleobject.cpp +++ b/src/location/labs/qmapcircleobject.cpp @@ -278,7 +278,8 @@ void QMapCircleObject::setMap(QGeoMap *map) QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected if (!map) { - // Map was set, now it has ben re-set to NULL + // Map was set, now it has ben re-set to NULL, but not inside d_ptr. + // so m_map inside d_ptr can still be used to remove itself, inside the destructor. d_ptr = new QMapCircleObjectPrivateDefault(*d); // Old pimpl deleted implicitly by QExplicitlySharedDataPointer } diff --git a/src/location/labs/qmapiconobject.cpp b/src/location/labs/qmapiconobject.cpp index 507492d2..be82ebbf 100644 --- a/src/location/labs/qmapiconobject.cpp +++ b/src/location/labs/qmapiconobject.cpp @@ -236,7 +236,8 @@ void QMapIconObject::setMap(QGeoMap *map) QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected if (!map) { - // Map was set, now it has ben re-set to NULL + // Map was set, now it has ben re-set to NULL, but not inside d_ptr. + // so m_map inside d_ptr can still be used to remove itself, inside the destructor. d_ptr = new QMapIconObjectPrivateDefault(*d); // Old pimpl deleted implicitly by QExplicitlySharedDataPointer } diff --git a/src/location/labs/qmapobjectview.cpp b/src/location/labs/qmapobjectview.cpp index e1161acd..175e7cc4 100644 --- a/src/location/labs/qmapobjectview.cpp +++ b/src/location/labs/qmapobjectview.cpp @@ -144,37 +144,6 @@ QList<QGeoMapObject *> QMapObjectView::geoMapObjectChildren() const return kids; } -void QMapObjectView::setMap(QGeoMap *map) -{ - QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data()); - if (d->m_map == map) - return; - - QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected - - for (int i = 0; i < m_userAddedMapObjects.size(); ++i) { - auto obj = m_userAddedMapObjects.at(i); - if (obj && obj->map() != map) - obj->setMap(map); - } - - if (!map) { - // Map was set, now it has ben re-set to NULL - flushDelegateModel(); - flushUserAddedMapObjects(); - d_ptr = new QMapObjectViewPrivateDefault(*d); - } else if (d->m_componentCompleted) { - // Map was null, now it's set AND delegateModel is already complete. - // some delegates may have been incubated but not added to the map. - for (int i = 0; i < m_pendingMapObjects.size(); ++i) { - auto obj = m_pendingMapObjects.at(i); - if (obj && obj->map() != map) - obj->setMap(map); - } - m_pendingMapObjects.clear(); - } -} - void QMapObjectView::classBegin() { QQmlContext *ctx = qmlContext(this); @@ -381,5 +350,36 @@ void QMapObjectView::flushUserAddedMapObjects() } } +void QMapObjectView::setMap(QGeoMap *map) +{ + QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data()); + if (d->m_map == map) + return; + + QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected + + for (int i = 0; i < m_userAddedMapObjects.size(); ++i) { + auto obj = m_userAddedMapObjects.at(i); + if (obj && obj->map() != map) + obj->setMap(map); + } + + if (!map) { + // Map was set, now it has ben re-set to NULL + flushDelegateModel(); + flushUserAddedMapObjects(); + d_ptr = new QMapObjectViewPrivateDefault(*d); + } else if (d->m_componentCompleted) { + // Map was null, now it's set AND delegateModel is already complete. + // some delegates may have been incubated but not added to the map. + for (int i = 0; i < m_pendingMapObjects.size(); ++i) { + auto obj = m_pendingMapObjects.at(i); + if (obj && obj->map() != map) + obj->setMap(map); + } + m_pendingMapObjects.clear(); + } +} + QT_END_NAMESPACE diff --git a/src/location/labs/qmappolygonobject.cpp b/src/location/labs/qmappolygonobject.cpp index adc3259f..1d495899 100644 --- a/src/location/labs/qmappolygonobject.cpp +++ b/src/location/labs/qmappolygonobject.cpp @@ -246,7 +246,8 @@ void QMapPolygonObject::setMap(QGeoMap *map) QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected if (!map) { - // Map was set, now it has ben re-set to NULL + // Map was set, now it has ben re-set to NULL, but not inside d_ptr. + // so m_map inside d_ptr can still be used to remove itself, inside the destructor. d_ptr = new QMapPolygonObjectPrivateDefault(*d); // Old pimpl deleted implicitly by QExplicitlySharedDataPointer } diff --git a/src/location/labs/qmappolylineobject.cpp b/src/location/labs/qmappolylineobject.cpp index bea79327..1c351962 100644 --- a/src/location/labs/qmappolylineobject.cpp +++ b/src/location/labs/qmappolylineobject.cpp @@ -209,7 +209,8 @@ void QMapPolylineObject::setMap(QGeoMap *map) QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected if (!map) { - // Map was set, now it has ben re-set to NULL + // Map was set, now it has ben re-set to NULL, but not inside d_ptr. + // so m_map inside d_ptr can still be used to remove itself, inside the destructor. d_ptr = new QMapPolylineObjectPrivateDefault(*d); // Old pimpl deleted implicitly by QExplicitlySharedDataPointer } diff --git a/src/location/labs/qmaprouteobject.cpp b/src/location/labs/qmaprouteobject.cpp index 7e36322c..c3365d30 100644 --- a/src/location/labs/qmaprouteobject.cpp +++ b/src/location/labs/qmaprouteobject.cpp @@ -170,7 +170,8 @@ void QMapRouteObject::setMap(QGeoMap *map) QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected if (!map) { - // Map was set, now it has ben re-set to NULL + // Map was set, now it has ben re-set to NULL, but not inside d_ptr. + // so m_map inside d_ptr can still be used to remove itself, inside the destructor. d_ptr = new QMapRouteObjectPrivate(*d); // Old pimpl deleted implicitly by QExplicitlySharedDataPointer } diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp new file mode 100644 index 00000000..e0e3a6d7 --- /dev/null +++ b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeomapobjectqsgsupport_p.h" +#include <QtLocation/private/qgeomap_p_p.h> + +QT_BEGIN_NAMESPACE + +static int findMapObject(QGeoMapObject *o, const QList<MapObject> &list) +{ + for (int i = 0; i < list.size(); ++i) + { + if (list.at(i).object.data() == o) + return i; + } + return -1; +} + +bool QGeoMapObjectQSGSupport::createMapObjectImplementation(QGeoMapObject *obj, QGeoMapPrivate *d) +{ + QExplicitlySharedDataPointer<QGeoMapObjectPrivate> pimpl = + QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(d->createMapObjectImplementation(obj)); + if (pimpl.constData()) { + bool res = obj->setImplementation(pimpl); + if (res) + emit m_map->sgNodeChanged(); + return res; + } + return false; +} + +QGeoMapObjectPrivate *QGeoMapObjectQSGSupport::createMapObjectImplementationPrivate(QGeoMapObject *obj) +{ + QGeoMapObjectPrivate *res = nullptr; + + { + QQSGMapObject *sgo = nullptr; + switch (obj->type()) { + case QGeoMapObject::PolylineType: { + QMapPolylineObjectPrivate &oldImpl = static_cast<QMapPolylineObjectPrivate &>(*obj->implementation()); + QMapPolylineObjectPrivateQSG *pimpl = + new QMapPolylineObjectPrivateQSG(oldImpl); + sgo = pimpl; + res = pimpl; + break; + } + case QGeoMapObject::PolygonType: { + QMapPolygonObjectPrivate &oldImpl = static_cast<QMapPolygonObjectPrivate &>(*obj->implementation()); + QMapPolygonObjectPrivateQSG *pimpl = + new QMapPolygonObjectPrivateQSG(oldImpl); + sgo = pimpl; + res = pimpl; + break; + } + case QGeoMapObject::CircleType: { + QMapCircleObjectPrivate &oldImpl = static_cast<QMapCircleObjectPrivate &>(*obj->implementation()); + QMapCircleObjectPrivateQSG *pimpl = + new QMapCircleObjectPrivateQSG(oldImpl); + sgo = pimpl; + res = pimpl; + break; + } + case QGeoMapObject::RouteType: { + QMapRouteObjectPrivate &oldImpl = static_cast<QMapRouteObjectPrivate &>(*obj->implementation()); + QMapRouteObjectPrivateQSG *pimpl = + new QMapRouteObjectPrivateQSG(oldImpl); + sgo = pimpl; + res = pimpl; + break; + } + case QGeoMapObject::IconType: { + QMapIconObjectPrivate &oldImpl = static_cast<QMapIconObjectPrivate &>(*obj->implementation()); + QMapIconObjectPrivateQSG *pimpl = + new QMapIconObjectPrivateQSG(oldImpl); + sgo = pimpl; + res = pimpl; + break; + } + default: + // Use the following warning only for debugging purposes. + // qWarning() << "QGeoMapObjectQSGSupport::createMapObjectImplementationPrivate: not instantiating pimpl for unsupported object type " << obj->type(); + break; + } + + if (res) { + QPointer<QGeoMapObject> p(obj); + MapObject mo(p, sgo); + m_pendingMapObjects << mo; + } + } + return res; +} + +QList<QGeoMapObject *> QGeoMapObjectQSGSupport::mapObjects() const +{ + return QList<QGeoMapObject *>(); +} + +void QGeoMapObjectQSGSupport::removeMapObject(QGeoMapObject *obj) +{ + int idx = findMapObject(obj, m_mapObjects); + if (idx >= 0) { + const MapObject &mo = m_mapObjects.takeAt(idx); + obj->disconnect(m_map); + m_removedMapObjects << mo; + emit m_map->sgNodeChanged(); + } else { + idx = findMapObject(obj, m_pendingMapObjects); + if (idx >= 0) { + m_pendingMapObjects.removeAt(idx); + obj->disconnect(m_map); + } else { + // obj not here. + } + } +} + +void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *window) +{ + for (int i = 0; i < m_removedMapObjects.size(); ++i) { + MapObject mo = m_removedMapObjects[i]; + if (mo.qsgNode) { + root->removeChildNode(mo.qsgNode); + delete mo.qsgNode; + mo.qsgNode = nullptr; + // mo.sgObject is now invalid as it is destroyed right after appending + // mo to m_removedMapObjects + } + } + m_removedMapObjects.clear(); + + for (int i = 0; i < m_mapObjects.size(); ++i) { + // already added as node + if (Q_UNLIKELY(!m_mapObjects.at(i).object)) { + qWarning() << "unexpected NULL pointer in m_mapObjects at "<<i; + continue; + } + + MapObject &mo = m_mapObjects[i]; + QQSGMapObject *sgo = mo.sgObject; + QSGNode *oldNode = mo.qsgNode; + mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, root, window); + if (Q_UNLIKELY(!mo.qsgNode)) { + qWarning() << "updateMapObjectNode for "<<mo.object->type() << " returned NULL"; + } else if (mo.visibleNode && (mo.visibleNode->visible() != mo.object->visible())) { + mo.visibleNode->setVisible(mo.object->visible()); + mo.qsgNode->markDirty(QSGNode::DirtySubtreeBlocked); + } + } + + QList<int> toRemove; + for (int i = 0; i < m_pendingMapObjects.size(); ++i) { + // already added as node + MapObject &mo = m_pendingMapObjects[i]; + QQSGMapObject *sgo = mo.sgObject; + QSGNode *oldNode = mo.qsgNode; + sgo->updateGeometry(); // or subtree will be blocked + mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, root, window); + if (mo.qsgNode) { + if (mo.visibleNode && (mo.visibleNode->visible() != mo.object->visible())) { + mo.visibleNode->setVisible(mo.object->visible()); + mo.qsgNode->markDirty(QSGNode::DirtySubtreeBlocked); + } + m_mapObjects << mo; + toRemove.push_front(i); + QObject::connect(mo.object, SIGNAL(visibleChanged()), m_map, SIGNAL(sgNodeChanged())); + } else { + // leave it to be processed, don't spit warnings + } + } + + for (int i: qAsConst(toRemove)) + m_pendingMapObjects.removeAt(i); +} + +void QGeoMapObjectQSGSupport::updateObjectsGeometry() +{ + for (int i = 0; i < m_mapObjects.size(); ++i) { + // already added as node + if (Q_UNLIKELY(!m_mapObjects.at(i).object)) { + qWarning() << "unexpected NULL pointer in m_mapObjects at "<<i; + continue; + } + + QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; + sgo->updateGeometry(); + } + emit m_map->sgNodeChanged(); +} + +QT_END_NAMESPACE diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h new file mode 100644 index 00000000..bb0477c5 --- /dev/null +++ b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGEOMAPOBJECTQSGSUPPORT_P_H +#define QGEOMAPOBJECTQSGSUPPORT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtLocation/private/qlocationglobal_p.h> +#include <QtLocation/private/qgeomapobject_p.h> +#include <QtLocation/private/qgeomapobject_p_p.h> +#include <QtLocation/private/qmappolylineobjectqsg_p_p.h> +#include <QtLocation/private/qmappolygonobjectqsg_p_p.h> +#include <QtLocation/private/qmapcircleobjectqsg_p_p.h> +#include <QtLocation/private/qmaprouteobjectqsg_p_p.h> +#include <QtLocation/private/qmapiconobjectqsg_p_p.h> +#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> +#include <QtCore/qpointer.h> + +QT_BEGIN_NAMESPACE + +struct Q_LOCATION_PRIVATE_EXPORT MapObject { + MapObject(QPointer<QGeoMapObject> &o, QQSGMapObject *sgo) + : object(o), sgObject(sgo) {} + + QPointer<QGeoMapObject> object; + QQSGMapObject *sgObject = nullptr; // this is a QMap*ObjectPrivateQSG. it becomes invalid when the pimpl is destroyed + VisibleNode *visibleNode = nullptr; // This is a Map*Node (like a MapPolygonNode) that is a QSGNode. This doesn't disappear by itself + QSGNode *qsgNode = nullptr; +}; + +class Q_LOCATION_PRIVATE_EXPORT QGeoMapObjectQSGSupport +{ +public: + bool createMapObjectImplementation(QGeoMapObject *obj, QGeoMapPrivate *d); + QGeoMapObjectPrivate *createMapObjectImplementationPrivate(QGeoMapObject *obj); + QList<QGeoMapObject *> mapObjects() const; + void removeMapObject(QGeoMapObject *obj); + void updateMapObjects(QSGNode *root, QQuickWindow *window); + void updateObjectsGeometry(); + + QList<MapObject> m_mapObjects; + QList<MapObject> m_pendingMapObjects; + QList<MapObject> m_removedMapObjects; + QGeoMap *m_map = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QGEOMAPOBJECTQSGSUPPORT_P_H diff --git a/src/location/labs/qsg/qmapcircleobjectqsg.cpp b/src/location/labs/qsg/qmapcircleobjectqsg.cpp index 9fe3ee0a..775016b9 100644 --- a/src/location/labs/qsg/qmapcircleobjectqsg.cpp +++ b/src/location/labs/qsg/qmapcircleobjectqsg.cpp @@ -60,7 +60,8 @@ QMapCircleObjectPrivateQSG::QMapCircleObjectPrivateQSG(const QMapCircleObjectPri QMapCircleObjectPrivateQSG::~QMapCircleObjectPrivateQSG() { - + if (m_map) + m_map->removeMapObject(q); } void QMapCircleObjectPrivateQSG::updateCirclePath() @@ -147,13 +148,18 @@ QGeoMapObjectPrivate *QMapCircleObjectPrivateQSG::clone() return new QMapCircleObjectPrivateQSG(static_cast<QMapCircleObjectPrivate &>(*this)); } -QSGNode *QMapCircleObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * /*window*/) +QSGNode *QMapCircleObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow * /*window*/) { +// Q_UNUSED(visibleNode) // coz of -Werror=unused-but-set-parameter MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode); bool created = false; if (!node) { node = new MapPolygonNode(); + *visibleNode = static_cast<VisibleNode *>(node); created = true; } diff --git a/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h b/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h index 17d8568a..4e8162fa 100644 --- a/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h +++ b/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h @@ -72,7 +72,10 @@ public: // QQSGMapObject void updateGeometry() override; - QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override; + QSGNode *updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) override; // QGeoMapCirclePrivate interface void setCenter(const QGeoCoordinate ¢er) override; diff --git a/src/location/labs/qsg/qmapiconobjectqsg.cpp b/src/location/labs/qsg/qmapiconobjectqsg.cpp index 53d16179..47c39695 100644 --- a/src/location/labs/qsg/qmapiconobjectqsg.cpp +++ b/src/location/labs/qsg/qmapiconobjectqsg.cpp @@ -43,26 +43,19 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqml.h> #include <QtNetwork/qnetworkaccessmanager.h> +#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> QT_BEGIN_NAMESPACE -class RootNode : public QSGTransformNode +class RootNode : public QSGTransformNode, public VisibleNode { public: - RootNode() : QSGTransformNode() - { } + RootNode() { } bool isSubtreeBlocked() const override { - return m_blocked; + return subtreeBlocked(); } - - void setSubtreeBlocked(bool blocked) - { - m_blocked = blocked; - } - - bool m_blocked = false; }; QMapIconObjectPrivateQSG::QMapIconObjectPrivateQSG(QGeoMapObject *q) @@ -80,7 +73,8 @@ QMapIconObjectPrivateQSG::QMapIconObjectPrivateQSG(const QMapIconObjectPrivate & QMapIconObjectPrivateQSG::~QMapIconObjectPrivateQSG() { - + if (m_map) + m_map->removeMapObject(q); } void QMapIconObjectPrivateQSG::updateGeometry() @@ -100,8 +94,12 @@ void QMapIconObjectPrivateQSG::updateGeometry() // TODO: support and test for zoomLevel } -QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode * root, QQuickWindow *window) +QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) { + Q_UNUSED(visibleNode) bool created = false; RootNode *node = static_cast<RootNode *>(oldNode); if (!node) { @@ -109,6 +107,7 @@ QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode m_imageNode = window->createImageNode(); m_imageNode->setOwnsTexture(true); node->appendChildNode(m_imageNode); + *visibleNode = static_cast<VisibleNode *>(node); created = true; } diff --git a/src/location/labs/qsg/qmapiconobjectqsg_p_p.h b/src/location/labs/qsg/qmapiconobjectqsg_p_p.h index a2f7cf40..c57828af 100644 --- a/src/location/labs/qsg/qmapiconobjectqsg_p_p.h +++ b/src/location/labs/qsg/qmapiconobjectqsg_p_p.h @@ -69,7 +69,10 @@ public: // QQSGMapObject void updateGeometry() override; - QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override; + QSGNode *updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) override; // QGeoMapIconPrivate interface void setCoordinate(const QGeoCoordinate &coordinate) override; diff --git a/src/location/labs/qsg/qmappolygonobjectqsg.cpp b/src/location/labs/qsg/qmappolygonobjectqsg.cpp index 27dcc80f..b9602a3a 100644 --- a/src/location/labs/qsg/qmappolygonobjectqsg.cpp +++ b/src/location/labs/qsg/qmappolygonobjectqsg.cpp @@ -57,7 +57,8 @@ QMapPolygonObjectPrivateQSG::QMapPolygonObjectPrivateQSG(const QMapPolygonObject QMapPolygonObjectPrivateQSG::~QMapPolygonObjectPrivateQSG() { - + if (m_map) + m_map->removeMapObject(q); } QList<QDoubleVector2D> QMapPolygonObjectPrivateQSG::projectPath() @@ -74,13 +75,18 @@ QList<QDoubleVector2D> QMapPolygonObjectPrivateQSG::projectPath() return geopathProjected_; } -QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * /*window*/) +QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow */*window*/) { + Q_UNUSED(visibleNode) MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode); bool created = false; if (!node) { node = new MapPolygonNode(); + *visibleNode = static_cast<VisibleNode *>(node); created = true; } diff --git a/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h b/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h index bd5efcff..b288528a 100644 --- a/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h +++ b/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h @@ -68,7 +68,10 @@ public: // QQSGMapObject void updateGeometry() override; - QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override; + QSGNode *updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) override; // QGeoMapPolylinePrivate interface QList<QGeoCoordinate> path() const override; diff --git a/src/location/labs/qsg/qmappolylineobjectqsg.cpp b/src/location/labs/qsg/qmappolylineobjectqsg.cpp index c0c3854e..6b782c77 100644 --- a/src/location/labs/qsg/qmappolylineobjectqsg.cpp +++ b/src/location/labs/qsg/qmappolylineobjectqsg.cpp @@ -61,7 +61,8 @@ QMapPolylineObjectPrivateQSG::QMapPolylineObjectPrivateQSG(const QMapPolylineObj QMapPolylineObjectPrivateQSG::~QMapPolylineObjectPrivateQSG() { - + if (m_map) + m_map->removeMapObject(q); } QList<QDoubleVector2D> QMapPolylineObjectPrivateQSG::projectPath() @@ -96,13 +97,18 @@ void QMapPolylineObjectPrivateQSG::updateGeometry() m_geometry.translate(origin - m_geometry.firstPointOffset()); } -QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * /*window*/) +QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow */*window*/) { + Q_UNUSED(visibleNode) MapPolylineNode *node = static_cast<MapPolylineNode *>(oldNode); bool created = false; if (!node) { node = new MapPolylineNode(); + *visibleNode = static_cast<VisibleNode *>(node); created = true; } diff --git a/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h b/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h index 52b5e89a..792413e5 100644 --- a/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h +++ b/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h @@ -68,7 +68,10 @@ public: // QQSGMapObject void updateGeometry() override; - QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override; + QSGNode *updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) override; // QGeoMapPolylinePrivate interface QList<QGeoCoordinate> path() const override; diff --git a/src/location/labs/qsg/qmaprouteobjectqsg.cpp b/src/location/labs/qsg/qmaprouteobjectqsg.cpp index a8728e08..eaea64f3 100644 --- a/src/location/labs/qsg/qmaprouteobjectqsg.cpp +++ b/src/location/labs/qsg/qmaprouteobjectqsg.cpp @@ -57,7 +57,8 @@ QMapRouteObjectPrivateQSG::QMapRouteObjectPrivateQSG(const QMapRouteObjectPrivat QMapRouteObjectPrivateQSG::~QMapRouteObjectPrivateQSG() { - + if (m_map) + m_map->removeMapObject(q); } void QMapRouteObjectPrivateQSG::updateGeometry() @@ -65,9 +66,12 @@ void QMapRouteObjectPrivateQSG::updateGeometry() m_polyline->updateGeometry(); } -QSGNode *QMapRouteObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * window) +QSGNode *QMapRouteObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) { - return m_polyline->updateMapObjectNode(oldNode, root, window); + return m_polyline->updateMapObjectNode(oldNode, visibleNode, root, window); } void QMapRouteObjectPrivateQSG::setRoute(const QDeclarativeGeoRoute *route) diff --git a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h index 1c612532..0c946259 100644 --- a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h +++ b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h @@ -68,7 +68,10 @@ public: // QQSGMapObject void updateGeometry() override; - QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override; + QSGNode *updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window) override; // QMapRouteObjectPrivate interface void setRoute(const QDeclarativeGeoRoute *route) override; diff --git a/src/location/labs/qsg/qqsgmapobject.cpp b/src/location/labs/qsg/qqsgmapobject.cpp index 5b4f7dbf..ccda12d8 100644 --- a/src/location/labs/qsg/qqsgmapobject.cpp +++ b/src/location/labs/qsg/qqsgmapobject.cpp @@ -35,6 +35,7 @@ ****************************************************************************/ #include "qqsgmapobject_p.h" +#include <QDebug> QT_BEGIN_NAMESPACE @@ -48,7 +49,10 @@ QQSGMapObject::~QQSGMapObject() } -QSGNode *QQSGMapObject::updateMapObjectNode(QSGNode *oldNode, QSGNode * /*root*/, QQuickWindow * /*window*/) +QSGNode *QQSGMapObject::updateMapObjectNode(QSGNode *oldNode, + VisibleNode **/*visibleNode*/, + QSGNode * /*root*/, + QQuickWindow * /*window*/) { delete oldNode; return 0; diff --git a/src/location/labs/qsg/qqsgmapobject_p.h b/src/location/labs/qsg/qqsgmapobject_p.h index d3e54a68..1aecc990 100644 --- a/src/location/labs/qsg/qqsgmapobject_p.h +++ b/src/location/labs/qsg/qqsgmapobject_p.h @@ -40,6 +40,7 @@ #include <QtLocation/private/qlocationglobal_p.h> #include <QtQuick/QSGOpacityNode> #include <QtLocation/private/qgeomapobject_p.h> +#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> QT_BEGIN_NAMESPACE @@ -50,10 +51,11 @@ public: QQSGMapObject(); virtual ~QQSGMapObject(); - virtual QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window); + virtual QSGNode *updateMapObjectNode(QSGNode *oldNode, + VisibleNode **visibleNode, + QSGNode *root, + QQuickWindow *window); virtual void updateGeometry(); - - QSGNode *node = nullptr; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h index e67340be..f6be5cae 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -151,13 +151,13 @@ public: virtual bool fitViewportToGeoRectangle(const QGeoRectangle &rectangle); virtual void setCopyrightVisible(bool visible); + virtual void removeMapObject(QGeoMapObject *obj); protected: QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0); void setCameraData(const QGeoCameraData &cameraData); void setCameraCapabilities(const QGeoCameraCapabilities &cameraCapabilities); virtual QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) = 0; - virtual void removeMapObject(QGeoMapObject *obj); Q_SIGNALS: void cameraDataChanged(const QGeoCameraData &cameraData); diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h index 18c72202..47780c47 100644 --- a/src/location/maps/qgeomap_p_p.h +++ b/src/location/maps/qgeomap_p_p.h @@ -80,6 +80,7 @@ public: const QGeoCameraCapabilities &cameraCapabilities() const; static const QGeoMapPrivate *get(const QGeoMap &map); + virtual QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj); protected: /* Hooks into the actual map implementations */ @@ -90,7 +91,6 @@ protected: virtual void addMapItem(QDeclarativeGeoMapItemBase *item); virtual void removeMapItem(QDeclarativeGeoMapItemBase *item); - virtual QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj); virtual QList<QGeoMapObject *> mapObjects() const; virtual void changeViewportSize(const QSize &size) = 0; // called by QGeoMap::setSize() diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp index 99146801..af0e263b 100644 --- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp +++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp @@ -47,12 +47,8 @@ #include <QtLocation/private/qmapcircleobjectqsg_p_p.h> #include <QtLocation/private/qmaprouteobjectqsg_p_p.h> #include <QtLocation/private/qmapiconobjectqsg_p_p.h> -struct MapObject { - MapObject(QPointer<QGeoMapObject> &o, QQSGMapObject *sgo) - : object(o), sgObject(sgo) {} - QPointer<QGeoMapObject> object; - QQSGMapObject *sgObject = nullptr; -}; +#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> +#include <QtLocation/private/qgeomapobjectqsgsupport_p.h> #endif QT_BEGIN_NAMESPACE @@ -61,18 +57,16 @@ class QGeoMapItemsOverlayPrivate : public QGeoMapPrivate { Q_DECLARE_PUBLIC(QGeoMapItemsOverlay) public: - QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine); + QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map); virtual ~QGeoMapItemsOverlayPrivate(); #ifdef LOCATIONLABS QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj) override; virtual QList<QGeoMapObject *> mapObjects() const override; - static int findMapObject(QGeoMapObject *o, const QList<MapObject> &list); void removeMapObject(QGeoMapObject *obj); void updateMapObjects(QSGNode *root, QQuickWindow *window); - QList<MapObject> m_mapObjects; - QList<MapObject> m_pendingMapObjects; + QGeoMapObjectQSGSupport m_qsgSupport; #endif void updateObjectsGeometry(); @@ -83,7 +77,7 @@ protected: }; QGeoMapItemsOverlay::QGeoMapItemsOverlay(QGeoMappingManagerEngineItemsOverlay *engine, QObject *parent) - : QGeoMap(*(new QGeoMapItemsOverlayPrivate(engine)), parent) + : QGeoMap(*(new QGeoMapItemsOverlayPrivate(engine, this)), parent) { } @@ -99,6 +93,16 @@ QGeoMap::Capabilities QGeoMapItemsOverlay::capabilities() const | SupportsAnchoringCoordinate); } +bool QGeoMapItemsOverlay::createMapObjectImplementation(QGeoMapObject *obj) +{ +#ifndef LOCATIONLABS + return false; +#else + Q_D(QGeoMapItemsOverlay); + return d->m_qsgSupport.createMapObjectImplementation(obj, d); +#endif +} + QSGNode *QGeoMapItemsOverlay::updateSceneGraph(QSGNode *node, QQuickWindow *window) { #ifndef LOCATIONLABS @@ -119,9 +123,18 @@ QSGNode *QGeoMapItemsOverlay::updateSceneGraph(QSGNode *node, QQuickWindow *wind #endif } -QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine) +void QGeoMapItemsOverlay::removeMapObject(QGeoMapObject *obj) +{ +#ifdef LOCATIONLABS + Q_D(QGeoMapItemsOverlay); + d->removeMapObject(obj); +#endif +} + +QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map) : QGeoMapPrivate(engine, new QGeoProjectionWebMercator) { + m_qsgSupport.m_map = map; } QGeoMapItemsOverlayPrivate::~QGeoMapItemsOverlayPrivate() @@ -131,138 +144,29 @@ QGeoMapItemsOverlayPrivate::~QGeoMapItemsOverlayPrivate() #ifdef LOCATIONLABS QGeoMapObjectPrivate *QGeoMapItemsOverlayPrivate::createMapObjectImplementation(QGeoMapObject *obj) { - switch (obj->type()) { - case QGeoMapObject::PolylineType: { - QMapPolylineObjectPrivate &oldImpl = static_cast<QMapPolylineObjectPrivate &>(*obj->implementation()); - QMapPolylineObjectPrivateQSG *pimpl = - new QMapPolylineObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::PolygonType: { - QMapPolygonObjectPrivate &oldImpl = static_cast<QMapPolygonObjectPrivate &>(*obj->implementation()); - QMapPolygonObjectPrivateQSG *pimpl = - new QMapPolygonObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::CircleType: { - QMapCircleObjectPrivate &oldImpl = static_cast<QMapCircleObjectPrivate &>(*obj->implementation()); - QMapCircleObjectPrivateQSG *pimpl = - new QMapCircleObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::RouteType: { - QMapRouteObjectPrivate &oldImpl = static_cast<QMapRouteObjectPrivate &>(*obj->implementation()); - QMapRouteObjectPrivateQSG *pimpl = - new QMapRouteObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - case QGeoMapObject::IconType: { - QMapIconObjectPrivate &oldImpl = static_cast<QMapIconObjectPrivate &>(*obj->implementation()); - QMapIconObjectPrivateQSG *pimpl = - new QMapIconObjectPrivateQSG(oldImpl); - QPointer<QGeoMapObject> p(obj); - MapObject mo(p, pimpl); - m_pendingMapObjects << mo; - return pimpl; - } - default: - qWarning() << "Unsupported object type: " << obj->type(); - break; - } - return nullptr; + return m_qsgSupport.createMapObjectImplementationPrivate(obj); } QList<QGeoMapObject *> QGeoMapItemsOverlayPrivate::mapObjects() const { - return QList<QGeoMapObject *>(); -} - -int QGeoMapItemsOverlayPrivate::findMapObject(QGeoMapObject *o, const QList<MapObject> &list) -{ - for (int i = 0; i < list.size(); ++i) - { - if (list.at(i).object.data() == o) - return i; - } - return -1; + return m_qsgSupport.mapObjects(); } void QGeoMapItemsOverlayPrivate::removeMapObject(QGeoMapObject *obj) { - int idx = findMapObject(obj, m_mapObjects); - if (idx >= 0) { - m_mapObjects.removeAt(idx); - } else { - idx = findMapObject(obj, m_pendingMapObjects); - if (idx >= 0) { - m_pendingMapObjects.removeAt(idx); - } else { - // obj not here. - } - } + m_qsgSupport.removeMapObject(obj); } void QGeoMapItemsOverlayPrivate::updateMapObjects(QSGNode *root, QQuickWindow *window) { - for (int i = 0; i < m_mapObjects.size(); ++i) { - // already added as node - if (!m_mapObjects.at(i).object) { - qWarning() << "m_mapObjects at "<<i<< " NULLed!!"; - continue; - } - - QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; - QSGNode *oldNode = sgo->node; - sgo->node = sgo->updateMapObjectNode(oldNode, root, window); - } - - QList<int> toRemove; - for (int i = 0; i < m_pendingMapObjects.size(); ++i) { - // already added as node - QQSGMapObject *sgo = m_pendingMapObjects.at(i).sgObject; - QSGNode *oldNode = sgo->node; - sgo->updateGeometry(); // or subtree will be blocked - sgo->node = sgo->updateMapObjectNode(oldNode, root, window); - if (sgo->node) { - m_mapObjects << m_pendingMapObjects.at(i); - toRemove.push_front(i); - } else { - // leave it to be processed - } - } - - for (int i: qAsConst(toRemove)) - m_pendingMapObjects.removeAt(i); + m_qsgSupport.updateMapObjects(root, window); } #endif void QGeoMapItemsOverlayPrivate::updateObjectsGeometry() { #ifdef LOCATIONLABS - Q_Q(QGeoMapItemsOverlay); - for (int i = 0; i < m_mapObjects.size(); ++i) { - // already added as node - if (!m_mapObjects.at(i).object) { - qWarning() << "m_mapObjects at "<<i<< " NULLed!!"; - continue; - } - - QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; - sgo->updateGeometry(); - } - emit q->sgNodeChanged(); + m_qsgSupport.updateObjectsGeometry(); #endif } diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h index 42a59f06..1594ffb3 100644 --- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h +++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h @@ -54,6 +54,8 @@ public: virtual ~QGeoMapItemsOverlay(); QGeoMap::Capabilities capabilities() const override; + bool createMapObjectImplementation(QGeoMapObject *obj) override; + void removeMapObject(QGeoMapObject *obj) override; protected: QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override; |