summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2009-11-05 04:03:47 (GMT)
committerAlan Alpert <alan.alpert@nokia.com>2009-11-05 04:46:23 (GMT)
commit0ef5d89b540be963d1a8131f6625f990a4fe66e8 (patch)
treefe640558b514dc1720525043b954aeafe3d15940
parent0ced984d3e2cb2a7a1a219ae7a9b09ff4e15a55c (diff)
downloadQt-0ef5d89b540be963d1a8131f6625f990a4fe66e8.zip
Qt-0ef5d89b540be963d1a8131f6625f990a4fe66e8.tar.gz
Qt-0ef5d89b540be963d1a8131f6625f990a4fe66e8.tar.bz2
Particles cleaned up and placed in in qmlgraphics/
API changes: Removed bool streamIn Added int emissionRate Added int emissionVariance Added void burst(count, emissionRate=-1) While rewriting the internals to accomodate this, all other outstanding particles bugs were believed fixed. Task-number: QT-2392 QT-2391 QT-2390 QT-2406
-rw-r--r--demos/declarative/minehunt/Explosion.qml7
-rw-r--r--demos/declarative/samegame/content/BoomBlock.qml12
-rw-r--r--doc/src/declarative/advtutorial4.qdoc6
-rw-r--r--examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml13
-rw-r--r--src/declarative/QmlChanges.txt2
-rw-r--r--src/declarative/extra/extra.pri2
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri2
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsparticles.cpp (renamed from src/declarative/extra/qmlgraphicsparticles.cpp)290
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsparticles_p.h (renamed from src/declarative/extra/qmlgraphicsparticles_p.h)52
-rw-r--r--tests/auto/declarative/qmlgraphicsparticles/data/particles.qml2
-rw-r--r--tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp7
11 files changed, 282 insertions, 113 deletions
diff --git a/demos/declarative/minehunt/Explosion.qml b/demos/declarative/minehunt/Explosion.qml
index a997048..e337c46 100644
--- a/demos/declarative/minehunt/Explosion.qml
+++ b/demos/declarative/minehunt/Explosion.qml
@@ -16,13 +16,10 @@ Item {
velocity: 100
velocityDeviation: 20
z: 100
- opacity: 0
- streamIn: false
+ opacity: 1
}
states: [ State { name: "exploding"; when: explode == true
- PropertyChanges { target: particles; count: 200 }
- PropertyChanges { target: particles; opacity: 1 }
- PropertyChanges { target: particles; emitting: false } // i.e. emit only once
+ StateChangeScript {script: particles.burst(200); }
}
]
diff --git a/demos/declarative/samegame/content/BoomBlock.qml b/demos/declarative/samegame/content/BoomBlock.qml
index b0c297b..723e62a 100644
--- a/demos/declarative/samegame/content/BoomBlock.qml
+++ b/demos/declarative/samegame/content/BoomBlock.qml
@@ -26,9 +26,11 @@ Item { id:block
}
Particles { id: particles
- width:1; height:1; anchors.centerIn: parent; opacity: 0
- lifeSpan: 700; lifeSpanDeviation: 600; count:0; streamIn: false
- angle: 0; angleDeviation: 360; velocity: 100; velocityDeviation:30
+ width:1; height:1; anchors.centerIn: parent;
+ emissionRate: 0;
+ lifeSpan: 700; lifeSpanDeviation: 600;
+ angle: 0; angleDeviation: 360;
+ velocity: 100; velocityDeviation:30;
source: {
if(type == 0){
"pics/redStar.png";
@@ -45,9 +47,7 @@ Item { id:block
PropertyChanges { target: img; opacity: 1 }
},
State{ name: "DeathState"; when: dying == true
- PropertyChanges { target: particles; count: 50 }
- PropertyChanges { target: particles; opacity: 1 }
- PropertyChanges { target: particles; emitting: false } // i.e. emit only once
+ StateChangeScript { script: particles.burst(50); }
PropertyChanges { target: img; opacity: 0 }
StateChangeScript { script: block.destroy(1000); }
}
diff --git a/doc/src/declarative/advtutorial4.qdoc b/doc/src/declarative/advtutorial4.qdoc
index e30fe84..5f8c0e9 100644
--- a/doc/src/declarative/advtutorial4.qdoc
+++ b/doc/src/declarative/advtutorial4.qdoc
@@ -106,9 +106,9 @@ the block, like so:
\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 3
-To fully understand this you'll want to look at the Particles element documentation, but it's important to note that count is set
-to zero.
-We next extend the 'dying' state, which triggers the particles by setting the count to non-zero. The code for the states now look
+To fully understand this you'll want to look at the Particles element documentation, but it's important to note that emissionRate is set
+to zero, so that no particles are emitted normally.
+We next extend the 'dying' state, which creates a burst of particles by calling the burst method on the particles element. The code for the states now look
like this:
\snippet declarative/tutorials/samegame/samegame4/content/BoomBlock.qml 4
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml
index 7ad8b07..4c2ba43 100644
--- a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml
+++ b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml
@@ -31,9 +31,11 @@ Item { id:block
//![3]
Particles { id: particles
- width:1; height:1; anchors.centerIn: parent; opacity: 0
- lifeSpan: 700; lifeSpanDeviation: 600; count:0; streamIn: false
- angle: 0; angleDeviation: 360; velocity: 100; velocityDeviation:30
+ width:1; height:1; anchors.centerIn: parent;
+ emissionRate: 0;
+ lifeSpan: 700; lifeSpanDeviation: 600;
+ angle: 0; angleDeviation: 360;
+ velocity: 100; velocityDeviation:30;
source: {
if(type == 0){
"pics/redStar.png";
@@ -52,10 +54,9 @@ Item { id:block
PropertyChanges { target: img; opacity: 1 }
},
State{ name: "DeathState"; when: dying == true
- PropertyChanges { target: particles; count: 50 }
- PropertyChanges { target: particles; opacity: 1 }
- PropertyChanges { target: particles; emitting: false } // i.e. emit only once
+ StateChangeScript { script: particles.burst(50); }
PropertyChanges { target: img; opacity: 0 }
+ StateChangeScript { script: block.destroy(1000); }
}
]
//![4]
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt
index 465ee9e..c85ef77 100644
--- a/src/declarative/QmlChanges.txt
+++ b/src/declarative/QmlChanges.txt
@@ -82,6 +82,7 @@ Loader: add sourceComponent property
Loader: add resizeMode property
ListView: preferredHighlightBegin, preferredHighlightEnd
ListView: strictlyEnforceHighlightRange
+Particles: Added emissionRate, emissionVariance and burst()
Deletions:
Column/VerticalPositioner: lost "margins" property
@@ -92,6 +93,7 @@ Flickable: removed "dragMode" property
ComponentInstance: removed. Replaced by Loader.sourceComponent
ListView: removed currentItemMode. Replaced by highligh range.
ListView: removed snapPos.
+Particles: removed streamIn. Replaced by emissionRate
Other Changes:
ids must be lowercase: Text { id: foo }, not Text { id: Foo }
diff --git a/src/declarative/extra/extra.pri b/src/declarative/extra/extra.pri
index 9d0e760..a81416d 100644
--- a/src/declarative/extra/extra.pri
+++ b/src/declarative/extra/extra.pri
@@ -4,7 +4,6 @@ SOURCES += \
extra/qmldatetimeformatter.cpp \
extra/qmlgraphicsintegermodel.cpp \
extra/qmlgraphicsanimatedimageitem.cpp \
- extra/qmlgraphicsparticles.cpp \
extra/qmlbehavior.cpp \
extra/qmlfontloader.cpp
@@ -15,7 +14,6 @@ HEADERS += \
extra/qmlgraphicsintegermodel_p.h \
extra/qmlgraphicsanimatedimageitem_p.h \
extra/qmlgraphicsanimatedimageitem_p_p.h \
- extra/qmlgraphicsparticles_p.h \
extra/qmlbehavior_p.h \
extra/qmlfontloader_p.h
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index cf71451..3c4e39a 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -42,6 +42,7 @@ HEADERS += \
graphicsitems/qmlgraphicsvisualitemmodel_p.h \
graphicsitems/qmlgraphicslistview_p.h \
graphicsitems/qmlgraphicsgraphicsobjectcontainer_p.h \
+ graphicsitems/qmlgraphicsparticles_p.h \
graphicsitems/qmlgraphicslayoutitem_p.h \
graphicsitems/qmlgraphicseffects.cpp
@@ -72,6 +73,7 @@ SOURCES += \
graphicsitems/qmlgraphicsvisualitemmodel.cpp \
graphicsitems/qmlgraphicslistview.cpp \
graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp \
+ graphicsitems/qmlgraphicsparticles.cpp \
graphicsitems/qmlgraphicslayoutitem.cpp \
contains(QT_CONFIG, webkit) {
diff --git a/src/declarative/extra/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp
index 0349a4e..d906fd3 100644
--- a/src/declarative/extra/qmlgraphicsparticles.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp
@@ -368,9 +368,10 @@ class QmlGraphicsParticlesPrivate : public QmlGraphicsItemPrivate
Q_DECLARE_PUBLIC(QmlGraphicsParticles)
public:
QmlGraphicsParticlesPrivate()
- : count(1), lifeSpan(1000), lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300)
- , angle(0), angleDev(0), velocity(0), velocityDev(0)
- , addParticleTime(0), addParticleCount(0), lastAdvTime(0), stream(false), streamDelay(0)
+ : 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)
, emitting(true), motion(0), pendingPixmapCache(false), clock(this)
{
}
@@ -392,6 +393,8 @@ public:
QUrl url;
QPixmap image;
int count;
+ int emissionRate;
+ qreal emissionVariance;
int lifeSpan;
int lifeSpanDev;
int fadeInDur;
@@ -400,17 +403,17 @@ public:
qreal angleDev;
qreal velocity;
qreal velocityDev;
+ qreal emissionCarry;
int addParticleTime;
int addParticleCount;
int lastAdvTime;
- bool stream;
- int streamDelay;
bool emitting;
QmlGraphicsParticleMotion *motion;
QmlGraphicsParticlesPainter *paintItem;
bool pendingPixmapCache;
+ QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs
QList<QmlGraphicsParticle> particles;
QTickAnimationProxy<QmlGraphicsParticlesPrivate, &QmlGraphicsParticlesPrivate::tick> clock;
@@ -439,40 +442,62 @@ void QmlGraphicsParticlesPrivate::tick(int time)
}
}
- while(removed-- && particles.count() < count && emitting)
- createParticle(time);
+ if(emissionRate == -1)//Otherwise leave emission to the emission rate
+ while(removed-- && ((count == -1) || particles.count() < count) && emitting)
+ createParticle(time);
if (!addParticleTime)
addParticleTime = time;
- if (particles.count() < count && emitting) {
- qreal perc = (lifeSpanDev <= 0)?(1.):(qreal(time - addParticleTime) / qreal(lifeSpanDev));
- int percCount = addParticleCount + (int)perc * (count - addParticleCount);
- int streamWidth = -1;
- if (stream){
- if (streamDelay > time){
- streamWidth = 0;
- }else{
- int missed = time - streamDelay;
- qreal streamWidthReal = qreal(count)/qreal(lifeSpan);
- if (streamWidthReal < 1){
- streamDelay = time + (int)(1.0/streamWidthReal);
- streamWidth = 1;
- streamWidth += missed/streamDelay;
- }else{
- streamWidth = qRound(streamWidthReal * (time-lastAdvTime));
- }
+ //Possibly emit new particles
+ if (((count == -1) || particles.count() < count) && emitting
+ && !(count==-1 && emissionRate==-1)) {
+ int emissionCount = -1;
+ if (emissionRate != -1){
+ qreal variance = 1.;
+ if (emissionVariance > 0.){
+ variance += (qreal(rand())/RAND_MAX) * emissionVariance * (rand()%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(rand())/RAND_MAX) * emissionVariance * (rand()%2?-1.:1.);
}
+ qreal workingEmission = bursts[i].second * (qreal(interval)/1000.);
+ workingEmission *= variance;
+ emission = (int)workingEmission;
+ emission = qMax(emission, 0);
}
- while(particles.count() < count &&
- (!stream || (particles.count() < percCount && streamWidth--)))
+ 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 || !emitting)) {
+ if (!(oldCount || particles.count()) && (!count || !emitting) && bursts.isEmpty()) {
lastAdvTime = 0;
clock.stop();
}
@@ -541,6 +566,8 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Particles,QmlGraphicsParticles)
\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
@@ -675,16 +702,27 @@ void QmlGraphicsParticles::setSource(const QUrl &name)
d->paintItem->update();
}
}
+ emit sourceChanged();
}
/*!
\qmlproperty int Particles::count
- This property holds the target number of particles
+ 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 theend 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.
+
+ If both count and emissionRate are set to -1, nothing will be emitted.
+
*/
/*!
\property QmlGraphicsParticles::count
- \brief the target number of particles
+ \brief the maximum number of particles
*/
int QmlGraphicsParticles::count() const
{
@@ -702,11 +740,93 @@ void QmlGraphicsParticles::setCount(int cnt)
d->count = cnt;
d->addParticleTime = 0;
d->addParticleCount = d->particles.count();
- if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count) {
+ if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emitting) {
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 QmlGraphicsParticles::emissionRate
+ \brief the emission rate of particles
+*/
+int QmlGraphicsParticles::emissionRate() const
+{
+ Q_D(const QmlGraphicsParticles);
+ return d->emissionRate;
+}
+void QmlGraphicsParticles::setEmissionRate(int er)
+{
+ Q_D(QmlGraphicsParticles);
+ if(er == d->emissionRate)
+ return;
+ d->emissionRate = er;
+ 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 QmlGraphicsParticles::emissionVariance
+ \brief how much the particle emission amounts vary per tick
+*/
+
+qreal QmlGraphicsParticles::emissionVariance() const
+{
+ Q_D(const QmlGraphicsParticles);
+ return d->emissionVariance;
+}
+
+void QmlGraphicsParticles::setEmissionVariance(qreal ev)
+{
+ Q_D(QmlGraphicsParticles);
+ if(d->emissionVariance == ev)
+ return;
+ d->emissionVariance = ev;
+ emit emissionVarianceChanged();
}
/*!
@@ -747,7 +867,10 @@ int QmlGraphicsParticles::lifeSpan() const
void QmlGraphicsParticles::setLifeSpan(int ls)
{
Q_D(QmlGraphicsParticles);
+ if(d->lifeSpan == ls)
+ return;
d->lifeSpan = ls;
+ emit lifeSpanChanged();
}
/*!
@@ -777,7 +900,10 @@ int QmlGraphicsParticles::lifeSpanDeviation() const
void QmlGraphicsParticles::setLifeSpanDeviation(int dev)
{
Q_D(QmlGraphicsParticles);
+ if(d->lifeSpanDev == dev)
+ return;
d->lifeSpanDev = dev;
+ emit lifeSpanDeviationChanged();
}
/*!
@@ -803,8 +929,10 @@ int QmlGraphicsParticles::fadeInDuration() const
void QmlGraphicsParticles::setFadeInDuration(int dur)
{
Q_D(QmlGraphicsParticles);
- if (dur >= 0.0)
- d->fadeInDur = dur;
+ if (dur < 0.0 || dur == d->fadeInDur)
+ return;
+ d->fadeInDur = dur;
+ emit fadeInDurationChanged();
}
/*!
@@ -822,8 +950,10 @@ int QmlGraphicsParticles::fadeOutDuration() const
void QmlGraphicsParticles::setFadeOutDuration(int dur)
{
Q_D(QmlGraphicsParticles);
- if (dur >= 0.0)
- d->fadeOutDur = dur;
+ if (dur < 0.0 || d->fadeOutDur == dur)
+ return;
+ d->fadeOutDur = dur;
+ emit fadeOutDurationChanged();
}
/*!
@@ -860,7 +990,11 @@ qreal QmlGraphicsParticles::angle() const
void QmlGraphicsParticles::setAngle(qreal angle)
{
Q_D(QmlGraphicsParticles);
- d->angle = angle * M_PI / 180.0;
+ qreal radAngle = angle * M_PI / 180.0;
+ if(radAngle == d->angle)
+ return;
+ d->angle = radAngle;
+ emit angleChanged();
}
/*!
@@ -890,7 +1024,11 @@ qreal QmlGraphicsParticles::angleDeviation() const
void QmlGraphicsParticles::setAngleDeviation(qreal dev)
{
Q_D(QmlGraphicsParticles);
- d->angleDev = dev * M_PI / 180.0;;
+ qreal radDev = dev * M_PI / 180.0;
+ if(radDev == d->angleDev)
+ return;
+ d->angleDev = radDev;
+ emit angleDeviationChanged();
}
/*!
@@ -927,7 +1065,11 @@ qreal QmlGraphicsParticles::velocity() const
void QmlGraphicsParticles::setVelocity(qreal velocity)
{
Q_D(QmlGraphicsParticles);
- d->velocity = velocity / 1000.0;
+ qreal realVel = velocity / 1000.0;
+ if(realVel == d->velocity)
+ return;
+ d->velocity = realVel;
+ emit velocityChanged();
}
/*!
@@ -957,38 +1099,11 @@ qreal QmlGraphicsParticles::velocityDeviation() const
void QmlGraphicsParticles::setVelocityDeviation(qreal velocity)
{
Q_D(QmlGraphicsParticles);
- d->velocityDev = velocity / 1000.0;
-}
-
-/*!
- \qmlproperty bool Particles::streamIn
- This property determines whether the particles stream in at a constant rate
-
- When stream is set to true the particles will stream in at a constant rate.
- Otherwise the particles will appear as a clump. Note that this only affects the
- start of the particle effect, variables such as lifespan deviation can cause the
- particles to unclump over time.
-*/
-/*!
- \property QmlGraphicsParticles::streamIn
- \brief determines whether the particles stream in at a constant rate
-
- When stream is set to true the particles will stream in at a constant rate.
- Otherwise the particles will appear as a clump. Note that this only affects the
- start of the particle effect, variables such as lifespan deviation can cause the
-
-*/
-//The name may need a rethink
-bool QmlGraphicsParticles::streamIn() const
-{
- Q_D(const QmlGraphicsParticles);
- return d->stream;
-}
-
-void QmlGraphicsParticles::setStreamIn(bool b)
-{
- Q_D(QmlGraphicsParticles);
- d->stream = b;
+ qreal realDev = velocity / 1000.0;
+ if(realDev == d->velocityDev)
+ return;
+ d->velocityDev = realDev;
+ emit velocityDeviationChanged();
}
/*!
@@ -1020,9 +1135,12 @@ bool QmlGraphicsParticles::emitting() const
void QmlGraphicsParticles::setEmitting(bool r)
{
Q_D(QmlGraphicsParticles);
+ if(d->emitting == r)
+ return;
d->emitting = r;
if (d->count && r)
d->clock.start();
+ emit emittingChanged();
}
/*!
\qmlproperty ParticleMotion Particles::motion
@@ -1057,6 +1175,31 @@ void QmlGraphicsParticles::setMotion(QmlGraphicsParticleMotion *motion)
d->motion = motion;
}
+/*!
+ \qmlmethod Particles::burst
+
+ 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 and emitting.
+
+ 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 QmlGraphicsParticles::burst(int count, int emissionRate)
+{
+ Q_D(QmlGraphicsParticles);
+ d->bursts << qMakePair(count, emissionRate);
+ if (d->clock.state() != QAbstractAnimation::Running && d->emitting)
+ d->clock.start();
+}
+
void QmlGraphicsParticlesPainter::updateSize()
{
if (!isComponentComplete())
@@ -1100,14 +1243,15 @@ void QmlGraphicsParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsI
const int myX = x() + parentItem()->x();
const int myY = y() + parentItem()->y();
- static QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData;
- if (pixmapData.count() < d->particles.count())
- pixmapData.resize(d->particles.count());
+ QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData;
+ 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 QmlGraphicsParticle &particle = d->particles.at(i);
- pixmapData[i].point = QPointF(particle.x - myX, particle.y - myY);
+ pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight);
pixmapData[i].opacity = particle.opacity;
//these never change
diff --git a/src/declarative/extra/qmlgraphicsparticles_p.h b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h
index 9eca762..851edd7 100644
--- a/src/declarative/extra/qmlgraphicsparticles_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h
@@ -145,18 +145,19 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsParticles : public QmlGraphicsItem
{
Q_OBJECT
- Q_PROPERTY(QUrl source READ source WRITE setSource)
- Q_PROPERTY(int count READ count WRITE setCount)
- Q_PROPERTY(int lifeSpan READ lifeSpan WRITE setLifeSpan)
- Q_PROPERTY(int lifeSpanDeviation READ lifeSpanDeviation WRITE setLifeSpanDeviation)
- Q_PROPERTY(int fadeInDuration READ fadeInDuration WRITE setFadeInDuration)
- Q_PROPERTY(int fadeOutDuration READ fadeOutDuration WRITE setFadeOutDuration)
- Q_PROPERTY(qreal angle READ angle WRITE setAngle)
- Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation)
- Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity)
- Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation)
- Q_PROPERTY(bool streamIn READ streamIn WRITE setStreamIn)
- Q_PROPERTY(bool emitting READ emitting WRITE setEmitting)
+ 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(bool emitting READ emitting WRITE setEmitting NOTIFY emittingChanged)
Q_PROPERTY(QmlGraphicsParticleMotion *motion READ motion WRITE setMotion)
Q_CLASSINFO("DefaultProperty", "motion")
@@ -170,6 +171,12 @@ public:
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);
@@ -194,9 +201,6 @@ public:
qreal velocityDeviation() const;
void setVelocityDeviation(qreal);
- bool streamIn() const;
- void setStreamIn(bool);
-
bool emitting() const;
void setEmitting(bool);
@@ -205,10 +209,28 @@ public:
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+public Q_SLOTS:
+ void burst(int count, int emissionRate=-1);
+
protected:
virtual void componentComplete();
QmlGraphicsParticles(QmlGraphicsParticlesPrivate &dd, QmlGraphicsItem *parent);
+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();
+
private Q_SLOTS:
void imageLoaded();
diff --git a/tests/auto/declarative/qmlgraphicsparticles/data/particles.qml b/tests/auto/declarative/qmlgraphicsparticles/data/particles.qml
index dccd2c7..c58927e 100644
--- a/tests/auto/declarative/qmlgraphicsparticles/data/particles.qml
+++ b/tests/auto/declarative/qmlgraphicsparticles/data/particles.qml
@@ -8,7 +8,7 @@ Rectangle{
objectName: "particles"
width:1; height:1; anchors.centerIn: parent; opacity: 1
lifeSpan: 100; lifeSpanDeviation: 20; count:1000;
- fadeInDuration: 20; fadeOutDuration: 20;
+ fadeInDuration: 20; fadeOutDuration: 20; count: -1; emissionRate: 1000
angle: 0; angleDeviation: 360; velocity: 500; velocityDeviation:30
source: "particle.png"
}
diff --git a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp
index e50437a..ed68eaf 100644
--- a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp
+++ b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp
@@ -91,8 +91,11 @@ void tst_QmlGraphicsParticles::properties()
particles->setVelocityDeviation(100.0);
QCOMPARE(particles->velocityDeviation(), 100.0);
- particles->setEmitting(false);
- QCOMPARE(particles->emitting(), false);
+ particles->setEmissionVariance(0.5);
+ QCOMPARE(particles->emissionVariance(),0.5);
+
+ particles->setEmissionRate(12);
+ QCOMPARE(particles->emissionRate(), 12);
}
void tst_QmlGraphicsParticles::runs()