summaryrefslogtreecommitdiff
path: root/src/location
diff options
context:
space:
mode:
Diffstat (limited to 'src/location')
-rw-r--r--src/location/declarativemaps/declarativemaps.pri3
-rw-r--r--src/location/declarativemaps/mapitemviewdelegateincubator.cpp54
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitembase.cpp77
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitembase_p.h39
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitemview.cpp453
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitemview_p.h55
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitemview_p_p.h87
8 files changed, 272 insertions, 498 deletions
diff --git a/src/location/declarativemaps/declarativemaps.pri b/src/location/declarativemaps/declarativemaps.pri
index 335dc55a..3cd7a529 100644
--- a/src/location/declarativemaps/declarativemaps.pri
+++ b/src/location/declarativemaps/declarativemaps.pri
@@ -5,7 +5,6 @@ INCLUDEPATH += declarativemaps
PRIVATE_HEADERS += \
declarativemaps/error_messages_p.h \
declarativemaps/qdeclarativegeomapitemview_p.h \
- declarativemaps/qdeclarativegeomapitemview_p_p.h \
declarativemaps/qdeclarativegeoserviceprovider_p.h \
declarativemaps/qdeclarativegeocodemodel_p.h \
declarativemaps/qdeclarativegeoroutemodel_p.h \
@@ -28,7 +27,6 @@ PRIVATE_HEADERS += \
declarativemaps/qquickgeomapgesturearea_p.h \
declarativemaps/qdeclarativegeomapitemgroup_p.h \
declarativemaps/qparameterizableobject_p.h \
- declarativemaps/mapitemviewdelegateincubator_p.h \
declarativemaps/qgeomapobject_p.h \
declarativemaps/qgeomapobject_p_p.h \
../imports/positioning/qquickgeocoordinateanimation_p.h
@@ -58,7 +56,6 @@ SOURCES += \
declarativemaps/qquickgeomapgesturearea.cpp \
declarativemaps/qparameterizableobject.cpp \
declarativemaps/qdeclarativegeomapitemgroup.cpp \
- declarativemaps/mapitemviewdelegateincubator.cpp \
declarativemaps/qgeomapobject.cpp \
../imports/positioning/qquickgeocoordinateanimation.cpp
diff --git a/src/location/declarativemaps/mapitemviewdelegateincubator.cpp b/src/location/declarativemaps/mapitemviewdelegateincubator.cpp
deleted file mode 100644
index c8500e4b..00000000
--- a/src/location/declarativemaps/mapitemviewdelegateincubator.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Copyright (C) 2015 Jolla Ltd, author: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtLocation module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mapitemviewdelegateincubator_p.h"
-#include "qdeclarativegeomapitemview_p.h"
-#include "qdeclarativegeomapitemview_p_p.h"
-
-QT_BEGIN_NAMESPACE
-
-MapItemViewDelegateIncubator::MapItemViewDelegateIncubator(QDeclarativeGeoMapItemView *view, QDeclarativeGeoMapItemViewItemData *itemData, bool batched)
-: m_view(view), m_itemData(itemData), m_batched(batched)
-{
-}
-
-void MapItemViewDelegateIncubator::statusChanged(QQmlIncubator::Status status)
-{
- m_view->incubatorStatusChanged(this, status, m_batched);
-}
-
-QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp
index f8218604..09f9d01c 100644
--- a/src/location/declarativemaps/qdeclarativegeomap.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomap.cpp
@@ -503,9 +503,7 @@ void QDeclarativeGeoMap::populateParameters()
*/
void QDeclarativeGeoMap::setupMapView(QDeclarativeGeoMapItemView *view)
{
- Q_UNUSED(view)
view->setMap(this);
- view->repopulate();
}
/*!
diff --git a/src/location/declarativemaps/qdeclarativegeomapitembase.cpp b/src/location/declarativemaps/qdeclarativegeomapitembase.cpp
index 7b3950db..faa06fef 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitembase.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapitembase.cpp
@@ -283,6 +283,44 @@ qreal QDeclarativeGeoMapItemBase::mapItemOpacity() const
return opacity();
}
+bool QDeclarativeGeoMapItemBase::prepareEnterTransition()
+{
+ if (m_transitionManager->m_transitionState == QDeclarativeGeoMapItemTransitionManager::EnterTransition
+ && m_transitionManager->isRunning())
+ return false;
+
+ if (m_transitionManager->m_transitionState != QDeclarativeGeoMapItemTransitionManager::EnterTransition) {
+ setVisible(true);
+ m_transitionManager->m_transitionState = QDeclarativeGeoMapItemTransitionManager::EnterTransition;
+ }
+ return true;
+}
+
+bool QDeclarativeGeoMapItemBase::prepareExitTransition()
+{
+ if (m_transitionManager->m_transitionState == QDeclarativeGeoMapItemTransitionManager::ExitTransition
+ && m_transitionManager->isRunning())
+ return false;
+
+ if (m_transitionManager->m_transitionState != QDeclarativeGeoMapItemTransitionManager::ExitTransition) {
+ m_transitionManager->m_transitionState = QDeclarativeGeoMapItemTransitionManager::ExitTransition;
+ }
+ return true;
+}
+
+void QDeclarativeGeoMapItemBase::finalizeEnterTransition()
+{
+ m_transitionManager->m_transitionState = QDeclarativeGeoMapItemTransitionManager::NoTransition;
+ emit enterTransitionFinished();
+}
+
+void QDeclarativeGeoMapItemBase::finalizeExitTransition()
+{
+ setVisible(false);
+ m_transitionManager->m_transitionState = QDeclarativeGeoMapItemTransitionManager::NoTransition;
+ emit exitTransitionFinished();
+}
+
bool QDeclarativeGeoMapItemBase::isPolishScheduled() const
{
return QQuickItemPrivate::get(this)->polishScheduled;
@@ -294,4 +332,43 @@ void QDeclarativeGeoMapItemBase::polishAndUpdate()
update();
}
+QDeclarativeGeoMapItemTransitionManager::QDeclarativeGeoMapItemTransitionManager(QDeclarativeGeoMapItemBase *mapItem)
+ : QQuickTransitionManager(), m_mapItem(mapItem)
+{
+}
+
+void QDeclarativeGeoMapItemTransitionManager::transitionEnter()
+{
+ if (m_transitionState == ExitTransition)
+ cancel();
+
+ if (!m_mapItem->prepareEnterTransition())
+ return;
+
+ if (m_view && m_view->m_enter)
+ transition(enterActions, m_view->m_enter, m_mapItem);
+ else
+ finished();
+}
+
+void QDeclarativeGeoMapItemTransitionManager::transitionExit()
+{
+ if (!m_mapItem->prepareExitTransition())
+ return;
+
+ if (m_view && m_view->m_exit)
+ transition(exitActions, m_view->m_exit, m_mapItem);
+ else
+ finished();
+}
+
+void QDeclarativeGeoMapItemTransitionManager::finished()
+{
+ if (m_transitionState == EnterTransition)
+ m_mapItem->finalizeEnterTransition();
+ else if (m_transitionState == ExitTransition)
+ m_mapItem->finalizeExitTransition();
+}
+
+
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeomapitembase_p.h b/src/location/declarativemaps/qdeclarativegeomapitembase_p.h
index edb97c10..162c6d71 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitembase_p.h
+++ b/src/location/declarativemaps/qdeclarativegeomapitembase_p.h
@@ -56,9 +56,12 @@
#include <QtLocation/private/qdeclarativegeomap_p.h>
#include <QtLocation/private/qlocationglobal_p.h>
#include <QtLocation/private/qgeomap_p.h>
+#include <QtQuick/private/qquicktransitionmanager_p_p.h>
+#include <QScopedPointer>
QT_BEGIN_NAMESPACE
-
+class QDeclarativeGeoMapItemTransitionManager;
+class QDeclarativeGeoMapItemBase;
class Q_LOCATION_PRIVATE_EXPORT QGeoMapViewportChangeEvent
{
public:
@@ -77,6 +80,29 @@ public:
bool rollChanged;
};
+class QDeclarativeGeoMapItemTransitionManager : public QQuickTransitionManager
+{
+public:
+ enum TransitionState {
+ NoTransition, EnterTransition, ExitTransition
+ };
+
+ QDeclarativeGeoMapItemTransitionManager(QDeclarativeGeoMapItemBase *mapItem);
+
+ void transitionEnter();
+ void transitionExit();
+
+protected:
+ void finished() override;
+
+public:
+ QDeclarativeGeoMapItemBase *m_mapItem;
+ QDeclarativeGeoMapItemView *m_view = nullptr;
+ QList<QQuickStateAction> enterActions;
+ QList<QQuickStateAction> exitActions;
+ TransitionState m_transitionState = NoTransition;
+};
+
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoMapItemBase : public QQuickItem
{
Q_OBJECT
@@ -99,8 +125,15 @@ public:
virtual QGeoMap::ItemType itemType() const = 0;
qreal mapItemOpacity() const;
+ virtual bool prepareEnterTransition();
+ virtual bool prepareExitTransition();
+ virtual void finalizeEnterTransition();
+ virtual void finalizeExitTransition();
+
Q_SIGNALS:
void mapItemOpacityChanged();
+ void enterTransitionFinished();
+ void exitTransitionFinished();
protected Q_SLOTS:
virtual void afterChildrenChanged();
@@ -124,7 +157,11 @@ private:
QDeclarativeGeoMapItemGroup *parentGroup_;
+ QScopedPointer<QDeclarativeGeoMapItemTransitionManager> m_transitionManager;
+
friend class QDeclarativeGeoMap;
+ friend class QDeclarativeGeoMapItemView;
+ friend class QDeclarativeGeoMapItemTransitionManager;
};
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeomapitemview.cpp b/src/location/declarativemaps/qdeclarativegeomapitemview.cpp
index ce7b4946..b49e675c 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitemview.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapitemview.cpp
@@ -37,15 +37,16 @@
****************************************************************************/
#include "qdeclarativegeomapitemview_p.h"
-#include "qdeclarativegeomapitemview_p_p.h"
#include "qdeclarativegeomap_p.h"
#include "qdeclarativegeomapitembase_p.h"
#include "mapitemviewdelegateincubator_p.h"
#include <QtCore/QAbstractItemModel>
#include <QtQml/QQmlContext>
-#include <QtQml/QQmlIncubator>
+#include <QtQml/private/qqmldelegatemodel_p.h>
#include <QtQml/private/qqmlopenmetaobject_p.h>
+#include <QtQuick/private/qquickanimation_p.h>
+#include <QtQml/QQmlListProperty>
QT_BEGIN_NAMESPACE
@@ -76,16 +77,20 @@ QT_BEGIN_NAMESPACE
QDeclarativeGeoMapItemView::QDeclarativeGeoMapItemView(QQuickItem *parent)
: QObject(parent), m_componentCompleted(false), m_delegate(0),
- m_itemModel(0), m_map(0), m_fitViewport(false), m_metaObjectType(0),
- m_readyIncubators(0), m_repopulating(false)
+ m_map(0), m_fitViewport(false), m_delegateModel(0)
{
+ m_exit = new QQuickTransition(this);
+ QQmlListProperty<QQuickAbstractAnimation> anims = m_exit->animations();
+ QQuickNumberAnimation *ani = new QQuickNumberAnimation(m_exit);
+ ani->setProperty(QStringLiteral("opacity"));
+ ani->setTo(0.0);
+ ani->setDuration(300.0);
+ anims.append(&anims, ani);
}
QDeclarativeGeoMapItemView::~QDeclarativeGeoMapItemView()
{
removeInstantiatedItems();
- if (m_metaObjectType)
- m_metaObjectType->release();
}
/*!
@@ -94,239 +99,103 @@ QDeclarativeGeoMapItemView::~QDeclarativeGeoMapItemView()
void QDeclarativeGeoMapItemView::componentComplete()
{
m_componentCompleted = true;
-}
+ if (!m_itemModel.isNull())
+ m_delegateModel->setModel(m_itemModel);
-void QDeclarativeGeoMapItemView::incubatorStatusChanged(MapItemViewDelegateIncubator *incubator,
- QQmlIncubator::Status status,
- bool batched)
-{
- if (status == QQmlIncubator::Loading)
- return;
+ if (m_delegate)
+ m_delegateModel->setDelegate(m_delegate);
- QDeclarativeGeoMapItemViewItemData *itemData = incubator->m_itemData;
- if (!itemData) {
- // Should never get here
- qWarning() << "MapItemViewDelegateIncubator incubating invalid itemData";
- return;
- }
-
- switch (status) {
- case QQmlIncubator::Ready:
- {
- QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(incubator->object());
- if (!item)
- break;
- itemData->item = item;
- if (!itemData->item) {
- qWarning() << "QDeclarativeGeoMapItemView map item delegate is of unsupported type.";
- delete incubator->object();
- } else {
- if (!batched) {
- m_map->addMapItem(itemData->item);
- fitViewport();
- } else {
- ++m_readyIncubators; // QSemaphore not needed as multiple threads not involved
-
- if (m_readyIncubators == m_itemDataBatched.size()) {
-
- // Clearing stuff older than the reset
- foreach (QDeclarativeGeoMapItemViewItemData *i, m_itemData)
- removeItemData(i);
- m_itemData.clear();
-
- // Adding everthing created after reset was issued
- foreach (QDeclarativeGeoMapItemViewItemData *i, m_itemDataBatched) {
- m_map->addMapItem(i->item);
- }
- m_itemData = m_itemDataBatched;
- m_itemDataBatched.clear();
-
- m_readyIncubators = 0;
- m_repopulating = false;
-
- fitViewport();
- }
- }
- }
- delete itemData->incubator;
- itemData->incubator = 0;
- break;
- }
- case QQmlIncubator::Null:
- // Should never get here
- delete itemData->incubator;
- itemData->incubator = 0;
- break;
- case QQmlIncubator::Error:
- qWarning() << "QDeclarativeGeoMapItemView map item creation failed.";
- delete itemData->incubator;
- itemData->incubator = 0;
- break;
- default:
- ;
- }
+ m_delegateModel->componentComplete();
}
-/*!
- \qmlproperty model QtLocation::MapItemView::model
-
- This property holds the model that provides data used for creating the map items defined by the
- delegate. Only QAbstractItemModel based models are supported.
-*/
-QVariant QDeclarativeGeoMapItemView::model() const
+void QDeclarativeGeoMapItemView::classBegin()
{
- return QVariant::fromValue(m_itemModel);
+ QQmlContext *ctx = qmlContext(this);
+ m_delegateModel = new QQmlDelegateModel(ctx, this);
+ m_delegateModel->classBegin();
+
+ connect(m_delegateModel, &QQmlInstanceModel::modelUpdated, this, &QDeclarativeGeoMapItemView::modelUpdated);
+ connect(m_delegateModel, &QQmlInstanceModel::createdItem, this, &QDeclarativeGeoMapItemView::createdItem);
+ connect(m_delegateModel, &QQmlInstanceModel::destroyingItem, this, &QDeclarativeGeoMapItemView::destroyingItem);
+ connect(m_delegateModel, &QQmlInstanceModel::initItem, this, &QDeclarativeGeoMapItemView::initItem);
}
-void QDeclarativeGeoMapItemView::setModel(const QVariant &model)
+void QDeclarativeGeoMapItemView::destroyingItem(QObject */*object*/)
{
- QAbstractItemModel *itemModel = model.value<QAbstractItemModel *>();
- if (itemModel == m_itemModel)
- return;
-
- if (m_itemModel) {
- disconnect(m_itemModel, SIGNAL(modelReset()), this, SLOT(itemModelReset()));
- disconnect(m_itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(itemModelRowsRemoved(QModelIndex,int,int)));
- disconnect(m_itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(itemModelRowsInserted(QModelIndex,int,int)));
- disconnect(m_itemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(itemModelRowsMoved(QModelIndex,int,int,QModelIndex,int)));
- disconnect(m_itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
- this, SLOT(itemModelDataChanged(QModelIndex,QModelIndex,QVector<int>)));
-
- removeInstantiatedItems(); // this also terminates ongong repopulations.
- m_metaObjectType->release();
- m_metaObjectType = 0;
-
- m_itemModel = 0;
- }
-
- if (itemModel) {
- m_itemModel = itemModel;
- connect(m_itemModel, SIGNAL(modelReset()), this, SLOT(itemModelReset()));
- connect(m_itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(itemModelRowsRemoved(QModelIndex,int,int)));
- connect(m_itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(itemModelRowsInserted(QModelIndex,int,int)));
- connect(m_itemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(itemModelRowsMoved(QModelIndex,int,int,QModelIndex,int)));
- connect(m_itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
- this, SLOT(itemModelDataChanged(QModelIndex,QModelIndex,QVector<int>)));
-
- m_metaObjectType = new QQmlOpenMetaObjectType(&QObject::staticMetaObject, 0);
- foreach (const QByteArray &name, m_itemModel->roleNames())
- m_metaObjectType->createProperty(name);
-
- instantiateAllItems();
- }
- emit modelChanged();
}
-/*!
- \internal
-*/
-void QDeclarativeGeoMapItemView::itemModelReset()
+void QDeclarativeGeoMapItemView::initItem(int /*index*/, QObject */*object*/)
{
- repopulate();
+
}
-/*!
- \internal
-*/
-void QDeclarativeGeoMapItemView::itemModelRowsInserted(const QModelIndex &index, int start, int end)
+void QDeclarativeGeoMapItemView::createdItem(int index, QObject */*object*/)
{
- Q_UNUSED(index)
-
- if (!m_componentCompleted || !m_map || !m_delegate || !m_itemModel)
+ if (!m_map)
return;
-
- for (int i = start; i <= end; ++i) {
- const QModelIndex insertedIndex = m_itemModel->index(i, 0, index);
- // If ran inside a qquickwidget which forces incubators to be synchronous, this call won't happen
- // with m_repopulating == true while incubators from a model reset are still incubating.
- // Note that having the model in a different thread is not supported in general.
- createItemForIndex(insertedIndex, m_repopulating);
- }
-
- fitViewport();
+ // createdItem is emitted on asynchronous creation. In which case, object has to be invoked again.
+ // See QQmlDelegateModel::object for further info.
+ QDeclarativeGeoMapItemBase *item =
+ qobject_cast<QDeclarativeGeoMapItemBase *>(m_delegateModel->object(index, QQmlIncubator::Asynchronous));
+ if (item)
+ addItemToMap(item, index);
}
-/*!
- \internal
-*/
-void QDeclarativeGeoMapItemView::itemModelRowsRemoved(const QModelIndex &index, int start, int end)
+void QDeclarativeGeoMapItemView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
{
- Q_UNUSED(index)
-
- if (!m_componentCompleted || !m_map || !m_delegate || !m_itemModel)
- return;
+ // move changes are expressed as one remove + one insert, with the same moveId.
+ // For simplicity, they will be treated as remove + insert.
+ // Changes will be also ignored, as they represent only data changes, not layout changes
+ if (reset) { // Assuming this means "remove everything already instantiated"
+ removeInstantiatedItems();
+ } else {
+ // Remove items from the back to the front to retain the mapping to what is received from the changesets
+ const QVector<QQmlChangeSet::Change> &removes = changeSet.removes();
+ std::map<int, int> mapRemoves;
+ for (int i = 0; i < removes.size(); i++)
+ mapRemoves.insert(std::pair<int, int>(removes.at(i).start(), i));
+
+ for (auto rit = mapRemoves.rbegin(); rit != mapRemoves.rend(); ++rit) {
+ const QQmlChangeSet::Change &c = removes.at(rit->second);
+ for (int idx = c.end() - 1; idx >= c.start(); --idx)
+ removeItemFromMap(idx);
+ }
+ }
- for (int i = end; i >= start; --i) {
- if (m_repopulating) {
- QDeclarativeGeoMapItemViewItemData *itemData = m_itemDataBatched.takeAt(i);
- if (!itemData)
- continue;
- if (itemData->incubator) {
- if (itemData->incubator->isReady()) {
- --m_readyIncubators;
- delete itemData->incubator->object();
- }
- itemData->incubator->clear();
- }
- delete itemData;
- } else {
- QDeclarativeGeoMapItemViewItemData *itemData = m_itemData.takeAt(i);
- removeItemData(itemData);
+ for (const QQmlChangeSet::Change &c: changeSet.inserts()) {
+ for (int idx = c.start(); idx < c.end(); idx++) {
+ QDeclarativeGeoMapItemBase *item =
+ qobject_cast<QDeclarativeGeoMapItemBase *>(m_delegateModel->object(idx, QQmlIncubator::Asynchronous));
+ if (item) // if not, a createdItem signal will be emitted.
+ addItemToMap(item, idx);
}
}
fitViewport();
}
-void QDeclarativeGeoMapItemView::itemModelRowsMoved(const QModelIndex &parent, int start, int end,
- const QModelIndex &destination, int row)
-{
- Q_UNUSED(parent)
- Q_UNUSED(start)
- Q_UNUSED(end)
- Q_UNUSED(destination)
- Q_UNUSED(row)
+/*!
+ \qmlproperty model QtLocation::MapItemView::model
- qWarning() << "QDeclarativeGeoMapItemView does not support models that move rows.";
+ This property holds the model that provides data used for creating the map items defined by the
+ delegate. Only QAbstractItemModel based models are supported.
+*/
+QVariant QDeclarativeGeoMapItemView::model() const
+{
+ return m_itemModel;
}
-void QDeclarativeGeoMapItemView::itemModelDataChanged(const QModelIndex &topLeft,
- const QModelIndex &bottomRight,
- const QVector<int> &roles)
+void QDeclarativeGeoMapItemView::setModel(const QVariant &model)
{
- Q_UNUSED(roles)
-
- if (!m_itemData.count() || (m_repopulating && !m_itemDataBatched.count()) )
+ if (model == m_itemModel)
return;
- for (int i = topLeft.row(); i <= bottomRight.row(); ++i) {
- const QModelIndex index = m_itemModel->index(i, 0);
- QDeclarativeGeoMapItemViewItemData *itemData;
- if (m_repopulating)
- itemData= m_itemDataBatched.at(i);
- else
- itemData= m_itemData.at(i);
-
- QHashIterator<int, QByteArray> iterator(m_itemModel->roleNames());
- while (iterator.hasNext()) {
- iterator.next();
-
- QVariant modelData = m_itemModel->data(index, iterator.key());
- if (!modelData.isValid())
- continue;
-
- itemData->context->setContextProperty(QString::fromLatin1(iterator.value().constData()),
- modelData);
- itemData->modelDataMeta->setValue(iterator.value(), modelData);
- }
- }
+ m_itemModel = model;
+ if (m_componentCompleted)
+ m_delegateModel->setModel(m_itemModel);
+
+ emit modelChanged();
}
/*!
@@ -347,8 +216,9 @@ void QDeclarativeGeoMapItemView::setDelegate(QQmlComponent *delegate)
return;
m_delegate = delegate;
+ if (m_componentCompleted)
+ m_delegateModel->setDelegate(m_delegate);
- repopulate();
emit delegateChanged();
}
@@ -365,11 +235,12 @@ bool QDeclarativeGeoMapItemView::autoFitViewport() const
return m_fitViewport;
}
-void QDeclarativeGeoMapItemView::setAutoFitViewport(const bool &fitViewport)
+void QDeclarativeGeoMapItemView::setAutoFitViewport(const bool &fit)
{
- if (fitViewport == m_fitViewport)
+ if (fit == m_fitViewport)
return;
- m_fitViewport = fitViewport;
+ m_fitViewport = fit;
+ fitViewport();
emit autoFitViewportChanged();
}
@@ -378,7 +249,8 @@ void QDeclarativeGeoMapItemView::setAutoFitViewport(const bool &fitViewport)
*/
void QDeclarativeGeoMapItemView::fitViewport()
{
- if (!m_map || !m_map->mapReady() || !m_fitViewport || m_repopulating)
+
+ if (!m_map || !m_map->mapReady() || !m_fitViewport)
return;
if (m_map->mapItems().size() > 0)
@@ -393,6 +265,7 @@ void QDeclarativeGeoMapItemView::setMap(QDeclarativeGeoMap *map)
if (!map || m_map) // changing map on the fly not supported
return;
m_map = map;
+ instantiateAllItems();
}
/*!
@@ -403,10 +276,9 @@ void QDeclarativeGeoMapItemView::removeInstantiatedItems()
if (!m_map)
return;
- terminateOngoingRepopulation();
- foreach (QDeclarativeGeoMapItemViewItemData *itemData, m_itemData)
- removeItemData(itemData);
- m_itemData.clear();
+ // Backward as removeItemFromMap modifies m_instantiatedItems
+ for (int i = m_instantiatedItems.size() -1; i >= 0 ; i--)
+ removeItemFromMap(i);
}
/*!
@@ -416,127 +288,70 @@ void QDeclarativeGeoMapItemView::removeInstantiatedItems()
*/
void QDeclarativeGeoMapItemView::instantiateAllItems()
{
- if (!m_componentCompleted || !m_map || !m_delegate || !m_itemModel)
+ // The assumption is that if m_instantiatedItems isn't empty, instantiated items have been already added
+ if (!m_componentCompleted || !m_map || !m_delegate || m_itemModel.isNull() || !m_instantiatedItems.isEmpty())
return;
- Q_ASSERT(!m_itemDataBatched.size());
- m_repopulating = true;
-
- // QQuickWidget forces incubators to synchronous mode. Thus itemDataChanged gets called during the for loop below.
- m_itemDataBatched.resize(m_itemModel->rowCount());
- for (int i = 0; i < m_itemModel->rowCount(); ++i) {
- const QModelIndex index = m_itemModel->index(i, 0);
- createItemForIndex(index, true);
+
+ // If here, m_delegateModel may contain data, but QQmlInstanceModel::object for each row hasn't been called yet.
+ for (int i = 0; i < m_delegateModel->count(); i++) {
+ QDeclarativeGeoMapItemBase *item =
+ qobject_cast<QDeclarativeGeoMapItemBase *>(m_delegateModel->object(i, QQmlIncubator::Asynchronous));
+ if (item) // else createdItem will be emitted.
+ addItemToMap(item, i);
}
fitViewport();
}
-/*
- * used internally
-*/
-void QDeclarativeGeoMapItemView::removeItemData(QDeclarativeGeoMapItemViewItemData *itemData)
+void QDeclarativeGeoMapItemView::removeItemFromMap(int index)
{
- if (!itemData)
- return;
- if (itemData->incubator) {
- if (itemData->incubator->isReady()) {
- if (itemData->incubator->object() == itemData->item) {
- m_map->removeMapItem(itemData->item); // removeMapItem checks whether the item is in the map, so it's safe to call.
- itemData->item = 0;
+ if (index >= 0 && index < m_instantiatedItems.size()) {
+ QDeclarativeGeoMapItemBase *item = m_instantiatedItems.takeAt(index);
+ if (m_exit && m_map) {
+ if (!item->m_transitionManager) {
+ QScopedPointer<QDeclarativeGeoMapItemTransitionManager>manager(new QDeclarativeGeoMapItemTransitionManager(item));
+ item->m_transitionManager.swap(manager);
+ item->m_transitionManager->m_view = this;
}
- delete itemData->incubator->object();
+ connect(item, &QDeclarativeGeoMapItemBase::exitTransitionFinished,
+ this, &QDeclarativeGeoMapItemView::exitTransitionFinished);
+ item->m_transitionManager->transitionExit();
+ } else {
+ if (m_map)
+ m_map->removeMapItem(item);
+ m_delegateModel->release(item);
}
- itemData->incubator->clear(); // stops ongoing incubation
}
- if (itemData->item)
- m_map->removeMapItem(itemData->item);
- delete itemData; // destroys the ->item too.
}
-void QDeclarativeGeoMapItemView::terminateOngoingRepopulation()
-{
- if (m_repopulating) {
- // Terminate the previous resetting task. Not all incubators finished, but
- // QQmlIncubatorController operates in the same thread, so it is safe
- // to check, here, whether incubators are ready or not, without having
- // to race with them.
-
- foreach (QDeclarativeGeoMapItemViewItemData *itemData, m_itemDataBatched)
- removeItemData(itemData);
-
- m_itemDataBatched.clear();
- m_readyIncubators = 0;
- m_repopulating = false;
- }
-}
-
-/*!
- \internal
- Removes and repopulates all items.
-*/
-void QDeclarativeGeoMapItemView::repopulate()
+void QDeclarativeGeoMapItemView::exitTransitionFinished()
{
- if (!m_itemModel || !m_itemModel->rowCount()) {
- removeInstantiatedItems();
- } else {
- terminateOngoingRepopulation();
- instantiateAllItems(); // removal of instantiated item done at incubation completion
- }
+ QDeclarativeGeoMapItemBase *item = static_cast<QDeclarativeGeoMapItemBase *>(sender());
+ disconnect(item, 0, this, 0);
+ if (m_map)
+ m_map->removeMapItem(item);
+ m_delegateModel->release(item);
}
-/*!
- \internal
-
- Note: this call is async. that is returns to the event loop before returning to the caller.
- May also trigger incubatorStatusChanged() before returning to the caller if the incubator is fast enough.
-*/
-void QDeclarativeGeoMapItemView::createItemForIndex(const QModelIndex &index, bool batched)
+void QDeclarativeGeoMapItemView::addItemToMap(QDeclarativeGeoMapItemBase *item, int index)
{
- // Expected to be already tested by caller.
- Q_ASSERT(m_delegate);
- Q_ASSERT(m_itemModel);
-
- QDeclarativeGeoMapItemViewItemData *itemData = new QDeclarativeGeoMapItemViewItemData;
-
- itemData->modelData = new QObject;
- itemData->modelDataMeta = new QQmlOpenMetaObject(itemData->modelData, m_metaObjectType, false);
- itemData->context = new QQmlContext(qmlContext(this));
-
- QHashIterator<int, QByteArray> iterator(m_itemModel->roleNames());
- while (iterator.hasNext()) {
- iterator.next();
-
- QVariant modelData = m_itemModel->data(index, iterator.key());
- if (!modelData.isValid())
- continue;
-
- itemData->context->setContextProperty(QString::fromLatin1(iterator.value().constData()),
- modelData);
+ if (!item || (m_map && item->quickMap() == m_map))
+ return;
- itemData->modelDataMeta->setValue(iterator.value(), modelData);
+ if (m_map) {
+ m_instantiatedItems.insert(index, item);
+ m_map->addMapItem(item);
+ if (m_enter) {
+ if (!item->m_transitionManager) {
+ QScopedPointer<QDeclarativeGeoMapItemTransitionManager>manager(new QDeclarativeGeoMapItemTransitionManager(item));
+ item->m_transitionManager.swap(manager);
+ }
+ item->m_transitionManager->m_view = this;
+ item->m_transitionManager->transitionEnter();
+ }
}
-
- itemData->context->setContextProperty(QLatin1String("model"), itemData->modelData);
- itemData->context->setContextProperty(QLatin1String("index"), index.row());
-
- if (batched || m_repopulating) {
- if (index.row() < m_itemDataBatched.size())
- m_itemDataBatched.replace(index.row(), itemData);
- else
- m_itemDataBatched.insert(index.row(), itemData);
- } else
- m_itemData.insert(index.row(), itemData);
- itemData->incubator = new MapItemViewDelegateIncubator(this, itemData, batched || m_repopulating);
-
- m_delegate->create(*itemData->incubator, itemData->context);
-}
-
-QDeclarativeGeoMapItemViewItemData::~QDeclarativeGeoMapItemViewItemData()
-{
- delete incubator;
- delete item;
- delete context;
- delete modelData;
}
QT_END_NAMESPACE
+
+
diff --git a/src/location/declarativemaps/qdeclarativegeomapitemview_p.h b/src/location/declarativemaps/qdeclarativegeomapitemview_p.h
index e1132025..a3bf8596 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitemview_p.h
+++ b/src/location/declarativemaps/qdeclarativegeomapitemview_p.h
@@ -51,11 +51,13 @@
//
#include <QtLocation/private/qlocationglobal_p.h>
-
+#include <map>
#include <QtCore/QModelIndex>
#include <QtQml/QQmlParserStatus>
#include <QtQml/QQmlIncubator>
#include <QtQml/qqml.h>
+#include <QtQml/private/qqmldelegatemodel_p.h>
+#include <QtQuick/private/qquicktransition_p.h>
QT_BEGIN_NAMESPACE
@@ -68,6 +70,7 @@ class QQmlOpenMetaObject;
class QQmlOpenMetaObjectType;
class MapItemViewDelegateIncubator;
class QDeclarativeGeoMapItemViewItemData;
+class QDeclarativeGeoMapItemView;
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoMapItemView : public QObject, public QQmlParserStatus
{
@@ -78,6 +81,8 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoMapItemView : public QObject, pub
Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(bool autoFitViewport READ autoFitViewport WRITE setAutoFitViewport NOTIFY autoFitViewportChanged)
+// Q_PROPERTY(QQuickTransition *enter MEMBER m_enter)
+// Q_PROPERTY(QQuickTransition *exit MEMBER m_exit)
public:
explicit QDeclarativeGeoMapItemView(QQuickItem *parent = 0);
@@ -90,60 +95,46 @@ public:
void setDelegate(QQmlComponent *);
bool autoFitViewport() const;
- void setAutoFitViewport(const bool &);
+ void setAutoFitViewport(const bool &fit);
void setMap(QDeclarativeGeoMap *);
- void repopulate();
void removeInstantiatedItems();
void instantiateAllItems();
- qreal zValue();
- void setZValue(qreal zValue);
-
// From QQmlParserStatus
- virtual void componentComplete();
- void classBegin() {}
+ void componentComplete() override;
+ void classBegin() override;
Q_SIGNALS:
void modelChanged();
void delegateChanged();
void autoFitViewportChanged();
-protected:
- void incubatorStatusChanged(MapItemViewDelegateIncubator *incubator,
- QQmlIncubator::Status status,
- bool batched);
-
private Q_SLOTS:
- void itemModelReset();
- void itemModelRowsInserted(const QModelIndex &index, int start, int end);
- void itemModelRowsRemoved(const QModelIndex &index, int start, int end);
- void itemModelRowsMoved(const QModelIndex &parent, int start, int end,
- const QModelIndex &destination, int row);
- void itemModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
- const QVector<int> &roles);
+ void destroyingItem(QObject *object);
+ void initItem(int index, QObject *object);
+ void createdItem(int index, QObject *object);
+ void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
+ void exitTransitionFinished();
private:
- void createItemForIndex(const QModelIndex &index, bool batched = false);
void fitViewport();
- void terminateOngoingRepopulation();
- void removeItemData(QDeclarativeGeoMapItemViewItemData *itemData);
+ void removeItemFromMap(int index);
+ void addItemToMap(QDeclarativeGeoMapItemBase *item, int index);
bool m_componentCompleted;
QQmlComponent *m_delegate;
- QAbstractItemModel *m_itemModel;
+ QVariant m_itemModel;
QDeclarativeGeoMap *m_map;
- QVector<QDeclarativeGeoMapItemViewItemData *> m_itemData;
- QVector<QDeclarativeGeoMapItemViewItemData *> m_itemDataBatched;
+ QList<QDeclarativeGeoMapItemBase *> m_instantiatedItems;
bool m_fitViewport;
-
- QQmlOpenMetaObjectType *m_metaObjectType;
- int m_readyIncubators;
- bool m_repopulating;
+ QQmlDelegateModel *m_delegateModel;
+ QQuickTransition *m_enter = nullptr;
+ QQuickTransition *m_exit = nullptr;
friend class QDeclarativeGeoMap;
- friend class QDeclarativeGeoMapItemViewItemData;
- friend class MapItemViewDelegateIncubator;
+ friend class QDeclarativeGeoMapItemBase;
+ friend class QDeclarativeGeoMapItemTransitionManager;
};
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeomapitemview_p_p.h b/src/location/declarativemaps/qdeclarativegeomapitemview_p_p.h
deleted file mode 100644
index 3ad3ceb4..00000000
--- a/src/location/declarativemaps/qdeclarativegeomapitemview_p_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtLocation module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEGEOMAPITEMVIEW_P_P_H
-#define QDECLARATIVEGEOMAPITEMVIEW_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QModelIndex>
-#include <QtQml/QQmlParserStatus>
-#include <QtQml/QQmlIncubator>
-#include <QtQml/qqml.h>
-#include <QtQml/private/qqmlopenmetaobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class MapItemViewDelegateIncubator;
-class QDeclarativeGeoMapItemView;
-class QDeclarativeGeoMapItemBase;
-
-class QDeclarativeGeoMapItemViewItemData
-{
-public:
- QDeclarativeGeoMapItemViewItemData()
- : incubator(0), item(0), context(0), modelData(0), modelDataMeta(0)
- {
- }
-
- ~QDeclarativeGeoMapItemViewItemData();
-
- MapItemViewDelegateIncubator *incubator;
- QDeclarativeGeoMapItemBase *item;
- QQmlContext *context;
- QObject *modelData;
- QQmlOpenMetaObject *modelDataMeta;
-
- friend class MapItemViewDelegateIncubator;
- friend class QDeclarativeGeoMapItemView;
-};
-
-Q_DECLARE_TYPEINFO(QDeclarativeGeoMapItemViewItemData, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVEGEOMAPITEMVIEW_P_P_H