summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-03-09 14:42:38 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-03-22 11:13:32 +0000
commit53b8d29733d912ce25dd45a6ceb9d1f20c4a998a (patch)
treeec4a6073d1bc1d21ab6fca0003608d888d1ec9fa
parent5c7e6ead198af76022df2bc9ecfb88e727b26bc5 (diff)
downloadqtlocation-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>
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapquickitem.cpp32
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapquickitem_p.h2
-rw-r--r--src/location/maps/qgeoprojection.cpp16
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