aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-06-10 16:07:33 +1000
committerAlan Alpert <alan.alpert@nokia.com>2011-06-10 16:07:33 +1000
commit7b28a7eebeb8cbe5d356fc9b24651a36d73ab1ad (patch)
tree819592ab14dfc9c7e59ea42d02e998b77d4aa210
parent6e69712287fa2d6087e5423cc4b7aace8b790894 (diff)
Add delegate property to ItemParticle
Also add burst(n,x,y) to ParticleEmitter, and a demo that uses both.
-rw-r--r--examples/declarative/particles/custom/blurparticles.qml40
-rw-r--r--examples/declarative/particles/custom/content/particle.pngbin0 -> 861 bytes
-rw-r--r--examples/declarative/particles/custom/fireworks.qml101
-rw-r--r--src/declarative/particles/qsgitemparticle.cpp78
-rw-r--r--src/declarative/particles/qsgitemparticle_p.h23
-rw-r--r--src/declarative/particles/qsgmodelparticle.cpp2
-rw-r--r--src/declarative/particles/qsgparticleemitter.cpp7
-rw-r--r--src/declarative/particles/qsgparticleemitter_p.h1
8 files changed, 224 insertions, 28 deletions
diff --git a/examples/declarative/particles/custom/blurparticles.qml b/examples/declarative/particles/custom/blurparticles.qml
index 8a3e9ad803..15da9ba9db 100644
--- a/examples/declarative/particles/custom/blurparticles.qml
+++ b/examples/declarative/particles/custom/blurparticles.qml
@@ -1,3 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
import QtQuick 2.0
import QtQuick.Particles 2.0
diff --git a/examples/declarative/particles/custom/content/particle.png b/examples/declarative/particles/custom/content/particle.png
new file mode 100644
index 0000000000..5c83896d22
--- /dev/null
+++ b/examples/declarative/particles/custom/content/particle.png
Binary files differ
diff --git a/examples/declarative/particles/custom/fireworks.qml b/examples/declarative/particles/custom/fireworks.qml
new file mode 100644
index 0000000000..edd4accfdf
--- /dev/null
+++ b/examples/declarative/particles/custom/fireworks.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle{
+ width: 360
+ height: 600
+ color: "black"
+ ParticleSystem{
+ id: otherSys
+ anchors.fill: parent
+ Emitter{
+ id: emitter
+ emitting: false
+ emitRate: 100
+ lifeSpan: 1000
+ emitCap: 1000
+ speed: AngledDirection{angleVariation:180; magnitudeVariation: 60}
+ }
+
+ ImageParticle{
+ source: "content/particle.png"
+ }
+ }
+ Component{
+ id: firework
+ Item{
+ id: container
+ width: 48
+ height: 48
+ Image{
+ width: 48
+ height: 48
+ id: img
+ source: "content/particle.png"
+ }
+ Timer{
+ interval: 1000 + 4000*Math.random()
+ running: true
+ repeat: false
+ onTriggered: {
+ img.visible = false;
+ emitter.burst(100, container.x+24, container.y+24);
+ }
+ }
+ }
+ }
+ ParticleSystem{
+ anchors.fill: parent
+ Emitter{
+ width: parent.width
+ y: parent.height
+ emitRate: 2
+ lifeSpan: 6000
+ speed: PointDirection{y:-100}
+ }
+ ItemParticle{
+ delegate: firework
+ }
+ }
+}
+
diff --git a/src/declarative/particles/qsgitemparticle.cpp b/src/declarative/particles/qsgitemparticle.cpp
index 819c823155..498dd90a87 100644
--- a/src/declarative/particles/qsgitemparticle.cpp
+++ b/src/declarative/particles/qsgitemparticle.cpp
@@ -42,14 +42,22 @@
#include "qsgitemparticle_p.h"
#include <QtDeclarative/private/qsgvisualitemmodel_p.h>
#include <qsgnode.h>
+#include <QTimer>
+#include <QDeclarativeComponent>
#include <QDebug>
QT_BEGIN_NAMESPACE
QSGItemParticle::QSGItemParticle(QSGItem *parent) :
- QSGParticlePainter(parent), m_fade(true)
+ QSGParticlePainter(parent), m_fade(true), m_delegate(0)
{
setFlag(QSGItem::ItemHasContents);
+ QTimer* manageDelegates = new QTimer(this);//TODO: don't leak
+ connect(manageDelegates, SIGNAL(timeout()),
+ this, SLOT(tick()));
+ manageDelegates->setInterval(16);
+ manageDelegates->setSingleShot(false);
+ manageDelegates->start();
}
@@ -79,33 +87,54 @@ void QSGItemParticle::give(QSGItem *item)
void QSGItemParticle::load(QSGParticleData* d)
{
- if(m_pendingItems.isEmpty())
- return;
int pos = particleTypeIndex(d);
- if(m_items[pos]){
- if(m_stasis.contains(m_items[pos]))
- qWarning() << "Current model particles prefers overwrite:false";
- //remove old item from the particle that is dying to make room for this one
- m_items[pos]->setOpacity(0.);
+ m_data[pos] = d;
+ m_loadables << pos;
+}
+
+void QSGItemParticle::tick()
+{
+ foreach(QSGItem* item, m_deletables){
+ if(m_fade)
+ item->setOpacity(0.);
QSGItemParticleAttached* mpa;
- if((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[pos], false))))
+ if((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(item))))
mpa->detach();//reparent as well?
- m_items[pos] = 0;
- m_data[pos] = 0;
+ //TODO: Delete iff we created it
m_activeCount--;
+ m_deletables.removeAll(item);
}
- m_items[pos] = m_pendingItems.front();
- m_pendingItems.pop_front();
- m_items[pos]->setX(d->curX() - m_items[pos]->width()/2);
- m_items[pos]->setY(d->curY() - m_items[pos]->height()/2);
- QSGItemParticleAttached* mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[pos]));
- if(mpa){
- mpa->m_mp = this;
- mpa->attach();
+
+ foreach(int pos, m_loadables){
+ if(m_stasis.contains(m_items[pos]))
+ qWarning() << "Current model particles prefers overwrite:false";
+ //remove old item from the particle that is dying to make room for this one
+ if(m_items[pos]){
+ m_deletables << m_items[pos];
+ m_activeCount--;
+ }
+ m_items[pos] = 0;
+ if(!m_pendingItems.isEmpty()){
+ m_items[pos] = m_pendingItems.front();
+ m_pendingItems.pop_front();
+ }else if(m_delegate){
+ m_items[pos] = qobject_cast<QSGItem*>(m_delegate->create(qmlContext(this)));
+ }
+ if(m_items[pos]){
+ m_items[pos]->setX(m_data[pos]->curX() - m_items[pos]->width()/2);//TODO: adjust for system?
+ m_items[pos]->setY(m_data[pos]->curY() - m_items[pos]->height()/2);
+ QSGItemParticleAttached* mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[pos]));
+ if(mpa){
+ mpa->m_mp = this;
+ mpa->attach();
+ }
+ m_items[pos]->setParentItem(this);
+ if(m_fade)
+ m_items[pos]->setOpacity(0.);
+ m_activeCount++;
+ }
+ m_loadables.removeAll(pos);
}
- m_items[pos]->setParentItem(this);
- m_data[pos] = d;
- m_activeCount++;
}
void QSGItemParticle::reload(QSGParticleData* d)
@@ -173,10 +202,7 @@ void QSGItemParticle::prepareNextFrame()
continue;
}
if(t >= 1.0){//Usually happens from load
- item->setOpacity(0.);
- QSGItemParticleAttached* mpa;
- if((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[i]))))
- mpa->detach();//reparent as well?
+ m_deletables << item;
m_items[i] = 0;
m_data[i] = 0;
m_activeCount--;
diff --git a/src/declarative/particles/qsgitemparticle_p.h b/src/declarative/particles/qsgitemparticle_p.h
index fa3516b631..3b7db519de 100644
--- a/src/declarative/particles/qsgitemparticle_p.h
+++ b/src/declarative/particles/qsgitemparticle_p.h
@@ -55,8 +55,8 @@ class QSGItemParticleAttached;
class QSGItemParticle : public QSGParticlePainter
{
Q_OBJECT
-
Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged)
+ Q_PROPERTY(QDeclarativeComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
public:
explicit QSGItemParticle(QSGItem *parent = 0);
@@ -69,9 +69,16 @@ public:
virtual int count();
static QSGItemParticleAttached *qmlAttachedProperties(QObject *object);
+ QDeclarativeComponent* delegate() const
+ {
+ return m_delegate;
+ }
+
signals:
void fadeChanged();
+ void delegateChanged(QDeclarativeComponent* arg);
+
public slots:
//TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it?
void freeze(QSGItem* item);
@@ -80,11 +87,22 @@ public slots:
void give(QSGItem* item);//give from modelparticle
void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();}
+ void setDelegate(QDeclarativeComponent* arg)
+ {
+ if (m_delegate != arg) {
+ m_delegate = arg;
+ emit delegateChanged(arg);
+ }
+ }
+
protected:
virtual void reset();
void prepareNextFrame();
+private slots:
+ void tick();
private:
- QList<QPointer<QSGItem> > m_deletables;
+ QList<QSGItem* > m_deletables;
+ QList< int > m_loadables;
int m_particleCount;
bool m_fade;
@@ -96,6 +114,7 @@ private:
QSet<QSGItem*> m_stasis;
qreal m_lastT;
int m_activeCount;
+ QDeclarativeComponent* m_delegate;
};
class QSGItemParticleAttached : public QObject
diff --git a/src/declarative/particles/qsgmodelparticle.cpp b/src/declarative/particles/qsgmodelparticle.cpp
index 704b9a298c..b0b4fa4ad2 100644
--- a/src/declarative/particles/qsgmodelparticle.cpp
+++ b/src/declarative/particles/qsgmodelparticle.cpp
@@ -177,6 +177,7 @@ void QSGModelParticle::processPending()
foreach(QSGItem* item, m_deletables){
item->setOpacity(0.);
m_model->release(item);
+ m_deletables.removeAll(item);
}
foreach(int pos, m_requests){
@@ -189,6 +190,7 @@ void QSGModelParticle::processPending()
mpa->attach();
}
m_items[pos]->setParentItem(this);
+ m_requests.removeAll(pos);
}
}
diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp
index 20f3c6bb4b..143338f798 100644
--- a/src/declarative/particles/qsgparticleemitter.cpp
+++ b/src/declarative/particles/qsgparticleemitter.cpp
@@ -121,6 +121,13 @@ void QSGParticleEmitter::burst(int num)
m_burstQueue << qMakePair(num, QPointF(x(), y()));
}
+void QSGParticleEmitter::burst(int num, qreal x, qreal y)
+{
+ if(!particleCount())
+ qWarning() << "burst called on an emitter with a particle count of zero";
+ m_burstQueue << qMakePair(num, QPointF(x, y));
+}
+
void QSGParticleEmitter::setMaxParticleCount(int arg)
{
if (m_maxParticleCount != arg) {
diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h
index 9fafd9d43d..65aca0c83e 100644
--- a/src/declarative/particles/qsgparticleemitter_p.h
+++ b/src/declarative/particles/qsgparticleemitter_p.h
@@ -142,6 +142,7 @@ signals:
public slots:
void pulse(qreal seconds);
void burst(int num);
+ void burst(int num, qreal x, qreal y);
void setEmitting(bool arg);