Extract Particles code to an independent library
[profile/ivi/qtdeclarative.git] / src / particles / qquickparticlepainter.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQuick module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickparticlepainter_p.h"
43 #include <QQuickCanvas>
44 #include <QDebug>
45 QT_BEGIN_NAMESPACE
46 /*!
47     \qmlclass ParticlePainter QQuickParticlePainter
48     \inqmlmodule QtQuick.Particles 2
49     \inherits ParticlePainter
50     \brief ParticlePainter elements allow you to specify how to paint particles.
51
52     The default implementation paints nothing. See the subclasses if you want to
53     paint something visible.
54
55 */
56 /*!
57     \qmlproperty ParticleSystem QtQuick.Particles2::ParticlePainter::system
58     This is the system whose particles can be painted by the element.
59     If the ParticlePainter is a direct child of a ParticleSystem, it will automatically be associated with it.
60 */
61 /*!
62     \qmlproperty list<string> QtQuick.Particles2::ParticlePainter::groups
63     Which logical particle groups will be painted.
64
65     If empty, it will paint the default particle group ("").
66 */
67 QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent) :
68     QQuickItem(parent),
69     m_system(0), m_count(0), m_pleaseReset(true), m_canvas(0)
70 {
71 }
72
73 void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &data)
74 {
75     if (change == QQuickItem::ItemSceneChange) {
76         if (m_canvas)
77             disconnect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()));
78         m_canvas = data.canvas;
79         if (m_canvas)
80             connect(m_canvas, SIGNAL(sceneGraphInvalidated()), this, SLOT(sceneGraphInvalidated()), Qt::DirectConnection);
81
82     }
83 }
84
85 void QQuickParticlePainter::componentComplete()
86 {
87     if (!m_system && qobject_cast<QQuickParticleSystem*>(parentItem()))
88         setSystem(qobject_cast<QQuickParticleSystem*>(parentItem()));
89     QQuickItem::componentComplete();
90 }
91
92
93 void QQuickParticlePainter::setSystem(QQuickParticleSystem *arg)
94 {
95     if (m_system != arg) {
96         m_system = arg;
97         if (m_system){
98             m_system->registerParticlePainter(this);
99             reset();
100         }
101         emit systemChanged(arg);
102     }
103 }
104
105 void QQuickParticlePainter::load(QQuickParticleData* d)
106 {
107     initialize(d->group, d->index);
108     if (m_pleaseReset)
109         return;
110     m_pendingCommits << qMakePair<int, int>(d->group, d->index);
111 }
112
113 void QQuickParticlePainter::reload(QQuickParticleData* d)
114 {
115     if (m_pleaseReset)
116         return;
117     m_pendingCommits << qMakePair<int, int>(d->group, d->index);
118 }
119
120 void QQuickParticlePainter::reset()
121 {
122     m_pendingCommits.clear();
123     m_pleaseReset = true;
124 }
125
126 void QQuickParticlePainter::setCount(int c)//### TODO: some resizeing so that particles can reallocate on size change instead of recreate
127 {
128     Q_ASSERT(c >= 0); //XXX
129     if (c == m_count)
130         return;
131     m_count = c;
132     emit countChanged();
133     reset();
134 }
135
136 int QQuickParticlePainter::count()
137 {
138     return m_count;
139 }
140
141 void QQuickParticlePainter::calcSystemOffset(bool resetPending)
142 {
143     if (!m_system || !parentItem())
144         return;
145     QPointF lastOffset = m_systemOffset;
146     m_systemOffset = -1 * this->mapFromItem(m_system, QPointF(0.0, 0.0));
147     if (lastOffset != m_systemOffset && !resetPending){
148         //Reload all particles//TODO: Necessary?
149         foreach (const QString &g, m_groups){
150             int gId = m_system->groupIds[g];
151             foreach (QQuickParticleData* d, m_system->groupData[gId]->data)
152                 reload(d);
153         }
154     }
155 }
156 typedef QPair<int,int> intPair;
157 void QQuickParticlePainter::performPendingCommits()
158 {
159     calcSystemOffset();
160     foreach (intPair p, m_pendingCommits)
161         commit(p.first, p.second);
162     m_pendingCommits.clear();
163 }
164
165 QT_END_NAMESPACE