summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-12-17 08:13:04 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-12-17 08:13:04 (GMT)
commitf79e0e89ea9061bbe93f43405a1ec954a41da1cc (patch)
tree2aa675c50ad2ba2fb935981c3fcc79161b09b706
parent4d6001bd1d75b80c53fcc716b5a51043713ff6f9 (diff)
downloadQt-f79e0e89ea9061bbe93f43405a1ec954a41da1cc.zip
Qt-f79e0e89ea9061bbe93f43405a1ec954a41da1cc.tar.gz
Qt-f79e0e89ea9061bbe93f43405a1ec954a41da1cc.tar.bz2
Make positioners fast.
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri2
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsanchors.cpp4
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h4
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsitem.cpp78
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsitem_p.h69
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h (renamed from src/declarative/graphicsitems/qmlgraphicsitemgeometrylistener_p.h)16
-rw-r--r--src/declarative/graphicsitems/qmlgraphicslistview.cpp6
-rw-r--r--src/declarative/graphicsitems/qmlgraphicspositioners.cpp181
-rw-r--r--src/declarative/graphicsitems/qmlgraphicspositioners_p.h16
-rw-r--r--src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h40
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h2
-rw-r--r--src/declarative/qml/qpodvector_p.h48
12 files changed, 267 insertions, 199 deletions
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index 5199c5d..eb6e0ad 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -48,7 +48,7 @@ HEADERS += \
$$PWD/qmlgraphicsgraphicsobjectcontainer_p.h \
$$PWD/qmlgraphicsparticles_p.h \
$$PWD/qmlgraphicslayoutitem_p.h \
- $$PWD/qmlgraphicsitemgeometrylistener_p.h \
+ $$PWD/qmlgraphicsitemchangelistener_p.h \
$$PWD/qmlgraphicseffects.cpp
SOURCES += \
diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp
index 0febf08..c2e1fa2 100644
--- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp
@@ -245,7 +245,7 @@ void QmlGraphicsAnchorsPrivate::addDepend(QmlGraphicsItem *item)
return;
QmlGraphicsItemPrivate *p =
static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(item));
- p->addGeometryListener(this);
+ p->addItemChangeListener(this, QmlGraphicsItemPrivate::Geometry);
}
void QmlGraphicsAnchorsPrivate::remDepend(QmlGraphicsItem *item)
@@ -254,7 +254,7 @@ void QmlGraphicsAnchorsPrivate::remDepend(QmlGraphicsItem *item)
return;
QmlGraphicsItemPrivate *p =
static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(item));
- p->removeGeometryListener(this);
+ p->removeItemChangeListener(this, QmlGraphicsItemPrivate::Geometry);
}
bool QmlGraphicsAnchorsPrivate::isItemComplete() const
diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h
index 91c8ff1..45c983f 100644
--- a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h
@@ -54,7 +54,7 @@
//
#include "qmlgraphicsanchors_p.h"
-#include "qmlgraphicsitemgeometrylistener_p.h"
+#include "qmlgraphicsitemchangelistener_p.h"
#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -91,7 +91,7 @@ Q_DECLARE_METATYPE(QmlGraphicsAnchorLine)
-class QmlGraphicsAnchorsPrivate : public QObjectPrivate, public QmlGraphicsItemGeometryListener
+class QmlGraphicsAnchorsPrivate : public QObjectPrivate, public QmlGraphicsItemChangeListener
{
Q_DECLARE_PUBLIC(QmlGraphicsAnchors)
public:
diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp
index 4d587e4d..aa73444 100644
--- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp
@@ -1478,18 +1478,24 @@ QmlGraphicsItem::QmlGraphicsItem(QmlGraphicsItemPrivate &dd, QmlGraphicsItem *pa
QmlGraphicsItem::~QmlGraphicsItem()
{
Q_D(QmlGraphicsItem);
- for (int ii = 0; ii < d->geometryListeners.count(); ++ii) {
- QmlGraphicsAnchorsPrivate *anchor = d->geometryListeners.at(ii)->anchorPrivate();
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ QmlGraphicsAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
if (anchor)
anchor->clearItem(this);
}
- if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor))
- for (int ii = 0; ii < d->geometryListeners.count(); ++ii) {
- QmlGraphicsAnchorsPrivate *anchor = d->geometryListeners.at(ii)->anchorPrivate();
+ if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor)) {
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ QmlGraphicsAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
if (anchor && anchor->item && anchor->item->parentItem() != this) //child will be deleted anyway
anchor->updateOnComplete();
}
- d->geometryListeners.clear();
+ }
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QmlGraphicsItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QmlGraphicsItemPrivate::Destroyed)
+ change.listener->itemDestroyed(this);
+ }
+ d->changeListeners.clear();
delete d->_anchorLines; d->_anchorLines = 0;
delete d->_anchors; d->_anchors = 0;
delete d->_stateGroup; d->_stateGroup = 0;
@@ -1975,20 +1981,17 @@ void QmlGraphicsItem::geometryChanged(const QRectF &newGeometry,
if (newGeometry.height() != oldGeometry.height())
emit heightChanged();
- for(int ii = 0; ii < d->geometryListeners.count(); ++ii) {
- QmlGraphicsItemGeometryListener *listener = d->geometryListeners.at(ii);
- listener->itemGeometryChanged(this, newGeometry, oldGeometry);
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QmlGraphicsItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QmlGraphicsItemPrivate::Geometry)
+ change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
}
}
-void QmlGraphicsItemPrivate::addGeometryListener(QmlGraphicsItemGeometryListener *listener)
-{
- geometryListeners.append(listener);
-}
-
-void QmlGraphicsItemPrivate::removeGeometryListener(QmlGraphicsItemGeometryListener *listener)
+void QmlGraphicsItemPrivate::removeItemChangeListener(QmlGraphicsItemChangeListener *listener, ChangeTypes types)
{
- geometryListeners.removeOne(listener);
+ ChangeListener change(listener, types);
+ changeListeners.removeOne(change);
}
/*! \internal */
@@ -2238,10 +2241,13 @@ void QmlGraphicsItem::setBaselineOffset(qreal offset)
d->_baselineOffset = offset;
emit baselineOffsetChanged();
- for(int ii = 0; ii < d->geometryListeners.count(); ++ii) {
- QmlGraphicsAnchorsPrivate *anchor = d->geometryListeners.at(ii)->anchorPrivate();
- if (anchor)
- anchor->updateVerticalAnchors();
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QmlGraphicsItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QmlGraphicsItemPrivate::Geometry) {
+ QmlGraphicsAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor)
+ anchor->updateVerticalAnchors();
+ }
}
}
@@ -2707,10 +2713,35 @@ bool QmlGraphicsItem::sceneEvent(QEvent *event)
QVariant QmlGraphicsItem::itemChange(GraphicsItemChange change,
const QVariant &value)
{
- if (change == ItemParentHasChanged) {
+ Q_D(const QmlGraphicsItem);
+ switch (change) {
+ case ItemParentHasChanged:
emit parentChanged();
- } else if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ break;
+ case ItemChildAddedChange:
+ case ItemChildRemovedChange:
emit childrenChanged();
+ break;
+ case ItemVisibleHasChanged: {
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QmlGraphicsItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QmlGraphicsItemPrivate::Visibility) {
+ change.listener->itemVisibilityChanged(this);
+ }
+ }
+ }
+ break;
+ case ItemOpacityHasChanged: {
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QmlGraphicsItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QmlGraphicsItemPrivate::Opacity) {
+ change.listener->itemOpacityChanged(this);
+ }
+ }
+ }
+ break;
+ default:
+ break;
}
return QGraphicsItem::itemChange(change, value);
@@ -3006,9 +3037,6 @@ QDebug operator<<(QDebug debug, QmlGraphicsItem *item)
return debug;
}
-int QmlGraphicsItemPrivate::heightIdx = -1;
-int QmlGraphicsItemPrivate::widthIdx = -1;
-
int QmlGraphicsItemPrivate::consistentTime = -1;
void QmlGraphicsItemPrivate::setConsistentTime(int t)
{
diff --git a/src/declarative/graphicsitems/qmlgraphicsitem_p.h b/src/declarative/graphicsitems/qmlgraphicsitem_p.h
index 9496590..07c821e 100644
--- a/src/declarative/graphicsitems/qmlgraphicsitem_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicsitem_p.h
@@ -57,7 +57,8 @@
#include "qmlgraphicsanchors_p.h"
#include "qmlgraphicsanchors_p_p.h"
-#include "qmlgraphicsitemgeometrylistener_p.h"
+#include "qmlgraphicsitemchangelistener_p.h"
+#include "qpodvector_p.h"
#include "../util/qmlstate_p.h"
#include "../util/qmlnullablevalue_p_p.h"
@@ -115,10 +116,6 @@ public:
smooth(false), keyHandler(0),
width(0), height(0), implicitWidth(0), implicitHeight(0)
{
- if (widthIdx == -1) {
- widthIdx = QmlGraphicsItem::staticMetaObject.indexOfSignal("widthChanged()");
- heightIdx = QmlGraphicsItem::staticMetaObject.indexOfSignal("heightChanged()");
- }
}
void init(QmlGraphicsItem *parent)
@@ -206,9 +203,28 @@ public:
return _anchorLines;
}
- void addGeometryListener(QmlGraphicsItemGeometryListener *);
- void removeGeometryListener(QmlGraphicsItemGeometryListener *);
- QList<QmlGraphicsItemGeometryListener *> geometryListeners;
+ enum ChangeType {
+ Geometry = 0x01,
+ SiblingOrder = 0x02,
+ Visibility = 0x04,
+ Opacity = 0x08,
+ Destroyed = 0x10
+ };
+
+ Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
+
+ struct ChangeListener {
+ ChangeListener(QmlGraphicsItemChangeListener *l, QmlGraphicsItemPrivate::ChangeTypes t) : listener(l), types(t) {}
+ QmlGraphicsItemChangeListener *listener;
+ QmlGraphicsItemPrivate::ChangeTypes types;
+ bool operator==(const ChangeListener &other) const { return listener == other.listener && types == other.types; }
+ };
+
+ void addItemChangeListener(QmlGraphicsItemChangeListener *listener, ChangeTypes types) {
+ changeListeners.append(ChangeListener(listener, types));
+ }
+ void removeItemChangeListener(QmlGraphicsItemChangeListener *, ChangeTypes types);
+ QPODVector<ChangeListener,4> changeListeners;
QmlStateGroup *states();
QmlStateGroup *_stateGroup;
@@ -246,32 +262,13 @@ public:
// Reimplemented from QGraphicsItemPrivate
virtual void siblingOrderChange()
{
- foreach(QmlGraphicsItemPrivate* other, siblingOrderNotifiees)
- other->otherSiblingOrderChange(this);
- }
- QList<QmlGraphicsItemPrivate*> siblingOrderNotifiees;
- void registerSiblingOrderNotification(QmlGraphicsItemPrivate* other)
- {
- siblingOrderNotifiees << other;
- }
- void unregisterSiblingOrderNotification(QmlGraphicsItemPrivate* other)
- {
- siblingOrderNotifiees.removeAll(other);
- }
- virtual void otherSiblingOrderChange(QmlGraphicsItemPrivate* other) {Q_UNUSED(other)}
-
- bool connectToWidthChanged(QObject *object, int index) {
- return QMetaObject::connect(q_func(), widthIdx, object, index);
- }
- bool disconnectFromWidthChanged(QObject *object, int index) {
- return QMetaObject::disconnect(q_func(), widthIdx, object, index);
- }
-
- bool connectToHeightChanged(QObject *object, int index) {
- return QMetaObject::connect(q_func(), heightIdx, object, index);
- }
- bool disconnectFromHeightChanged(QObject *object, int index) {
- return QMetaObject::disconnect(q_func(), heightIdx, object, index);
+ Q_Q(QmlGraphicsItem);
+ for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QmlGraphicsItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QmlGraphicsItemPrivate::SiblingOrder) {
+ change.listener->itemSiblingOrderChanged(q);
+ }
+ }
}
static int consistentTime;
@@ -280,10 +277,10 @@ public:
static void start(QTime &);
static int elapsed(QTime &);
static int restart(QTime &);
- static int widthIdx;
- static int heightIdx;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QmlGraphicsItemPrivate::ChangeTypes);
+
QT_END_NAMESPACE
#endif // QMLGRAPHICSITEM_P_H
diff --git a/src/declarative/graphicsitems/qmlgraphicsitemgeometrylistener_p.h b/src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h
index 6230e93..f430df0 100644
--- a/src/declarative/graphicsitems/qmlgraphicsitemgeometrylistener_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QMLGRAPHICSITEMGEOMETRYLISTENER
-#define QMLGRAPHICSITEMGEOMETRYLISTENER
+#ifndef QMLGRAPHICSITEMCHANGELISTENER
+#define QMLGRAPHICSITEMCHANGELISTENER
//
// W A R N I N G
@@ -53,18 +53,24 @@
// We mean it.
//
+#include <QtCore/qglobal.h>
+
QT_BEGIN_NAMESPACE
class QRectF;
class QmlGraphicsItem;
class QmlGraphicsAnchorsPrivate;
-class QmlGraphicsItemGeometryListener
+class QmlGraphicsItemChangeListener
{
public:
- virtual void itemGeometryChanged(QmlGraphicsItem *, const QRectF &newGeometry, const QRectF &oldGeometry) = 0;
+ virtual void itemGeometryChanged(QmlGraphicsItem *, const QRectF &, const QRectF &) {}
+ virtual void itemSiblingOrderChanged(QmlGraphicsItem *) {}
+ virtual void itemVisibilityChanged(QmlGraphicsItem *) {}
+ virtual void itemOpacityChanged(QmlGraphicsItem *) {}
+ virtual void itemDestroyed(QmlGraphicsItem *) {}
virtual QmlGraphicsAnchorsPrivate *anchorPrivate() { return 0; }
};
QT_END_NAMESPACE
-#endif // QMLGRAPHICSITEMGEOMETRYLISTENER
+#endif // QMLGRAPHICSITEMCHANGELISTENER
diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp
index d4d201a..5db3b26 100644
--- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp
@@ -218,7 +218,7 @@ public:
//----------------------------------------------------------------------------
-class QmlGraphicsListViewPrivate : public QmlGraphicsFlickablePrivate, private QmlGraphicsItemGeometryListener
+class QmlGraphicsListViewPrivate : public QmlGraphicsFlickablePrivate, private QmlGraphicsItemChangeListener
{
Q_DECLARE_PUBLIC(QmlGraphicsListView)
@@ -607,7 +607,7 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex)
listItem->item->setZValue(1);
listItem->item->setParent(q->viewport());
QmlGraphicsItemPrivate *itemPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(item));
- itemPrivate->addGeometryListener(this);
+ itemPrivate->addItemChangeListener(this, QmlGraphicsItemPrivate::Geometry);
if (sectionCriteria && sectionCriteria->delegate()) {
if (listItem->attached->m_prevSection != listItem->attached->m_section)
createSection(listItem);
@@ -631,7 +631,7 @@ void QmlGraphicsListViewPrivate::releaseItem(FxListItem *item)
trackedItem = 0;
}
QmlGraphicsItemPrivate *itemPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(item->item));
- itemPrivate->removeGeometryListener(this);
+ itemPrivate->removeItemChangeListener(this, QmlGraphicsItemPrivate::Geometry);
if (model->release(item->item) == 0) {
// item was not destroyed, and we no longer reference it.
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp
index 17fe59f..aa724a3 100644
--- a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp
@@ -54,38 +54,23 @@
QT_BEGIN_NAMESPACE
-int QmlGraphicsBasePositionerPrivate::prePosIdx = -1;
-int QmlGraphicsBasePositionerPrivate::visibleIdx = -1;
-int QmlGraphicsBasePositionerPrivate::opacityIdx = -1;
-
+static const QmlGraphicsItemPrivate::ChangeTypes watchedChanges
+ = QmlGraphicsItemPrivate::Geometry
+ | QmlGraphicsItemPrivate::SiblingOrder
+ | QmlGraphicsItemPrivate::Visibility
+ | QmlGraphicsItemPrivate::Opacity
+ | QmlGraphicsItemPrivate::Destroyed;
void QmlGraphicsBasePositionerPrivate::watchChanges(QmlGraphicsItem *other)
{
- Q_Q(QmlGraphicsBasePositioner);
- QMetaObject::connect(other, visibleIdx, q, prePosIdx);
- QMetaObject::connect(other, opacityIdx, q, prePosIdx);
-
QmlGraphicsItemPrivate *otherPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(other));
-
- otherPrivate->addGeometryListener(this);
-
- otherPrivate->registerSiblingOrderNotification(this);
- watched << other;
+ otherPrivate->addItemChangeListener(this, watchedChanges);
}
void QmlGraphicsBasePositionerPrivate::unwatchChanges(QmlGraphicsItem* other)
{
- Q_Q(QmlGraphicsBasePositioner);
QmlGraphicsItemPrivate *otherPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(other));
- bool stillAlive = false; //Use the returns from disconnect to see if it was deleted or just reparented
- stillAlive |= QMetaObject::disconnect(other, visibleIdx, q, prePosIdx);
- stillAlive |= QMetaObject::disconnect(other, opacityIdx, q, prePosIdx);
-
- otherPrivate->removeGeometryListener(this);
-
- if(stillAlive)
- otherPrivate->unregisterSiblingOrderNotification(this);
- watched.removeAll(other);
+ otherPrivate->removeItemChangeListener(this, watchedChanges);
}
/*!
@@ -120,6 +105,14 @@ QmlGraphicsBasePositioner::QmlGraphicsBasePositioner(QmlGraphicsBasePositionerPr
d->init(at);
}
+QmlGraphicsBasePositioner::~QmlGraphicsBasePositioner()
+{
+ Q_D(QmlGraphicsBasePositioner);
+ for (int i = 0; i < positionedItems.count(); ++i)
+ d->unwatchChanges(positionedItems.at(i).item);
+ positionedItems.clear();
+}
+
int QmlGraphicsBasePositioner::spacing() const
{
Q_D(const QmlGraphicsBasePositioner);
@@ -162,10 +155,12 @@ void QmlGraphicsBasePositioner::setAdd(QmlTransition *add)
void QmlGraphicsBasePositioner::componentComplete()
{
+ Q_D(QmlGraphicsBasePositioner);
QmlGraphicsItem::componentComplete();
#ifdef Q_ENABLE_PERFORMANCE_LOG
QmlPerfTimer<QmlPerf::BasepositionerComponentComplete> cc;
#endif
+ positionedItems.reserve(d->QGraphicsItemPrivate::children.count());
prePositioning();
}
@@ -175,18 +170,19 @@ QVariant QmlGraphicsBasePositioner::itemChange(GraphicsItemChange change,
Q_D(QmlGraphicsBasePositioner);
if (change == ItemChildAddedChange){
QmlGraphicsItem* child = value.value<QmlGraphicsItem*>();
- if(!child)
- return QVariant();
- if(!d->watched.contains(child))
- d->watchChanges(child);
- prePositioning();
- }else if (change == ItemChildRemovedChange) {
+ if (child)
+ prePositioning();
+ } else if (change == ItemChildRemovedChange) {
QmlGraphicsItem* child = value.value<QmlGraphicsItem*>();
- if(!child)
- return QVariant();
- if(d->watched.contains(child))
- d->unwatchChanges(child);
- prePositioning();
+ if (child) {
+ QmlGraphicsBasePositioner::PositionedItem posItem(child);
+ int idx = positionedItems.find(posItem);
+ if (idx >= 0) {
+ d->unwatchChanges(child);
+ positionedItems.remove(idx);
+ }
+ prePositioning();
+ }
}
return QmlGraphicsItem::itemChange(change, value);
@@ -202,29 +198,31 @@ void QmlGraphicsBasePositioner::prePositioning()
//Need to order children by creation order modified by stacking order
QList<QGraphicsItem *> children = childItems();
qSort(children.begin(), children.end(), d->insertionOrder);
- positionedItems.clear();
- d->newItems.clear();
for (int ii = 0; ii < children.count(); ++ii) {
QmlGraphicsItem *child = qobject_cast<QmlGraphicsItem *>(children.at(ii));
if (!child)
continue;
- if(!d->watched.contains(child))
+ PositionedItem *item = 0;
+ PositionedItem posItem(child);
+ int wIdx = positionedItems.find(posItem);
+ if (wIdx < 0) {
d->watchChanges(child);
- if(child->opacity() <= 0.0 || !child->isVisible())
+ positionedItems.append(posItem);
+ item = &positionedItems[positionedItems.count()-1];
+ } else {
+ item = &positionedItems[wIdx];
+ }
+ if (child->opacity() <= 0.0 || !child->isVisible()) {
+ item->isVisible = false;
continue;
- if (!d->items.contains(child)){
- d->items += child;
- d->newItems += child;
}
- positionedItems << child;
- }
- if(d->items.count() > positionedItems.count()){
- //Assumed that (aside from init) every add/remove triggers this check
- //thus the above check will be triggered every time an item is removed
- QSet<QmlGraphicsItem *> deletedItems = d->items - positionedItems.toSet();
- foreach(QmlGraphicsItem *child, deletedItems)
- d->items -= child;
+ if (!item->isVisible) {
+ item->isVisible = true;
+ item->isNew = true;
+ } else {
+ item->isNew = false;
+ }
}
doPositioning();
if(d->addTransition || d->moveTransition)
@@ -232,42 +230,43 @@ void QmlGraphicsBasePositioner::prePositioning()
//Set implicit size to the size of its children
qreal h = 0.0f;
qreal w = 0.0f;
- foreach(QmlGraphicsItem *child, d->items){
- if(!child->isVisible() || child->opacity() <= 0)
- continue;
- h = qMax(h, child->y() + child->height());
- w = qMax(w, child->x() + child->width());
+ for (int i = 0; i < positionedItems.count(); ++i) {
+ const PositionedItem &posItem = positionedItems.at(i);
+ if (posItem.isVisible) {
+ h = qMax(h, posItem.item->y() + posItem.item->height());
+ w = qMax(w, posItem.item->x() + posItem.item->width());
+ }
}
setImplicitHeight(h);
setImplicitWidth(w);
}
-void QmlGraphicsBasePositioner::positionX(int x, QmlGraphicsItem* target)
+void QmlGraphicsBasePositioner::positionX(int x, const PositionedItem &target)
{
Q_D(QmlGraphicsBasePositioner);
if(d->type == Horizontal || d->type == Both){
if(!d->addTransition && !d->moveTransition){
- target->setX(x);
+ target.item->setX(x);
}else{
- if(d->newItems.contains(target))
- d->addActions << Action(target, QLatin1String("x"), QVariant(x));
+ if(target.isNew)
+ d->addActions << Action(target.item, QLatin1String("x"), QVariant(x));
else
- d->moveActions << Action(target, QLatin1String("x"), QVariant(x));
+ d->moveActions << Action(target.item, QLatin1String("x"), QVariant(x));
}
}
}
-void QmlGraphicsBasePositioner::positionY(int y, QmlGraphicsItem* target)
+void QmlGraphicsBasePositioner::positionY(int y, const PositionedItem &target)
{
Q_D(QmlGraphicsBasePositioner);
if(d->type == Vertical || d->type == Both){
if(!d->addTransition && !d->moveTransition){
- target->setY(y);
+ target.item->setY(y);
}else{
- if(d->newItems.contains(target))
- d->addActions << Action(target, QLatin1String("y"), QVariant(y));
+ if(target.isNew)
+ d->addActions << Action(target.item, QLatin1String("y"), QVariant(y));
else
- d->moveActions << Action(target, QLatin1String("y"), QVariant(y));
+ d->moveActions << Action(target.item, QLatin1String("y"), QVariant(y));
}
}
}
@@ -401,14 +400,14 @@ void QmlGraphicsColumn::doPositioning()
int voffset = 0;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
- QmlGraphicsItem *child = positionedItems.at(ii);
- if (!child || isInvisible(child))
+ const PositionedItem &child = positionedItems.at(ii);
+ if (!child.item || isInvisible(child.item))
continue;
- if(child->y() != voffset)
+ if(child.item->y() != voffset)
positionY(voffset, child);
- voffset += child->height();
+ voffset += child.item->height();
voffset += spacing();
}
}
@@ -506,14 +505,14 @@ void QmlGraphicsRow::doPositioning()
int hoffset = 0;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
- QmlGraphicsItem *child = positionedItems.at(ii);
- if (!child || isInvisible(child))
+ const PositionedItem &child = positionedItems.at(ii);
+ if (!child.item || isInvisible(child.item))
continue;
- if(child->x() != hoffset)
+ if(child.item->x() != hoffset)
positionX(hoffset, child);
- hoffset += child->width();
+ hoffset += child.item->width();
hoffset += spacing();
}
}
@@ -670,13 +669,13 @@ void QmlGraphicsGrid::doPositioning()
if (childIndex == positionedItems.count())
continue;
- QmlGraphicsItem *child = positionedItems.at(childIndex++);
- if (!child || isInvisible(child))
+ const PositionedItem &child = positionedItems.at(childIndex++);
+ if (!child.item || isInvisible(child.item))
continue;
- if (child->width() > maxColWidth[j])
- maxColWidth[j] = child->width();
- if (child->height() > maxRowHeight[i])
- maxRowHeight[i] = child->height();
+ if (child.item->width() > maxColWidth[j])
+ maxColWidth[j] = child.item->width();
+ if (child.item->height() > maxRowHeight[i])
+ maxRowHeight[i] = child.item->height();
}
}
@@ -684,10 +683,11 @@ void QmlGraphicsGrid::doPositioning()
int yoffset=0;
int curRow =0;
int curCol =0;
- foreach(QmlGraphicsItem* child, positionedItems){
- if (!child || isInvisible(child))
+ for (int i = 0; i < positionedItems.count(); ++i) {
+ const PositionedItem &child = positionedItems.at(i);
+ if (!child.item || isInvisible(child.item))
continue;
- if((child->x()!=xoffset)||(child->y()!=yoffset)){
+ if((child.item->x()!=xoffset)||(child.item->y()!=yoffset)){
positionX(xoffset, child);
positionY(yoffset, child);
}
@@ -805,37 +805,38 @@ void QmlGraphicsFlow::doPositioning()
int voffset = 0;
int linemax = 0;
- foreach(QmlGraphicsItem* child, positionedItems){
- if (!child || isInvisible(child))
+ for (int i = 0; i < positionedItems.count(); ++i) {
+ const PositionedItem &child = positionedItems.at(i);
+ if (!child.item || isInvisible(child.item))
continue;
if (d->flow == LeftToRight) {
- if (hoffset && hoffset + child->width() > width()) {
+ if (hoffset && hoffset + child.item->width() > width()) {
hoffset = 0;
voffset += linemax + spacing();
linemax = 0;
}
} else {
- if (voffset && voffset + child->height() > height()) {
+ if (voffset && voffset + child.item->height() > height()) {
voffset = 0;
hoffset += linemax + spacing();
linemax = 0;
}
}
- if(child->x() != hoffset || child->y() != voffset){
+ if(child.item->x() != hoffset || child.item->y() != voffset){
positionX(hoffset, child);
positionY(voffset, child);
}
if (d->flow == LeftToRight) {
- hoffset += child->width();
+ hoffset += child.item->width();
hoffset += spacing();
- linemax = qMax(linemax, qCeil(child->height()));
+ linemax = qMax(linemax, qCeil(child.item->height()));
} else {
- voffset += child->height();
+ voffset += child.item->height();
voffset += spacing();
- linemax = qMax(linemax, qCeil(child->width()));
+ linemax = qMax(linemax, qCeil(child.item->width()));
}
}
}
diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h
index c8f846a..0e6d134 100644
--- a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h
@@ -45,6 +45,7 @@
#include "qmlgraphicsitem.h"
#include "../util/qmlstate_p.h"
+#include "qpodvector_p.h"
#include <QtCore/QObject>
#include <QtCore/QString>
@@ -66,6 +67,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsBasePositioner : public QmlGraphicsItem
public:
enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
QmlGraphicsBasePositioner(PositionerType, QmlGraphicsItem *parent);
+ ~QmlGraphicsBasePositioner();
int spacing() const;
void setSpacing(int);
@@ -90,9 +92,17 @@ protected Q_SLOTS:
void prePositioning();
protected:
- QList<QmlGraphicsItem *> positionedItems;
- void positionX(int,QmlGraphicsItem* target);
- void positionY(int,QmlGraphicsItem* target);
+ struct PositionedItem {
+ PositionedItem(QmlGraphicsItem *i) : item(i), isNew(false), isVisible(true) {}
+ bool operator==(const PositionedItem &other) const { return other.item == item; }
+ QmlGraphicsItem *item;
+ bool isNew;
+ bool isVisible;
+ };
+
+ QPODVector<PositionedItem,8> positionedItems;
+ void positionX(int,const PositionedItem &target);
+ void positionY(int,const PositionedItem &target);
private:
Q_DISABLE_COPY(QmlGraphicsBasePositioner)
diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h
index 63c1c83..55a31c7 100644
--- a/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h
@@ -64,9 +64,10 @@
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QTimer>
+#include <QDebug>
QT_BEGIN_NAMESPACE
-class QmlGraphicsBasePositionerPrivate : public QmlGraphicsItemPrivate, public QmlGraphicsItemGeometryListener
+class QmlGraphicsBasePositionerPrivate : public QmlGraphicsItemPrivate, public QmlGraphicsItemChangeListener
{
Q_DECLARE_PUBLIC(QmlGraphicsBasePositioner)
@@ -77,29 +78,15 @@ public:
{
}
- ~QmlGraphicsBasePositionerPrivate()
- {
- watched.removeAll(0);
- foreach(QmlGraphicsItem* other, watched)
- unwatchChanges(other);//Need to deregister from a list in QmlGI Private
- }
-
void init(QmlGraphicsBasePositioner::PositionerType at)
{
type = at;
- if (prePosIdx == -1) {
- prePosIdx = QmlGraphicsBasePositioner::staticMetaObject.indexOfSlot("prePositioning()");
- visibleIdx = QmlGraphicsItem::staticMetaObject.indexOfSignal("visibleChanged()");
- opacityIdx = QmlGraphicsItem::staticMetaObject.indexOfSignal("opacityChanged()");
- }
}
int spacing;
QmlGraphicsBasePositioner::PositionerType type;
QmlTransition *moveTransition;
QmlTransition *addTransition;
- QSet<QmlGraphicsItem *> items;
- QSet<QmlGraphicsItem *> newItems;
QmlStateOperation::ActionList addActions;
QmlStateOperation::ActionList moveActions;
QmlTransitionManager addTransitionManager;
@@ -107,14 +94,9 @@ public:
void watchChanges(QmlGraphicsItem *other);
void unwatchChanges(QmlGraphicsItem* other);
- QList<QGuard<QmlGraphicsItem> > watched;//Can't have QSet and QGuard at the same time?
bool queuedPositioning;
- static int prePosIdx;
- static int visibleIdx;
- static int opacityIdx;
-
- virtual void otherSiblingOrderChange(QmlGraphicsItemPrivate* other)
+ virtual void itemSiblingOrderChanged(QmlGraphicsItem* other)
{
Q_Q(QmlGraphicsBasePositioner);
Q_UNUSED(other);
@@ -132,6 +114,22 @@ public:
if (newGeometry.size() != oldGeometry.size())
q->prePositioning();
}
+ virtual void itemVisibilityChanged(QmlGraphicsItem *)
+ {
+ Q_Q(QmlGraphicsBasePositioner);
+ q->prePositioning();
+ }
+ virtual void itemOpacityChanged(QmlGraphicsItem *)
+ {
+ Q_Q(QmlGraphicsBasePositioner);
+ q->prePositioning();
+ }
+
+ void itemDestroyed(QmlGraphicsItem *item)
+ {
+ Q_Q(QmlGraphicsBasePositioner);
+ q->positionedItems.removeOne(QmlGraphicsBasePositioner::PositionedItem(item));
+ }
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h
index 4e8a19b..bd9202b 100644
--- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h
@@ -82,7 +82,7 @@ public:
virtual ReleaseFlags release(QmlGraphicsItem *item) = 0;
virtual void completeItem() = 0;
virtual QVariant evaluate(int index, const QString &expression, QObject *objectContext) = 0;
- virtual QVariant value(int index, const QString &role) { return QVariant(); }
+ virtual QVariant value(int, const QString &) { return QVariant(); }
virtual int indexOf(QmlGraphicsItem *item, QObject *objectContext) const = 0;
diff --git a/src/declarative/qml/qpodvector_p.h b/src/declarative/qml/qpodvector_p.h
index 3fe2e65..add6e98 100644
--- a/src/declarative/qml/qpodvector_p.h
+++ b/src/declarative/qml/qpodvector_p.h
@@ -54,10 +54,11 @@
//
#include <QtCore/qglobal.h>
+#include <QDebug>
QT_BEGIN_NAMESPACE
-template<class T>
+template<class T, int Increment=1024>
class QPODVector
{
public:
@@ -87,23 +88,28 @@ public:
void insert(int idx, const T &v) {
if (m_count == m_capacity) {
- m_capacity += 1024;
+ m_capacity += Increment;
m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
}
int moveCount = m_count - idx;
- if (moveCount)
+ if (moveCount) {
+ qDebug() << "insert" << m_count << idx;
::memmove(m_data + idx + 1, m_data + idx, moveCount * sizeof(T));
+ }
m_count++;
m_data[idx] = v;
}
- void insertBlank(int idx, int count) {
- int newSize = m_count + count;
- if (newSize >= m_capacity) {
- m_capacity = (newSize + 1023) & 0xFFFFFC00;
+ void reserve(int count) {
+ if (count >= m_capacity) {
+ m_capacity = (count + (Increment-1)) & (0xFFFFFFFF - Increment + 1);
m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
}
+ }
+ void insertBlank(int idx, int count) {
+ int newSize = m_count + count;
+ reserve(newSize);
int moveCount = m_count - idx;
if (moveCount)
::memmove(m_data + idx + count, m_data + idx,
@@ -118,12 +124,34 @@ public:
moveCount * sizeof(T));
m_count -= count;
}
-
+
+ void removeOne(const T &v) {
+ int idx = 0;
+ while (idx < m_count) {
+ if (m_data[idx] == v) {
+ remove(idx);
+ return;
+ }
+ ++idx;
+ }
+ }
+
+ int find(const T &v) {
+ for (int idx = 0; idx < m_count; ++idx)
+ if (m_data[idx] == v)
+ return idx;
+ return -1;
+ }
+
+ bool contains(const T &v) {
+ return find(v) != -1;
+ }
+
int count() const {
return m_count;
}
- void copyAndClear(QPODVector<T> &other) {
+ void copyAndClear(QPODVector<T,Increment> &other) {
if (other.m_data) ::free(other.m_data);
other.m_count = m_count;
other.m_capacity = m_capacity;
@@ -133,7 +161,7 @@ public:
m_data = 0;
}
- QPODVector<T> &operator<<(const T &v) { append(v); return *this; }
+ QPODVector<T,Increment> &operator<<(const T &v) { append(v); return *this; }
private:
QPODVector(const QPODVector &);
QPODVector &operator=(const QPODVector &);