summaryrefslogtreecommitdiff
path: root/src/location/declarativemaps
diff options
context:
space:
mode:
Diffstat (limited to 'src/location/declarativemaps')
-rw-r--r--src/location/declarativemaps/declarativemaps.pri5
-rw-r--r--src/location/declarativemaps/error_messages.cpp2
-rw-r--r--src/location/declarativemaps/error_messages_p.h (renamed from src/location/declarativemaps/error_messages.h)12
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem.cpp87
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem_p.h9
-rw-r--r--src/location/declarativemaps/qdeclarativegeocodemodel.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap.cpp147
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap_p.h8
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapcopyrightsnotice.cpp18
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapquickitem.cpp34
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapquickitem_p.h2
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroute.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroutemodel.cpp6
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroutesegment.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem.cpp51
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem_p.h6
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp52
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem_p.h8
-rw-r--r--src/location/declarativemaps/qdeclarativerectanglemapitem.cpp37
-rw-r--r--src/location/declarativemaps/qdeclarativerectanglemapitem_p.h3
-rw-r--r--src/location/declarativemaps/qquickgeomapgesturearea.cpp227
-rw-r--r--src/location/declarativemaps/qquickgeomapgesturearea_p.h26
22 files changed, 513 insertions, 233 deletions
diff --git a/src/location/declarativemaps/declarativemaps.pri b/src/location/declarativemaps/declarativemaps.pri
index e1054001..34c9f588 100644
--- a/src/location/declarativemaps/declarativemaps.pri
+++ b/src/location/declarativemaps/declarativemaps.pri
@@ -2,10 +2,8 @@ QT += quick-private network positioning-private qml-private core-private gui-pri
INCLUDEPATH += declarativemaps
-PUBLIC_HEADERS += \
- declarativemaps/error_messages.h
-
PRIVATE_HEADERS += \
+ declarativemaps/error_messages_p.h \
declarativemaps/qdeclarativegeomapitemview_p.h \
declarativemaps/qdeclarativegeomapitemview_p_p.h \
declarativemaps/qdeclarativegeoserviceprovider_p.h \
@@ -59,6 +57,7 @@ SOURCES += \
../imports/positioning/qquickgeocoordinateanimation.cpp \
declarativemaps/mapitemviewdelegateincubator.cpp
+load(qt_build_paths)
LIBS_PRIVATE += -L$$MODULE_BASE_OUTDIR/lib -lpoly2tri$$qtPlatformTargetSuffix() -lclip2tri$$qtPlatformTargetSuffix()
diff --git a/src/location/declarativemaps/error_messages.cpp b/src/location/declarativemaps/error_messages.cpp
index a2557f79..7b51b7ad 100644
--- a/src/location/declarativemaps/error_messages.cpp
+++ b/src/location/declarativemaps/error_messages.cpp
@@ -33,7 +33,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "error_messages.h"
+#include "error_messages_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/location/declarativemaps/error_messages.h b/src/location/declarativemaps/error_messages_p.h
index 81c43b34..cdd531d1 100644
--- a/src/location/declarativemaps/error_messages.h
+++ b/src/location/declarativemaps/error_messages_p.h
@@ -37,6 +37,18 @@
#ifndef ERROR_MESSAGES_H
#define ERROR_MESSAGES_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 <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
index a4eee272..274225c0 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
@@ -142,7 +142,7 @@ QGeoMapCircleGeometry::QGeoMapCircleGeometry()
/*!
\internal
*/
-void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QGeoCoordinate> &circlePath, const QGeoMap &map)
+void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map)
{
// Not checking for !screenDirty anymore, as everything is now recalculated.
clear();
@@ -175,13 +175,13 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QGeoCoordinate>
fill << tl << tr << br << bl;
QList<QDoubleVector2D> hole;
- for (const QGeoCoordinate &c: circlePath)
- hole << map.geoProjection().geoToWrappedMapProjection(c);
+ for (const QDoubleVector2D &c: circlePath)
+ hole << map.geoProjection().wrapMapProjection(c);
c2t::clip2tri clipper;
clipper.addSubjectPath(QClipperUtils::qListToPath(fill), true);
clipper.addClipPolygon(QClipperUtils::qListToPath(hole));
- Paths difference = clipper.execute(c2t::clip2tri::Difference, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
+ Paths difference = clipper.execute(c2t::clip2tri::Difference, QtClipperLib::pftEvenOdd, QtClipperLib::pftEvenOdd);
// 2)
QDoubleVector2D lb = map.geoProjection().geoToWrappedMapProjection(srcOrigin_);
@@ -192,7 +192,7 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QGeoCoordinate>
for (const Path &p: difference)
clipper.addSubjectPath(p, true);
clipper.addClipPolygon(QClipperUtils::qListToPath(visibleRegion));
- Paths res = clipper.execute(c2t::clip2tri::Intersection, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
+ Paths res = clipper.execute(c2t::clip2tri::Intersection, QtClipperLib::pftEvenOdd, QtClipperLib::pftEvenOdd);
clippedPaths = QClipperUtils::pathsToQList(res);
// 2.1) update srcOrigin_ with the point with minimum X/Y
@@ -358,8 +358,10 @@ void QDeclarativeCircleMapItem::markSourceDirtyAndUpdate()
void QDeclarativeCircleMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *map)
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
- if (map)
- markSourceDirtyAndUpdate();
+ if (!map)
+ return;
+ updateCirclePath();
+ markSourceDirtyAndUpdate();
}
/*!
@@ -375,6 +377,7 @@ void QDeclarativeCircleMapItem::setCenter(const QGeoCoordinate &center)
return;
circle_.setCenter(center);
+ updateCirclePath();
markSourceDirtyAndUpdate();
emit centerChanged(center);
}
@@ -418,6 +421,7 @@ void QDeclarativeCircleMapItem::setRadius(qreal radius)
return;
circle_.setRadius(radius);
+ updateCirclePath();
markSourceDirtyAndUpdate();
emit radiusChanged(radius);
}
@@ -472,24 +476,19 @@ void QDeclarativeCircleMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- if (geometry_.isSourceDirty()) {
- circlePath_.clear();
- calculatePeripheralPoints(circlePath_, circle_.center(), circle_.radius(), CircleSamples);
- }
-
- QList<QGeoCoordinate> originalCirclePath = circlePath_;
+ QList<QDoubleVector2D> circlePath = circlePath_;
- int pathCount = circlePath_.size();
- bool preserve = preserveCircleGeometry(circlePath_, circle_.center(), circle_.radius());
+ int pathCount = circlePath.size();
+ bool preserve = preserveCircleGeometry(circlePath, circle_.center(), circle_.radius());
geometry_.setPreserveGeometry(true, circle_.boundingGeoRectangle().topLeft()); // to set the geoLeftBound_
geometry_.setPreserveGeometry(preserve, circle_.boundingGeoRectangle().topLeft());
bool invertedCircle = false;
- if (crossEarthPole(circle_.center(), circle_.radius()) && circlePath_.size() == pathCount) {
- geometry_.updateScreenPointsInvert(circlePath_, *map()); // invert fill area for really huge circles
+ if (crossEarthPole(circle_.center(), circle_.radius()) && circlePath.size() == pathCount) {
+ geometry_.updateScreenPointsInvert(circlePath, *map()); // invert fill area for really huge circles
invertedCircle = true;
} else {
- geometry_.updateSourcePoints(*map(), circlePath_);
+ geometry_.updateSourcePoints(*map(), circlePath);
geometry_.updateScreenPoints(*map());
}
@@ -498,11 +497,11 @@ void QDeclarativeCircleMapItem::updatePolish()
geoms << &geometry_;
if (border_.color() != Qt::transparent && border_.width() > 0) {
- QList<QGeoCoordinate> closedPath = circlePath_;
+ QList<QDoubleVector2D> closedPath = circlePath;
closedPath << closedPath.first();
if (invertedCircle) {
- closedPath = originalCirclePath;
+ closedPath = circlePath_;
closedPath << closedPath.first();
std::reverse(closedPath.begin(), closedPath.end());
}
@@ -549,6 +548,20 @@ void QDeclarativeCircleMapItem::afterViewportChanged(const QGeoMapViewportChange
/*!
\internal
*/
+void QDeclarativeCircleMapItem::updateCirclePath()
+{
+ if (!map())
+ return;
+ QList<QGeoCoordinate> path;
+ calculatePeripheralPoints(path, circle_.center(), circle_.radius(), CircleSamples);
+ circlePath_.clear();
+ for (const QGeoCoordinate &c : path)
+ circlePath_ << map()->geoProjection().geoToMapProjection(c);
+}
+
+/*!
+ \internal
+*/
bool QDeclarativeCircleMapItem::contains(const QPointF &point) const
{
return (geometry_.contains(point) || borderGeometry_.contains(point));
@@ -569,7 +582,7 @@ QGeoMap::ItemType QDeclarativeCircleMapItem::itemType() const
*/
void QDeclarativeCircleMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- if (updatingGeometry_ || newGeometry == oldGeometry) {
+ if (!map() || !circle_.isValid() || updatingGeometry_ || newGeometry == oldGeometry) {
QDeclarativeGeoMapItemBase::geometryChanged(newGeometry, oldGeometry);
return;
}
@@ -583,7 +596,7 @@ void QDeclarativeCircleMapItem::geometryChanged(const QRectF &newGeometry, const
// call to this function.
}
-bool QDeclarativeCircleMapItem::preserveCircleGeometry (QList<QGeoCoordinate> &path,
+bool QDeclarativeCircleMapItem::preserveCircleGeometry (QList<QDoubleVector2D> &path,
const QGeoCoordinate &center, qreal distance)
{
// if circle crosses north/south pole, then don't preserve circular shape,
@@ -612,7 +625,7 @@ bool QDeclarativeCircleMapItem::preserveCircleGeometry (QList<QGeoCoordinate> &p
* | ____ |
* \__/ \__/
*/
-void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinate> &path,
+void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QDoubleVector2D> &path,
const QGeoCoordinate &center,
qreal distance)
{
@@ -623,11 +636,11 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat
bool crossSouthPole = distanceToSouthPole < distance;
QList<int> wrapPathIndex;
- QDoubleVector2D prev = map()->geoProjection().wrapMapProjection(map()->geoProjection().geoToMapProjection(path.at(0)));
+ QDoubleVector2D prev = map()->geoProjection().wrapMapProjection(path.at(0));
for (int i = 1; i <= path.count(); ++i) {
int index = i % path.count();
- QDoubleVector2D point = map()->geoProjection().wrapMapProjection(map()->geoProjection().geoToMapProjection(path.at(index)));
+ QDoubleVector2D point = map()->geoProjection().wrapMapProjection(path.at(index));
double diff = qAbs(point.x() - prev.x());
if (diff > 0.5) {
continue;
@@ -637,7 +650,7 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat
// find the points in path where wrapping occurs
for (int i = 1; i <= path.count(); ++i) {
int index = i % path.count();
- QDoubleVector2D point = map()->geoProjection().wrapMapProjection(map()->geoProjection().geoToMapProjection(path.at(index)));
+ QDoubleVector2D point = map()->geoProjection().wrapMapProjection(path.at(index));
if ( (qAbs(point.x() - prev.x())) >= 0.5 ) {
wrapPathIndex << index;
if (wrapPathIndex.size() == 2 || !(crossNorthPole && crossSouthPole))
@@ -648,25 +661,25 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat
// insert two additional coords at top/bottom map corners of the map for shape
// to be drawn correctly
if (wrapPathIndex.size() > 0) {
- qreal newPoleLat = 90;
- QGeoCoordinate wrapCoord = path.at(wrapPathIndex[0]);
+ qreal newPoleLat = 0; // 90 latitude
+ QDoubleVector2D wrapCoord = path.at(wrapPathIndex[0]);
if (wrapPathIndex.size() == 2) {
- QGeoCoordinate wrapCoord2 = path.at(wrapPathIndex[1]);
- if (wrapCoord2.latitude() > wrapCoord.latitude())
- newPoleLat = -90;
+ QDoubleVector2D wrapCoord2 = path.at(wrapPathIndex[1]);
+ if (wrapCoord2.y() < wrapCoord.y())
+ newPoleLat = 1; // -90 latitude
} else if (center.latitude() < 0) {
- newPoleLat = -90;
+ newPoleLat = 1; // -90 latitude
}
for (int i = 0; i < wrapPathIndex.size(); ++i) {
int index = wrapPathIndex[i] == 0 ? 0 : wrapPathIndex[i] + i*2;
int prevIndex = (index - 1) < 0 ? (path.count() - 1): index - 1;
- QGeoCoordinate coord0 = path.at(prevIndex);
- QGeoCoordinate coord1 = path.at(index);
- coord0.setLatitude(newPoleLat);
- coord1.setLatitude(newPoleLat);
+ QDoubleVector2D coord0 = path.at(prevIndex);
+ QDoubleVector2D coord1 = path.at(index);
+ coord0.setY(newPoleLat);
+ coord1.setY(newPoleLat);
path.insert(index ,coord1);
path.insert(index, coord0);
- newPoleLat = -newPoleLat;
+ newPoleLat = 1.0 - newPoleLat;
}
}
}
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem_p.h b/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
index bcbd67d8..511e3b17 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
@@ -63,7 +63,7 @@ class QGeoMapCircleGeometry : public QGeoMapPolygonGeometry
public:
QGeoMapCircleGeometry();
- void updateScreenPointsInvert(const QList<QGeoCoordinate> &circlePath, const QGeoMap &map);
+ void updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map);
};
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeCircleMapItem : public QDeclarativeGeoMapItemBase
@@ -110,16 +110,17 @@ protected Q_SLOTS:
virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) Q_DECL_OVERRIDE;
private:
- bool preserveCircleGeometry(QList<QGeoCoordinate> &path, const QGeoCoordinate &center,
+ void updateCirclePath();
+ bool preserveCircleGeometry(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
qreal distance);
- void updateCirclePathForRendering(QList<QGeoCoordinate> &path, const QGeoCoordinate &center,
+ void updateCirclePathForRendering(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
qreal distance);
private:
QGeoCircle circle_;
QDeclarativeMapLineProperties border_;
QColor color_;
- QList<QGeoCoordinate> circlePath_;
+ QList<QDoubleVector2D> circlePath_;
bool dirtyMaterial_;
QGeoMapCircleGeometry geometry_;
QGeoMapPolylineGeometry borderGeometry_;
diff --git a/src/location/declarativemaps/qdeclarativegeocodemodel.cpp b/src/location/declarativemaps/qdeclarativegeocodemodel.cpp
index f7422ec2..d874f9a2 100644
--- a/src/location/declarativemaps/qdeclarativegeocodemodel.cpp
+++ b/src/location/declarativemaps/qdeclarativegeocodemodel.cpp
@@ -35,7 +35,7 @@
****************************************************************************/
#include "qdeclarativegeocodemodel_p.h"
-#include "error_messages.h"
+#include "error_messages_p.h"
#include <QtCore/QCoreApplication>
#include <QtQml/QQmlInfo>
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp
index 8ab29c1a..9f4dae3f 100644
--- a/src/location/declarativemaps/qdeclarativegeomap.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomap.cpp
@@ -45,6 +45,7 @@
#include "qdeclarativegeomapparameter_p.h"
#include <QtPositioning/QGeoCircle>
#include <QtPositioning/QGeoRectangle>
+#include <QtPositioning/QGeoPath>
#include <QtQuick/QQuickWindow>
#include <QtQuick/QSGRectangleNode>
#include <QtQuick/private/qquickwindow_p.h>
@@ -139,7 +140,7 @@ QT_BEGIN_NAMESPACE
\section2 Example Usage
The following snippet shows a simple Map and the necessary Plugin type
- to use it. The map is centered over Oslo, Norway, with zoom level 10.
+ to use it. The map is centered over Oslo, Norway, with zoom level 14.
\quotefromfile minimal_map/main.qml
\skipto import
@@ -189,7 +190,7 @@ QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent)
m_activeMapType = new QDeclarativeGeoMapType(QGeoMapType(QGeoMapType::NoMap,
tr("No Map"),
- tr("No Map"), false, false, 0), this);
+ tr("No Map"), false, false, 0, QByteArrayLiteral("")), this);
m_cameraData.setCenter(QGeoCoordinate(51.5073,-0.1277)); //London city center
m_cameraData.setZoomLevel(8.0);
@@ -278,17 +279,17 @@ void QDeclarativeGeoMap::onMapChildrenChanged()
copyrights = m_copyrights.data();
- connect(m_map, SIGNAL(copyrightsChanged(QImage)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QImage)),
copyrights, SLOT(copyrightsChanged(QImage)));
- connect(m_map, SIGNAL(copyrightsChanged(QImage)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QImage)),
this, SIGNAL(copyrightsChanged(QImage)));
- connect(m_map, SIGNAL(copyrightsChanged(QString)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QString)),
copyrights, SLOT(copyrightsChanged(QString)));
- connect(m_map, SIGNAL(copyrightsChanged(QString)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QString)),
this, SIGNAL(copyrightsChanged(QString)));
- connect(m_map, SIGNAL(copyrightsStyleSheetChanged(QString)),
+ connect(m_map.data(), SIGNAL(copyrightsStyleSheetChanged(QString)),
copyrights, SLOT(onCopyrightsStyleSheetChanged(QString)));
connect(copyrights, SIGNAL(linkActivated(QString)),
@@ -419,6 +420,9 @@ void QDeclarativeGeoMap::initialize()
emit fieldOfViewChanged(m_cameraData.fieldOfView());
emit mapReadyChanged(true);
+
+ if (m_copyrights)
+ update();
}
/*!
@@ -721,7 +725,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
*/
void QDeclarativeGeoMap::mappingManagerInitialized()
{
- m_map = m_mappingManager->createMap(this);
+ m_map = QPointer<QGeoMap>(m_mappingManager->createMap(this));
if (!m_map)
return;
@@ -734,12 +738,20 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
m_supportedMapTypes.append(type);
}
- if (!m_supportedMapTypes.isEmpty()) {
- QDeclarativeGeoMapType *type = m_supportedMapTypes.at(0);
- m_activeMapType = type;
- m_map->setActiveMapType(type->mapType());
- } else {
+ if (m_activeMapType && m_plugin->name().toLatin1() == m_activeMapType->mapType().pluginName()) {
m_map->setActiveMapType(m_activeMapType->mapType());
+ } else {
+ if (m_activeMapType)
+ m_activeMapType->deleteLater();
+
+ if (!m_supportedMapTypes.isEmpty()) {
+ m_activeMapType = m_supportedMapTypes.at(0);
+ m_map->setActiveMapType(m_activeMapType->mapType());
+ } else {
+ m_activeMapType = new QDeclarativeGeoMapType(QGeoMapType(QGeoMapType::NoMap,
+ tr("No Map"),
+ tr("No Map"), false, false, 0, QByteArrayLiteral("")), this);
+ }
}
// Update camera capabilities
@@ -747,32 +759,50 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
// Map tiles are built in this call. m_map->minimumZoom() becomes operational
// after this has been called at least once, after creation.
-
+ // However, getting into the following block may fire a copyrightsChanged that would get lost,
+ // as the connections are set up after.
+ QString copyrightString;
+ QImage copyrightImage;
if (!m_initialized && width() > 0 && height() > 0) {
+ QMetaObject::Connection copyrightStringCatcherConnection =
+ connect(m_map.data(),
+ QOverload<const QString &>::of(&QGeoMap::copyrightsChanged),
+ [&copyrightString](const QString &copy){ copyrightString = copy; });
+ QMetaObject::Connection copyrightImageCatcherConnection =
+ connect(m_map.data(),
+ QOverload<const QImage &>::of(&QGeoMap::copyrightsChanged),
+ [&copyrightImage](const QImage &copy){ copyrightImage = copy; });
m_map->setViewportSize(QSize(width(), height()));
initialize();
+ QObject::disconnect(copyrightStringCatcherConnection);
+ QObject::disconnect(copyrightImageCatcherConnection);
}
m_copyrights = new QDeclarativeGeoMapCopyrightNotice(this);
m_copyrights->onCopyrightsStyleSheetChanged(m_map->copyrightsStyleSheet());
- connect(m_map, SIGNAL(copyrightsChanged(QImage)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QImage)),
m_copyrights.data(), SLOT(copyrightsChanged(QImage)));
- connect(m_map, SIGNAL(copyrightsChanged(QImage)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QImage)),
this, SIGNAL(copyrightsChanged(QImage)));
- connect(m_map, SIGNAL(copyrightsChanged(QString)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QString)),
m_copyrights.data(), SLOT(copyrightsChanged(QString)));
- connect(m_map, SIGNAL(copyrightsChanged(QString)),
+ connect(m_map.data(), SIGNAL(copyrightsChanged(QString)),
this, SIGNAL(copyrightsChanged(QString)));
- connect(m_map, SIGNAL(copyrightsStyleSheetChanged(QString)),
+ if (!copyrightString.isEmpty())
+ emit m_map.data()->copyrightsChanged(copyrightString);
+ else if (!copyrightImage.isNull())
+ emit m_map.data()->copyrightsChanged(copyrightImage);
+
+ connect(m_map.data(), SIGNAL(copyrightsStyleSheetChanged(QString)),
m_copyrights.data(), SLOT(onCopyrightsStyleSheetChanged(QString)));
connect(m_copyrights.data(), SIGNAL(linkActivated(QString)),
this, SIGNAL(copyrightLinkActivated(QString)));
- connect(m_map, &QGeoMap::sgNodeChanged, this, &QQuickItem::update);
- connect(m_map, &QGeoMap::cameraCapabilitiesChanged, this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged);
+ connect(m_map.data(), &QGeoMap::sgNodeChanged, this, &QQuickItem::update);
+ connect(m_map.data(), &QGeoMap::cameraCapabilitiesChanged, this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged);
// set visibility of copyright notice
m_copyrights->setCopyrightsVisible(m_copyrightsVisible);
@@ -788,7 +818,7 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
// Any map items that were added before the plugin was ready
// need to have setMap called again
- foreach (const QPointer<QDeclarativeGeoMapItemBase> &item, m_mapItems) {
+ for (const QPointer<QDeclarativeGeoMapItemBase> &item : qAsConst(m_mapItems)) {
if (item) {
item->setMap(this, m_map);
m_map->addMapItem(item.data()); // m_map filters out what is not supported.
@@ -808,8 +838,11 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
// All map parameters that were added before the plugin was ready
// need to be added to m_map
- for (QDeclarativeGeoMapParameter *p : m_mapParameters)
+ for (QDeclarativeGeoMapParameter *p : qAsConst(m_mapParameters))
m_map->addParameter(p);
+
+ if (m_initialized)
+ update();
}
/*!
@@ -841,7 +874,7 @@ void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel, bool userSe
m_gestureArea->setMinimumZoomLevel(minimumZoomLevel);
- if (zoomLevel() < minimumZoomLevel)
+ if (zoomLevel() < minimumZoomLevel && (m_gestureArea->enabled() || !m_cameraCapabilities.overzoomEnabled()))
setZoomLevel(minimumZoomLevel);
if (oldMinimumZoomLevel != minimumZoomLevel)
@@ -884,7 +917,7 @@ void QDeclarativeGeoMap::setMaximumZoomLevel(qreal maximumZoomLevel, bool userSe
m_gestureArea->setMaximumZoomLevel(maximumZoomLevel);
- if (zoomLevel() > maximumZoomLevel)
+ if (zoomLevel() > maximumZoomLevel && (m_gestureArea->enabled() || !m_cameraCapabilities.overzoomEnabled()))
setZoomLevel(maximumZoomLevel);
if (oldMaximumZoomLevel != maximumZoomLevel)
@@ -912,10 +945,27 @@ qreal QDeclarativeGeoMap::maximumZoomLevel() const
This property holds the zoom level for the map.
Larger values for the zoom level provide more detail. Zoom levels
- are always non-negative. The default value is 8.0.
+ are always non-negative. The default value is 8.0. Depending on the plugin in use,
+ values outside the [minimumZoomLevel, maximumZoomLevel] range, which represent the range for which
+ tiles are available, may be accepted, or clamped.
*/
void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
{
+ return setZoomLevel(zoomLevel, m_cameraCapabilities.overzoomEnabled());
+}
+
+/*!
+ \internal
+
+ Sets the zoom level.
+ Larger values for the zoom level provide more detail. Zoom levels
+ are always non-negative. The default value is 8.0. Values outside the
+ [minimumZoomLevel, maximumZoomLevel] range, which represent the range for which
+ tiles are available, can be accepted or clamped by setting the overzoom argument
+ to true or false respectively.
+*/
+void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel, bool overzoom)
+{
if (m_cameraData.zoomLevel() == zoomLevel || zoomLevel < 0)
return;
@@ -923,7 +973,9 @@ void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
bool centerHasChanged = false;
if (m_initialized) {
- m_cameraData.setZoomLevel(qBound(minimumZoomLevel(), zoomLevel, maximumZoomLevel()));
+ m_cameraData.setZoomLevel(qBound<qreal>(overzoom ? m_map->minimumZoom() : minimumZoomLevel(),
+ zoomLevel,
+ overzoom ? 30 : maximumZoomLevel()));
m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(m_cameraData);
QGeoCoordinate coord = m_cameraData.center();
coord.setLatitude(qBound(-m_maximumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
@@ -1267,10 +1319,12 @@ QGeoShape QDeclarativeGeoMap::visibleRegion() const
if (!m_map || !width() || !height())
return m_visibleRegion;
- QGeoCoordinate tl = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0, 0));
- QGeoCoordinate br = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(width(), height()));
+ const QList<QDoubleVector2D> &visibleRegion = m_map->geoProjection().visibleRegion();
+ QGeoPath path;
+ for (const QDoubleVector2D &c: visibleRegion)
+ path.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(c));
- return QGeoRectangle(tl, br);
+ return path.boundingGeoRectangle();
}
/*!
@@ -1330,7 +1384,7 @@ QColor QDeclarativeGeoMap::color() const
This property holds whether the map has been successfully initialized and is ready to be used.
Some methods, such as \l fromCoordinate and \l toCoordinate, will not work before the map is ready.
Due to the architecture of the \l Map, it's advised to use the signal emitted for this property
- in place of \l Component.onCompleted, to make sure that everything behaves as expected.
+ in place of \l {QtQml::Component::completed()}{Component.onCompleted}, to make sure that everything behaves as expected.
\since 5.9
*/
@@ -1518,6 +1572,7 @@ void QDeclarativeGeoMap::touchEvent(QTouchEvent *event)
}
}
+#if QT_CONFIG(wheelevent)
/*!
\internal
*/
@@ -1529,6 +1584,7 @@ void QDeclarativeGeoMap::wheelEvent(QWheelEvent *event)
QQuickItem::wheelEvent(event);
}
+#endif
bool QDeclarativeGeoMap::isInteractive()
{
@@ -1696,7 +1752,7 @@ void QDeclarativeGeoMap::clearMapParameters()
QList<QObject *> QDeclarativeGeoMap::mapParameters()
{
QList<QObject *> ret;
- for (QDeclarativeGeoMapParameter *p : m_mapParameters)
+ for (QDeclarativeGeoMapParameter *p : qAsConst(m_mapParameters))
ret << p;
return ret;
}
@@ -1842,10 +1898,16 @@ void QDeclarativeGeoMap::removeMapItemGroup(QDeclarativeGeoMapItemGroup *itemGro
void QDeclarativeGeoMap::setActiveMapType(QDeclarativeGeoMapType *mapType)
{
if (m_activeMapType->mapType() != mapType->mapType()) {
- m_activeMapType = mapType;
- if (m_map)
- m_map->setActiveMapType(mapType->mapType());
- emit activeMapTypeChanged();
+ if (m_map) {
+ if (mapType->mapType().pluginName() == m_plugin->name().toLatin1()) {
+ m_map->setActiveMapType(mapType->mapType());
+ m_activeMapType = mapType;
+ emit activeMapTypeChanged();
+ }
+ } else {
+ m_activeMapType = mapType;
+ emit activeMapTypeChanged();
+ }
}
}
@@ -1862,7 +1924,7 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF
m_gestureArea->setSize(newGeometry.size());
QQuickItem::geometryChanged(newGeometry, oldGeometry);
- if (!m_map || !newGeometry.size().isValid())
+ if (!m_map || newGeometry.size().isEmpty())
return;
m_map->setViewportSize(newGeometry.size().toSize());
@@ -2039,7 +2101,7 @@ bool QDeclarativeGeoMap::sendMouseEvent(QMouseEvent *event)
QQuickItem *grabber = win ? win->mouseGrabberItem() : 0;
bool stealEvent = m_gestureArea->isActive();
- if ((stealEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab())) {
+ if ((stealEvent || contains(localPos)) && (!grabber || (!grabber->keepMouseGrab() && !grabber->keepTouchGrab()))) {
QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
mouseEvent->setAccepted(false);
@@ -2060,7 +2122,7 @@ bool QDeclarativeGeoMap::sendMouseEvent(QMouseEvent *event)
stealEvent = m_gestureArea->isActive();
grabber = win ? win->mouseGrabberItem() : 0;
- if (grabber && stealEvent && !grabber->keepMouseGrab() && grabber != this)
+ if (grabber && stealEvent && !grabber->keepMouseGrab() && !grabber->keepTouchGrab() && grabber != this)
grabMouse();
if (stealEvent) {
@@ -2077,11 +2139,12 @@ bool QDeclarativeGeoMap::sendMouseEvent(QMouseEvent *event)
bool QDeclarativeGeoMap::sendTouchEvent(QTouchEvent *event)
{
- const QQuickPointerDevice *touchDevice = QQuickPointerDevice::touchDevice(event->device());
+ QQuickPointerDevice *touchDevice = QQuickPointerDevice::touchDevice(event->device());
const QTouchEvent::TouchPoint &point = event->touchPoints().first();
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window());
- auto touchPointGrabberItem = [touchDevice](const QTouchEvent::TouchPoint &point) -> QQuickItem* {
- if (QQuickEventPoint *eventPointer = touchDevice->pointerEvent()->pointById(point.id()))
+ auto touchPointGrabberItem = [touchDevice, windowPriv](const QTouchEvent::TouchPoint &point) -> QQuickItem* {
+ if (QQuickEventPoint *eventPointer = windowPriv->pointerEventInstance(touchDevice)->pointById(point.id()))
return eventPointer->grabber();
return nullptr;
};
diff --git a/src/location/declarativemaps/qdeclarativegeomap_p.h b/src/location/declarativemaps/qdeclarativegeomap_p.h
index da430ce5..f07a2e7f 100644
--- a/src/location/declarativemaps/qdeclarativegeomap_p.h
+++ b/src/location/declarativemaps/qdeclarativegeomap_p.h
@@ -59,7 +59,7 @@
#include <QtCore/QList>
#include <QtCore/QPointer>
#include <QtGui/QColor>
-#include <QtPositioning/qgeoshape.h>
+#include <QtPositioning/qgeorectangle.h>
#include <QtLocation/private/qgeomap_p.h>
QT_BEGIN_NAMESPACE
@@ -214,7 +214,9 @@ protected:
void mouseUngrabEvent() Q_DECL_OVERRIDE ;
void touchUngrabEvent() Q_DECL_OVERRIDE;
void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE ;
+#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE ;
+#endif
bool childMouseEventFilter(QQuickItem *item, QEvent *event) Q_DECL_OVERRIDE;
bool sendMouseEvent(QMouseEvent *event);
@@ -226,6 +228,8 @@ protected:
void setError(QGeoServiceProvider::Error error, const QString &errorString);
void initialize();
+ void setZoomLevel(qreal zoomLevel, bool overzoom);
+
private Q_SLOTS:
void mappingManagerInitialized();
void pluginReady();
@@ -248,7 +252,7 @@ private:
QList<QDeclarativeGeoMapType *> m_supportedMapTypes;
QList<QDeclarativeGeoMapItemView *> m_mapViews;
QQuickGeoMapGestureArea *m_gestureArea;
- QGeoMap *m_map;
+ QPointer<QGeoMap> m_map;
QPointer<QDeclarativeGeoMapCopyrightNotice> m_copyrights;
QList<QPointer<QDeclarativeGeoMapItemBase> > m_mapItems;
QList<QPointer<QDeclarativeGeoMapItemGroup> > m_mapItemGroups;
diff --git a/src/location/declarativemaps/qdeclarativegeomapcopyrightsnotice.cpp b/src/location/declarativemaps/qdeclarativegeomapcopyrightsnotice.cpp
index fdfb645a..1101eb18 100644
--- a/src/location/declarativemaps/qdeclarativegeomapcopyrightsnotice.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapcopyrightsnotice.cpp
@@ -169,7 +169,11 @@ void QDeclarativeGeoMapCopyrightNotice::setStyleSheet(const QString &styleSheet)
if (!m_html.isEmpty() && m_copyrightsHtml) {
delete m_copyrightsHtml;
createCopyright();
+#if QT_CONFIG(texthtmlparser)
m_copyrightsHtml->setHtml(m_html);
+#else
+ m_copyrightsHtml->setPlainText(m_html);
+#endif
}
rasterizeHtmlAndUpdate();
emit styleSheetChanged(m_styleSheet);
@@ -231,8 +235,10 @@ void QDeclarativeGeoMapCopyrightNotice::rasterizeHtmlAndUpdate()
void QDeclarativeGeoMapCopyrightNotice::createCopyright()
{
m_copyrightsHtml = new QTextDocument(this);
+#if QT_CONFIG(cssparser)
if (!m_styleSheet.isEmpty())
m_copyrightsHtml->setDefaultStyleSheet(m_styleSheet);
+#endif
// The default 4 makes the copyright too wide and tall.
m_copyrightsHtml->setDocumentMargin(0);
@@ -289,12 +295,20 @@ void QDeclarativeGeoMapCopyrightNotice::copyrightsChanged(const QString &copyrig
// Divfy, so we can style the background. The extra <span> is a
// workaround to QTBUG-58838 and should be removed when it gets fixed.
+#if QT_CONFIG(texthtmlparser)
m_html = QStringLiteral("<div id='copyright-root'><span>") + copyrightsHtml + QStringLiteral("</span></div>");
+#else
+ m_html = copyrightsHtml;
+#endif
if (!m_copyrightsHtml)
createCopyright();
+#if QT_CONFIG(texthtmlparser)
m_copyrightsHtml->setHtml(m_html);
+#else
+ m_copyrightsHtml->setPlainText(m_html);
+#endif
rasterizeHtmlAndUpdate();
}
@@ -307,7 +321,11 @@ void QDeclarativeGeoMapCopyrightNotice::onCopyrightsStyleSheetChanged(const QStr
if (!m_html.isEmpty() && m_copyrightsHtml) {
delete m_copyrightsHtml;
createCopyright();
+#if QT_CONFIG(texthtmlparser)
m_copyrightsHtml->setHtml(m_html);
+#else
+ m_copyrightsHtml->setPlainText(m_html);
+#endif
}
rasterizeHtmlAndUpdate();
emit styleSheetChanged(m_styleSheet);
diff --git a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
index 5a10f39f..cb5cce9a 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() {}
@@ -158,7 +159,7 @@ QDeclarativeGeoMapQuickItem::~QDeclarativeGeoMapQuickItem() {}
*/
void QDeclarativeGeoMapQuickItem::setCoordinate(const QGeoCoordinate &coordinate)
{
- if (coordinate_ == coordinate)
+ if (coordinate_ == coordinate || !coordinate.isValid())
return;
coordinate_ = coordinate;
@@ -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/declarativemaps/qdeclarativegeoroute.cpp b/src/location/declarativemaps/qdeclarativegeoroute.cpp
index bce0af80..039b1297 100644
--- a/src/location/declarativemaps/qdeclarativegeoroute.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroute.cpp
@@ -147,7 +147,7 @@ qreal QDeclarativeGeoRoute::distance() const
}
/*!
- \qmlproperty QJSValue QtLocation::Route::path
+ \qmlproperty list<coordinate> QtLocation::Route::path
Read-only property which holds the geographical coordinates of this route.
Coordinates are listed in the order in which they would be traversed by someone
diff --git a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
index 8787271e..94bd63c8 100644
--- a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
@@ -36,7 +36,7 @@
#include "qdeclarativegeoroutemodel_p.h"
#include "qdeclarativegeoroute_p.h"
-#include "error_messages.h"
+#include "error_messages_p.h"
#include "locationvaluetypehelper_p.h"
#include <QtCore/QCoreApplication>
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
geographic routes from a backend provider. Routes include data about driving
directions between two points, walking directions with multiple waypoints,
and various other similar concepts. It functions much like other Model
- types in QML (see for example \l {Models and Views in Qt Quick#ListModel}{ListModel} and
+ types in QML (see for example \l {Models and Views in Qt Quick#Models}{ListModel} and
\l XmlListModel), and interacts with views such as \l MapItemView, and \l{ListView}.
Like \l Map and \l GeocodeModel, all the data for a RouteModel to work comes
@@ -764,7 +764,7 @@ void QDeclarativeGeoRouteQuery::setNumberAlternativeRoutes(int numberAlternative
}
/*!
- \qmlproperty QJSValue RouteQuery::waypoints
+ \qmlproperty list<coordinate> RouteQuery::waypoints
The waypoint coordinates of the desired route.
diff --git a/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp b/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp
index 77a8a41a..dbeaa62c 100644
--- a/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp
@@ -128,7 +128,7 @@ QDeclarativeGeoManeuver *QDeclarativeGeoRouteSegment::maneuver() const
}
/*!
- \qmlproperty QJSValue QtLocation::RouteSegment::path
+ \qmlproperty list<coordinate> QtLocation::RouteSegment::path
Read-only property which holds the geographical coordinates of this segment.
Coordinates are listed in the order in which they would be traversed by someone
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
index 857aec41..daa1a9fc 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
@@ -36,7 +36,7 @@
#include "qdeclarativepolygonmapitem_p.h"
#include "qlocationutils_p.h"
-#include "error_messages.h"
+#include "error_messages_p.h"
#include "locationvaluetypehelper_p.h"
#include <QtLocation/private/qgeomap_p.h>
@@ -141,7 +141,7 @@ QGeoMapPolygonGeometry::QGeoMapPolygonGeometry()
\internal
*/
void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path)
+ const QList<QDoubleVector2D> &path)
{
if (!sourceDirty_)
return;
@@ -161,11 +161,8 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
QDoubleVector2D wrappedLeftBound(qInf(), qInf());
// 1)
for (int i = 0; i < path.size(); ++i) {
- const QGeoCoordinate &coord = path.at(i);
- if (!coord.isValid())
- continue;
-
- QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(map.geoProjection().geoToMapProjection(coord));
+ const QDoubleVector2D &coord = path.at(i);
+ QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(coord);
// We can get NaN if the map isn't set up correctly, or the projection
// is faulty -- probably best thing to do is abort
@@ -193,7 +190,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
c2t::clip2tri clipper;
clipper.addSubjectPath(QClipperUtils::qListToPath(wrappedPath), true);
clipper.addClipPolygon(QClipperUtils::qListToPath(visibleRegion));
- Paths res = clipper.execute(c2t::clip2tri::Intersection, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
+ Paths res = clipper.execute(c2t::clip2tri::Intersection, QtClipperLib::pftEvenOdd, QtClipperLib::pftEvenOdd);
clippedPaths = QClipperUtils::pathsToQList(res);
// 2.1) update srcOrigin_ and leftBoundWrapped with the point with minimum X
@@ -380,6 +377,7 @@ void QDeclarativePolygonMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *m
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
if (map) {
+ regenerateCache();
geometry_.markSourceDirty();
borderGeometry_.markSourceDirty();
polishAndUpdate();
@@ -437,6 +435,7 @@ void QDeclarativePolygonMapItem::setPath(const QJSValue &value)
geopath_.setPath(pathList);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
@@ -453,8 +452,11 @@ void QDeclarativePolygonMapItem::setPath(const QJSValue &value)
void QDeclarativePolygonMapItem::addCoordinate(const QGeoCoordinate &coordinate)
{
- geopath_.addCoordinate(coordinate);
+ if (!coordinate.isValid())
+ return;
+ geopath_.addCoordinate(coordinate);
+ updateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
@@ -478,6 +480,7 @@ void QDeclarativePolygonMapItem::removeCoordinate(const QGeoCoordinate &coordina
if (geopath_.path().length() == length)
return;
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
@@ -542,7 +545,7 @@ void QDeclarativePolygonMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- geometry_.updateSourcePoints(*map(), geopath_.path());
+ geometry_.updateSourcePoints(*map(), geopathProjected_);
geometry_.updateScreenPoints(*map());
QList<QGeoMapItemGeometry *> geoms;
@@ -550,7 +553,7 @@ void QDeclarativePolygonMapItem::updatePolish()
borderGeometry_.clear();
if (border_.color() != Qt::transparent && border_.width() > 0) {
- QList<QGeoCoordinate> closedPath = geopath_.path();
+ QList<QDoubleVector2D> closedPath = geopathProjected_;
closedPath << closedPath.first();
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
@@ -605,6 +608,29 @@ void QDeclarativePolygonMapItem::afterViewportChanged(const QGeoMapViewportChang
/*!
\internal
*/
+void QDeclarativePolygonMapItem::regenerateCache()
+{
+ if (!map())
+ return;
+ geopathProjected_.clear();
+ geopathProjected_.reserve(geopath_.path().size());
+ for (const QGeoCoordinate &c : geopath_.path())
+ geopathProjected_ << map()->geoProjection().geoToMapProjection(c);
+}
+
+/*!
+ \internal
+*/
+void QDeclarativePolygonMapItem::updateCache()
+{
+ if (!map())
+ return;
+ geopathProjected_ << map()->geoProjection().geoToMapProjection(geopath_.path().last());
+}
+
+/*!
+ \internal
+*/
bool QDeclarativePolygonMapItem::contains(const QPointF &point) const
{
return (geometry_.contains(point) || borderGeometry_.contains(point));
@@ -625,7 +651,7 @@ QGeoMap::ItemType QDeclarativePolygonMapItem::itemType() const
*/
void QDeclarativePolygonMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- if (updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
+ if (!map() || !geopath_.isValid() || updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
QDeclarativeGeoMapItemBase::geometryChanged(newGeometry, oldGeometry);
return;
}
@@ -640,6 +666,7 @@ void QDeclarativePolygonMapItem::geometryChanged(const QRectF &newGeometry, cons
return;
geopath_.translate(offsetLati, offsetLongi);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
index 9a46bb2c..a928ae39 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
@@ -68,7 +68,7 @@ public:
inline void setAssumeSimple(bool value) { assumeSimple_ = value; }
void updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path);
+ const QList<QDoubleVector2D> &path);
void updateScreenPoints(const QGeoMap &map);
@@ -122,9 +122,11 @@ protected Q_SLOTS:
virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) Q_DECL_OVERRIDE;
private:
- void pathPropertyChanged();
+ void regenerateCache();
+ void updateCache();
QGeoPath geopath_;
+ QList<QDoubleVector2D> geopathProjected_;
QDeclarativeMapLineProperties border_;
QColor color_;
bool dirtyMaterial_;
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index cdc0175e..aedb9811 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -36,7 +36,7 @@
#include "qdeclarativepolylinemapitem_p.h"
#include "qlocationutils_p.h"
-#include "error_messages.h"
+#include "error_messages_p.h"
#include "locationvaluetypehelper_p.h"
#include "qdoublevector2d_p.h"
#include <QtLocation/private/qgeomap_p.h>
@@ -179,7 +179,7 @@ QGeoMapPolylineGeometry::QGeoMapPolylineGeometry()
}
QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
QDoubleVector2D &leftBoundWrapped)
{
/*
@@ -202,11 +202,8 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
QDoubleVector2D wrappedLeftBound(qInf(), qInf());
// 1)
for (int i = 0; i < path.size(); ++i) {
- const QGeoCoordinate &coord = path.at(i);
- if (!coord.isValid())
- continue;
-
- QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(map.geoProjection().geoToMapProjection(coord));
+ const QDoubleVector2D &coord = path.at(i);
+ QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(coord);
// We can get NaN if the map isn't set up correctly, or the projection
// is faulty -- probably best thing to do is abort
@@ -310,7 +307,7 @@ void QGeoMapPolylineGeometry::pathToScreen(const QGeoMap &map,
\internal
*/
void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
const QGeoCoordinate geoLeftBound)
{
if (!sourceDirty_)
@@ -556,6 +553,7 @@ void QDeclarativePolylineMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
if (map) {
+ regenerateCache();
geometry_.markSourceDirty();
polishAndUpdate();
}
@@ -618,6 +616,7 @@ void QDeclarativePolylineMapItem::setPathFromGeoList(const QList<QGeoCoordinate>
geopath_.setPath(path);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -646,8 +645,12 @@ int QDeclarativePolylineMapItem::pathLength() const
*/
void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate)
{
+ if (!coordinate.isValid())
+ return;
+
geopath_.addCoordinate(coordinate);
+ updateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -669,6 +672,7 @@ void QDeclarativePolylineMapItem::insertCoordinate(int index, const QGeoCoordina
geopath_.insertCoordinate(index, coordinate);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -691,6 +695,7 @@ void QDeclarativePolylineMapItem::replaceCoordinate(int index, const QGeoCoordin
geopath_.replaceCoordinate(index, coordinate);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -741,6 +746,8 @@ void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordin
geopath_.removeCoordinate(coordinate);
if (geopath_.path().length() == length)
return;
+
+ regenerateCache();
markSourceDirtyAndUpdate();
emit pathChanged();
}
@@ -763,6 +770,7 @@ void QDeclarativePolylineMapItem::removeCoordinate(int index)
geopath_.removeCoordinate(index);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -792,7 +800,7 @@ QDeclarativeMapLineProperties *QDeclarativePolylineMapItem::line()
*/
void QDeclarativePolylineMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- if (updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
+ if (!map() || !geopath_.isValid() || updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
QDeclarativeGeoMapItemBase::geometryChanged(newGeometry, oldGeometry);
return;
}
@@ -807,6 +815,7 @@ void QDeclarativePolylineMapItem::geometryChanged(const QRectF &newGeometry, con
return;
geopath_.translate(offsetLati, offsetLongi);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -830,6 +839,29 @@ void QDeclarativePolylineMapItem::afterViewportChanged(const QGeoMapViewportChan
/*!
\internal
*/
+void QDeclarativePolylineMapItem::regenerateCache()
+{
+ if (!map())
+ return;
+ geopathProjected_.clear();
+ geopathProjected_.reserve(geopath_.path().size());
+ for (const QGeoCoordinate &c : geopath_.path())
+ geopathProjected_ << map()->geoProjection().geoToMapProjection(c);
+}
+
+/*!
+ \internal
+*/
+void QDeclarativePolylineMapItem::updateCache()
+{
+ if (!map())
+ return;
+ geopathProjected_ << map()->geoProjection().geoToMapProjection(geopath_.path().last());
+}
+
+/*!
+ \internal
+*/
void QDeclarativePolylineMapItem::updatePolish()
{
if (!map() || geopath_.path().length() == 0)
@@ -838,7 +870,7 @@ void QDeclarativePolylineMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- geometry_.updateSourcePoints(*map(), geopath_.path(), geopath_.boundingGeoRectangle().topLeft());
+ geometry_.updateSourcePoints(*map(), geopathProjected_, geopath_.boundingGeoRectangle().topLeft());
geometry_.updateScreenPoints(*map(), line_.width());
setWidth(geometry_.sourceBoundingBox().width());
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
index 55703258..ec57c980 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
@@ -91,7 +91,7 @@ public:
QGeoMapPolylineGeometry();
void updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
const QGeoCoordinate geoLeftBound);
void updateScreenPoints(const QGeoMap &map,
@@ -99,7 +99,7 @@ public:
protected:
QList<QList<QDoubleVector2D> > clipPath(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
QDoubleVector2D &leftBoundWrapped);
void pathToScreen(const QGeoMap &map,
@@ -162,9 +162,11 @@ protected Q_SLOTS:
virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) Q_DECL_OVERRIDE;
private:
- void pathPropertyChanged();
+ void regenerateCache();
+ void updateCache();
QGeoPath geopath_;
+ QList<QDoubleVector2D> geopathProjected_;
QDeclarativeMapLineProperties line_;
QColor color_;
bool dirtyMaterial_;
diff --git a/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp b/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
index 1bfbf1fd..79750416 100644
--- a/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
@@ -134,8 +134,10 @@ QDeclarativeRectangleMapItem::~QDeclarativeRectangleMapItem()
void QDeclarativeRectangleMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *map)
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
- if (map)
- markSourceDirtyAndUpdate();
+ if (!map)
+ return;
+ updatePath();
+ markSourceDirtyAndUpdate();
}
/*!
@@ -167,6 +169,7 @@ void QDeclarativeRectangleMapItem::setTopLeft(const QGeoCoordinate &topLeft)
return;
rectangle_.setTopLeft(topLeft);
+ updatePath();
markSourceDirtyAndUpdate();
emit topLeftChanged(topLeft);
}
@@ -198,6 +201,7 @@ void QDeclarativeRectangleMapItem::setBottomRight(const QGeoCoordinate &bottomRi
return;
rectangle_.setBottomRight(bottomRight);
+ updatePath();
markSourceDirtyAndUpdate();
emit bottomRightChanged(bottomRight);
}
@@ -274,14 +278,8 @@ void QDeclarativeRectangleMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- QList<QGeoCoordinate> path;
- path << rectangle_.topLeft();
- path << QGeoCoordinate(rectangle_.topLeft().latitude(), rectangle_.bottomRight().longitude());
- path << rectangle_.bottomRight();
- path << QGeoCoordinate(rectangle_.bottomRight().latitude(), rectangle_.topLeft().longitude());
-
geometry_.setPreserveGeometry(true, rectangle_.topLeft());
- geometry_.updateSourcePoints(*map(), path);
+ geometry_.updateSourcePoints(*map(), pathMercator_);
geometry_.updateScreenPoints(*map());
QList<QGeoMapItemGeometry *> geoms;
@@ -289,7 +287,7 @@ void QDeclarativeRectangleMapItem::updatePolish()
borderGeometry_.clear();
if (border_.color() != Qt::transparent && border_.width() > 0) {
- QList<QGeoCoordinate> closedPath = path;
+ QList<QDoubleVector2D> closedPath = pathMercator_;
closedPath << closedPath.first();
borderGeometry_.setPreserveGeometry(true, rectangle_.topLeft());
@@ -352,9 +350,25 @@ QGeoMap::ItemType QDeclarativeRectangleMapItem::itemType() const
/*!
\internal
*/
+void QDeclarativeRectangleMapItem::updatePath()
+{
+ if (!map())
+ return;
+ pathMercator_.clear();
+ pathMercator_ << map()->geoProjection().geoToMapProjection(rectangle_.topLeft());
+ pathMercator_ << map()->geoProjection().geoToMapProjection(
+ QGeoCoordinate(rectangle_.topLeft().latitude(), rectangle_.bottomRight().longitude()));
+ pathMercator_ << map()->geoProjection().geoToMapProjection(rectangle_.bottomRight());
+ pathMercator_ << map()->geoProjection().geoToMapProjection(
+ QGeoCoordinate(rectangle_.bottomRight().latitude(), rectangle_.topLeft().longitude()));
+}
+
+/*!
+ \internal
+*/
void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- if (updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
+ if (!map() || !rectangle_.isValid() || updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
QDeclarativeGeoMapItemBase::geometryChanged(newGeometry, oldGeometry);
return;
}
@@ -369,6 +383,7 @@ void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, co
return;
rectangle_.translate(offsetLati, offsetLongi);
+ updatePath();
geometry_.setPreserveGeometry(true, rectangle_.topLeft());
borderGeometry_.setPreserveGeometry(true, rectangle_.topLeft());
markSourceDirtyAndUpdate();
diff --git a/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h b/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h
index b65db813..ca7ca9b7 100644
--- a/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h
@@ -53,6 +53,7 @@
#include <QtLocation/private/qgeomapitemgeometry_p.h>
#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
#include <QtLocation/private/qdeclarativepolygonmapitem_p.h>
+#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
@@ -97,6 +98,7 @@ Q_SIGNALS:
void colorChanged(const QColor &color);
protected:
+ void updatePath();
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void updatePolish() Q_DECL_OVERRIDE;
@@ -112,6 +114,7 @@ private:
QGeoMapPolygonGeometry geometry_;
QGeoMapPolylineGeometry borderGeometry_;
bool updatingGeometry_;
+ QList<QDoubleVector2D> pathMercator_;
};
//////////////////////////////////////////////////////////////////////
diff --git a/src/location/declarativemaps/qquickgeomapgesturearea.cpp b/src/location/declarativemaps/qquickgeomapgesturearea.cpp
index c0dbe0ad..a40afd68 100644
--- a/src/location/declarativemaps/qquickgeomapgesturearea.cpp
+++ b/src/location/declarativemaps/qquickgeomapgesturearea.cpp
@@ -37,11 +37,13 @@
#include "qquickgeomapgesturearea_p.h"
#include "qquickgeocoordinateanimation_p.h"
#include "qdeclarativegeomap_p.h"
-#include "error_messages.h"
+#include "error_messages_p.h"
#include <QtGui/QGuiApplication>
#include <QtGui/qevent.h>
+#if QT_CONFIG(wheelevent)
#include <QtGui/QWheelEvent>
+#endif
#include <QtGui/QStyleHints>
#include <QtQml/qqmlinfo.h>
#include <QtQuick/QQuickWindow>
@@ -60,7 +62,7 @@
#define QML_MAP_FLICK_DEFAULTDECELERATION 2500
#define QML_MAP_FLICK_MAXIMUMDECELERATION 10000
-#define QML_MAP_FLICK_VELOCITY_SAMPLE_PERIOD 50
+#define QML_MAP_FLICK_VELOCITY_SAMPLE_PERIOD 38
// FlickThreshold determines how far the "mouse" must have moved
// before we perform a flick.
static const int FlickThreshold = 20;
@@ -69,9 +71,18 @@ static const qreal MinimumFlickVelocity = 75.0;
// Tolerance for detecting two finger sliding start
static const qreal MaximumParallelPosition = 40.0; // in degrees
// Tolerance for detecting parallel sliding
-static const qreal MaximumParallelSlidingAngle = 5.0; // in degrees
+static const qreal MaximumParallelSlidingAngle = 4.0; // in degrees
// Tolerance for starting rotation
static const qreal MinimumRotationStartingAngle = 15.0; // in degrees
+// Tolerance for starting pinch
+static const qreal MinimumPinchDelta = 40; // in pixels
+// Tolerance for starting tilt when sliding vertical
+static const qreal MinimumPanToTiltDelta = 80; // in pixels;
+
+static qreal distanceBetweenTouchPoints(const QPointF &p1, const QPointF &p2)
+{
+ return QLineF(p1, p2).length();
+}
// Returns the new map center after anchoring coordinate to anchorPoint on the screen
// Approach: find the displacement in (wrapped) mercator space, and apply that to the center
@@ -85,10 +96,15 @@ static QGeoCoordinate anchorCoordinateToPoint(QGeoMap &map, const QGeoCoordinate
return map.geoProjection().wrappedMapProjectionToGeo(centerProj + coordProj - anchorProj);
}
+static qreal angleFromPoints(const QPointF &p1, const QPointF &p2)
+{
+ return QLineF(p1, p2).angle();
+}
+
// Keeps it in +- 180
static qreal touchAngle(const QPointF &p1, const QPointF &p2)
{
- qreal angle = QLineF(p1, p2).angle();
+ qreal angle = angleFromPoints(p1, p2);
if (angle > 180)
angle -= 360;
return angle;
@@ -118,7 +134,17 @@ static qreal vectorSize(const QPointF &vector)
return std::sqrt(vector.x() * vector.x() + vector.y() * vector.y());
}
-static bool movingParallel(const QPointF &p1old, const QPointF &p1new, const QPointF &p2old, const QPointF &p2new)
+// This linearizes the angles around 0, and keep it linear around 180, allowing to differentiate
+// touch angles that are supposed to be parallel (0 or 180 depending on what finger goes first)
+static qreal touchAngleTilting(const QPointF &p1, const QPointF &p2)
+{
+ qreal angle = angleFromPoints(p1, p2);
+ if (angle > 270)
+ angle -= 360;
+ return angle;
+}
+
+static bool movingParallelVertical(const QPointF &p1old, const QPointF &p1new, const QPointF &p2old, const QPointF &p2new)
{
if (!pointDragged(p1old, p1new) || !pointDragged(p2old, p2new))
return false;
@@ -130,8 +156,8 @@ static bool movingParallel(const QPointF &p1old, const QPointF &p1new, const QPo
if (v1v2size < vectorSize(v1) || v1v2size < vectorSize(v2)) // going in opposite directions
return false;
- const qreal newAngle = touchAngle(p1new, p2new);
- const qreal oldAngle = touchAngle(p1old, p2old);
+ const qreal newAngle = touchAngleTilting(p1new, p2new);
+ const qreal oldAngle = touchAngleTilting(p1old, p2old);
const qreal angleDiff = angleDelta(newAngle, oldAngle);
if (qAbs(angleDiff) > MaximumParallelSlidingAngle)
@@ -482,7 +508,7 @@ QQuickGeoMapGestureArea::QQuickGeoMapGestureArea(QDeclarativeGeoMap *map)
/*!
\internal
*/
-void QQuickGeoMapGestureArea::setMap(QGeoMap *map)
+void QQuickGeoMapGestureArea::setMap(QPointer<QGeoMap> map)
{
if (m_map || !map)
return;
@@ -916,6 +942,7 @@ void QQuickGeoMapGestureArea::handleTouchEvent(QTouchEvent *event)
update();
}
+#if QT_CONFIG(wheelevent)
void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
{
if (!m_map)
@@ -925,7 +952,9 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
const QPointF &preZoomPoint = event->posF();
const double zoomLevelDelta = event->angleDelta().y() * qreal(0.001);
- m_declarativeMap->setZoomLevel(m_declarativeMap->zoomLevel() + zoomLevelDelta);
+ // Gesture area should always honor maxZL, but Map might not.
+ m_declarativeMap->setZoomLevel(qMin<qreal>(m_declarativeMap->zoomLevel() + zoomLevelDelta, maximumZoomLevel()),
+ false);
const QPointF &postZoomPoint = m_map->geoProjection().coordinateToItemPosition(wheelGeoPos, false).toPointF();
if (preZoomPoint != postZoomPoint) // need to re-anchor the wheel geoPos to the event position
@@ -933,14 +962,14 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
event->accept();
}
+#endif
/*!
\internal
*/
void QQuickGeoMapGestureArea::clearTouchData()
{
- m_velocityX = 0;
- m_velocityY = 0;
+ m_flickVector = QVector2D();
m_touchPointsCentroid.setX(0);
m_touchPointsCentroid.setY(0);
m_touchCenterCoord.setLongitude(0);
@@ -953,7 +982,7 @@ void QQuickGeoMapGestureArea::clearTouchData()
/*!
\internal
*/
-void QQuickGeoMapGestureArea::updateVelocityList(const QPointF &pos)
+void QQuickGeoMapGestureArea::updateFlickParameters(const QPointF &pos)
{
// Take velocity samples every sufficient period of time, used later to determine the flick
// duration and speed (when mouse is released).
@@ -961,17 +990,40 @@ void QQuickGeoMapGestureArea::updateVelocityList(const QPointF &pos)
if (elapsed >= QML_MAP_FLICK_VELOCITY_SAMPLE_PERIOD) {
elapsed /= 1000.;
- int dyFromLastPos = pos.y() - m_lastPos.y();
- int dxFromLastPos = pos.x() - m_lastPos.x();
+ qreal vel = distanceBetweenTouchPoints(pos, m_lastPos) / elapsed;
+ m_flickVector = (QVector2D(pos) - QVector2D(m_lastPos)).normalized();
+ m_flickVector *= qBound<qreal>(-m_flick.m_maxVelocity, vel, m_flick.m_maxVelocity);
+
m_lastPos = pos;
m_lastPosTime.restart();
- qreal velX = qreal(dxFromLastPos) / elapsed;
- qreal velY = qreal(dyFromLastPos) / elapsed;
- m_velocityX = qBound<qreal>(-m_flick.m_maxVelocity, velX, m_flick.m_maxVelocity);
- m_velocityY = qBound<qreal>(-m_flick.m_maxVelocity, velY, m_flick.m_maxVelocity);
}
}
+void QQuickGeoMapGestureArea::setTouchPointState(const QQuickGeoMapGestureArea::TouchPointState state)
+{
+ m_touchPointState = state;
+}
+
+void QQuickGeoMapGestureArea::setFlickState(const QQuickGeoMapGestureArea::FlickState state)
+{
+ m_flickState = state;
+}
+
+void QQuickGeoMapGestureArea::setTiltState(const QQuickGeoMapGestureArea::TiltState state)
+{
+ m_tiltState = state;
+}
+
+void QQuickGeoMapGestureArea::setRotationState(const QQuickGeoMapGestureArea::RotationState state)
+{
+ m_rotationState = state;
+}
+
+void QQuickGeoMapGestureArea::setPinchState(const QQuickGeoMapGestureArea::PinchState state)
+{
+ m_pinchState = state;
+}
+
/*!
\internal
*/
@@ -1033,29 +1085,29 @@ void QQuickGeoMapGestureArea::touchPointStateMachine()
if (m_allPoints.count() == 1) {
clearTouchData();
startOneTouchPoint();
- m_touchPointState = touchPoints1;
+ setTouchPointState(touchPoints1);
} else if (m_allPoints.count() >= 2) {
clearTouchData();
startTwoTouchPoints();
- m_touchPointState = touchPoints2;
+ setTouchPointState(touchPoints2);
}
break;
case touchPoints1:
if (m_allPoints.count() == 0) {
- m_touchPointState = touchPoints0;
+ setTouchPointState(touchPoints0);
} else if (m_allPoints.count() == 2) {
m_touchCenterCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_touchPointsCentroid), false);
startTwoTouchPoints();
- m_touchPointState = touchPoints2;
+ setTouchPointState(touchPoints2);
}
break;
case touchPoints2:
if (m_allPoints.count() == 0) {
- m_touchPointState = touchPoints0;
+ setTouchPointState(touchPoints0);
} else if (m_allPoints.count() == 1) {
m_touchCenterCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_touchPointsCentroid), false);
startOneTouchPoint();
- m_touchPointState = touchPoints1;
+ setTouchPointState(touchPoints1);
}
break;
};
@@ -1095,7 +1147,7 @@ void QQuickGeoMapGestureArea::startOneTouchPoint()
void QQuickGeoMapGestureArea::updateOneTouchPoint()
{
m_touchPointsCentroid = mapFromScene(m_allPoints.at(0).scenePos());
- updateVelocityList(m_touchPointsCentroid);
+ updateFlickParameters(m_touchPointsCentroid);
}
/*!
@@ -1114,6 +1166,8 @@ void QQuickGeoMapGestureArea::startTwoTouchPoints()
m_startCoord.setLatitude(m_startCoord.latitude() + startCoord.latitude() -
m_touchCenterCoord.latitude());
m_twoTouchAngleStart = touchAngle(m_sceneStartPoint1, m_sceneStartPoint2); // Initial angle used for calculating rotation
+ m_distanceBetweenTouchPointsStart = distanceBetweenTouchPoints(m_sceneStartPoint1, m_sceneStartPoint2);
+ m_twoTouchPointsCentroidStart = (m_sceneStartPoint1 + m_sceneStartPoint2) / 2;
}
/*!
@@ -1123,11 +1177,9 @@ void QQuickGeoMapGestureArea::updateTwoTouchPoints()
{
QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos());
QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos());
- qreal dx = p1.x() - p2.x();
- qreal dy = p1.y() - p2.y();
- m_distanceBetweenTouchPoints = sqrt(dx * dx + dy * dy);
+ m_distanceBetweenTouchPoints = distanceBetweenTouchPoints(p1, p2);
m_touchPointsCentroid = (p1 + p2) / 2;
- updateVelocityList(m_touchPointsCentroid);
+ updateFlickParameters(m_touchPointsCentroid);
m_twoTouchAngle = touchAngle(p1, p2);
}
@@ -1142,31 +1194,31 @@ void QQuickGeoMapGestureArea::tiltStateMachine()
switch (m_tiltState) {
case tiltInactive:
if (m_allPoints.count() >= 2) {
- if (!isRotationActive() && !isPanActive() && !isPinchActive() && canStartTilt()) {
+ if (!isRotationActive() && !isPinchActive() && canStartTilt()) { // only gesture that can be overridden: pan/flick
m_declarativeMap->setKeepMouseGrab(true);
m_declarativeMap->setKeepTouchGrab(true);
startTilt();
- m_tiltState = tiltActive;
+ setTiltState(tiltActive);
} else {
- m_tiltState = tiltInactiveTwoPoints;
+ setTiltState(tiltInactiveTwoPoints);
}
}
break;
case tiltInactiveTwoPoints:
if (m_allPoints.count() <= 1) {
- m_tiltState = tiltInactive;
+ setTiltState(tiltInactive);
} else {
- if (!isRotationActive() && !isPanActive() && !isPinchActive() && canStartTilt()) {
+ if (!isRotationActive() && !isPinchActive() && canStartTilt()) { // only gesture that can be overridden: pan/flick
m_declarativeMap->setKeepMouseGrab(true);
m_declarativeMap->setKeepTouchGrab(true);
startTilt();
- m_tiltState = tiltActive;
+ setTiltState(tiltActive);
}
}
break;
case tiltActive:
if (m_allPoints.count() <= 1) {
- m_tiltState = tiltInactive;
+ setTiltState(tiltInactive);
m_declarativeMap->setKeepMouseGrab(m_preventStealing);
m_declarativeMap->setKeepTouchGrab(m_preventStealing);
endTilt();
@@ -1191,6 +1243,11 @@ void QQuickGeoMapGestureArea::tiltStateMachine()
}
}
+bool validateTouchAngleForTilting(const qreal angle)
+{
+ return ((qAbs(angle) - 180.0) < MaximumParallelPosition) || (qAbs(angle) < MaximumParallelPosition);
+}
+
/*!
\internal
*/
@@ -1199,8 +1256,9 @@ bool QQuickGeoMapGestureArea::canStartTilt()
if (m_allPoints.count() >= 2) {
QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos());
QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos());
- if (qAbs(m_twoTouchAngle) < MaximumParallelPosition
- && movingParallel(m_sceneStartPoint1, p1, m_sceneStartPoint2, p2)) {
+ if (validateTouchAngleForTilting(m_twoTouchAngle)
+ && movingParallelVertical(m_sceneStartPoint1, p1, m_sceneStartPoint2, p2)
+ && qAbs(m_twoTouchPointsCentroidStart.y() - m_touchPointsCentroid.y()) > MinimumPanToTiltDelta) {
m_pinch.m_event.setCenter(mapFromScene(m_touchPointsCentroid));
m_pinch.m_event.setAngle(m_twoTouchAngle);
m_pinch.m_event.setPoint1(p1);
@@ -1208,7 +1266,7 @@ bool QQuickGeoMapGestureArea::canStartTilt()
m_pinch.m_event.setPointCount(m_allPoints.count());
m_pinch.m_event.setAccepted(true);
emit tiltStarted(&m_pinch.m_event);
- return m_pinch.m_event.accepted();
+ return true;
}
}
return false;
@@ -1219,6 +1277,11 @@ bool QQuickGeoMapGestureArea::canStartTilt()
*/
void QQuickGeoMapGestureArea::startTilt()
{
+ if (isPanActive()) {
+ stopPan();
+ setFlickState(flickInactive);
+ }
+
m_pinch.m_tilt.m_startTouchCentroid = m_touchPointsCentroid;
m_pinch.m_tilt.m_startTilt = m_declarativeMap->tilt();
}
@@ -1278,27 +1341,27 @@ void QQuickGeoMapGestureArea::rotationStateMachine()
m_declarativeMap->setKeepMouseGrab(true);
m_declarativeMap->setKeepTouchGrab(true);
startRotation();
- m_rotationState = rotationActive;
+ setRotationState(rotationActive);
} else {
- m_rotationState = rotationInactiveTwoPoints;
+ setRotationState(rotationInactiveTwoPoints);
}
}
break;
case rotationInactiveTwoPoints:
if (m_allPoints.count() <= 1) {
- m_rotationState = rotationInactive;
+ setRotationState(rotationInactive);
} else {
if (!isTiltActive() && canStartRotation()) {
m_declarativeMap->setKeepMouseGrab(true);
m_declarativeMap->setKeepTouchGrab(true);
startRotation();
- m_rotationState = rotationActive;
+ setRotationState(rotationActive);
}
}
break;
case rotationActive:
if (m_allPoints.count() <= 1) {
- m_rotationState = rotationInactive;
+ setRotationState(rotationInactive);
m_declarativeMap->setKeepMouseGrab(m_preventStealing);
m_declarativeMap->setKeepTouchGrab(m_preventStealing);
endRotation();
@@ -1355,7 +1418,7 @@ bool QQuickGeoMapGestureArea::canStartRotation()
void QQuickGeoMapGestureArea::startRotation()
{
m_pinch.m_rotation.m_startBearing = m_declarativeMap->bearing();
- m_pinch.m_rotation.m_previousTouchAngle = m_twoTouchAngleStart;
+ m_pinch.m_rotation.m_previousTouchAngle = m_twoTouchAngle;
m_pinch.m_rotation.m_totalAngle = 0.0;
}
@@ -1416,27 +1479,27 @@ void QQuickGeoMapGestureArea::pinchStateMachine()
m_declarativeMap->setKeepMouseGrab(true);
m_declarativeMap->setKeepTouchGrab(true);
startPinch();
- m_pinchState = pinchActive;
+ setPinchState(pinchActive);
} else {
- m_pinchState = pinchInactiveTwoPoints;
+ setPinchState(pinchInactiveTwoPoints);
}
}
break;
case pinchInactiveTwoPoints:
if (m_allPoints.count() <= 1) {
- m_pinchState = pinchInactive;
+ setPinchState(pinchInactive);
} else {
if (!isTiltActive() && canStartPinch()) {
m_declarativeMap->setKeepMouseGrab(true);
m_declarativeMap->setKeepTouchGrab(true);
startPinch();
- m_pinchState = pinchActive;
+ setPinchState(pinchActive);
}
}
break;
case pinchActive:
if (m_allPoints.count() <= 1) { // Once started, pinch goes off only when finger(s) are release
- m_pinchState = pinchInactive;
+ setPinchState(pinchInactive);
m_declarativeMap->setKeepMouseGrab(m_preventStealing);
m_declarativeMap->setKeepTouchGrab(m_preventStealing);
endPinch();
@@ -1469,8 +1532,7 @@ bool QQuickGeoMapGestureArea::canStartPinch()
if (m_allPoints.count() >= 2) {
QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos());
QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos());
- if (pointDragged(m_sceneStartPoint1, p1)
- || pointDragged(m_sceneStartPoint2, p2)) {
+ if (qAbs(m_distanceBetweenTouchPoints - m_distanceBetweenTouchPointsStart) > MinimumPinchDelta) {
m_pinch.m_event.setCenter(mapFromScene(m_touchPointsCentroid));
m_pinch.m_event.setAngle(m_twoTouchAngle);
m_pinch.m_event.setPoint1(p1);
@@ -1534,7 +1596,7 @@ void QQuickGeoMapGestureArea::updatePinch()
qreal perPinchMinimumZoomLevel = qMax(m_pinch.m_zoom.m_start - m_pinch.m_zoom.maximumChange, m_pinch.m_zoom.m_minimum);
qreal perPinchMaximumZoomLevel = qMin(m_pinch.m_zoom.m_start + m_pinch.m_zoom.maximumChange, m_pinch.m_zoom.m_maximum);
newZoomLevel = qMin(qMax(perPinchMinimumZoomLevel, newZoomLevel), perPinchMaximumZoomLevel);
- m_declarativeMap->setZoomLevel(newZoomLevel);
+ m_declarativeMap->setZoomLevel(qMin<qreal>(newZoomLevel, maximumZoomLevel()), false);
m_pinch.m_zoom.m_previous = newZoomLevel;
}
}
@@ -1572,14 +1634,14 @@ void QQuickGeoMapGestureArea::panStateMachine()
m_startCoord.setLongitude(newStartCoord.longitude());
m_startCoord.setLatitude(newStartCoord.latitude());
m_declarativeMap->setKeepMouseGrab(true);
- m_flickState = panActive;
+ setFlickState(panActive);
}
break;
case panActive:
if (m_allPoints.count() == 0) {
if (!tryStartFlick())
{
- m_flickState = flickInactive;
+ setFlickState(flickInactive);
// mark as inactive for use by camera
if (m_pinchState == pinchInactive && m_rotationState == rotationInactive && m_tiltState == tiltInactive) {
m_declarativeMap->setKeepMouseGrab(m_preventStealing);
@@ -1587,7 +1649,7 @@ void QQuickGeoMapGestureArea::panStateMachine()
}
emit panFinished();
} else {
- m_flickState = flickActive;
+ setFlickState(flickActive);
emit panFinished();
emit flickStarted();
}
@@ -1597,7 +1659,7 @@ void QQuickGeoMapGestureArea::panStateMachine()
if (m_allPoints.count() > 0) { // re touched before movement ended
stopFlick();
m_declarativeMap->setKeepMouseGrab(true);
- m_flickState = panActive;
+ setFlickState(panActive);
}
break;
}
@@ -1655,35 +1717,26 @@ bool QQuickGeoMapGestureArea::tryStartFlick()
if ((m_acceptedGestures & FlickGesture) == 0)
return false;
// if we drag then pause before release we should not cause a flick.
- qreal velocityX = 0.0;
- qreal velocityY = 0.0;
- if (m_lastPosTime.elapsed() < QML_MAP_FLICK_VELOCITY_SAMPLE_PERIOD) {
- velocityY = m_velocityY;
- velocityX = m_velocityX;
- }
- int flickTimeY = 0;
- int flickTimeX = 0;
- int flickPixelsX = 0;
- int flickPixelsY = 0;
- if (qAbs(velocityY) > MinimumFlickVelocity && qAbs(m_touchPointsCentroid.y() - m_sceneStartPoint1.y()) > FlickThreshold) {
- // calculate Y flick animation values
- qreal acceleration = m_flick.m_deceleration;
- if ((velocityY > 0.0f) == (m_flick.m_deceleration > 0.0f))
- acceleration = acceleration * -1.0f;
- flickTimeY = static_cast<int>(-1000 * velocityY / acceleration);
- flickPixelsY = (flickTimeY * velocityY) / (1000.0 * 2);
- }
- if (qAbs(velocityX) > MinimumFlickVelocity && qAbs(m_touchPointsCentroid.x() - m_sceneStartPoint1.x()) > FlickThreshold) {
- // calculate X flick animation values
+ qreal flickSpeed = 0.0;
+ if (m_lastPosTime.elapsed() < QML_MAP_FLICK_VELOCITY_SAMPLE_PERIOD)
+ flickSpeed = m_flickVector.length();
+
+ int flickTime = 0;
+ int flickPixels = 0;
+ QVector2D flickVector;
+
+ if (qAbs(flickSpeed) > MinimumFlickVelocity
+ && distanceBetweenTouchPoints(m_touchPointsCentroid, m_sceneStartPoint1) > FlickThreshold) {
qreal acceleration = m_flick.m_deceleration;
- if ((velocityX > 0.0f) == (m_flick.m_deceleration > 0.0f))
+ if ((flickSpeed > 0.0f) == (m_flick.m_deceleration > 0.0f))
acceleration = acceleration * -1.0f;
- flickTimeX = static_cast<int>(-1000 * velocityX / acceleration);
- flickPixelsX = (flickTimeX * velocityX) / (1000.0 * 2);
+ flickTime = static_cast<int>(-1000 * flickSpeed / acceleration);
+ flickPixels = (flickTime * flickSpeed) / 2000.0;
+ flickVector = m_flickVector.normalized() * flickPixels;
}
- int flickTime = qMax(flickTimeY, flickTimeX);
+
if (flickTime > 0) {
- startFlick(flickPixelsX, flickPixelsY, flickTime);
+ startFlick(flickVector.x(), flickVector.y(), flickTime);
return true;
}
return false;
@@ -1734,9 +1787,8 @@ void QQuickGeoMapGestureArea::stopPan()
if (m_flickState == flickActive) {
stopFlick();
} else if (m_flickState == panActive) {
- m_velocityX = 0;
- m_velocityY = 0;
- m_flickState = flickInactive;
+ m_flickVector = QVector2D();
+ setFlickState(flickInactive);
m_declarativeMap->setKeepMouseGrab(m_preventStealing);
emit panFinished();
emit panActiveChanged();
@@ -1751,8 +1803,7 @@ void QQuickGeoMapGestureArea::stopFlick()
{
if (!m_flick.m_animation)
return;
- m_velocityX = 0;
- m_velocityY = 0;
+ m_flickVector = QVector2D();
if (m_flick.m_animation->isRunning())
m_flick.m_animation->stop();
else
@@ -1763,7 +1814,7 @@ void QQuickGeoMapGestureArea::handleFlickAnimationStopped()
{
m_declarativeMap->setKeepMouseGrab(m_preventStealing);
if (m_flickState == flickActive) {
- m_flickState = flickInactive;
+ setFlickState(flickInactive);
emit flickFinished();
emit panActiveChanged();
m_map->prefetchData();
diff --git a/src/location/declarativemaps/qquickgeomapgesturearea_p.h b/src/location/declarativemaps/qquickgeomapgesturearea_p.h
index 5cafec0d..5daa39cf 100644
--- a/src/location/declarativemaps/qquickgeomapgesturearea_p.h
+++ b/src/location/declarativemaps/qquickgeomapgesturearea_p.h
@@ -50,11 +50,13 @@
#include <QtLocation/private/qlocationglobal_p.h>
+#include <QtCore/QPointer>
#include <QtQuick/QQuickItem>
#include <QTouchEvent>
#include <QDebug>
#include <QElapsedTimer>
#include <QtPositioning/qgeocoordinate.h>
+#include <QtGui/QVector2D>
QT_BEGIN_NAMESPACE
@@ -161,7 +163,9 @@ public:
void setFlickDeceleration(qreal deceleration);
void handleTouchEvent(QTouchEvent *event);
+#if QT_CONFIG(wheelevent)
void handleWheelEvent(QWheelEvent *event);
+#endif
void handleMousePressEvent(QMouseEvent *event);
void handleMouseMoveEvent(QMouseEvent *event);
void handleMouseReleaseEvent(QMouseEvent *event);
@@ -174,7 +178,7 @@ public:
void setMaximumZoomLevel(qreal max);
qreal maximumZoomLevel() const;
- void setMap(QGeoMap *map);
+ void setMap(QPointer<QGeoMap> map);
bool preventStealing() const;
void setPreventStealing(bool prevent);
@@ -260,10 +264,10 @@ private Q_SLOTS:
private:
void stopPan();
void clearTouchData();
- void updateVelocityList(const QPointF &pos);
+ void updateFlickParameters(const QPointF &pos);
private:
- QGeoMap *m_map;
+ QPointer<QGeoMap> m_map;
QDeclarativeGeoMap *m_declarativeMap;
bool m_enabled;
@@ -324,12 +328,11 @@ private:
// these are calculated regardless of gesture or number of touch points
- qreal m_velocityX;
- qreal m_velocityY;
+ QVector2D m_flickVector;
QElapsedTimer m_lastPosTime;
QPointF m_lastPos;
- QList<QTouchEvent::TouchPoint> m_allPoints;
- QList<QTouchEvent::TouchPoint> m_touchPoints;
+ QVector<QTouchEvent::TouchPoint> m_allPoints;
+ QVector<QTouchEvent::TouchPoint> m_touchPoints;
QScopedPointer<QTouchEvent::TouchPoint> m_mousePoint;
QPointF m_sceneStartPoint1;
@@ -340,10 +343,13 @@ private:
qreal m_twoTouchAngle;
qreal m_twoTouchAngleStart;
qreal m_distanceBetweenTouchPoints;
+ qreal m_distanceBetweenTouchPointsStart;
+ QPointF m_twoTouchPointsCentroidStart;
QPointF m_touchPointsCentroid;
bool m_preventStealing;
bool m_panEnabled;
+private:
// prototype state machine...
enum TouchPointState
{
@@ -379,6 +385,12 @@ private:
panActive,
flickActive
} m_flickState;
+
+ inline void setTouchPointState(const TouchPointState state);
+ inline void setFlickState(const FlickState state);
+ inline void setTiltState(const TiltState state);
+ inline void setRotationState(const RotationState state);
+ inline void setPinchState(const PinchState state);
};
QT_END_NAMESPACE