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