Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickparticlepainter.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
5
7#include <QQuickWindow>
8#include <QDebug>
10/*!
11 \qmltype ParticlePainter
12 \nativetype QQuickParticlePainter
13 \inqmlmodule QtQuick.Particles
14 \inherits Item
15 \brief For specifying how to paint particles.
16 \ingroup qtquick-particles
17
18 The default implementation paints nothing. See the subclasses if you want to
19 paint something visible.
20
21*/
22/*!
23 \qmlproperty ParticleSystem QtQuick.Particles::ParticlePainter::system
24 This is the system whose particles can be painted by the element.
25 If the ParticlePainter is a direct child of a ParticleSystem, it will automatically be associated with it.
26*/
27/*!
28 \qmlproperty list<string> QtQuick.Particles::ParticlePainter::groups
29 Which logical particle groups will be painted.
30
31 If empty, it will paint the default particle group ("").
32*/
33QQuickParticlePainter::QQuickParticlePainter(QQuickItem *parent)
34 : QQuickItem(parent)
35 , m_system(nullptr)
36 , m_count(0)
37 , m_pleaseReset(true)
38 , m_window(nullptr)
39 , m_windowChanged(false)
40 , m_groupIdsNeedRecalculation(false)
41{
42}
43
44void QQuickParticlePainter::itemChange(ItemChange change, const ItemChangeData &data)
45{
46 if (change == QQuickItem::ItemSceneChange) {
47 if (m_window) {
48 disconnect(m_window, &QQuickWindow::sceneGraphInvalidated,
49 this, &QQuickParticlePainter::sceneGraphInvalidated);
50 }
51 m_window = data.window;
52 m_windowChanged = true;
53 if (m_window) {
54 connect(m_window, &QQuickWindow::sceneGraphInvalidated,
55 this, &QQuickParticlePainter::sceneGraphInvalidated, Qt::DirectConnection);
56 }
57 }
58 QQuickItem::itemChange(change, data);
59}
60
61void QQuickParticlePainter::componentComplete()
62{
63 if (!m_system && qobject_cast<QQuickParticleSystem*>(parentItem()))
64 setSystem(qobject_cast<QQuickParticleSystem*>(parentItem()));
65 QQuickItem::componentComplete();
66}
67
68void QQuickParticlePainter::recalculateGroupIds() const
69{
70 if (!m_system) {
71 m_groupIds.clear();
72 return;
73 }
74
75 m_groupIdsNeedRecalculation = false;
76 m_groupIds.clear();
77
78 const auto groupList = groups();
79 for (const QString &str : groupList) {
80 QQuickParticleGroupData::ID groupId = m_system->groupIds.value(str, QQuickParticleGroupData::InvalidID);
81 if (groupId == QQuickParticleGroupData::InvalidID) {
82 // invalid data, not finished setting up, or whatever. Fallback: do not cache.
83 m_groupIdsNeedRecalculation = true;
84 } else {
85 m_groupIds.append(groupId);
86 }
87 }
88}
89
90void QQuickParticlePainter::setSystem(QQuickParticleSystem *arg)
91{
92 if (m_system != arg) {
93 m_system = arg;
94 m_groupIdsNeedRecalculation = true;
95 if (m_system){
96 m_system->registerParticlePainter(this);
97 reset();
98 }
99 emit systemChanged(arg);
100 }
101}
102
103void QQuickParticlePainter::setGroups(const QStringList &arg)
104{
105 if (m_groups != arg) {
106 m_groups = arg;
107 m_groupIdsNeedRecalculation = true;
108 //Note: The system watches this as it has to recalc things when groups change. It will request a reset if necessary
109 Q_EMIT groupsChanged(arg);
110 }
111}
112
113void QQuickParticlePainter::load(QQuickParticleData* d)
114{
115 initialize(d->groupId, d->index);
116 if (m_pleaseReset)
117 return;
118 m_pendingCommits << qMakePair(d->groupId, d->index);
119}
120
121void QQuickParticlePainter::reload(QQuickParticleData* d)
122{
123 if (m_pleaseReset)
124 return;
125 m_pendingCommits << qMakePair(d->groupId, d->index);
126}
127
128void QQuickParticlePainter::reset()
129{
130 m_pendingCommits.clear();
131 m_pleaseReset = true;
132}
133
134void QQuickParticlePainter::setCount(int c)//### TODO: some resizeing so that particles can reallocate on size change instead of recreate
135{
136 Q_ASSERT(c >= 0); //XXX
137 if (c == m_count)
138 return;
139 m_count = c;
140 emit countChanged();
141 reset();
142}
143
144void QQuickParticlePainter::calcSystemOffset(bool resetPending)
145{
146 if (!m_system || !parentItem())
147 return;
148 QPointF lastOffset = m_systemOffset;
149 m_systemOffset = -1 * this->mapFromItem(m_system, QPointF(0.0, 0.0));
150 if (lastOffset != m_systemOffset && !resetPending){
151 //Reload all particles//TODO: Necessary?
152 foreach (const QString &g, m_groups){
153 int gId = m_system->groupIds[g];
154 foreach (QQuickParticleData* d, m_system->groupData[gId]->data)
155 reload(d);
156 }
157 }
158}
159typedef QPair<int,int> intPair;
160void QQuickParticlePainter::performPendingCommits()
161{
162 calcSystemOffset();
163 foreach (intPair p, m_pendingCommits)
164 commit(p.first, p.second);
165 m_pendingCommits.clear();
166}
167
168QT_END_NAMESPACE
169
170#include "moc_qquickparticlepainter_p.cpp"
Combined button and popup list for selecting options.
QPair< int, int > intPair