172 p.x += interval * p.x_velocity; |
177 p.x += interval * p.x_velocity; |
173 p.y += interval * p.y_velocity; |
178 p.y += interval * p.y_velocity; |
174 } |
179 } |
175 |
180 |
176 /*! |
181 /*! |
177 \qmlclass ParticleMotionGravity |
182 \qmlclass ParticleMotionGravity QDeclarativeParticleMotionGravity |
178 \since 4.7 |
183 \since 4.7 |
179 \brief The ParticleMotionGravity object moves particles towards a point. |
184 \brief The ParticleMotionGravity object moves particles towards a point. |
|
185 |
|
186 This motion attracts the particles to the specified point with the specified acceleration. |
|
187 To mimic earth gravity, set yattractor to -6360000 and acceleration to 9.8. |
|
188 |
|
189 The defaults are all 0, not earth gravity, and so no motion will occur without setting |
|
190 at least the acceleration property. |
|
191 |
180 |
192 |
181 \sa Particles |
193 \sa Particles |
182 */ |
194 */ |
183 |
195 |
184 /*! |
196 /*! |
185 \internal |
197 \internal |
186 \class QDeclarativeParticleMotionGravity |
198 \class QDeclarativeParticleMotionGravity |
187 \ingroup group_effects |
199 \ingroup group_effects |
188 \brief The QDeclarativeParticleMotionGravity class moves the particles towards a point. |
200 \brief The QDeclarativeParticleMotionGravity class moves the particles towards a point. |
|
201 |
189 */ |
202 */ |
190 |
203 |
191 /*! |
204 /*! |
192 \qmlproperty real ParticleMotionGravity::xattractor |
205 \qmlproperty real ParticleMotionGravity::xattractor |
193 \qmlproperty real ParticleMotionGravity::yattractor |
206 \qmlproperty real ParticleMotionGravity::yattractor |
239 emit accelerationChanged(); |
252 emit accelerationChanged(); |
240 } |
253 } |
241 |
254 |
242 void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval) |
255 void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval) |
243 { |
256 { |
244 qreal xdiff = p.x - _xAttr; |
257 qreal xdiff = _xAttr - p.x; |
245 qreal ydiff = p.y - _yAttr; |
258 qreal ydiff = _yAttr - p.y; |
246 |
259 qreal absXdiff = qAbs(xdiff); |
247 qreal xcomp = xdiff / (xdiff + ydiff); |
260 qreal absYdiff = qAbs(ydiff); |
248 qreal ycomp = ydiff / (xdiff + ydiff); |
261 |
|
262 qreal xcomp = xdiff / (absXdiff + absYdiff); |
|
263 qreal ycomp = ydiff / (absXdiff + absYdiff); |
249 |
264 |
250 p.x_velocity += xcomp * _accel * interval; |
265 p.x_velocity += xcomp * _accel * interval; |
251 p.y_velocity += ycomp * _accel * interval; |
266 p.y_velocity += ycomp * _accel * interval; |
252 |
267 |
253 p.x += interval * p.x_velocity; |
268 p.x += interval * p.x_velocity; |
254 p.y += interval * p.y_velocity; |
269 p.y += interval * p.y_velocity; |
255 } |
270 } |
256 |
271 |
257 /*! |
272 /*! |
258 \qmlclass ParticleMotionWander |
273 \qmlclass ParticleMotionWander QDeclarativeParticleMotionWander |
259 \since 4.7 |
274 \since 4.7 |
260 \brief The ParticleMotionWander object moves particles in a somewhat random fashion. |
275 \brief The ParticleMotionWander object moves particles in a somewhat random fashion. |
261 |
276 |
262 The particles will continue roughly in the original direction, however will randomly |
277 The particles will continue roughly in the original direction, however will randomly |
263 drift to each side. |
278 drift to each side. |
301 The particles will continue roughly in the original direction, however will randomly |
316 The particles will continue roughly in the original direction, however will randomly |
302 drift to each side. |
317 drift to each side. |
303 */ |
318 */ |
304 |
319 |
305 /*! |
320 /*! |
306 \qmlproperty real QDeclarativeParticleMotionWander::xvariance |
321 \qmlproperty real ParticleMotionWander::xvariance |
307 \qmlproperty real QDeclarativeParticleMotionWander::yvariance |
322 \qmlproperty real ParticleMotionWander::yvariance |
308 |
323 |
309 These properties set the amount to wander in the x and y directions. |
324 These properties set the amount to wander in the x and y directions. |
310 */ |
325 */ |
311 |
326 |
312 /*! |
327 /*! |
313 \qmlproperty real QDeclarativeParticleMotionWander::pace |
328 \qmlproperty real ParticleMotionWander::pace |
314 This property holds how quickly the paricles will move from side to side. |
329 This property holds how quickly the paricles will move from side to side. |
315 */ |
330 */ |
316 |
331 |
317 void QDeclarativeParticleMotionWander::advance(QDeclarativeParticle &p, int interval) |
332 void QDeclarativeParticleMotionWander::advance(QDeclarativeParticle &p, int interval) |
318 { |
333 { |
433 QDeclarativeParticlesPrivate() |
448 QDeclarativeParticlesPrivate() |
434 : count(1), emissionRate(-1), emissionVariance(0.5), lifeSpan(1000) |
449 : count(1), emissionRate(-1), emissionVariance(0.5), lifeSpan(1000) |
435 , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300) |
450 , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300) |
436 , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.) |
451 , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.) |
437 , addParticleTime(0), addParticleCount(0), lastAdvTime(0) |
452 , addParticleTime(0), addParticleCount(0), lastAdvTime(0) |
438 , motion(0), pendingPixmapCache(false), clock(this) |
453 , motion(0), clock(this) |
439 { |
454 { |
440 } |
455 } |
441 |
456 |
442 ~QDeclarativeParticlesPrivate() |
457 ~QDeclarativeParticlesPrivate() |
443 { |
458 { |
471 int addParticleCount; |
486 int addParticleCount; |
472 int lastAdvTime; |
487 int lastAdvTime; |
473 QDeclarativeParticleMotion *motion; |
488 QDeclarativeParticleMotion *motion; |
474 QDeclarativeParticlesPainter *paintItem; |
489 QDeclarativeParticlesPainter *paintItem; |
475 |
490 |
476 bool pendingPixmapCache; |
|
477 |
491 |
478 QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs |
492 QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs |
479 QList<QDeclarativeParticle> particles; |
493 QList<QDeclarativeParticle> particles; |
480 TickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock; |
494 TickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock; |
481 |
495 |
728 } |
739 } |
729 |
740 |
730 void QDeclarativeParticles::imageLoaded() |
741 void QDeclarativeParticles::imageLoaded() |
731 { |
742 { |
732 Q_D(QDeclarativeParticles); |
743 Q_D(QDeclarativeParticles); |
733 d->pendingPixmapCache = false; |
744 if (d->image.isError()) |
734 QString errorString; |
745 qmlInfo(this) << d->image.error(); |
735 if (QDeclarativePixmapCache::get(d->url, &d->image, &errorString)==QDeclarativePixmapReply::Error) |
|
736 qmlInfo(this) << errorString; |
|
737 d->paintItem->updateSize(); |
746 d->paintItem->updateSize(); |
738 d->paintItem->update(); |
747 d->paintItem->update(); |
739 } |
748 } |
740 |
749 |
741 void QDeclarativeParticles::setSource(const QUrl &name) |
750 void QDeclarativeParticles::setSource(const QUrl &name) |
743 Q_D(QDeclarativeParticles); |
752 Q_D(QDeclarativeParticles); |
744 |
753 |
745 if ((d->url.isEmpty() == name.isEmpty()) && name == d->url) |
754 if ((d->url.isEmpty() == name.isEmpty()) && name == d->url) |
746 return; |
755 return; |
747 |
756 |
748 if (d->pendingPixmapCache) { |
|
749 QDeclarativePixmapCache::cancel(d->url, this); |
|
750 d->pendingPixmapCache = false; |
|
751 } |
|
752 if (name.isEmpty()) { |
757 if (name.isEmpty()) { |
753 d->url = name; |
758 d->url = name; |
754 d->image = QPixmap(); |
759 d->image.clear(this); |
755 d->paintItem->updateSize(); |
760 d->paintItem->updateSize(); |
756 d->paintItem->update(); |
761 d->paintItem->update(); |
757 } else { |
762 } else { |
758 d->url = name; |
763 d->url = name; |
759 Q_ASSERT(!name.isRelative()); |
764 Q_ASSERT(!name.isRelative()); |
760 QString errorString; |
765 d->image.load(qmlEngine(this), d->url); |
761 QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->image, &errorString); |
766 if (d->image.isLoading()) { |
762 if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) { |
767 d->image.connectFinished(this, SLOT(imageLoaded())); |
763 QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url); |
|
764 connect(reply, SIGNAL(finished()), this, SLOT(imageLoaded())); |
|
765 d->pendingPixmapCache = true; |
|
766 } else { |
768 } else { |
767 if (status == QDeclarativePixmapReply::Error) |
769 if (d->image.isError()) |
768 qmlInfo(this) << errorString; |
770 qmlInfo(this) << d->image.error(); |
769 //### unify with imageLoaded |
771 //### unify with imageLoaded |
770 d->paintItem->updateSize(); |
772 d->paintItem->updateSize(); |
771 d->paintItem->update(); |
773 d->paintItem->update(); |
772 } |
774 } |
773 } |
775 } |
1282 return; |
1284 return; |
1283 |
1285 |
1284 const int myX = x() + parentItem()->x(); |
1286 const int myX = x() + parentItem()->x(); |
1285 const int myY = y() + parentItem()->y(); |
1287 const int myY = y() + parentItem()->y(); |
1286 |
1288 |
1287 #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) |
|
1288 QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData; |
1289 QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData; |
1289 #else |
|
1290 QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData; |
|
1291 #endif |
|
1292 pixmapData.resize(d->particles.count()); |
1290 pixmapData.resize(d->particles.count()); |
1293 |
1291 |
1294 const QRectF sourceRect = d->image.rect(); |
1292 const QRectF sourceRect = d->image.rect(); |
1295 qreal halfPWidth = sourceRect.width()/2.; |
1293 qreal halfPWidth = sourceRect.width()/2.; |
1296 qreal halfPHeight = sourceRect.height()/2.; |
1294 qreal halfPHeight = sourceRect.height()/2.; |
1297 for (int i = 0; i < d->particles.count(); ++i) { |
1295 for (int i = 0; i < d->particles.count(); ++i) { |
1298 const QDeclarativeParticle &particle = d->particles.at(i); |
1296 const QDeclarativeParticle &particle = d->particles.at(i); |
1299 #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) |
|
1300 pixmapData[i].x = particle.x - myX + halfPWidth; |
1297 pixmapData[i].x = particle.x - myX + halfPWidth; |
1301 pixmapData[i].y = particle.y - myY + halfPHeight; |
1298 pixmapData[i].y = particle.y - myY + halfPHeight; |
1302 #else |
|
1303 pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight); |
|
1304 #endif |
|
1305 pixmapData[i].opacity = particle.opacity; |
1299 pixmapData[i].opacity = particle.opacity; |
1306 |
1300 |
1307 //these never change |
1301 //these never change |
1308 pixmapData[i].rotation = 0; |
1302 pixmapData[i].rotation = 0; |
1309 pixmapData[i].scaleX = 1; |
1303 pixmapData[i].scaleX = 1; |
1310 pixmapData[i].scaleY = 1; |
1304 pixmapData[i].scaleY = 1; |
1311 #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) |
|
1312 pixmapData[i].sourceLeft = sourceRect.left(); |
1305 pixmapData[i].sourceLeft = sourceRect.left(); |
1313 pixmapData[i].sourceTop = sourceRect.top(); |
1306 pixmapData[i].sourceTop = sourceRect.top(); |
1314 pixmapData[i].width = sourceRect.width(); |
1307 pixmapData[i].width = sourceRect.width(); |
1315 pixmapData[i].height = sourceRect.height(); |
1308 pixmapData[i].height = sourceRect.height(); |
1316 #else |
1309 } |
1317 pixmapData[i].source = sourceRect; |
|
1318 #endif |
|
1319 } |
|
1320 #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) |
|
1321 p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image); |
1310 p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image); |
1322 #else |
|
1323 qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image); |
|
1324 #endif |
|
1325 } |
1311 } |
1326 |
1312 |
1327 void QDeclarativeParticles::componentComplete() |
1313 void QDeclarativeParticles::componentComplete() |
1328 { |
1314 { |
1329 Q_D(QDeclarativeParticles); |
1315 Q_D(QDeclarativeParticles); |