diff options
Diffstat (limited to 'src/location/declarativemaps/qdeclarativegeomap.cpp')
-rw-r--r-- | src/location/declarativemaps/qdeclarativegeomap.cpp | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index 7fd5f78a..fc282829 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -198,7 +198,7 @@ QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent) setAcceptHoverEvents(false); setAcceptedMouseButtons(Qt::LeftButton); setFlags(QQuickItem::ItemHasContents | QQuickItem::ItemClipsChildrenToShape); - setFiltersChildMouseEvents(true); + setFiltersChildMouseEvents(true); // needed for childMouseEventFilter to work. m_activeMapType = new QDeclarativeGeoMapType(QGeoMapType(QGeoMapType::NoMap, tr("No Map"), @@ -707,7 +707,8 @@ void QDeclarativeGeoMap::mappingManagerInitialized() emit m_map->copyrightsChanged(copyrightImage); - connect(m_map.data(), &QGeoMap::sgNodeChanged, this, &QQuickItem::update); + connect(window(), &QQuickWindow::beforeSynchronizing, this, &QDeclarativeGeoMap::updateItemToWindowTransform, Qt::DirectConnection); + connect(m_map.data(), &QGeoMap::sgNodeChanged, this, &QDeclarativeGeoMap::onSGNodeChanged); connect(m_map.data(), &QGeoMap::cameraCapabilitiesChanged, this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged); // This prefetches a buffer around the map @@ -2175,6 +2176,38 @@ bool QDeclarativeGeoMap::removeMapItemView_real(QDeclarativeGeoMapItemView *item return removeMapItemGroup_real(itemView); // at this point, all delegate instances have been removed. } +void QDeclarativeGeoMap::updateItemToWindowTransform() +{ + if (!m_initialized) + return; + + // Update itemToWindowTransform into QGeoProjection + const QTransform item2WindowOld = m_map->geoProjection().itemToWindowTransform(); + QTransform item2Window = QQuickItemPrivate::get(this)->itemToWindowTransform(); + if (!property("layer").isNull() && property("layer").value<QObject *>()->property("enabled").toBool()) + item2Window.reset(); // When layer is enabled, the item is rendered offscreen with no transformation, then the layer is applied + + m_map->setItemToWindowTransform(item2Window); + + // This method is called at every redraw, including those redraws not generated by + // sgNodeChanged. + // In these cases, *if* the item2windowTransform has changed (e.g., if transformation of + // the item or one of its ancestors changed), a forced update of the map items using accelerated + // GL implementation has to be performed in order to have them pulling the updated itemToWindowTransform. + if (!m_sgNodeHasChanged && item2WindowOld != item2Window) { + for (auto i: qAsConst(m_mapItems)) + i->setMaterialDirty(); + } + + m_sgNodeHasChanged = false; +} + +void QDeclarativeGeoMap::onSGNodeChanged() +{ + m_sgNodeHasChanged = true; + update(); +} + /*! \qmlmethod void QtLocation::Map::addMapItemView(MapItemView itemView) @@ -2289,17 +2322,31 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF } /*! - \qmlmethod void QtLocation::Map::fitViewportToMapItems() + \qmlmethod void QtLocation::Map::fitViewportToMapItems(list<MapItems> items = {}) + + If no argument is provided, fits the current viewport to the boundary of all map items. + The camera is positioned in the center of the map items, and at the largest integral zoom level + possible which allows all map items to be visible on screen. + If \a items is provided, fits the current viewport to the boundary of the specified map items only. - Fits the current viewport to the boundary of all map items. The camera is positioned - in the center of the map items, and at the largest integral zoom level possible which - allows all map items to be visible on screen. + \note This method gained the optional \a items argument since Qt 5.15. + In previous releases, this method fitted the map to all map items. \sa fitViewportToVisibleMapItems */ -void QDeclarativeGeoMap::fitViewportToMapItems() +void QDeclarativeGeoMap::fitViewportToMapItems(const QVariantList &items) { - fitViewportToMapItemsRefine(true, false); + if (items.size()) { + QList<QPointer<QDeclarativeGeoMapItemBase> > itms; + for (const QVariant &i: items) { + QDeclarativeGeoMapItemBase *itm = qobject_cast<QDeclarativeGeoMapItemBase *>(i.value<QObject *>()); + if (itm) + itms.append(itm); + } + fitViewportToMapItemsRefine(itms, true, false); + } else { + fitViewportToMapItemsRefine(m_mapItems, true, false); + } } /*! @@ -2313,18 +2360,20 @@ void QDeclarativeGeoMap::fitViewportToMapItems() */ void QDeclarativeGeoMap::fitViewportToVisibleMapItems() { - fitViewportToMapItemsRefine(true, true); + fitViewportToMapItemsRefine(m_mapItems, true, true); } /*! \internal */ -void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisible) +void QDeclarativeGeoMap::fitViewportToMapItemsRefine(const QList<QPointer<QDeclarativeGeoMapItemBase> > &mapItems, + bool refine, + bool onlyVisible) { if (!m_map) return; - if (m_mapItems.size() == 0) + if (mapItems.size() == 0) return; double minX = qInf(); @@ -2339,10 +2388,10 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisib // find bounds of all map items int itemCount = 0; - for (int i = 0; i < m_mapItems.count(); ++i) { - if (!m_mapItems.at(i)) + for (int i = 0; i < mapItems.count(); ++i) { + if (!mapItems.at(i)) continue; - QDeclarativeGeoMapItemBase *item = m_mapItems.at(i).data(); + QDeclarativeGeoMapItemBase *item = mapItems.at(i).data(); if (!item || (onlyVisible && (!item->isVisible() || item->mapItemOpacity() <= 0.0))) continue; @@ -2393,7 +2442,7 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisib if (itemCount == 0) { if (haveQuickItem) - fitViewportToMapItemsRefine(false, onlyVisible); + fitViewportToMapItemsRefine(mapItems, false, onlyVisible); return; } double bboxWidth = maxX - minX; @@ -2423,7 +2472,7 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisib // as map quick items retain the same screen size after the camera zooms in/out // we refine the viewport again to achieve better results if (refine) - fitViewportToMapItemsRefine(false, onlyVisible); + fitViewportToMapItemsRefine(mapItems, false, onlyVisible); } /*! |