diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-03-09 14:42:38 +0100 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-03-22 11:13:32 +0000 |
commit | 53b8d29733d912ce25dd45a6ceb9d1f20c4a998a (patch) | |
tree | ec4a6073d1bc1d21ab6fca0003608d888d1ec9fa /src/location | |
parent | 5c7e6ead198af76022df2bc9ecfb88e727b26bc5 (diff) | |
download | qtlocation-53b8d29733d912ce25dd45a6ceb9d1f20c4a998a.tar.gz |
Fix for disappearing MapQuickItems with tilted camera
This patch fixes a bug that makes MapQuickItem disappear when
the zoomLevel property is set, the camera is tilted and zoomed in
very close to the item, causing the coordinate of the map quick item
to end behind the camera.
Task-number: QTBUG-59397
Change-Id: Iae92204917729eb9daaf8592db318613bf57b966
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src/location')
-rw-r--r-- | src/location/declarativemaps/qdeclarativegeomapquickitem.cpp | 32 | ||||
-rw-r--r-- | src/location/declarativemaps/qdeclarativegeomapquickitem_p.h | 2 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 16 |
3 files changed, 34 insertions, 16 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp index 5a10f39f..0976bd06 100644 --- a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp +++ b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp @@ -139,6 +139,7 @@ QDeclarativeGeoMapQuickItem::QDeclarativeGeoMapQuickItem(QQuickItem *parent) opacityContainer_ = new QQuickItem(this); opacityContainer_->setParentItem(this); opacityContainer_->setFlag(ItemHasContents, true); + setFiltersChildMouseEvents(true); } QDeclarativeGeoMapQuickItem::~QDeclarativeGeoMapQuickItem() {} @@ -181,6 +182,20 @@ void QDeclarativeGeoMapQuickItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap * polishAndUpdate(); } } +// See QQuickMultiPointTouchArea::childMouseEventFilter for reference +bool QDeclarativeGeoMapQuickItem::childMouseEventFilter(QQuickItem *receiver, QEvent *event) +{ + if (isEnabled() && isVisible()) { + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::TouchBegin: + dragStartCoordinate_ = coordinate_; + default: + break; + } + } + return QQuickItem::childMouseEventFilter(receiver, event); +} /*! \internal @@ -195,10 +210,19 @@ void QDeclarativeGeoMapQuickItem::geometryChanged(const QRectF &newGeometry, con QGeoCoordinate newCoordinate; // with zoomLevel set the anchorPoint has to be factored into the transformation to properly transform around it. - if (zoomLevel_ != 0.0) - newCoordinate = map()->geoProjection().itemPositionToCoordinate(QDoubleVector2D(x(), y()), false); - else + if (zoomLevel_ != 0.0) { + // When dragStartCoordinate_ can't be projected to screen, dragging must be disabled. + if (!map()->geoProjection().isProjectable(map()->geoProjection().geoToWrappedMapProjection(dragStartCoordinate_))) + return; + + QDoubleVector2D pos = map()->geoProjection().coordinateToItemPosition(dragStartCoordinate_, false); + // oldGeometry.topLeft() is always intended to be (0,0), even when for some reason it's not. + pos.setX(pos.x() + newGeometry.topLeft().x()); + pos.setY(pos.y() + newGeometry.topLeft().y()); + newCoordinate = map()->geoProjection().itemPositionToCoordinate(pos, false); + } else { newCoordinate = map()->geoProjection().itemPositionToCoordinate(QDoubleVector2D(x(), y()) + QDoubleVector2D(anchorPoint_), false); + } if (newCoordinate.isValid()) setCoordinate(newCoordinate); @@ -367,7 +391,7 @@ void QDeclarativeGeoMapQuickItem::updatePolish() matrix_->appendToItem(opacityContainer_); } matrix_->setMatrix(map()->geoProjection().quickItemTransformation(coordinate(), anchorPoint_, zoomLevel_)); - setPositionOnMap(coordinate(), QPointF(0,0)); + setPosition(QPointF(0,0)); } else { if (matrix_) matrix_->setMatrix(QMatrix4x4()); diff --git a/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h b/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h index cce94d85..2035a997 100644 --- a/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h +++ b/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h @@ -108,6 +108,7 @@ Q_SIGNALS: protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; void updatePolish() Q_DECL_OVERRIDE; + bool childMouseEventFilter(QQuickItem *item, QEvent *event) Q_DECL_OVERRIDE; protected Q_SLOTS: virtual void afterChildrenChanged() Q_DECL_OVERRIDE; @@ -115,6 +116,7 @@ protected Q_SLOTS: private: qreal scaleFactor(); + QGeoCoordinate dragStartCoordinate_; QGeoCoordinate coordinate_; QGeoRectangle geoshape_; QPointer<QQuickItem> sourceItem_; diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp index 1a9981d3..81f3a947 100644 --- a/src/location/maps/qgeoprojection.cpp +++ b/src/location/maps/qgeoprojection.cpp @@ -258,11 +258,6 @@ QMatrix4x4 QGeoProjectionWebMercator::quickItemTransformation(const QGeoCoordina const QDoubleVector2D anchorScaled = QDoubleVector2D(anchorPoint.x(), anchorPoint.y()) * scale; const QDoubleVector2D anchorMercator = anchorScaled / mapWidth(); - // Check for coord OOB, only coordinate is going to be projected to item position, so - // testing also coordAnchored might be superfluous - if (!isProjectable(coordWrapped)) - return QMatrix4x4(); - const QDoubleVector2D coordAnchored = coordWrapped - anchorMercator; const QDoubleVector2D coordAnchoredScaled = coordAnchored * m_sideLength; QDoubleMatrix4x4 matTranslateScale; @@ -272,21 +267,18 @@ QMatrix4x4 QGeoProjectionWebMercator::quickItemTransformation(const QGeoCoordina (std::floor(zoomLevel) - std::floor(m_cameraData.zoomLevel()))); matTranslateScale.scale(scale); - const QDoubleVector2D coordOnScreen = wrappedMapProjectionToItemPosition(coordWrapped); - QDoubleMatrix4x4 matTransformation; - matTransformation.translate(-coordOnScreen.x(), -coordOnScreen.y(), 0); - matTransformation *= m_quickItemTransformation; - /* - * The full transformation chain for quickItemTransformation() is: + * The full transformation chain for quickItemTransformation() would be: * matScreenShift * m_quickItemTransformation * matTranslate * matScale * where: * matScreenShift = translate(-coordOnScreen.x(), -coordOnScreen.y(), 0) * matTranslate = translate(coordAnchoredScaled.x(), coordAnchoredScaled.y(), 0.0) * matScale = scale(scale) + * + * However, matScreenShift is removed, as setPosition(0,0) is used in place of setPositionOnScreen. */ - return toMatrix4x4(matTransformation * matTranslateScale); + return toMatrix4x4(m_quickItemTransformation * matTranslateScale); } bool QGeoProjectionWebMercator::isProjectable(const QDoubleVector2D &wrappedProjection) const |