summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2010-03-11 07:33:49 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2010-03-11 07:33:49 (GMT)
commit79dc9daa146410c7da8d4691e9a4489251980ab3 (patch)
tree2dbc8acba470d4943ffe5e527da71290812e043e /src/declarative
parent162287900e724947e976ec5bdcc1bcb99639b5ab (diff)
parent54bdab8b88777488f9f0d944698fbb155cf703af (diff)
downloadQt-79dc9daa146410c7da8d4691e9a4489251980ab3.zip
Qt-79dc9daa146410c7da8d4691e9a4489251980ab3.tar.gz
Qt-79dc9daa146410c7da8d4691e9a4489251980ab3.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/QmlChanges.txt1
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri4
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocuspanel.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocuspanel_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocusscope.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocusscope_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp71
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview_p.h5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp6
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp70
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeparticles.cpp1317
-rw-r--r--src/declarative/graphicsitems/qdeclarativeparticles_p.h258
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp142
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h28
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp3
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp64
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h3
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp7
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp98
-rw-r--r--src/declarative/util/qdeclarativeanimation_p.h21
-rw-r--r--src/declarative/util/qdeclarativeanimation_p_p.h13
-rw-r--r--src/declarative/util/qdeclarativestate.cpp62
-rw-r--r--src/declarative/util/qdeclarativestate_p.h8
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp244
-rw-r--r--src/declarative/util/qdeclarativestateoperations_p.h9
-rw-r--r--src/declarative/util/qdeclarativetransitionmanager.cpp26
-rw-r--r--src/declarative/util/qdeclarativeutilmodule.cpp1
28 files changed, 702 insertions, 1776 deletions
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt
index 591fb3d..f83dd58 100644
--- a/src/declarative/QmlChanges.txt
+++ b/src/declarative/QmlChanges.txt
@@ -1,6 +1,7 @@
=============================================================================
The changes below are pre Qt 4.7.0 alpha
+ListView, GridView::positionViewAtIndex() gained a 'mode' parameter
Flickable: renamed viewportWidth -> contentWidth
Flickable: renamed viewportHeight -> contentHeight
Flickable: renamed viewportX -> contentX
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index 3ff92b1..d30651b 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -48,7 +48,6 @@ HEADERS += \
$$PWD/qdeclarativevisualitemmodel_p.h \
$$PWD/qdeclarativelistview_p.h \
$$PWD/qdeclarativegraphicsobjectcontainer_p.h \
- $$PWD/qdeclarativeparticles_p.h \
$$PWD/qdeclarativelayoutitem_p.h \
$$PWD/qdeclarativeitemchangelistener_p.h \
$$PWD/qdeclarativeeffects.cpp
@@ -82,5 +81,4 @@ SOURCES += \
$$PWD/qdeclarativevisualitemmodel.cpp \
$$PWD/qdeclarativelistview.cpp \
$$PWD/qdeclarativegraphicsobjectcontainer.cpp \
- $$PWD/qdeclarativeparticles.cpp \
- $$PWD/qdeclarativelayoutitem.cpp \
+ $$PWD/qdeclarativelayoutitem.cpp
diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
index 0323a59..20524b6 100644
--- a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
@@ -41,6 +41,8 @@
#include "qdeclarativefocuspanel_p.h"
+#include "qdeclarativeitem_p.h"
+
#include <QtGui/qgraphicsscene.h>
#include <QEvent>
@@ -65,7 +67,8 @@ QT_BEGIN_NAMESPACE
QDeclarativeFocusPanel::QDeclarativeFocusPanel(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
- setFlag(ItemIsPanel);
+ Q_D(QDeclarativeItem);
+ d->flags |= QGraphicsItem::ItemIsPanel;
}
QDeclarativeFocusPanel::~QDeclarativeFocusPanel()
diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h
index 1ad8b6e..d9ca0b0 100644
--- a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h
+++ b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h
@@ -66,6 +66,7 @@ protected:
private:
Q_DISABLE_COPY(QDeclarativeFocusPanel)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem)
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
index 384a47b..484df13 100644
--- a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
+++ b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
@@ -41,6 +41,8 @@
#include "qdeclarativefocusscope_p.h"
+#include "qdeclarativeitem_p.h"
+
QT_BEGIN_NAMESPACE
/*!
@@ -62,7 +64,8 @@ QT_BEGIN_NAMESPACE
QDeclarativeFocusScope::QDeclarativeFocusScope(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
- setFlag(QGraphicsItem::ItemIsFocusScope);
+ Q_D(QDeclarativeItem);
+ d->flags |= QGraphicsItem::ItemIsFocusScope;
}
QDeclarativeFocusScope::~QDeclarativeFocusScope()
diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h
index cd480b4..c65a07c 100644
--- a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h
+++ b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h
@@ -54,6 +54,7 @@ QT_MODULE(Declarative)
class Q_DECLARATIVE_EXPORT QDeclarativeFocusScope : public QDeclarativeItem
{
Q_OBJECT
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem)
public:
QDeclarativeFocusScope(QDeclarativeItem *parent=0);
virtual ~QDeclarativeFocusScope();
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index e66bcf6..b1391f9 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -1666,47 +1666,84 @@ void QDeclarativeGridView::moveCurrentIndexRight()
}
/*!
- \qmlmethod GridView::positionViewAtIndex(int index)
+ \qmlmethod GridView::positionViewAtIndex(int index, PositionMode mode)
+
+ Positions the view such that the \a index is at the position specified by
+ \a mode:
+
+ \list
+ \o Beginning - position item at the top (or left for TopToBottom flow) of the view.
+ \o Center- position item in the center of the view.
+ \o End - position item at bottom (or right for horizontal orientation) of the view.
+ \o Visible - if any part of the item is visible then take no action, otherwise
+ bring the item into view.
+ \o Contain - ensure the entire item is visible. If the item is larger than
+ the view the item is positioned at the top (or left for TopToBottom flow) of the view.
+ \endlist
- Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view.
If positioning the view at the index would cause empty space to be displayed at
- the end of the view, the view will be positioned at the end.
+ the beginning or end of the view, the view will be positioned at the boundary.
It is not recommended to use contentX or contentY to position the view
at a particular index. This is unreliable since removing items from the start
- of the list does not cause all other items to be repositioned.
+ of the view does not cause all other items to be repositioned.
The correct way to bring an item into view is with positionViewAtIndex.
*/
-void QDeclarativeGridView::positionViewAtIndex(int index)
+void QDeclarativeGridView::positionViewAtIndex(int index, int mode)
{
Q_D(QDeclarativeGridView);
if (!d->isValid() || index < 0 || index >= d->model->count())
return;
+ if (mode < Beginning || mode > Contain)
+ return;
- qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent();
+ qreal pos = d->position();
FxGridItem *item = d->visibleItem(index);
- if (item) {
- // Already created - just move to top of view
- int pos = qMin(item->rowPos(), maxExtent);
- d->setPosition(pos);
- } else {
- int pos = d->rowPosAt(index);
+ if (!item) {
+ int itemPos = d->rowPosAt(index);
// save the currently visible items in case any of them end up visible again
QList<FxGridItem*> oldVisible = d->visibleItems;
d->visibleItems.clear();
d->visibleIndex = index - index % d->columns;
- d->setPosition(pos);
- // setPosition() will cause refill. Adjust if we have moved beyond range
- if (d->position() > maxExtent)
- d->setPosition(maxExtent);
+ d->setPosition(itemPos);
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
d->releaseItem(oldVisible.at(i));
+ item = d->visibleItem(index);
+ }
+ if (item) {
+ qreal itemPos = item->rowPos();
+ switch (mode) {
+ case Beginning:
+ pos = itemPos;
+ break;
+ case Center:
+ pos = itemPos - (d->size() - d->rowSize())/2;
+ break;
+ case End:
+ pos = itemPos - d->size() + d->rowSize();
+ break;
+ case Visible:
+ if (itemPos > pos + d->size())
+ pos = itemPos - d->size() + d->rowSize();
+ else if (item->endRowPos() < pos)
+ pos = itemPos;
+ break;
+ case Contain:
+ if (item->endRowPos() > pos + d->size())
+ pos = itemPos - d->size() + d->rowSize();
+ if (itemPos < pos)
+ pos = itemPos;
+ }
+ qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent();
+ pos = qMin(pos, maxExtent);
+ qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent();
+ pos = qMax(pos, minExtent);
+ d->setPosition(pos);
}
d->fixupPosition();
}
-
void QDeclarativeGridView::componentComplete()
{
Q_D(QDeclarativeGridView);
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index 8e253e5..f14ec14 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -137,6 +137,9 @@ public:
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
+ enum PositionMode { Beginning, Center, End, Visible, Contain };
+ Q_ENUMS(PositionMode)
+
static QDeclarativeGridViewAttached *qmlAttachedProperties(QObject *);
public Q_SLOTS:
@@ -144,7 +147,7 @@ public Q_SLOTS:
void moveCurrentIndexDown();
void moveCurrentIndexLeft();
void moveCurrentIndexRight();
- void positionViewAtIndex(int index);
+ void positionViewAtIndex(int index, int mode);
Q_SIGNALS:
void countChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 2d05c7c..2ac55a4 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -65,7 +65,6 @@
#include "qdeclarativelistview_p.h"
#include "qdeclarativeloader_p.h"
#include "qdeclarativemousearea_p.h"
-#include "qdeclarativeparticles_p.h"
#include "qdeclarativepath_p.h"
#include "qdeclarativepathview_p.h"
#include "qdeclarativerectangle_p.h"
@@ -108,11 +107,6 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterType<QDeclarativeLoader>("Qt",4,6,"Loader");
qmlRegisterType<QDeclarativeMouseArea>("Qt",4,6,"MouseArea");
qmlRegisterType<QGraphicsOpacityEffect>("Qt",4,6,"Opacity");
- qmlRegisterType<QDeclarativeParticleMotion>("Qt",4,6,"ParticleMotion");
- qmlRegisterType<QDeclarativeParticleMotionGravity>("Qt",4,6,"ParticleMotionGravity");
- qmlRegisterType<QDeclarativeParticleMotionLinear>("Qt",4,6,"ParticleMotionLinear");
- qmlRegisterType<QDeclarativeParticleMotionWander>("Qt",4,6,"ParticleMotionWander");
- qmlRegisterType<QDeclarativeParticles>("Qt",4,6,"Particles");
qmlRegisterType<QDeclarativePath>("Qt",4,6,"Path");
qmlRegisterType<QDeclarativePathAttribute>("Qt",4,6,"PathAttribute");
qmlRegisterType<QDeclarativePathCubic>("Qt",4,6,"PathCubic");
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index b988e6e..9e6a67a 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -2180,11 +2180,23 @@ void QDeclarativeListView::decrementCurrentIndex()
}
/*!
- \qmlmethod ListView::positionViewAtIndex(int index)
+ \qmlmethod ListView::positionViewAtIndex(int index, PositionMode mode)
+
+ Positions the view such that the \a index is at the position specified by
+ \a mode:
+
+ \list
+ \o Beginning - position item at the top (or left for horizontal orientation) of the view.
+ \o Center- position item in the center of the view.
+ \o End - position item at bottom (or right for horizontal orientation) of the view.
+ \o Visible - if any part of the item is visible then take no action, otherwise
+ bring the item into view.
+ \o Contain - ensure the entire item is visible. If the item is larger than
+ the view the item is positioned at the top (or left for horizontal orientation) of the view.
+ \endlist
- Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view.
If positioning the view at the index would cause empty space to be displayed at
- the end of the view, the view will be positioned at the end.
+ the beginning or end of the view, the view will be positioned at the boundary.
It is not recommended to use contentX or contentY to position the view
at a particular index. This is unreliable since removing items from the start
@@ -2192,32 +2204,58 @@ void QDeclarativeListView::decrementCurrentIndex()
the actual start of the view can vary based on the size of the delegates.
The correct way to bring an item into view is with positionViewAtIndex.
*/
-void QDeclarativeListView::positionViewAtIndex(int index)
+void QDeclarativeListView::positionViewAtIndex(int index, int mode)
{
Q_D(QDeclarativeListView);
if (!d->isValid() || index < 0 || index >= d->model->count())
return;
+ if (mode < Beginning || mode > Contain)
+ return;
- qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent();
+ qreal pos = d->position();
FxListItem *item = d->visibleItem(index);
- if (item) {
- // Already created - just move to top of view
- int pos = qMin(item->position(), maxExtent);
- d->setPosition(pos);
- } else {
- int pos = d->positionAt(index);
+ if (!item) {
+ int itemPos = d->positionAt(index);
// save the currently visible items in case any of them end up visible again
QList<FxListItem*> oldVisible = d->visibleItems;
d->visibleItems.clear();
- d->visiblePos = pos;
+ d->visiblePos = itemPos;
d->visibleIndex = index;
- d->setPosition(pos);
- // setPosition() will cause refill. Adjust if we have moved beyond range.
- if (d->position() > maxExtent)
- d->setPosition(maxExtent);
+ d->setPosition(itemPos);
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
d->releaseItem(oldVisible.at(i));
+ item = d->visibleItem(index);
+ }
+ if (item) {
+ const qreal itemPos = item->position();
+ switch (mode) {
+ case Beginning:
+ pos = itemPos;
+ break;
+ case Center:
+ pos = itemPos - (d->size() - item->size())/2;
+ break;
+ case End:
+ pos = itemPos - d->size() + item->size();
+ break;
+ case Visible:
+ if (itemPos > pos + d->size())
+ pos = itemPos - d->size() + item->size();
+ else if (item->endPosition() < pos)
+ pos = itemPos;
+ break;
+ case Contain:
+ if (item->endPosition() > pos + d->size())
+ pos = itemPos - d->size() + item->size();
+ if (itemPos < pos)
+ pos = itemPos;
+ }
+ qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent();
+ pos = qMin(pos, maxExtent);
+ qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent();
+ pos = qMax(pos, minExtent);
+ d->setPosition(pos);
}
d->fixupPosition();
}
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index 1bf9652..0c2677c 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -191,10 +191,13 @@ public:
static QDeclarativeListViewAttached *qmlAttachedProperties(QObject *);
+ enum PositionMode { Beginning, Center, End, Visible, Contain };
+ Q_ENUMS(PositionMode)
+
public Q_SLOTS:
void incrementCurrentIndex();
void decrementCurrentIndex();
- void positionViewAtIndex(int index);
+ void positionViewAtIndex(int index, int mode);
Q_SIGNALS:
void countChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeparticles.cpp b/src/declarative/graphicsitems/qdeclarativeparticles.cpp
deleted file mode 100644
index 593c80a..0000000
--- a/src/declarative/graphicsitems/qdeclarativeparticles.cpp
+++ /dev/null
@@ -1,1317 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdeclarativeparticles_p.h"
-
-#include "qdeclarativeitem_p.h"
-
-#include <qdeclarativepixmapcache_p.h>
-#include <qfxperf_p_p.h>
-#include <qdeclarativeanimation_p_p.h>
-
-#include <QNetworkReply>
-#include <QPainter>
-#include <QtGui/qdrawutil.h>
-#include <QVarLengthArray>
-
-#include <stdlib.h>
-#include <math.h>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#define M_PI_2 (M_PI / 2.)
-#endif
-#ifndef INT_MAX
-#define INT_MAX 2147483647
-#endif
-
-QT_BEGIN_NAMESPACE
-#define PI_SQR 9.8696044
-// parabolic approximation
-inline qreal fastSin(qreal theta)
-{
- const qreal b = 4 / M_PI;
- const qreal c = -4 / PI_SQR;
-
- qreal y = b * theta + c * theta * qAbs(theta);
- return y;
-}
-
-inline qreal fastCos(qreal theta)
-{
- theta += M_PI_2;
- if (theta > M_PI)
- theta -= 2 * M_PI;
-
- return fastSin(theta);
-}
-
-class QDeclarativeParticle
-{
-public:
- QDeclarativeParticle(int time) : lifeSpan(1000), fadeOutAge(800)
- , opacity(0), birthTime(time), x_velocity(0), y_velocity(0)
- , state(FadeIn), data(0)
- {
- }
-
- int lifeSpan;
- int fadeOutAge;
- qreal x;
- qreal y;
- qreal opacity;
- int birthTime;
- qreal x_velocity;
- qreal y_velocity;
- enum State { FadeIn, Solid, FadeOut };
- State state;
- void *data;
-};
-
-//---------------------------------------------------------------------------
-
-/*!
- \class QDeclarativeParticleMotion
- \ingroup group_effects
- \brief The QDeclarativeParticleMotion class is the base class for particle motion.
- \internal
-
- This class causes the particles to remain static.
-*/
-
-/*!
- Constructs a QDeclarativeParticleMotion with parent object \a parent.
-*/
-QDeclarativeParticleMotion::QDeclarativeParticleMotion(QObject *parent) :
- QObject(parent)
-{
-}
-
-/*!
- Move the \a particle to its new position. \a interval is the number of
- milliseconds elapsed since it was last moved.
-*/
-void QDeclarativeParticleMotion::advance(QDeclarativeParticle &particle, int interval)
-{
- Q_UNUSED(particle);
- Q_UNUSED(interval);
-}
-
-/*!
- The \a particle has just been created. Some motion strategies require
- additional state information. This can be allocated by this function.
-*/
-void QDeclarativeParticleMotion::created(QDeclarativeParticle &particle)
-{
- Q_UNUSED(particle);
-}
-
-/*!
- The \a particle is about to be destroyed. Any additional memory
- that has been allocated for the particle should be freed.
-*/
-void QDeclarativeParticleMotion::destroy(QDeclarativeParticle &particle)
-{
- Q_UNUSED(particle);
-}
-
-/*!
- \qmlclass ParticleMotionLinear
- \since 4.7
- \brief The ParticleMotionLinear object moves particles linearly.
-
- \sa Particles
-*/
-
-/*!
- \internal
- \class QDeclarativeParticleMotionLinear
- \ingroup group_effects
- \brief The QDeclarativeParticleMotionLinear class moves the particles linearly.
-*/
-
-void QDeclarativeParticleMotionLinear::advance(QDeclarativeParticle &p, int interval)
-{
- p.x += interval * p.x_velocity;
- p.y += interval * p.y_velocity;
-}
-
-/*!
- \qmlclass ParticleMotionGravity
- \since 4.7
- \brief The ParticleMotionGravity object moves particles towards a point.
-
- \sa Particles
-*/
-
-/*!
- \internal
- \class QDeclarativeParticleMotionGravity
- \ingroup group_effects
- \brief The QDeclarativeParticleMotionGravity class moves the particles towards a point.
-*/
-
-/*!
- \qmlproperty qreal ParticleMotionGravity::xattractor
- \qmlproperty qreal ParticleMotionGravity::yattractor
- These properties hold the x and y coordinates of the point attracting the particles.
-*/
-
-/*!
- \qmlproperty qreal ParticleMotionGravity::acceleration
- This property holds the acceleration to apply to the particles.
-*/
-
-/*!
- \property QDeclarativeParticleMotionGravity::xattractor
- \brief the x coordinate of the point attracting the particles.
-*/
-
-/*!
- \property QDeclarativeParticleMotionGravity::yattractor
- \brief the y coordinate of the point attracting the particles.
-*/
-
-/*!
- \property QDeclarativeParticleMotionGravity::acceleration
- \brief the acceleration to apply to the particles.
-*/
-
-void QDeclarativeParticleMotionGravity::setXAttractor(qreal x)
-{
- if (qFuzzyCompare(x, _xAttr))
- return;
- _xAttr = x;
- emit xattractorChanged();
-}
-
-void QDeclarativeParticleMotionGravity::setYAttractor(qreal y)
-{
- if (qFuzzyCompare(y, _yAttr))
- return;
- _yAttr = y;
- emit yattractorChanged();
-}
-
-void QDeclarativeParticleMotionGravity::setAcceleration(qreal accel)
-{
- qreal scaledAccel = accel/1000000.0;
- if (qFuzzyCompare(scaledAccel, _accel))
- return;
- _accel = scaledAccel;
- emit accelerationChanged();
-}
-
-void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval)
-{
- qreal xdiff = p.x - _xAttr;
- qreal ydiff = p.y - _yAttr;
-
- qreal xcomp = xdiff / (xdiff + ydiff);
- qreal ycomp = ydiff / (xdiff + ydiff);
-
- p.x_velocity += xcomp * _accel * interval;
- p.y_velocity += ycomp * _accel * interval;
-
- p.x += interval * p.x_velocity;
- p.y += interval * p.y_velocity;
-}
-
-/*!
- \qmlclass ParticleMotionWander
- \since 4.7
- \brief The ParticleMotionWander object moves particles in a somewhat random fashion.
-
- The particles will continue roughly in the original direction, however will randomly
- drift to each side.
-
- The code below produces an effect similar to falling snow.
-
- \qml
-Rectangle {
- width: 240
- height: 320
- color: "black"
-
- Particles {
- y: 0
- width: parent.width
- height: 30
- source: "star.png"
- lifeSpan: 5000
- count: 50
- angle: 70
- angleDeviation: 36
- velocity: 30
- velocityDeviation: 10
- ParticleMotionWander {
- xvariance: 30
- pace: 100
- }
- }
-}
- \endqml
-
- \sa Particles
-*/
-
-/*!
- \internal
- \class QDeclarativeParticleMotionWander
- \ingroup group_effects
- \brief The QDeclarativeParticleMotionWander class moves particles in a somewhat random fashion.
-
- The particles will continue roughly in the original direction, however will randomly
- drift to each side.
-*/
-
-/*!
- \qmlproperty qreal QDeclarativeParticleMotionWander::xvariance
- \qmlproperty qreal QDeclarativeParticleMotionWander::yvariance
-
- These properties set the amount to wander in the x and y directions.
-*/
-
-/*!
- \qmlproperty qreal QDeclarativeParticleMotionWander::pace
- This property holds how quickly the paricles will move from side to side.
-*/
-
-void QDeclarativeParticleMotionWander::advance(QDeclarativeParticle &p, int interval)
-{
- if (!particles)
- particles = qobject_cast<QDeclarativeParticles*>(parent());
- if (particles) {
- Data *d = (Data*)p.data;
- if (_xvariance != 0.) {
- qreal xdiff = p.x_velocity - d->x_targetV;
- if ((xdiff > d->x_peak && d->x_var > 0.0) || (xdiff < -d->x_peak && d->x_var < 0.0)) {
- d->x_var = -d->x_var;
- d->x_peak = _xvariance + _xvariance * qreal(qrand()) / RAND_MAX;
- }
- p.x_velocity += d->x_var * interval;
- }
- p.x += interval * p.x_velocity;
-
- if (_yvariance != 0.) {
- qreal ydiff = p.y_velocity - d->y_targetV;
- if ((ydiff > d->y_peak && d->y_var > 0.0) || (ydiff < -d->y_peak && d->y_var < 0.0)) {
- d->y_var = -d->y_var;
- d->y_peak = _yvariance + _yvariance * qreal(qrand()) / RAND_MAX;
- }
- p.y_velocity += d->y_var * interval;
- }
- p.y += interval * p.y_velocity;
- }
-}
-
-void QDeclarativeParticleMotionWander::created(QDeclarativeParticle &p)
-{
- if (!p.data) {
- Data *d = new Data;
- p.data = (void*)d;
- d->x_targetV = p.x_velocity;
- d->y_targetV = p.y_velocity;
- d->x_peak = _xvariance;
- d->y_peak = _yvariance;
- d->x_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0;
- d->y_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0;
- }
-}
-
-void QDeclarativeParticleMotionWander::destroy(QDeclarativeParticle &p)
-{
- if (p.data)
- delete (Data*)p.data;
-}
-
-void QDeclarativeParticleMotionWander::setXVariance(qreal var)
-{
- qreal scaledVar = var / 1000.0;
- if (qFuzzyCompare(scaledVar, _xvariance))
- return;
- _xvariance = scaledVar;
- emit xvarianceChanged();
-}
-
-void QDeclarativeParticleMotionWander::setYVariance(qreal var)
-{
- qreal scaledVar = var / 1000.0;
- if (qFuzzyCompare(scaledVar, _yvariance))
- return;
- _yvariance = scaledVar;
- emit yvarianceChanged();
-}
-
-void QDeclarativeParticleMotionWander::setPace(qreal pace)
-{
- qreal scaledPace = pace / 1000.0;
- if (qFuzzyCompare(scaledPace, _pace))
- return;
- _pace = scaledPace;
- emit paceChanged();
-}
-
-//---------------------------------------------------------------------------
-class QDeclarativeParticlesPainter : public QDeclarativeItem
-{
-public:
- QDeclarativeParticlesPainter(QDeclarativeParticlesPrivate *p, QDeclarativeItem* parent)
- : QDeclarativeItem(parent), d(p)
- {
- setFlag(QGraphicsItem::ItemHasNoContents, false);
- maxX = minX = maxY = minY = 0;
- }
-
- void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-
- void updateSize();
-
- qreal maxX;
- qreal minX;
- qreal maxY;
- qreal minY;
- QDeclarativeParticlesPrivate* d;
-};
-
-//---------------------------------------------------------------------------
-class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeParticles)
-public:
- QDeclarativeParticlesPrivate()
- : count(1), emissionRate(-1), emissionVariance(0.5), lifeSpan(1000)
- , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300)
- , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.)
- , addParticleTime(0), addParticleCount(0), lastAdvTime(0)
- , motion(0), pendingPixmapCache(false), clock(this)
- {
- }
-
- ~QDeclarativeParticlesPrivate()
- {
- }
-
- void init()
- {
- Q_Q(QDeclarativeParticles);
- paintItem = new QDeclarativeParticlesPainter(this, q);
- }
-
- void tick(int time);
- void createParticle(int time);
- void updateOpacity(QDeclarativeParticle &p, int age);
-
- QUrl url;
- QPixmap image;
- int count;
- int emissionRate;
- qreal emissionVariance;
- int lifeSpan;
- int lifeSpanDev;
- int fadeInDur;
- int fadeOutDur;
- qreal angle;
- qreal angleDev;
- qreal velocity;
- qreal velocityDev;
- qreal emissionCarry;
- int addParticleTime;
- int addParticleCount;
- int lastAdvTime;
- QDeclarativeParticleMotion *motion;
- QDeclarativeParticlesPainter *paintItem;
-
- bool pendingPixmapCache;
-
- QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs
- QList<QDeclarativeParticle> particles;
- QTickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock;
-
-};
-
-void QDeclarativeParticlesPrivate::tick(int time)
-{
- Q_Q(QDeclarativeParticles);
- if (!motion)
- motion = new QDeclarativeParticleMotionLinear(q);
-
- int oldCount = particles.count();
- int removed = 0;
- int interval = time - lastAdvTime;
- for (int i = 0; i < particles.count(); ) {
- QDeclarativeParticle &particle = particles[i];
- int age = time - particle.birthTime;
- if (age >= particle.lifeSpan) {
- QDeclarativeParticle part = particles.takeAt(i);
- motion->destroy(part);
- ++removed;
- } else {
- updateOpacity(particle, age);
- motion->advance(particle, interval);
- ++i;
- }
- }
-
- if(emissionRate == -1)//Otherwise leave emission to the emission rate
- while(removed-- && ((count == -1) || particles.count() < count))
- createParticle(time);
-
- if (!addParticleTime)
- addParticleTime = time;
-
- //Possibly emit new particles
- if (((count == -1) || particles.count() < count) && emissionRate
- && !(count==-1 && emissionRate==-1)) {
- int emissionCount = -1;
- if (emissionRate != -1){
- qreal variance = 1.;
- if (emissionVariance > 0.){
- variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.);
- }
- qreal emission = emissionRate * (qreal(interval)/1000.);
- emission = emission * variance + emissionCarry;
- double tmpDbl;
- emissionCarry = modf(emission, &tmpDbl);
- emissionCount = (int)tmpDbl;
- emissionCount = qMax(0,emissionCount);
- }
- while(((count == -1) || particles.count() < count) &&
- (emissionRate==-1 || emissionCount--))
- createParticle(time);
- }
-
- //Deal with emissions from requested bursts
- for(int i=0; i<bursts.size(); i++){
- int emission = 0;
- if(bursts[i].second == -1){
- emission = bursts[i].first;
- }else{
- qreal variance = 1.;
- if (emissionVariance > 0.){
- variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.);
- }
- qreal workingEmission = bursts[i].second * (qreal(interval)/1000.);
- workingEmission *= variance;
- emission = (int)workingEmission;
- emission = qMax(emission, 0);
- }
- emission = qMin(emission, bursts[i].first);
- bursts[i].first -= emission;
- while(emission--)
- createParticle(time);
- }
- for(int i=bursts.size()-1; i>=0; i--)
- if(bursts[i].first <= 0)
- bursts.removeAt(i);
-
- lastAdvTime = time;
- paintItem->updateSize();
- paintItem->update();
- if (!(oldCount || particles.count()) && (!count || !emissionRate) && bursts.isEmpty()) {
- lastAdvTime = 0;
- clock.stop();
- }
-}
-
-void QDeclarativeParticlesPrivate::createParticle(int time)
-{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QDeclarativePerfTimer<QDeclarativePerf::CreateParticle> x;
-#endif
- Q_Q(QDeclarativeParticles);
- QDeclarativeParticle p(time);
- p.x = q->x() + q->width() * qreal(qrand()) / RAND_MAX - image.width()/2.0;
- p.y = q->y() + q->height() * qreal(qrand()) / RAND_MAX - image.height()/2.0;
- p.lifeSpan = lifeSpan;
- if (lifeSpanDev)
- p.lifeSpan += int(lifeSpanDev/2 - lifeSpanDev * qreal(qrand()) / RAND_MAX);
- p.fadeOutAge = p.lifeSpan - fadeOutDur;
- if (fadeInDur == 0.) {
- p.state= QDeclarativeParticle::Solid;
- p.opacity = 1.0;
- }
- qreal a = angle;
- if (angleDev)
- a += angleDev/2 - angleDev * qreal(qrand()) / RAND_MAX;
- if (a > M_PI)
- a = a - 2 * M_PI;
- qreal v = velocity;
- if (velocityDev)
- v += velocityDev/2 - velocityDev * qreal(qrand()) / RAND_MAX;
- p.x_velocity = v * fastCos(a);
- p.y_velocity = v * fastSin(a);
- particles.append(p);
- motion->created(particles.last());
-}
-
-void QDeclarativeParticlesPrivate::updateOpacity(QDeclarativeParticle &p, int age)
-{
- switch (p.state) {
- case QDeclarativeParticle::FadeIn:
- if (age <= fadeInDur) {
- p.opacity = qreal(age) / fadeInDur;
- break;
- } else {
- p.opacity = 1.0;
- p.state = QDeclarativeParticle::Solid;
- // Fall through
- }
- case QDeclarativeParticle::Solid:
- if (age <= p.fadeOutAge) {
- break;
- } else {
- p.state = QDeclarativeParticle::FadeOut;
- // Fall through
- }
- case QDeclarativeParticle::FadeOut:
- p.opacity = qreal(p.lifeSpan - age) / fadeOutDur;
- break;
- }
-}
-
-/*!
- \qmlclass Particles
- \since 4.7
- \brief The Particles object generates and moves particles.
- \inherits Item
-
- This element provides preliminary support for particles in QML,
- and may be heavily changed or removed in later versions.
-
- The particles created by this object cannot be dealt with
- directly, they can only be controlled through the parameters of
- the Particles object. The particles are all the same pixmap,
- specified by the user.
-
- The particles are painted relative to the parent of the Particles
- object. Moving the Particles object will not move the particles
- already emitted.
-
- The below example creates two differently behaving particle
- sources. The top one has particles falling from the top like
- snow, the lower one has particles expelled up like a fountain.
-
- \qml
-Rectangle {
- width: 240
- height: 320
- color: "black"
- Particles {
- y: 0
- width: parent.width
- height: 30
- source: "star.png"
- lifeSpan: 5000
- count: 50
- angle: 70
- angleDeviation: 36
- velocity: 30
- velocityDeviation: 10
- ParticleMotionWander {
- xvariance: 30
- pace: 100
- }
- }
- Particles {
- y: 300
- x: 120
- width: 1
- height: 1
- source: "star.png"
- lifeSpan: 5000
- count: 200
- angle: 270
- angleDeviation: 45
- velocity: 50
- velocityDeviation: 30
- ParticleMotionGravity {
- yattractor: 1000
- xattractor: 0
- acceleration: 25
- }
- }
-}
- \endqml
- \image particles.gif
-*/
-
-/*!
- \internal
- \class QDeclarativeParticles
- \ingroup group_effects
- \brief The QDeclarativeParticles class generates and moves particles.
-*/
-
-QDeclarativeParticles::QDeclarativeParticles(QDeclarativeItem *parent)
- : QDeclarativeItem(*(new QDeclarativeParticlesPrivate), parent)
-{
- Q_D(QDeclarativeParticles);
- d->init();
-}
-
-QDeclarativeParticles::~QDeclarativeParticles()
-{
- Q_D(QDeclarativeParticles);
- if (d->pendingPixmapCache)
- QDeclarativePixmapCache::cancel(d->url, this);
-}
-
-/*!
- \qmlproperty string Particles::source
- This property holds the URL of the particle image.
-*/
-
-/*!
- \property QDeclarativeParticles::source
- \brief the URL of the particle image.
-*/
-QUrl QDeclarativeParticles::source() const
-{
- Q_D(const QDeclarativeParticles);
- return d->url;
-}
-
-void QDeclarativeParticles::imageLoaded()
-{
- Q_D(QDeclarativeParticles);
- d->pendingPixmapCache = false;
- QDeclarativePixmapCache::get(d->url, &d->image);
- d->paintItem->updateSize();
- d->paintItem->update();
-}
-
-void QDeclarativeParticles::setSource(const QUrl &name)
-{
- Q_D(QDeclarativeParticles);
-
- if ((d->url.isEmpty() == name.isEmpty()) && name == d->url)
- return;
-
- if (d->pendingPixmapCache) {
- QDeclarativePixmapCache::cancel(d->url, this);
- d->pendingPixmapCache = false;
- }
- if (name.isEmpty()) {
- d->url = name;
- d->image = QPixmap();
- d->paintItem->updateSize();
- d->paintItem->update();
- } else {
- d->url = name;
- Q_ASSERT(!name.isRelative());
- QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->image);
- if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) {
- QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url);
- connect(reply, SIGNAL(finished()), this, SLOT(imageLoaded()));
- d->pendingPixmapCache = true;
- } else {
- //### unify with imageLoaded
- d->paintItem->updateSize();
- d->paintItem->update();
- }
- }
- emit sourceChanged();
-}
-
-/*!
- \qmlproperty int Particles::count
- This property holds the maximum number of particles
-
- The particles element emits particles until it has count active
- particles. When this number is reached, new particles are not emitted until
- some of the current particles reach the end of their lifespan.
-
- If count is -1 then there is no maximum number of active particles, and
- particles will be constantly emitted at the rate specified by emissionRate.
-
- The default value for count is 1.
-
- If both count and emissionRate are set to -1, nothing will be emitted.
-
-*/
-
-/*!
- \property QDeclarativeParticles::count
- \brief the maximum number of particles
-*/
-int QDeclarativeParticles::count() const
-{
- Q_D(const QDeclarativeParticles);
- return d->count;
-}
-
-void QDeclarativeParticles::setCount(int cnt)
-{
- Q_D(QDeclarativeParticles);
- if (cnt == d->count)
- return;
-
- int oldCount = d->count;
- d->count = cnt;
- d->addParticleTime = 0;
- d->addParticleCount = d->particles.count();
- if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) {
- d->clock.start();
- }
- d->paintItem->updateSize();
- d->paintItem->update();
- emit countChanged();
-}
-
-
-/*!
- \qmlproperty int Particles::emissionRate
- This property holds the target number of particles to emit every second.
-
- The particles element will emit up to emissionRate particles every
- second. Fewer particles may be emitted per second if the maximum number of
- particles has been reached.
-
- If emissionRate is set to -1 there is no limit to the number of
- particles emitted per second, and particles will be instantly emitted to
- reach the maximum number of particles specified by count.
-
- The default value for emissionRate is -1.
-
- If both count and emissionRate are set to -1, nothing will be emitted.
-*/
-
-/*!
- \property QDeclarativeParticles::emissionRate
- \brief the emission rate of particles
-*/
-int QDeclarativeParticles::emissionRate() const
-{
- Q_D(const QDeclarativeParticles);
- return d->emissionRate;
-}
-void QDeclarativeParticles::setEmissionRate(int er)
-{
- Q_D(QDeclarativeParticles);
- if(er == d->emissionRate)
- return;
- d->emissionRate = er;
- if (d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) {
- d->clock.start();
- }
- emit emissionRateChanged();
-}
-
-/*!
- \qmlproperty qreal Particles::emissionVariance
- This property holds how inconsistent the rate of particle emissions are.
- It is a number between 0 (no variance) and 1 (some variance).
-
- The expected number of particles emitted per second is emissionRate. If
- emissionVariance is 0 then particles will be emitted consistently throughout
- each second to reach that number. If emissionVariance is greater than 0 the
- rate of particle emission will vary randomly throughout the second, with the
- consequence that the actual number of particles emitted in one second will
- vary randomly as well.
-
- emissionVariance is the maximum deviation from emitting
- emissionRate particles per second. An emissionVariance of 0 means you should
- get exactly emissionRate particles emitted per second,
- and an emissionVariance of 1 means you will get between zero and two times
- emissionRate particles per second, but you should get emissionRate particles
- per second on average.
-
- Note that even with an emissionVariance of 0 there may be some variance due
- to performance and hardware constraints.
-
- The default value of emissionVariance is 0.5
-*/
-
-/*!
- \property QDeclarativeParticles::emissionVariance
- \brief how much the particle emission amounts vary per tick
-*/
-
-qreal QDeclarativeParticles::emissionVariance() const
-{
- Q_D(const QDeclarativeParticles);
- return d->emissionVariance;
-}
-
-void QDeclarativeParticles::setEmissionVariance(qreal ev)
-{
- Q_D(QDeclarativeParticles);
- if(d->emissionVariance == ev)
- return;
- d->emissionVariance = ev;
- emit emissionVarianceChanged();
-}
-
-/*!
- \qmlproperty int Particles::lifeSpan
- \qmlproperty int Particles::lifeSpanDeviation
-
- These properties describe the life span of each particle.
-
- The default lifespan for a particle is 1000ms.
-
- lifeSpanDeviation randomly varies the lifeSpan up to the specified variation. For
- example, the following creates particles whose lifeSpan will vary
- from 150ms to 250ms:
-
- \qml
-Particles {
- source: "star.png"
- lifeSpan: 200
- lifeSpanDeviation: 100
-}
- \endqml
-*/
-
-/*!
- \property QDeclarativeParticles::lifeSpan
- \brief the life span of each particle.
-
- Default value is 1000ms.
-
- \sa QDeclarativeParticles::lifeSpanDeviation
-*/
-int QDeclarativeParticles::lifeSpan() const
-{
- Q_D(const QDeclarativeParticles);
- return d->lifeSpan;
-}
-
-void QDeclarativeParticles::setLifeSpan(int ls)
-{
- Q_D(QDeclarativeParticles);
- if(d->lifeSpan == ls)
- return;
- d->lifeSpan = ls;
- emit lifeSpanChanged();
-}
-
-/*!
- \property QDeclarativeParticles::lifeSpanDeviation
- \brief the maximum possible deviation from the set lifeSpan.
-
- Randomly varies the lifeSpan up to the specified variation. For
- example, the following creates particles whose lifeSpan will vary
- from 150ms to 250ms:
-
-\qml
-Particles {
- source: "star.png"
- lifeSpan: 200
- lifeSpanDeviation: 100
-}
-\endqml
-
- \sa QDeclarativeParticles::lifeSpan
-*/
-int QDeclarativeParticles::lifeSpanDeviation() const
-{
- Q_D(const QDeclarativeParticles);
- return d->lifeSpanDev;
-}
-
-void QDeclarativeParticles::setLifeSpanDeviation(int dev)
-{
- Q_D(QDeclarativeParticles);
- if(d->lifeSpanDev == dev)
- return;
- d->lifeSpanDev = dev;
- emit lifeSpanDeviationChanged();
-}
-
-/*!
- \qmlproperty int Particles::fadeInDuration
- \qmlproperty int Particles::fadeOutDuration
- These properties hold the time taken to fade the particles in and out.
-
- By default fade in is 200ms and fade out is 300ms.
-*/
-
-/*!
- \property QDeclarativeParticles::fadeInDuration
- \brief the time taken to fade in the particles.
-
- Default value is 200ms.
-*/
-int QDeclarativeParticles::fadeInDuration() const
-{
- Q_D(const QDeclarativeParticles);
- return d->fadeInDur;
-}
-
-void QDeclarativeParticles::setFadeInDuration(int dur)
-{
- Q_D(QDeclarativeParticles);
- if (dur < 0.0 || dur == d->fadeInDur)
- return;
- d->fadeInDur = dur;
- emit fadeInDurationChanged();
-}
-
-/*!
- \property QDeclarativeParticles::fadeOutDuration
- \brief the time taken to fade out the particles.
-
- Default value is 300ms.
-*/
-int QDeclarativeParticles::fadeOutDuration() const
-{
- Q_D(const QDeclarativeParticles);
- return d->fadeOutDur;
-}
-
-void QDeclarativeParticles::setFadeOutDuration(int dur)
-{
- Q_D(QDeclarativeParticles);
- if (dur < 0.0 || d->fadeOutDur == dur)
- return;
- d->fadeOutDur = dur;
- emit fadeOutDurationChanged();
-}
-
-/*!
- \qmlproperty real Particles::angle
- \qmlproperty real Particles::angleDeviation
-
- These properties control particle direction.
-
- angleDeviation randomly varies the direction up to the specified variation. For
- example, the following creates particles whose initial direction will
- vary from 15 degrees to 105 degrees:
-
- \qml
-Particles {
- source: "star.png"
- angle: 60
- angleDeviation: 90
-}
- \endqml
-*/
-
-/*!
- \property QDeclarativeParticles::angle
- \brief the initial angle of direction.
-
- \sa QDeclarativeParticles::angleDeviation
-*/
-qreal QDeclarativeParticles::angle() const
-{
- Q_D(const QDeclarativeParticles);
- return d->angle * 180.0 / M_PI;
-}
-
-void QDeclarativeParticles::setAngle(qreal angle)
-{
- Q_D(QDeclarativeParticles);
- qreal radAngle = angle * M_PI / 180.0;
- if(radAngle == d->angle)
- return;
- d->angle = radAngle;
- emit angleChanged();
-}
-
-/*!
- \property QDeclarativeParticles::angleDeviation
- \brief the maximum possible deviation from the set angle.
-
- Randomly varies the direction up to the specified variation. For
- example, the following creates particles whose initial direction will
- vary from 15 degrees to 105 degrees:
-
-\qml
-Particles {
- source: "star.png"
- angle: 60
- angleDeviation: 90
-}
-\endqml
-
- \sa QDeclarativeParticles::angle
-*/
-qreal QDeclarativeParticles::angleDeviation() const
-{
- Q_D(const QDeclarativeParticles);
- return d->angleDev * 180.0 / M_PI;
-}
-
-void QDeclarativeParticles::setAngleDeviation(qreal dev)
-{
- Q_D(QDeclarativeParticles);
- qreal radDev = dev * M_PI / 180.0;
- if(radDev == d->angleDev)
- return;
- d->angleDev = radDev;
- emit angleDeviationChanged();
-}
-
-/*!
- \qmlproperty real Particles::velocity
- \qmlproperty real Particles::velocityDeviation
-
- These properties control the velocity of the particles.
-
- velocityDeviation randomly varies the velocity up to the specified variation. For
- example, the following creates particles whose initial velocity will
- vary from 40 to 60.
-
- \qml
-Particles {
- source: "star.png"
- velocity: 50
- velocityDeviation: 20
-}
- \endqml
-*/
-
-/*!
- \property QDeclarativeParticles::velocity
- \brief the initial velocity of the particles.
-
- \sa QDeclarativeParticles::velocityDeviation
-*/
-qreal QDeclarativeParticles::velocity() const
-{
- Q_D(const QDeclarativeParticles);
- return d->velocity * 1000.0;
-}
-
-void QDeclarativeParticles::setVelocity(qreal velocity)
-{
- Q_D(QDeclarativeParticles);
- qreal realVel = velocity / 1000.0;
- if(realVel == d->velocity)
- return;
- d->velocity = realVel;
- emit velocityChanged();
-}
-
-/*!
- \property QDeclarativeParticles::velocityDeviation
- \brief the maximum possible deviation from the set velocity.
-
- Randomly varies the velocity up to the specified variation. For
- example, the following creates particles whose initial velocity will
- vary from 40 to 60.
-
-\qml
-Particles {
- source: "star.png"
- velocity: 50
- velocityDeviation: 20
-}
-\endqml
-
- \sa QDeclarativeParticles::velocity
-*/
-qreal QDeclarativeParticles::velocityDeviation() const
-{
- Q_D(const QDeclarativeParticles);
- return d->velocityDev * 1000.0;
-}
-
-void QDeclarativeParticles::setVelocityDeviation(qreal velocity)
-{
- Q_D(QDeclarativeParticles);
- qreal realDev = velocity / 1000.0;
- if(realDev == d->velocityDev)
- return;
- d->velocityDev = realDev;
- emit velocityDeviationChanged();
-}
-
-/*!
- \qmlproperty ParticleMotion Particles::motion
- This property sets the type of motion to apply to the particles.
-
- When a particle is created it will have an initial direction and velocity.
- The motion of the particle during its lifeSpan is then influenced by the
- motion property.
-
- Default motion is ParticleMotionLinear.
-*/
-
-/*!
- \property QDeclarativeParticles::motion
- \brief sets the type of motion to apply to the particles.
-
- When a particle is created it will have an initial direction and velocity.
- The motion of the particle during its lifeSpan is then influenced by the
- motion property.
-
- Default motion is QDeclarativeParticleMotionLinear.
-*/
-QDeclarativeParticleMotion *QDeclarativeParticles::motion() const
-{
- Q_D(const QDeclarativeParticles);
- return d->motion;
-}
-
-void QDeclarativeParticles::setMotion(QDeclarativeParticleMotion *motion)
-{
- Q_D(QDeclarativeParticles);
- if (motion == d->motion)
- return;
- d->motion = motion;
- emit motionChanged();
-}
-
-/*!
- \qmlmethod Particles::burst(int count, int emissionRate)
-
- Initiates a burst of particles.
-
- This method takes two arguments. The first argument is the number
- of particles to emit and the second argument is the emissionRate for the
- burst. If the second argument is omitted, it is treated as -1. The burst
- of particles has a separate emissionRate and count to the normal emission of
- particles. The burst uses the same values as normal emission for all other
- properties, including emissionVariance.
-
- The normal emission of particles will continue during the burst, however
- the particles created by the burst count towards the maximum number used by
- normal emission. To avoid this behavior, use two Particles elements.
-
-*/
-void QDeclarativeParticles::burst(int count, int emissionRate)
-{
- Q_D(QDeclarativeParticles);
- d->bursts << qMakePair(count, emissionRate);
- if (d->clock.state() != QAbstractAnimation::Running)
- d->clock.start();
-}
-
-void QDeclarativeParticlesPainter::updateSize()
-{
- if (!d->_componentComplete)
- return;
-
- const int parentX = parentItem()->x();
- const int parentY = parentItem()->y();
- for (int i = 0; i < d->particles.count(); ++i) {
- const QDeclarativeParticle &particle = d->particles.at(i);
- if(particle.x > maxX)
- maxX = particle.x;
- if(particle.x < minX)
- minX = particle.x;
- if(particle.y > maxY)
- maxY = particle.y;
- if(particle.y < minY)
- minY = particle.y;
- }
-
- int myWidth = (int)(maxX-minX+0.5)+d->image.width();
- int myX = (int)(minX - parentX);
- int myHeight = (int)(maxY-minY+0.5)+d->image.height();
- int myY = (int)(minY - parentY);
- setWidth(myWidth);
- setHeight(myHeight);
- setX(myX);
- setY(myY);
-}
-
-void QDeclarativeParticles::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
-{
- Q_UNUSED(p);
- //painting is done by the ParticlesPainter, so it can have the right size
-}
-
-void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
-{
- if (d->image.isNull() || d->particles.isEmpty())
- return;
-
- const int myX = x() + parentItem()->x();
- const int myY = y() + parentItem()->y();
-
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData;
-#else
- QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData;
-#endif
- pixmapData.resize(d->particles.count());
-
- const QRectF sourceRect = d->image.rect();
- qreal halfPWidth = sourceRect.width()/2.;
- qreal halfPHeight = sourceRect.height()/2.;
- for (int i = 0; i < d->particles.count(); ++i) {
- const QDeclarativeParticle &particle = d->particles.at(i);
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- pixmapData[i].x = particle.x - myX + halfPWidth;
- pixmapData[i].y = particle.y - myY + halfPHeight;
-#else
- pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight);
-#endif
- pixmapData[i].opacity = particle.opacity;
-
- //these never change
- pixmapData[i].rotation = 0;
- pixmapData[i].scaleX = 1;
- pixmapData[i].scaleY = 1;
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- pixmapData[i].sourceLeft = sourceRect.left();
- pixmapData[i].sourceTop = sourceRect.top();
- pixmapData[i].width = sourceRect.width();
- pixmapData[i].height = sourceRect.height();
-#else
- pixmapData[i].source = sourceRect;
-#endif
- }
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image);
-#else
- qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image);
-#endif
-}
-
-void QDeclarativeParticles::componentComplete()
-{
- Q_D(QDeclarativeParticles);
- QDeclarativeItem::componentComplete();
- if (d->count && d->emissionRate) {
- d->paintItem->updateSize();
- d->clock.start();
- }
- if (d->lifeSpanDev > d->lifeSpan)
- d->lifeSpanDev = d->lifeSpan;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeparticles_p.h b/src/declarative/graphicsitems/qdeclarativeparticles_p.h
deleted file mode 100644
index 06acbb9..0000000
--- a/src/declarative/graphicsitems/qdeclarativeparticles_p.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEPARTICLES_H
-#define QDECLARATIVEPARTICLES_H
-
-#include "qdeclarativeitem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeParticle;
-class QDeclarativeParticles;
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotion : public QObject
-{
- Q_OBJECT
-public:
- QDeclarativeParticleMotion(QObject *parent=0);
-
- virtual void advance(QDeclarativeParticle &, int interval);
- virtual void created(QDeclarativeParticle &);
- virtual void destroy(QDeclarativeParticle &);
-};
-
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion
-{
- Q_OBJECT
-public:
- QDeclarativeParticleMotionLinear(QObject *parent=0)
- : QDeclarativeParticleMotion(parent) {}
-
- virtual void advance(QDeclarativeParticle &, int interval);
-};
-
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion
-{
- Q_OBJECT
-
- Q_PROPERTY(qreal xattractor READ xAttractor WRITE setXAttractor NOTIFY xattractorChanged)
- Q_PROPERTY(qreal yattractor READ yAttractor WRITE setYAttractor NOTIFY yattractorChanged)
- Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
-public:
- QDeclarativeParticleMotionGravity(QObject *parent=0)
- : QDeclarativeParticleMotion(parent), _xAttr(0.0), _yAttr(0.0), _accel(0.00005) {}
-
- qreal xAttractor() const { return _xAttr; }
- void setXAttractor(qreal x);
-
- qreal yAttractor() const { return _yAttr; }
- void setYAttractor(qreal y);
-
- qreal acceleration() const { return _accel * 1000000; }
- void setAcceleration(qreal accel);
-
- virtual void advance(QDeclarativeParticle &, int interval);
-
-Q_SIGNALS:
- void xattractorChanged();
- void yattractorChanged();
- void accelerationChanged();
-
-private:
- qreal _xAttr;
- qreal _yAttr;
- qreal _accel;
-};
-
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion
-{
- Q_OBJECT
-public:
- QDeclarativeParticleMotionWander()
- : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0) {}
-
- virtual void advance(QDeclarativeParticle &, int interval);
- virtual void created(QDeclarativeParticle &);
- virtual void destroy(QDeclarativeParticle &);
-
- struct Data {
- qreal x_targetV;
- qreal y_targetV;
- qreal x_peak;
- qreal y_peak;
- qreal x_var;
- qreal y_var;
- };
-
- Q_PROPERTY(qreal xvariance READ xVariance WRITE setXVariance NOTIFY xvarianceChanged)
- qreal xVariance() const { return _xvariance * 1000.0; }
- void setXVariance(qreal var);
-
- Q_PROPERTY(qreal yvariance READ yVariance WRITE setYVariance NOTIFY yvarianceChanged)
- qreal yVariance() const { return _yvariance * 1000.0; }
- void setYVariance(qreal var);
-
- Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged)
- qreal pace() const { return _pace * 1000.0; }
- void setPace(qreal pace);
-
-Q_SIGNALS:
- void xvarianceChanged();
- void yvarianceChanged();
- void paceChanged();
-
-private:
- QDeclarativeParticles *particles;
- qreal _xvariance;
- qreal _yvariance;
- qreal _pace;
-};
-
-class QDeclarativeParticlesPrivate;
-class Q_DECLARATIVE_EXPORT QDeclarativeParticles : public QDeclarativeItem
-{
- Q_OBJECT
-
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
- Q_PROPERTY(int emissionRate READ emissionRate WRITE setEmissionRate NOTIFY emissionRateChanged)
- Q_PROPERTY(qreal emissionVariance READ emissionVariance WRITE setEmissionVariance NOTIFY emissionVarianceChanged)
- Q_PROPERTY(int lifeSpan READ lifeSpan WRITE setLifeSpan NOTIFY lifeSpanChanged)
- Q_PROPERTY(int lifeSpanDeviation READ lifeSpanDeviation WRITE setLifeSpanDeviation NOTIFY lifeSpanDeviationChanged)
- Q_PROPERTY(int fadeInDuration READ fadeInDuration WRITE setFadeInDuration NOTIFY fadeInDurationChanged)
- Q_PROPERTY(int fadeOutDuration READ fadeOutDuration WRITE setFadeOutDuration NOTIFY fadeOutDurationChanged)
- Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
- Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged)
- Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
- Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged)
- Q_PROPERTY(QDeclarativeParticleMotion *motion READ motion WRITE setMotion NOTIFY motionChanged)
- Q_CLASSINFO("DefaultProperty", "motion")
-
-public:
- QDeclarativeParticles(QDeclarativeItem *parent=0);
- ~QDeclarativeParticles();
-
- QUrl source() const;
- void setSource(const QUrl &);
-
- int count() const;
- void setCount(int cnt);
-
- int emissionRate() const;
- void setEmissionRate(int);
-
- qreal emissionVariance() const;
- void setEmissionVariance(qreal);
-
- int lifeSpan() const;
- void setLifeSpan(int);
-
- int lifeSpanDeviation() const;
- void setLifeSpanDeviation(int);
-
- int fadeInDuration() const;
- void setFadeInDuration(int);
-
- int fadeOutDuration() const;
- void setFadeOutDuration(int);
-
- qreal angle() const;
- void setAngle(qreal);
-
- qreal angleDeviation() const;
- void setAngleDeviation(qreal);
-
- qreal velocity() const;
- void setVelocity(qreal);
-
- qreal velocityDeviation() const;
- void setVelocityDeviation(qreal);
-
- QDeclarativeParticleMotion *motion() const;
- void setMotion(QDeclarativeParticleMotion *);
-
- void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-
-public Q_SLOTS:
- void burst(int count, int emissionRate=-1);
-
-protected:
- virtual void componentComplete();
-
-Q_SIGNALS:
- void sourceChanged();
- void countChanged();
- void emissionRateChanged();
- void emissionVarianceChanged();
- void lifeSpanChanged();
- void lifeSpanDeviationChanged();
- void fadeInDurationChanged();
- void fadeOutDurationChanged();
- void angleChanged();
- void angleDeviationChanged();
- void velocityChanged();
- void velocityDeviationChanged();
- void emittingChanged();
- void motionChanged();
-
-private Q_SLOTS:
- void imageLoaded();
-
-private:
- Q_DISABLE_COPY(QDeclarativeParticles)
- Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeParticles)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QDeclarativeParticleMotion)
-QML_DECLARE_TYPE(QDeclarativeParticleMotionLinear)
-QML_DECLARE_TYPE(QDeclarativeParticleMotionGravity)
-QML_DECLARE_TYPE(QDeclarativeParticleMotionWander)
-QML_DECLARE_TYPE(QDeclarativeParticles)
-
-QT_END_HEADER
-
-#endif
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 88ca5cd..bc78b5b 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -223,7 +223,7 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF
int QDeclarativeBinding::propertyIndex()
{
Q_D(QDeclarativeBinding);
- return d->bindingData()->property.index();
+ return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property);
}
bool QDeclarativeBinding::enabled() const
@@ -259,23 +259,57 @@ void QDeclarativeAbstractBinding::addToObject(QObject *object)
{
Q_ASSERT(object);
+ if (m_object == object)
+ return;
+
+ int index = propertyIndex();
+
removeFromObject();
Q_ASSERT(!m_prevBinding);
- QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true);
- m_nextBinding = data->bindings;
- if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
- m_prevBinding = &data->bindings;
- data->bindings = this;
m_object = object;
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true);
+
+ if (index & 0xFF000000) {
+ // Value type
- data->setBindingBit(m_object, propertyIndex());
+ int coreIndex = index & 0xFFFFFF;
+
+ // Find the value type proxy (if there is one)
+ QDeclarativeValueTypeProxyBinding *proxy = 0;
+ if (data->hasBindingBit(coreIndex)) {
+ QDeclarativeAbstractBinding *b = data->bindings;
+ while (b && b->propertyIndex() != coreIndex)
+ b = b->m_nextBinding;
+ Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy);
+ proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(b);
+ }
+
+ if (!proxy)
+ proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex);
+ proxy->addToObject(object);
+
+ m_nextBinding = proxy->m_bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &proxy->m_bindings;
+ proxy->m_bindings = this;
+
+ } else {
+ m_nextBinding = data->bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &data->bindings;
+ data->bindings = this;
+
+ data->setBindingBit(m_object, index);
+ }
}
void QDeclarativeAbstractBinding::removeFromObject()
{
if (m_prevBinding) {
+ int index = propertyIndex();
+
Q_ASSERT(m_object);
*m_prevBinding = m_nextBinding;
@@ -283,8 +317,14 @@ void QDeclarativeAbstractBinding::removeFromObject()
m_prevBinding = 0;
m_nextBinding = 0;
- QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false);
- if (data) data->clearBindingBit(propertyIndex());
+ if (index & 0xFF000000) {
+ // Value type - we don't remove the proxy from the object. It will sit their happily
+ // doing nothing for ever more.
+ } else {
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false);
+ if (data) data->clearBindingBit(index);
+ }
+
m_object = 0;
}
}
@@ -305,4 +345,88 @@ void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate
if (e) m_mePtr = 0;
}
+QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index)
+: m_object(o), m_index(index), m_bindings(0)
+{
+}
+
+QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding()
+{
+ while (m_bindings) {
+ QDeclarativeAbstractBinding *binding = m_bindings;
+ binding->setEnabled(false, 0);
+ binding->destroy();
+ }
+}
+
+void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (e) {
+ addToObject(m_object);
+
+ QDeclarativeAbstractBinding *bindings = m_bindings;
+ m_bindings = 0;
+ recursiveEnable(bindings, flags);
+ } else {
+ removeFromObject();
+
+ QDeclarativeAbstractBinding *bindings = m_bindings;
+ m_bindings = 0;
+ recursiveDisable(bindings);
+ }
+}
+
+void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBinding *b, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (!b)
+ return;
+
+ QDeclarativeAbstractBinding *next = b->m_nextBinding;
+ b->m_prevBinding = 0;
+ b->m_nextBinding = 0;
+ Q_ASSERT(b->m_mePtr == 0);
+ b->m_mePtr = &b;
+
+ recursiveEnable(next, flags);
+
+ if (b)
+ b->setEnabled(true, flags);
+}
+
+void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBinding *b)
+{
+ if (!b)
+ return;
+
+ recursiveDisable(b->m_nextBinding);
+
+ b->setEnabled(false, 0);
+
+ Q_ASSERT(b->m_prevBinding == 0);
+ Q_ASSERT(b->m_nextBinding == 0);
+ b->m_nextBinding = m_bindings;
+ if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding;
+ b->m_prevBinding = &m_bindings;
+ m_bindings = b;
+}
+
+int QDeclarativeValueTypeProxyBinding::propertyIndex()
+{
+ return m_index;
+}
+
+void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags)
+{
+}
+
+QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int propertyIndex)
+{
+ QDeclarativeAbstractBinding *binding = m_bindings;
+
+ while (binding && binding->propertyIndex() != propertyIndex)
+ binding = binding->m_nextBinding;
+
+ return binding;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 1a714f0..21e3248 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -74,6 +74,9 @@ public:
virtual QString expression() const;
+ enum Type { PropertyBinding, ValueTypeProxy };
+ virtual Type bindingType() const { return PropertyBinding; }
+
void setEnabled(bool e) { setEnabled(e, QDeclarativePropertyPrivate::DontRemoveBinding); }
virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags) = 0;
virtual int propertyIndex() = 0;
@@ -92,6 +95,7 @@ private:
friend class QDeclarativeProperty;
friend class QDeclarativePropertyPrivate;
friend class QDeclarativeVME;
+ friend class QDeclarativeValueTypeProxyBinding;
QObject *m_object;
QDeclarativeAbstractBinding **m_mePtr;
@@ -99,6 +103,30 @@ private:
QDeclarativeAbstractBinding *m_nextBinding;
};
+class QDeclarativeValueTypeProxyBinding : public QDeclarativeAbstractBinding
+{
+public:
+ QDeclarativeValueTypeProxyBinding(QObject *o, int coreIndex);
+ virtual ~QDeclarativeValueTypeProxyBinding();
+
+ virtual Type bindingType() const { return ValueTypeProxy; }
+
+ virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags);
+ virtual int propertyIndex();
+ virtual void update(QDeclarativePropertyPrivate::WriteFlags);
+
+ QDeclarativeAbstractBinding *binding(int propertyIndex);
+
+private:
+ void recursiveEnable(QDeclarativeAbstractBinding *, QDeclarativePropertyPrivate::WriteFlags);
+ void recursiveDisable(QDeclarativeAbstractBinding *);
+
+ friend class QDeclarativeAbstractBinding;
+ QObject *m_object;
+ int m_index;
+ QDeclarativeAbstractBinding *m_bindings;
+};
+
class QDeclarativeContext;
class QDeclarativeBindingPrivate;
class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, public QDeclarativeAbstractBinding
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index dc4a676..68780b6 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -351,7 +351,8 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
}
}
- QDeclarativeAbstractBinding *delBinding = QDeclarativePropertyPrivate::setBinding(obj, *lastData, 0);
+ QDeclarativeAbstractBinding *delBinding =
+ QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0);
if (delBinding)
delBinding->destroy();
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 945d098..8ca5406 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -598,7 +598,6 @@ QMetaMethod QDeclarativeProperty::method() const
return QMetaMethod();
}
-
/*!
Returns the binding associated with this property, or 0 if no binding
exists.
@@ -617,13 +616,18 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that)
return 0;
QDeclarativeAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == that.d->core.coreIndex)
- return binding;
+ while (binding && binding->propertyIndex() != that.d->core.coreIndex)
binding = binding->m_nextBinding;
+
+ if (binding && that.d->valueType.valueTypeCoreIdx != -1) {
+ if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) {
+ QDeclarativeValueTypeProxyBinding *proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(binding);
+
+ binding = proxy->binding(bindingIndex(that));
+ }
}
- return 0;
+
+ return binding;
}
/*!
@@ -650,36 +654,36 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that,
return 0;
}
- return that.d->setBinding(that.d->object, that.d->core, newBinding, flags);
+ return that.d->setBinding(that.d->object, that.d->core.coreIndex,
+ that.d->valueType.valueTypeCoreIdx, newBinding, flags);
}
QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::setBinding(QObject *object, const QDeclarativePropertyCache::Data &core,
- QDeclarativeAbstractBinding *newBinding, WriteFlags flags)
+QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex,
+ QDeclarativeAbstractBinding *newBinding, WriteFlags flags)
{
QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, 0 != newBinding);
+ QDeclarativeAbstractBinding *binding = 0;
- if (data && data->hasBindingBit(core.coreIndex)) {
- QDeclarativeAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == core.coreIndex) {
- binding->setEnabled(false);
+ if (data && data->hasBindingBit(coreIndex)) {
+ binding = data->bindings;
- if (newBinding)
- newBinding->setEnabled(true, flags);
+ while (binding && binding->propertyIndex() != coreIndex)
+ binding = binding->m_nextBinding;
+ }
- return binding; // ### QDeclarativeAbstractBinding;
- }
+ if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) {
+ int index = coreIndex | (valueTypeIndex << 24);
+ binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);
+ }
- binding = binding->m_nextBinding;
- }
- }
+ if (binding)
+ binding->setEnabled(false);
- if (newBinding)
+ if (newBinding)
newBinding->setEnabled(true, flags);
- return 0;
+ return binding;
}
/*!
@@ -1253,6 +1257,18 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &
return that.d->valueType.valueTypeCoreIdx;
}
+/*!
+ Returns the "property index" for use in bindings. The top 8 bits are the value type
+ offset, and 0 otherwise. The bottom 24-bits are the regular property index.
+*/
+int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that)
+{
+ int rv = that.d->core.coreIndex;
+ if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1)
+ rv = rv | (that.d->valueType.valueTypeCoreIdx << 24);
+ return rv;
+}
+
struct SerializedData {
bool isValueType;
QDeclarativePropertyCache::Data core;
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index c31e2d3..26b85b8 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -110,7 +110,7 @@ public:
const QVariant &value, int flags);
static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &,
QDeclarativeContext *, WriteFlags flags = 0);
- static QDeclarativeAbstractBinding *setBinding(QObject *, const QDeclarativePropertyCache::Data &,
+ static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */,
QDeclarativeAbstractBinding *,
WriteFlags flags = DontRemoveBinding);
@@ -133,6 +133,7 @@ public:
QDeclarativeExpression *) ;
static bool write(const QDeclarativeProperty &that, const QVariant &, WriteFlags);
static int valueTypeCoreIndex(const QDeclarativeProperty &that);
+ static int bindingIndex(const QDeclarativeProperty &that);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags)
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index 9cb65f8..a567c38 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -41,6 +41,8 @@
#include "qdeclarativevaluetypescriptclass_p.h"
+#include "qdeclarativebinding_p.h"
+#include "qdeclarativeproperty_p.h"
#include "qdeclarativeengine_p.h"
#include "qdeclarativeguard_p.h"
@@ -115,6 +117,11 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
{
QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+ QDeclarativeAbstractBinding *delBinding =
+ QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0);
+ if (delBinding)
+ delBinding->destroy();
+
QVariant v = QDeclarativeScriptClass::toVariant(engine, value);
ref->type->read(ref->object, ref->property);
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 20449d7..d77ef40 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -2447,12 +2447,15 @@ QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent)
QDeclarative_setParent_noEvent(d->topLevelGroup, this);
d->startAction = new QActionAnimation;
+ QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup);
d->topLevelGroup->addAnimation(d->startAction);
d->ag = new QParallelAnimationGroup;
+ QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup);
d->topLevelGroup->addAnimation(d->ag);
d->endAction = new QActionAnimation;
+ QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup);
d->topLevelGroup->addAnimation(d->endAction);
}
@@ -2743,4 +2746,99 @@ QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation()
return d->topLevelGroup;
}
+/*!
+ \qmlclass AnchorAnimation QDeclarativeAnchorAnimation
+ \since 4.7
+ \inherits Animation
+ \brief The AnchorAnimation element allows you to animate anchor changes.
+
+ AnchorAnimation will animated any changes specified by a state's AnchorChanges.
+ In the following snippet we animate the addition of a right anchor to our item.
+ \qml
+ Item {
+ id: myItem
+ width: 100
+ }
+ ...
+ State {
+ AnchorChanges {
+ target: myItem
+ anchors.right: container.right
+ }
+ }
+ ...
+ Transition {
+ //smoothly reanchor myItem and move into new position
+ AnchorAnimation {}
+ }
+ \endqml
+
+ \sa AnchorChanges
+*/
+
+QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent)
+: QDeclarativeAbstractAnimation(*(new QDeclarativeAnchorAnimationPrivate), parent)
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ d->va = new QDeclarativeBulkValueAnimator;
+ QDeclarative_setParent_noEvent(d->va, this);
+}
+
+QDeclarativeAnchorAnimation::~QDeclarativeAnchorAnimation()
+{
+}
+
+QAbstractAnimation *QDeclarativeAnchorAnimation::qtAnimation()
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ return d->va;
+}
+
+/*!
+ \qmlproperty list<Item> AnchorAnimation::targets
+ The items to reanchor.
+
+ If no targets are specified all AnchorChanges will be
+ animated by the AnchorAnimation.
+*/
+QDeclarativeListProperty<QDeclarativeItem> QDeclarativeAnchorAnimation::targets()
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ return QDeclarativeListProperty<QDeclarativeItem>(this, d->targets);
+}
+
+void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ PropertyUpdater *data = new PropertyUpdater;
+ data->interpolatorType = QMetaType::QReal;
+ data->interpolator = d->interpolator;
+
+ data->reverse = direction == Backward ? true : false;
+ data->fromSourced = false;
+ data->fromDefined = false;
+
+ for (int ii = 0; ii < actions.count(); ++ii) {
+ QDeclarativeAction &action = actions[ii];
+ if (action.event && action.event->typeName() == QLatin1String("AnchorChanges")
+ && (d->targets.isEmpty() || d->targets.contains(static_cast<QDeclarativeAnchorChanges*>(action.event)->object()))) {
+ data->actions << static_cast<QDeclarativeAnchorChanges*>(action.event)->additionalActions();
+ }
+ }
+
+ if (data->actions.count()) {
+ if (!d->rangeIsSet) {
+ d->va->setStartValue(qreal(0));
+ d->va->setEndValue(qreal(1));
+ d->rangeIsSet = true;
+ }
+ d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+ d->va->setFromSourcedValue(&data->fromSourced);
+ } else {
+ delete data;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h
index af48309..eb339f6 100644
--- a/src/declarative/util/qdeclarativeanimation_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p.h
@@ -480,6 +480,26 @@ protected:
virtual QAbstractAnimation *qtAnimation();
};
+class QDeclarativeAnchorAnimationPrivate;
+class QDeclarativeAnchorAnimation : public QDeclarativeAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDeclarativeAnchorAnimation)
+ Q_PROPERTY(QDeclarativeListProperty<QDeclarativeItem> targets READ targets)
+
+public:
+ QDeclarativeAnchorAnimation(QObject *parent=0);
+ virtual ~QDeclarativeAnchorAnimation();
+
+ QDeclarativeListProperty<QDeclarativeItem> targets();
+
+protected:
+ virtual void transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeAbstractAnimation)
@@ -495,6 +515,7 @@ QML_DECLARE_TYPE(QDeclarativeParallelAnimation)
QML_DECLARE_TYPE(QDeclarativeVector3dAnimation)
QML_DECLARE_TYPE(QDeclarativeRotationAnimation)
QML_DECLARE_TYPE(QDeclarativeParentAnimation)
+QML_DECLARE_TYPE(QDeclarativeAnchorAnimation)
QT_END_HEADER
diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h
index ae82a90..0460312 100644
--- a/src/declarative/util/qdeclarativeanimation_p_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p_p.h
@@ -393,6 +393,19 @@ public:
QPointF computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const;
};
+class QDeclarativeAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeAnchorAnimation)
+public:
+ QDeclarativeAnchorAnimationPrivate() : rangeIsSet(false), va(0),
+ interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {}
+
+ bool rangeIsSet;
+ QDeclarativeBulkValueAnimator *va;
+ QVariantAnimation::Interpolator interpolator;
+ QList<QDeclarativeItem*> targets;
+};
+
QT_END_NAMESPACE
#endif // QDECLARATIVEANIMATION_P_H
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 1d70d33..802ff1c 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -96,21 +96,12 @@ void QDeclarativeActionEvent::reverse()
{
}
-QList<QDeclarativeAction> QDeclarativeActionEvent::extraActions()
-{
- return QList<QDeclarativeAction>();
-}
-
bool QDeclarativeActionEvent::changesBindings()
{
return false;
}
-void QDeclarativeActionEvent::clearForwardBindings()
-{
-}
-
-void QDeclarativeActionEvent::clearReverseBindings()
+void QDeclarativeActionEvent::clearBindings()
{
}
@@ -368,47 +359,60 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit
for (int ii = 0; ii < applyList.count(); ++ii) {
QDeclarativeAction &action = applyList[ii];
- bool found = false;
-
- int jj;
if (action.event) {
if (!action.event->isReversable())
continue;
- for (jj = 0; jj < d->revertList.count(); ++jj) {
+ bool found = false;
+ for (int jj = 0; jj < d->revertList.count(); ++jj) {
QDeclarativeActionEvent *event = d->revertList.at(jj).event;
if (event && event->typeName() == action.event->typeName()) {
if (action.event->override(event)) {
found = true;
+
+ if (action.event != d->revertList.at(jj).event) {
+ action.event->copyOriginals(d->revertList.at(jj).event);
+
+ QDeclarativeSimpleAction r(action);
+ additionalReverts << r;
+ d->revertList.removeAt(jj);
+ } else if (action.event->isRewindable()) //###why needed?
+ action.event->saveCurrentValues();
+
break;
}
}
}
- if (!found || action.event != d->revertList.at(jj).event)
+ if (!found) {
action.event->saveOriginals();
- else if (action.event->isRewindable())
- action.event->saveCurrentValues();
+ // Only need to revert the applyList action if the previous
+ // state doesn't have a higher priority revert already
+ QDeclarativeSimpleAction r(action);
+ additionalReverts << r;
+ }
} else {
+ bool found = false;
action.fromBinding = QDeclarativePropertyPrivate::binding(action.property);
- for (jj = 0; jj < d->revertList.count(); ++jj) {
+ for (int jj = 0; jj < d->revertList.count(); ++jj) {
if (d->revertList.at(jj).property == action.property) {
found = true;
+ if (d->revertList.at(jj).binding != action.fromBinding) {
+ action.deleteFromBinding();
+ }
break;
}
}
- }
- if (!found) {
- if (!action.restore) {
- action.deleteFromBinding();
- } else {
- // Only need to revert the applyList action if the previous
- // state doesn't have a higher priority revert already
- QDeclarativeSimpleAction r(action);
- additionalReverts << r;
+ if (!found) {
+ if (!action.restore) {
+ action.deleteFromBinding();
+ } else {
+ // Only need to revert the applyList action if the previous
+ // state doesn't have a higher priority revert already
+ QDeclarativeSimpleAction r(action);
+ additionalReverts << r;
+ }
}
- } else if (d->revertList.at(jj).binding != action.fromBinding) {
- action.deleteFromBinding();
}
}
diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h
index 0c6e7a3..ee2b7e8 100644
--- a/src/declarative/util/qdeclarativestate_p.h
+++ b/src/declarative/util/qdeclarativestate_p.h
@@ -92,17 +92,15 @@ public:
virtual bool isReversable();
virtual void reverse();
virtual void saveOriginals() {}
+ virtual void copyOriginals(QDeclarativeActionEvent *) {}
virtual bool isRewindable() { return isReversable(); }
virtual void rewind() {}
virtual void saveCurrentValues() {}
-
- //virtual bool hasExtraActions();
- virtual QList<QDeclarativeAction> extraActions();
+ virtual void saveTargetValues() {}
virtual bool changesBindings();
- virtual void clearForwardBindings();
- virtual void clearReverseBindings();
+ virtual void clearBindings();
virtual bool override(QDeclarativeActionEvent*other);
};
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index f13c691..6f5bb66 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -403,6 +403,17 @@ void QDeclarativeParentChange::saveOriginals()
d->origStackBefore = d->rewindStackBefore;
}
+void QDeclarativeParentChange::copyOriginals(QDeclarativeActionEvent *other)
+{
+ Q_D(QDeclarativeParentChange);
+ QDeclarativeParentChange *pc = static_cast<QDeclarativeParentChange*>(other);
+
+ d->origParent = pc->d_func()->rewindParent;
+ d->origStackBefore = pc->d_func()->rewindStackBefore;
+
+ saveCurrentValues();
+}
+
void QDeclarativeParentChange::execute()
{
Q_D(QDeclarativeParentChange);
@@ -568,11 +579,10 @@ QString QDeclarativeStateChangeScript::typeName() const
}
\endqml
- AnchorChanges will 'inject' \c x, \c y, \c width, and \c height changes into the transition,
- so you can animate them as you would normally changes to these properties:
+ AnchorChanges can be animated using AnchorAnimation.
\qml
//animate our anchor changes
- NumberAnimation { targets: content; properties: "x,y,width,height" }
+ AnchorAnimation {}
\endqml
For more information on anchors see \l {anchor-layout}{Anchor Layouts}.
@@ -585,10 +595,10 @@ class QDeclarativeAnchorChangesPrivate : public QObjectPrivate
public:
QDeclarativeAnchorChangesPrivate() : target(0) {}
- QString name;
QDeclarativeItem *target;
QString resetString;
QStringList resetList;
+
QDeclarativeAnchorLine left;
QDeclarativeAnchorLine right;
QDeclarativeAnchorLine horizontalCenter;
@@ -617,6 +627,24 @@ public:
qreal fromY;
qreal fromWidth;
qreal fromHeight;
+
+ qreal toX;
+ qreal toY;
+ qreal toWidth;
+ qreal toHeight;
+
+ qreal rewindX;
+ qreal rewindY;
+ qreal rewindWidth;
+ qreal rewindHeight;
+
+ bool applyOrigLeft;
+ bool applyOrigRight;
+ bool applyOrigHCenter;
+ bool applyOrigTop;
+ bool applyOrigBottom;
+ bool applyOrigVCenter;
+ bool applyOrigBaseline;
};
/*!
@@ -769,6 +797,38 @@ void QDeclarativeAnchorChanges::execute()
if (!d->target)
return;
+ //incorporate any needed "reverts"
+ if (d->applyOrigLeft)
+ d->target->anchors()->setLeft(d->origLeft);
+ if (d->applyOrigRight)
+ d->target->anchors()->setRight(d->origRight);
+ if (d->applyOrigHCenter)
+ d->target->anchors()->setHorizontalCenter(d->origHCenter);
+ if (d->applyOrigTop)
+ d->target->anchors()->setTop(d->origTop);
+ if (d->applyOrigBottom)
+ d->target->anchors()->setBottom(d->origBottom);
+ if (d->applyOrigVCenter)
+ d->target->anchors()->setVerticalCenter(d->origVCenter);
+ if (d->applyOrigBaseline)
+ d->target->anchors()->setBaseline(d->origBaseline);
+
+ //reset any anchors that have been specified
+ if (d->resetList.contains(QLatin1String("left")))
+ d->target->anchors()->resetLeft();
+ if (d->resetList.contains(QLatin1String("right")))
+ d->target->anchors()->resetRight();
+ if (d->resetList.contains(QLatin1String("horizontalCenter")))
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->resetList.contains(QLatin1String("top")))
+ d->target->anchors()->resetTop();
+ if (d->resetList.contains(QLatin1String("bottom")))
+ d->target->anchors()->resetBottom();
+ if (d->resetList.contains(QLatin1String("verticalCenter")))
+ d->target->anchors()->resetVerticalCenter();
+ if (d->resetList.contains(QLatin1String("baseline")))
+ d->target->anchors()->resetBaseline();
+
//set any anchors that have been specified
if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
d->target->anchors()->setLeft(d->left);
@@ -797,6 +857,22 @@ void QDeclarativeAnchorChanges::reverse()
if (!d->target)
return;
+ //reset any anchors set by the state
+ if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetLeft();
+ if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetRight();
+ if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetTop();
+ if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBottom();
+ if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBaseline();
+
//restore previous anchors
if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
d->target->anchors()->setLeft(d->origLeft);
@@ -819,31 +895,33 @@ QString QDeclarativeAnchorChanges::typeName() const
return QLatin1String("AnchorChanges");
}
-QList<QDeclarativeAction> QDeclarativeAnchorChanges::extraActions()
+QList<QDeclarativeAction> QDeclarativeAnchorChanges::additionalActions()
{
Q_D(QDeclarativeAnchorChanges);
QList<QDeclarativeAction> extra;
- //### try to be smarter about which ones we add.
- // or short-circuit later on if they haven't actually changed.
- // we shouldn't set explicit width if there wasn't one before.
if (d->target) {
QDeclarativeAction a;
- a.fromValue = d->fromX;
- a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
- extra << a;
-
- a.fromValue = d->fromY;
- a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
- extra << a;
-
- a.fromValue = d->fromWidth;
- a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
- extra << a;
-
- a.fromValue = d->fromHeight;
- a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
- extra << a;
+ if (d->fromX != d->toX) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
+ a.toValue = d->toX;
+ extra << a;
+ }
+ if (d->fromY != d->toY) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
+ a.toValue = d->toY;
+ extra << a;
+ }
+ if (d->fromWidth != d->toWidth) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
+ a.toValue = d->toWidth;
+ extra << a;
+ }
+ if (d->fromHeight != d->toHeight) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
+ a.toValue = d->toHeight;
+ extra << a;
+ }
}
return extra;
@@ -865,10 +943,52 @@ void QDeclarativeAnchorChanges::saveOriginals()
d->origVCenter = d->target->anchors()->verticalCenter();
d->origBaseline = d->target->anchors()->baseline();
+ d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
+ = d->applyOrigBottom = d->applyOrigHCenter = d->applyOrigBaseline = false;
+
saveCurrentValues();
}
-void QDeclarativeAnchorChanges::clearForwardBindings()
+void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ QDeclarativeAnchorChanges *ac = static_cast<QDeclarativeAnchorChanges*>(other);
+ QDeclarativeAnchorChangesPrivate *acp = ac->d_func();
+
+ //probably also need to revert some things
+ d->applyOrigLeft = (acp->left.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("left")));
+
+ d->applyOrigRight = (acp->right.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("right")));
+
+ d->applyOrigHCenter = (acp->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("horizontalCenter")));
+
+ d->applyOrigTop = (acp->top.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("top")));
+
+ d->applyOrigBottom = (acp->bottom.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("bottom")));
+
+ d->applyOrigVCenter = (acp->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("verticalCenter")));
+
+ d->applyOrigBaseline = (acp->baseline.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("baseline")));
+
+ d->origLeft = ac->d_func()->origLeft;
+ d->origRight = ac->d_func()->origRight;
+ d->origHCenter = ac->d_func()->origHCenter;
+ d->origTop = ac->d_func()->origTop;
+ d->origBottom = ac->d_func()->origBottom;
+ d->origVCenter = ac->d_func()->origVCenter;
+ d->origBaseline = ac->d_func()->origBaseline;
+
+ saveCurrentValues();
+}
+
+void QDeclarativeAnchorChanges::clearBindings()
{
Q_D(QDeclarativeAnchorChanges);
d->fromX = d->target->x();
@@ -876,6 +996,22 @@ void QDeclarativeAnchorChanges::clearForwardBindings()
d->fromWidth = d->target->width();
d->fromHeight = d->target->height();
+ //reset any anchors with corresponding reverts
+ if (d->applyOrigLeft)
+ d->target->anchors()->resetLeft();
+ if (d->applyOrigRight)
+ d->target->anchors()->resetRight();
+ if (d->applyOrigHCenter)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->applyOrigTop)
+ d->target->anchors()->resetTop();
+ if (d->applyOrigBottom)
+ d->target->anchors()->resetBottom();
+ if (d->applyOrigVCenter)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->applyOrigBaseline)
+ d->target->anchors()->resetBaseline();
+
//reset any anchors that have been specified
if (d->resetList.contains(QLatin1String("left")))
d->target->anchors()->resetLeft();
@@ -909,47 +1045,6 @@ void QDeclarativeAnchorChanges::clearForwardBindings()
d->target->anchors()->resetBaseline();
}
-void QDeclarativeAnchorChanges::clearReverseBindings()
-{
- Q_D(QDeclarativeAnchorChanges);
- d->fromX = d->target->x();
- d->fromY = d->target->y();
- d->fromWidth = d->target->width();
- d->fromHeight = d->target->height();
-
- //reset any anchors that were set in the state
- if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetLeft();
- if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetRight();
- if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetHorizontalCenter();
- if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetTop();
- if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBottom();
- if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetVerticalCenter();
- if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBaseline();
-
- //reset any anchors that were set in the original state
- if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetLeft();
- if (d->origRight.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetRight();
- if (d->origHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetHorizontalCenter();
- if (d->origTop.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetTop();
- if (d->origBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBottom();
- if (d->origVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetVerticalCenter();
- if (d->origBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBaseline();
-}
-
bool QDeclarativeAnchorChanges::override(QDeclarativeActionEvent*other)
{
if (other->typeName() != QLatin1String("AnchorChanges"))
@@ -982,6 +1077,11 @@ void QDeclarativeAnchorChanges::rewind()
d->target->anchors()->setVerticalCenter(d->rewindVCenter);
if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
d->target->anchors()->setBaseline(d->rewindBaseline);
+
+ d->target->setX(d->rewindX);
+ d->target->setY(d->rewindY);
+ d->target->setWidth(d->rewindWidth);
+ d->target->setHeight(d->rewindHeight);
}
void QDeclarativeAnchorChanges::saveCurrentValues()
@@ -994,6 +1094,20 @@ void QDeclarativeAnchorChanges::saveCurrentValues()
d->rewindBottom = d->target->anchors()->bottom();
d->rewindVCenter = d->target->anchors()->verticalCenter();
d->rewindBaseline = d->target->anchors()->baseline();
+
+ d->rewindX = d->target->x();
+ d->rewindY = d->target->y();
+ d->rewindWidth = d->target->width();
+ d->rewindHeight = d->target->height();
+}
+
+void QDeclarativeAnchorChanges::saveTargetValues()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->toX = d->target->x();
+ d->toY = d->target->y();
+ d->toWidth = d->target->width();
+ d->toHeight = d->target->height();
}
#include <qdeclarativestateoperations.moc>
diff --git a/src/declarative/util/qdeclarativestateoperations_p.h b/src/declarative/util/qdeclarativestateoperations_p.h
index dd4248023..66a8717 100644
--- a/src/declarative/util/qdeclarativestateoperations_p.h
+++ b/src/declarative/util/qdeclarativestateoperations_p.h
@@ -107,6 +107,7 @@ public:
virtual ActionList actions();
virtual void saveOriginals();
+ virtual void copyOriginals(QDeclarativeActionEvent*);
virtual void execute();
virtual bool isReversable();
virtual void reverse();
@@ -196,13 +197,15 @@ public:
virtual void reverse();
virtual QString typeName() const;
virtual bool override(QDeclarativeActionEvent*other);
- virtual QList<QDeclarativeAction> extraActions();
virtual bool changesBindings();
virtual void saveOriginals();
- virtual void clearForwardBindings();
- virtual void clearReverseBindings();
+ virtual void copyOriginals(QDeclarativeActionEvent*);
+ virtual void clearBindings();
virtual void rewind();
virtual void saveCurrentValues();
+
+ QList<QDeclarativeAction> additionalActions();
+ virtual void saveTargetValues();
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp
index e1143fa..f07fb23 100644
--- a/src/declarative/util/qdeclarativetransitionmanager.cpp
+++ b/src/declarative/util/qdeclarativetransitionmanager.cpp
@@ -126,10 +126,7 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
QDeclarativePropertyPrivate::setBinding(action.property, 0); // Disable current binding
if (action.event && action.event->changesBindings()) { //### assume isReversable()?
d->bindingsList << action;
- if (action.reverseEvent)
- action.event->clearReverseBindings();
- else
- action.event->clearForwardBindings();
+ action.event->clearBindings();
}
}
@@ -144,8 +141,6 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
if (!d->bindingsList.isEmpty()) {
- //### do extra actions here?
-
// Apply all the property and binding changes
for (int ii = 0; ii < applyList.size(); ++ii) {
const QDeclarativeAction &action = applyList.at(ii);
@@ -158,17 +153,18 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
action.event->reverse();
else
action.event->execute();
- applyList << action.event->extraActions();
}
}
// Read all the end values for binding changes
for (int ii = 0; ii < applyList.size(); ++ii) {
QDeclarativeAction *action = &applyList[ii];
- if (action->event)
+ if (action->event) {
+ action->event->saveTargetValues();
continue;
+ }
const QDeclarativeProperty &prop = action->property;
- if (action->toBinding || !action->toValue.isValid()) { //### is this always right (used for exta actions)
+ if (action->toBinding || !action->toValue.isValid()) {
action->toValue = prop.read();
}
}
@@ -177,15 +173,9 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
foreach(const QDeclarativeAction &action, applyList) {
if (action.event) {
if (action.event->isReversable()) {
- if (action.reverseEvent) { //reverse the reverse
- action.event->clearForwardBindings();
- action.event->rewind();
- action.event->clearReverseBindings();
- } else {
- action.event->clearReverseBindings();
- action.event->rewind();
- action.event->clearForwardBindings();
- }
+ action.event->clearBindings();
+ action.event->rewind();
+ action.event->clearBindings();
}
continue;
}
diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp
index 9c3b0aa..4d4678a 100644
--- a/src/declarative/util/qdeclarativeutilmodule.cpp
+++ b/src/declarative/util/qdeclarativeutilmodule.cpp
@@ -75,6 +75,7 @@
void QDeclarativeUtilModule::defineModule()
{
+ qmlRegisterType<QDeclarativeAnchorAnimation>("Qt",4,6,"AnchorAnimation");
qmlRegisterType<QDeclarativeAnchorChanges>("Qt",4,6,"AnchorChanges");
qmlRegisterType<QDeclarativeBehavior>("Qt",4,6,"Behavior");
qmlRegisterType<QDeclarativeBind>("Qt",4,6,"Binding");