aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-05-23 15:16:00 +1000
committerAlan Alpert <alan.alpert@nokia.com>2011-05-23 15:16:00 +1000
commit52d1ff7d3f302d3f4fc84085e4c4c9bd31c4e359 (patch)
treef393b3dc07c8efcf2617ceb6ad80adb9a4e83d53
parent2c5df92e860f8fba494b62ce6ee619766f004490 (diff)
Split up ModelParticle
Now has DataParticle (with model and delegate) and an ItemParticle (which you just feed items manually). ModelParticle left for now for damage control - it will probably just disappear someday.
-rw-r--r--demos/declarative/flickr/content/StreamView.qml2
-rw-r--r--examples/declarative/particles/modelparticles/bubbles.qml2
-rw-r--r--examples/declarative/particles/modelparticles/gridsplosion.qml2
-rw-r--r--examples/declarative/particles/modelparticles/package.qml2
-rw-r--r--examples/declarative/particles/modelparticles/stream.qml3
-rw-r--r--src/imports/particles/dataparticle.cpp274
-rw-r--r--src/imports/particles/dataparticle.h145
-rw-r--r--src/imports/particles/itemparticle.cpp205
-rw-r--r--src/imports/particles/itemparticle.h126
-rw-r--r--src/imports/particles/main.cpp4
-rw-r--r--src/imports/particles/modelparticle.cpp1
-rw-r--r--src/imports/particles/particles.pro8
-rw-r--r--src/imports/particles/particlesystem.cpp2
-rw-r--r--src/imports/particles/particlesystem.h4
14 files changed, 772 insertions, 8 deletions
diff --git a/demos/declarative/flickr/content/StreamView.qml b/demos/declarative/flickr/content/StreamView.qml
index 26384d3c07..26a3f35e63 100644
--- a/demos/declarative/flickr/content/StreamView.qml
+++ b/demos/declarative/flickr/content/StreamView.qml
@@ -52,7 +52,7 @@ Item{
anchors.fill:parent
overwrite: false
}
- ModelParticle{
+ DataParticle{
id: mp
fade: false
system: sys
diff --git a/examples/declarative/particles/modelparticles/bubbles.qml b/examples/declarative/particles/modelparticles/bubbles.qml
index 711d52d522..80d03a9ea7 100644
--- a/examples/declarative/particles/modelparticles/bubbles.qml
+++ b/examples/declarative/particles/modelparticles/bubbles.qml
@@ -70,7 +70,7 @@ Item{
system: sys
xDrift: 200
}
- ModelParticle{
+ DataParticle{
id: mp
z: 0
system: sys
diff --git a/examples/declarative/particles/modelparticles/gridsplosion.qml b/examples/declarative/particles/modelparticles/gridsplosion.qml
index a654124587..d45ef392e0 100644
--- a/examples/declarative/particles/modelparticles/gridsplosion.qml
+++ b/examples/declarative/particles/modelparticles/gridsplosion.qml
@@ -80,7 +80,7 @@ Item{
width: 120
height: 120
}
- ModelParticle{
+ DataParticle{
system: sys
model: theModel.parts.particles
}
diff --git a/examples/declarative/particles/modelparticles/package.qml b/examples/declarative/particles/modelparticles/package.qml
index 402cdea84a..d5c104b480 100644
--- a/examples/declarative/particles/modelparticles/package.qml
+++ b/examples/declarative/particles/modelparticles/package.qml
@@ -69,7 +69,7 @@ Rectangle {
width: 200; height:200
model: visualModel.parts.list
}
- ModelParticle{
+ DataParticle{
x: 200; width: 200; height:200
model: visualModel.parts.grid
system: sys
diff --git a/examples/declarative/particles/modelparticles/stream.qml b/examples/declarative/particles/modelparticles/stream.qml
index b67d6c42af..4a697184d2 100644
--- a/examples/declarative/particles/modelparticles/stream.qml
+++ b/examples/declarative/particles/modelparticles/stream.qml
@@ -94,7 +94,7 @@ Item{
colorVariation: 0
z: 1000
}
- ModelParticle{
+ ItemParticle{
id: mp
z: 0
system: sys
@@ -231,6 +231,7 @@ Item{
fillMode: Image.PreserveAspectFit;
width: parent.width-4; height: parent.height-4
onStatusChanged: if(img.status == Image.Ready){
+ container.opacity = 0;
loading.opacity = 0;
mp.take(container);
}
diff --git a/src/imports/particles/dataparticle.cpp b/src/imports/particles/dataparticle.cpp
new file mode 100644
index 0000000000..a2965e8c71
--- /dev/null
+++ b/src/imports/particles/dataparticle.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** 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 Declarative 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 "dataparticle.h"
+#include <QtDeclarative/private/qsgvisualitemmodel_p.h>
+#include <qsgnode.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+DataParticle::DataParticle(QSGItem *parent) :
+ ParticleType(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true), m_modelCount(0)
+{
+ setFlag(QSGItem::ItemHasContents);
+}
+
+QVariant DataParticle::model() const
+{
+ return m_dataSource;
+}
+
+void DataParticle::setModel(const QVariant &arg)
+{
+ if(arg == m_dataSource)
+ return;
+ m_dataSource = arg;
+ if(qobject_cast<QSGVisualDataModel*>(arg.value<QObject*>())) {
+ if(m_ownModel && m_model)
+ delete m_model;
+ m_model = qobject_cast<QSGVisualDataModel*>(arg.value<QObject*>());
+ m_ownModel = false;
+ }else{
+ if(!m_model || !m_ownModel)
+ m_model = new QSGVisualDataModel(qmlContext(this));
+ m_model->setModel(m_dataSource);
+ m_ownModel = true;
+ }
+ if(m_comp)
+ m_model->setDelegate(m_comp);
+ emit modelChanged();
+ emit modelCountChanged();
+ connect(m_model, SIGNAL(countChanged()),
+ this, SIGNAL(modelCountChanged()));
+ connect(m_model, SIGNAL(countChanged()),
+ this, SLOT(updateCount()));
+ updateCount();
+}
+
+void DataParticle::updateCount()
+{
+ int newCount = 0;
+ if(m_model)
+ newCount = m_model->count();
+ if(newCount < 0)
+ return;//WTF?
+ if(m_modelCount == 0 || newCount == 0){
+ m_available.clear();
+ for(int i=0; i<newCount; i++)
+ m_available << i;
+ }else if(newCount < m_modelCount){
+ for(int i=newCount; i<m_modelCount; i++) //existing ones must leave normally, but aren't readded
+ m_available.removeAll(i);
+ }else if(newCount > m_modelCount){
+ for(int i=m_modelCount; i<newCount; i++)
+ m_available << i;
+ }
+ m_modelCount = newCount;
+}
+
+QDeclarativeComponent *DataParticle::delegate() const
+{
+ if(m_model)
+ return m_model->delegate();
+ return 0;
+}
+
+void DataParticle::setDelegate(QDeclarativeComponent *comp)
+{
+ if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(m_model))
+ if (comp == dataModel->delegate())
+ return;
+ m_comp = comp;
+ if(m_model)
+ m_model->setDelegate(comp);
+ emit delegateChanged();
+}
+
+int DataParticle::modelCount() const
+{
+ if(m_model)
+ const_cast<DataParticle*>(this)->updateCount();//TODO: Investigate why this doesn't get called properly
+ return m_modelCount;
+}
+
+
+void DataParticle::freeze(QSGItem* item)
+{
+ m_stasis << item;
+}
+
+
+void DataParticle::unfreeze(QSGItem* item)
+{
+ m_stasis.remove(item);
+}
+
+void DataParticle::load(ParticleData* d)
+{
+ if(!m_model || !m_model->count())
+ return;
+ int pos = particleTypeIndex(d);
+ if(m_available.isEmpty())
+ return;
+ 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_available << m_idx[pos];
+ m_model->release(m_items[pos]);
+ m_idx[pos] = -1;
+ m_items[pos] = 0;
+ m_data[pos] = 0;
+ m_activeCount--;
+ }
+ m_items[pos] = m_model->item(m_available.first());
+ m_idx[pos] = m_available.first();
+ m_available.pop_front();
+ DataParticleAttached* mpa = qobject_cast<DataParticleAttached*>(qmlAttachedPropertiesObject<DataParticle>(m_items[pos]));
+ if(mpa){
+ mpa->m_mp = this;
+ mpa->attach();
+ }
+ m_items[pos]->setParentItem(this);
+ m_data[pos] = d;
+ m_activeCount++;
+}
+
+void DataParticle::reload(ParticleData* d)
+{
+ //No-op unless we start copying the data.
+}
+
+void DataParticle::setCount(int c)
+{
+ ParticleType::setCount(c);//###Do we need our own?
+ m_particleCount = c;
+ reset();
+}
+
+int DataParticle::count()
+{
+ return m_particleCount;
+}
+
+void DataParticle::reset()
+{
+ ParticleType::reset();
+ //TODO: Cleanup items?
+ m_items.resize(m_particleCount);
+ m_data.resize(m_particleCount);
+ m_idx.resize(m_particleCount);
+ m_items.fill(0);
+ m_data.fill(0);
+ m_idx.fill(-1);
+ //m_available.clear();//Should this be reset too?
+ //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal?
+}
+
+
+QSGNode* DataParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
+{
+ //Dummy update just to get painting tick
+ if(m_pleaseReset){
+ m_pleaseReset = false;
+ reset();
+ }
+ prepareNextFrame();
+
+ update();//Get called again
+ if(n)
+ n->markDirty(QSGNode::DirtyMaterial);
+ return QSGItem::updatePaintNode(n,d);
+}
+
+void DataParticle::prepareNextFrame()
+{
+ qint64 timeStamp = m_system->systemSync(this);
+ qreal curT = timeStamp/1000.0;
+ qreal dt = curT - m_lastT;
+ m_lastT = curT;
+ if(!m_activeCount)
+ return;
+
+ //TODO: Size, better fade?
+ for(int i=0; i<m_particleCount; i++){
+ QSGItem* item = m_items[i];
+ ParticleData* data = m_data[i];
+ if(!item || !data)
+ continue;
+ qreal t = ((timeStamp/1000.0) - data->pv.t) / data->pv.lifeSpan;
+ if(m_stasis.contains(item)) {
+ m_data[i]->pv.t += dt;//Stasis effect
+ continue;
+ }
+ if(t >= 1.0){//Usually happens from load
+ item->setOpacity(0.);
+ m_available << m_idx[i];
+ m_model->release(m_items[i]);
+ m_idx[i] = -1;
+ m_items[i] = 0;
+ m_data[i] = 0;
+ m_activeCount--;
+ }else{//Fade
+ if(m_fade){
+ qreal o = 1.;
+ if(t<0.2)
+ o = t*5;
+ if(t>0.8)
+ o = (1-t)*5;
+ item->setOpacity(o);
+ }else{
+ item->setOpacity(1.);//###Without fade, it's just a binary toggle - if we turn it off we have to turn it back on
+ }
+ }
+ item->setX(data->curX() - item->width()/2);
+ item->setY(data->curY() - item->height()/2);
+ }
+}
+
+DataParticleAttached *DataParticle::qmlAttachedProperties(QObject *object)
+{
+ return new DataParticleAttached(object);
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/particles/dataparticle.h b/src/imports/particles/dataparticle.h
new file mode 100644
index 0000000000..e048450894
--- /dev/null
+++ b/src/imports/particles/dataparticle.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** 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 Declarative 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 DATAPARTICLE_H
+#define DATAPARTICLE_H
+#include "particle.h"
+#include <QPointer>
+#include <QSet>
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QSGVisualDataModel;
+class DataParticleAttached;
+
+class DataParticle : public ParticleType
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
+ Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+ Q_PROPERTY(int modelCount READ modelCount NOTIFY modelCountChanged)
+ Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged)
+ Q_CLASSINFO("DefaultProperty", "delegate")
+public:
+ explicit DataParticle(QSGItem *parent = 0);
+ QVariant model() const;
+ void setModel(const QVariant &);
+
+ QDeclarativeComponent *delegate() const;
+ void setDelegate(QDeclarativeComponent *);
+
+ int modelCount() const;
+
+ bool fade() const { return m_fade; }
+
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ virtual void load(ParticleData*);
+ virtual void reload(ParticleData*);
+ virtual void setCount(int c);
+ virtual int count();
+
+ static DataParticleAttached *qmlAttachedProperties(QObject *object);
+signals:
+ void modelChanged();
+ void delegateChanged();
+ void modelCountChanged();
+ void fadeChanged();
+
+public slots:
+ void freeze(QSGItem* item);
+ void unfreeze(QSGItem* item);
+ void take(QSGItem* item,bool prioritize=false);//take by modelparticle
+ void give(QSGItem* item);//give from modelparticle
+
+ void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();}
+protected:
+ virtual void reset();
+ void prepareNextFrame();
+private slots:
+ void updateCount();
+private:
+ bool m_ownModel;
+ QDeclarativeComponent* m_comp;
+ QSGVisualDataModel *m_model;
+ QVariant m_dataSource;
+ QList<QPointer<QSGItem> > m_deletables;
+ int m_particleCount;
+ bool m_fade;
+
+ QList<QSGItem*> m_pendingItems;
+ QVector<QSGItem*> m_items;
+ QVector<ParticleData*> m_data;
+ QVector<int> m_idx;
+ QList<int> m_available;
+ QSet<QSGItem*> m_stasis;
+ qreal m_lastT;
+ int m_activeCount;
+ int m_modelCount;
+};
+
+class DataParticleAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(DataParticle* particle READ particle CONSTANT);
+public:
+ DataParticleAttached(QObject* parent)
+ : QObject(parent), m_mp(0)
+ {;}
+ DataParticle* particle() {return m_mp;}
+ void detach(){emit detached();}
+ void attach(){emit attached();}
+private:
+ DataParticle* m_mp;
+ friend class DataParticle;
+Q_SIGNALS:
+ void detached();
+ void attached();
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPEINFO(DataParticle, QML_HAS_ATTACHED_PROPERTIES)
+
+QT_END_HEADER
+#endif // DATAPARTICLE_H
diff --git a/src/imports/particles/itemparticle.cpp b/src/imports/particles/itemparticle.cpp
new file mode 100644
index 0000000000..e31309cf21
--- /dev/null
+++ b/src/imports/particles/itemparticle.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** 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 Declarative 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 "itemparticle.h"
+#include <QtDeclarative/private/qsgvisualitemmodel_p.h>
+#include <qsgnode.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+ItemParticle::ItemParticle(QSGItem *parent) :
+ ParticleType(parent), m_fade(true)
+{
+ setFlag(QSGItem::ItemHasContents);
+}
+
+
+void ItemParticle::freeze(QSGItem* item)
+{
+ m_stasis << item;
+}
+
+
+void ItemParticle::unfreeze(QSGItem* item)
+{
+ m_stasis.remove(item);
+}
+
+void ItemParticle::take(QSGItem *item, bool prioritize)
+{
+ if(prioritize)
+ m_pendingItems.push_front(item);
+ else
+ m_pendingItems.push_back(item);
+}
+
+void ItemParticle::give(QSGItem *item)
+{
+ //TODO: This
+}
+
+void ItemParticle::load(ParticleData* 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.);
+ ItemParticleAttached* mpa;
+ if((mpa = qobject_cast<ItemParticleAttached*>(qmlAttachedPropertiesObject<ItemParticle>(m_items[pos], false))))
+ mpa->detach();//reparent as well?
+ m_items[pos] = 0;
+ m_data[pos] = 0;
+ m_activeCount--;
+ }
+ 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);
+ ItemParticleAttached* mpa = qobject_cast<ItemParticleAttached*>(qmlAttachedPropertiesObject<ItemParticle>(m_items[pos]));
+ if(mpa){
+ mpa->m_mp = this;
+ mpa->attach();
+ }
+ m_items[pos]->setParentItem(this);
+ m_data[pos] = d;
+ m_activeCount++;
+}
+
+void ItemParticle::reload(ParticleData* d)
+{
+ //No-op unless we start copying the data.
+}
+
+void ItemParticle::setCount(int c)
+{
+ ParticleType::setCount(c);//###Do we need our own?
+ m_particleCount = c;
+ reset();
+}
+
+int ItemParticle::count()
+{
+ return m_particleCount;
+}
+
+void ItemParticle::reset()
+{
+ ParticleType::reset();
+ //TODO: Cleanup items?
+ m_items.resize(m_particleCount);
+ m_data.resize(m_particleCount);
+ m_items.fill(0);
+ m_data.fill(0);
+ //m_pendingItems.clear();//TODO: Should this be done? If so, Emit signal?
+}
+
+
+QSGNode* ItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
+{
+ //Dummy update just to get painting tick
+ if(m_pleaseReset){
+ m_pleaseReset = false;
+ reset();
+ }
+ prepareNextFrame();
+
+ update();//Get called again
+ if(n)
+ n->markDirty(QSGNode::DirtyMaterial);
+ return QSGItem::updatePaintNode(n,d);
+}
+
+void ItemParticle::prepareNextFrame()
+{
+ qint64 timeStamp = m_system->systemSync(this);
+ qreal curT = timeStamp/1000.0;
+ qreal dt = curT - m_lastT;
+ m_lastT = curT;
+ if(!m_activeCount)
+ return;
+
+ //TODO: Size, better fade?
+ for(int i=0; i<m_particleCount; i++){
+ QSGItem* item = m_items[i];
+ ParticleData* data = m_data[i];
+ if(!item || !data)
+ continue;
+ qreal t = ((timeStamp/1000.0) - data->pv.t) / data->pv.lifeSpan;
+ if(m_stasis.contains(item)) {
+ m_data[i]->pv.t += dt;//Stasis effect
+ continue;
+ }
+ if(t >= 1.0){//Usually happens from load
+ item->setOpacity(0.);
+ ItemParticleAttached* mpa;
+ if((mpa = qobject_cast<ItemParticleAttached*>(qmlAttachedPropertiesObject<ItemParticle>(m_items[i]))))
+ mpa->detach();//reparent as well?
+ m_items[i] = 0;
+ m_data[i] = 0;
+ m_activeCount--;
+ }else{//Fade
+ if(m_fade){
+ qreal o = 1.;
+ if(t<0.2)
+ o = t*5;
+ if(t>0.8)
+ o = (1-t)*5;
+ item->setOpacity(o);
+ }else{
+ item->setOpacity(1.);//###Without fade, it's just a binary toggle - if we turn it off we have to turn it back on
+ }
+ }
+ item->setX(data->curX() - item->width()/2);
+ item->setY(data->curY() - item->height()/2);
+ }
+}
+
+ItemParticleAttached *ItemParticle::qmlAttachedProperties(QObject *object)
+{
+ return new ItemParticleAttached(object);
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/particles/itemparticle.h b/src/imports/particles/itemparticle.h
new file mode 100644
index 0000000000..606a361584
--- /dev/null
+++ b/src/imports/particles/itemparticle.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 Declarative 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 ITEMPARTICLE_H
+#define ITEMPARTICLE_H
+#include "particle.h"
+#include <QPointer>
+#include <QSet>
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QSGVisualDataModel;
+class ItemParticleAttached;
+
+class ItemParticle : public ParticleType
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged)
+public:
+ explicit ItemParticle(QSGItem *parent = 0);
+
+ bool fade() const { return m_fade; }
+
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ virtual void load(ParticleData*);
+ virtual void reload(ParticleData*);
+ virtual void setCount(int c);
+ virtual int count();
+
+ static ItemParticleAttached *qmlAttachedProperties(QObject *object);
+signals:
+ void fadeChanged();
+
+public slots:
+ void freeze(QSGItem* item);
+ void unfreeze(QSGItem* item);
+ void take(QSGItem* item,bool prioritize=false);//take by modelparticle
+ void give(QSGItem* item);//give from modelparticle
+
+ void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();}
+protected:
+ virtual void reset();
+ void prepareNextFrame();
+private slots:
+ void updateCount();
+private:
+ QList<QPointer<QSGItem> > m_deletables;
+ int m_particleCount;
+ bool m_fade;
+
+ QList<QSGItem*> m_pendingItems;
+ QVector<QSGItem*> m_items;
+ QVector<ParticleData*> m_data;
+ QVector<int> m_idx;
+ QList<int> m_available;
+ QSet<QSGItem*> m_stasis;
+ qreal m_lastT;
+ int m_activeCount;
+};
+
+class ItemParticleAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(ItemParticle* particle READ particle CONSTANT);
+public:
+ ItemParticleAttached(QObject* parent)
+ : QObject(parent), m_mp(0)
+ {;}
+ ItemParticle* particle() {return m_mp;}
+ void detach(){emit detached();}
+ void attach(){emit attached();}
+private:
+ ItemParticle* m_mp;
+ friend class ItemParticle;
+Q_SIGNALS:
+ void detached();
+ void attached();
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPEINFO(ItemParticle, QML_HAS_ATTACHED_PROPERTIES)
+
+QT_END_HEADER
+#endif // ITEMPARTICLE_H
diff --git a/src/imports/particles/main.cpp b/src/imports/particles/main.cpp
index 3343d9a859..c90ea78b7f 100644
--- a/src/imports/particles/main.cpp
+++ b/src/imports/particles/main.cpp
@@ -71,6 +71,8 @@
#include "coloredparticle.h"
#include "spriteparticle.h"
#include "modelparticle.h"
+#include "dataparticle.h"
+#include "itemparticle.h"
#include "superparticle.h"
#include "ultraparticle.h"
//#include "pairedparticle.h"
@@ -109,6 +111,8 @@ void ParticlesPlugin::registerTypes(const char *uri)
qmlRegisterType<ColoredParticle>(uri, 2, 0, "ColoredParticle");
qmlRegisterType<SpriteParticle>(uri, 2, 0, "SpriteParticle");
qmlRegisterType<ModelParticle>(uri, 2, 0, "ModelParticle");
+ qmlRegisterType<DataParticle>(uri, 2, 0, "DataParticle");
+ qmlRegisterType<ItemParticle>(uri, 2, 0, "ItemParticle");
//qmlRegisterType<PairedParticle>(uri, 2, 0, "PairedParticle");
qmlRegisterType<DeformableParticle>(uri, 2, 0, "DeformableParticle");
qmlRegisterType<SuperParticle>(uri, 2, 0, "SuperParticle");
diff --git a/src/imports/particles/modelparticle.cpp b/src/imports/particles/modelparticle.cpp
index 9d326db83d..85d6e15157 100644
--- a/src/imports/particles/modelparticle.cpp
+++ b/src/imports/particles/modelparticle.cpp
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
ModelParticle::ModelParticle(QSGItem *parent) :
ParticleType(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true), m_modelCount(0)
{
+ qDebug() << "Deprecation warning: ModelParticle has bifurcated. I really should just delete this class";//TODO: What he said
setFlag(QSGItem::ItemHasContents);
}
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
index 91cf5bae77..1ce3f8eeb4 100644
--- a/src/imports/particles/particles.pro
+++ b/src/imports/particles/particles.pro
@@ -49,7 +49,9 @@ HEADERS += \
pictureaffector.h \
superparticle.h \
ultraparticle.h \
- burstemitter.h
+ burstemitter.h \
+ dataparticle.h \
+ itemparticle.h
SOURCES += \
V1/qdeclarativeparticles.cpp \
@@ -98,7 +100,9 @@ SOURCES += \
pictureaffector.cpp \
superparticle.cpp \
ultraparticle.cpp \
- burstemitter.cpp
+ burstemitter.cpp \
+ dataparticle.cpp \
+ itemparticle.cpp
QT += declarative opengl
#Because we use QDeclarativePixmapCache once...
diff --git a/src/imports/particles/particlesystem.cpp b/src/imports/particles/particlesystem.cpp
index f89eda4aaf..0c9180c2d8 100644
--- a/src/imports/particles/particlesystem.cpp
+++ b/src/imports/particles/particlesystem.cpp
@@ -67,7 +67,7 @@ ParticleData::ParticleData()
}
ParticleSystem::ParticleSystem(QSGItem *parent) :
- QSGItem(parent), m_particle_count(0), m_running(true) , m_startTime(0), m_overwrite(true)
+ QSGItem(parent), m_particle_count(0), m_running(true) , m_startTime(0), m_overwrite(false)
{
m_groupIds = QHash<QString, int>();
}
diff --git a/src/imports/particles/particlesystem.h b/src/imports/particles/particlesystem.h
index fc5575d3a7..fbb0e7424f 100644
--- a/src/imports/particles/particlesystem.h
+++ b/src/imports/particles/particlesystem.h
@@ -74,6 +74,10 @@ class ParticleSystem : public QSGItem
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(bool overwrite READ overwrite WRITE setOverwrite NOTIFY overwriteChanged)//XXX: Should just be an implementation detail, but I can't decide which way
+ /* The problem is that it ought to be false (usually) for stasis effects like model particles,
+ but it ought to be true (usually) for burst effects where you want it to burst, and forget the old stuff
+ Ideally burst never overflows? But that leads to crappy behaviour from crappy users...
+ */
public:
explicit ParticleSystem(QSGItem *parent = 0);