Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qanimationgroup.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
// Qt-Security score:significant reason:default
4
5
/*!
6
\class QAnimationGroup
7
\inmodule QtCore
8
\brief The QAnimationGroup class is an abstract base class for groups of animations.
9
\since 4.6
10
\ingroup animation
11
12
An animation group is a container for animations (subclasses of
13
QAbstractAnimation). A group is usually responsible for managing
14
the \l{QAbstractAnimation::State}{state} of its animations, i.e.,
15
it decides when to start, stop, resume, and pause them. Currently,
16
Qt provides two such groups: QParallelAnimationGroup and
17
QSequentialAnimationGroup. Look up their class descriptions for
18
details.
19
20
Since QAnimationGroup inherits from QAbstractAnimation, you can
21
combine groups, and easily construct complex animation graphs.
22
You can query QAbstractAnimation for the group it belongs to
23
(using the \l{QAbstractAnimation::}{group()} function).
24
25
To start a top-level animation group, you simply use the
26
\l{QAbstractAnimation::}{start()} function from
27
QAbstractAnimation. By a top-level animation group, we think of a
28
group that itself is not contained within another group. Starting
29
sub groups directly is not supported, and may lead to unexpected
30
behavior.
31
32
\omit OK, we'll put in a snippet on this here \endomit
33
34
QAnimationGroup provides methods for adding and retrieving
35
animations. Besides that, you can remove animations by calling
36
\l removeAnimation(), and clear the animation group by calling
37
clear(). You may keep track of changes in the group's
38
animations by listening to QEvent::ChildAdded and
39
QEvent::ChildRemoved events.
40
41
\omit OK, let's find a snippet here as well. \endomit
42
43
QAnimationGroup takes ownership of the animations it manages, and
44
ensures that they are deleted when the animation group is deleted.
45
46
\sa QAbstractAnimation, QVariantAnimation, {The Animation Framework}
47
*/
48
49
#
include
"qanimationgroup.h"
50
#
include
<
QtCore
/
qdebug
.
h
>
51
#
include
<
QtCore
/
qcoreevent
.
h
>
52
#
include
"qanimationgroup_p.h"
53
54
#
include
<
algorithm
>
55
56
QT_BEGIN_NAMESPACE
57
58
59
/*!
60
Constructs a QAnimationGroup.
61
\a parent is passed to QObject's constructor.
62
*/
63
QAnimationGroup::QAnimationGroup(QObject *parent)
64
: QAbstractAnimation(*
new
QAnimationGroupPrivate, parent)
65
{
66
}
67
68
/*!
69
\internal
70
*/
71
QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent)
72
: QAbstractAnimation(dd, parent)
73
{
74
}
75
76
/*!
77
Destroys the animation group. It will also destroy all its animations.
78
*/
79
QAnimationGroup::~QAnimationGroup()
80
{
81
Q_D(QAnimationGroup);
82
// We need to clear the animations now while we are still a valid QAnimationGroup.
83
// If we wait until ~QObject() the QAbstractAnimation's pointer back to us would
84
// point to a QObject, not a valid QAnimationGroup.
85
d->clear(
true
);
86
}
87
88
/*!
89
Returns a pointer to the animation at \a index in this group. This
90
function is useful when you need access to a particular animation. \a
91
index is between 0 and animationCount() - 1.
92
93
\sa animationCount(), indexOfAnimation()
94
*/
95
QAbstractAnimation *QAnimationGroup::animationAt(
int
index)
const
96
{
97
Q_D(
const
QAnimationGroup);
98
99
if
(index < 0 || index >= d->animations.size()) {
100
qWarning(
"QAnimationGroup::animationAt: index is out of bounds"
);
101
return
nullptr
;
102
}
103
104
return
d->animations.at(index);
105
}
106
107
108
/*!
109
Returns the number of animations managed by this group.
110
111
\sa indexOfAnimation(), addAnimation(), animationAt()
112
*/
113
int
QAnimationGroup::animationCount()
const
114
{
115
Q_D(
const
QAnimationGroup);
116
return
d->animations.size();
117
}
118
119
/*!
120
Returns the index of \a animation. The returned index can be passed
121
to the other functions that take an index as an argument.
122
123
\sa insertAnimation(), animationAt(), takeAnimation()
124
*/
125
int
QAnimationGroup::indexOfAnimation(QAbstractAnimation *animation)
const
126
{
127
Q_D(
const
QAnimationGroup);
128
return
d->animations.indexOf(animation);
129
}
130
131
/*!
132
Adds \a animation to this group. This will call insertAnimation with
133
index equals to animationCount().
134
135
\note The group takes ownership of the animation.
136
137
//! [animation-loop]
138
\warning This method does not check for animation loops. It's the
139
developer's responsibility to make sure that the added \a animation does not
140
include \c {this} animation group directly or indirectly.
141
//! [animation-loop]
142
143
\sa removeAnimation()
144
*/
145
void
QAnimationGroup::addAnimation(QAbstractAnimation *animation)
146
{
147
Q_D(QAnimationGroup);
148
insertAnimation(d->animations.size(), animation);
149
}
150
151
/*!
152
Inserts \a animation into this animation group at \a index.
153
If \a index is 0 the animation is inserted at the beginning.
154
If \a index is animationCount(), the animation is inserted at the end.
155
156
\note The group takes ownership of the animation.
157
158
\include qanimationgroup.cpp animation-loop
159
160
\sa takeAnimation(), addAnimation(), indexOfAnimation(), removeAnimation()
161
*/
162
void
QAnimationGroup::insertAnimation(
int
index, QAbstractAnimation *animation)
163
{
164
Q_D(QAnimationGroup);
165
166
if
(index < 0 || index > d->animations.size()) {
167
qWarning(
"QAnimationGroup::insertAnimation: index is out of bounds"
);
168
return
;
169
}
170
171
if
(QAnimationGroup *oldGroup = animation->group()) {
172
oldGroup->removeAnimation(animation);
173
// ensure we don't insert out of bounds if oldGroup == this
174
index = qMin(index, d->animations.size());
175
}
176
177
d->animations.insert(index, animation);
178
QAbstractAnimationPrivate::get(animation)->group =
this
;
179
// this will make sure that ChildAdded event is sent to 'this'
180
animation->setParent(
this
);
181
d->animationInsertedAt(index);
182
}
183
184
/*!
185
Removes \a animation from this group. The ownership of \a animation is
186
transferred to the caller.
187
188
\sa takeAnimation(), insertAnimation(), addAnimation()
189
*/
190
void
QAnimationGroup::removeAnimation(QAbstractAnimation *animation)
191
{
192
Q_D(QAnimationGroup);
193
194
if
(!animation) {
195
qWarning(
"QAnimationGroup::remove: cannot remove null animation"
);
196
return
;
197
}
198
qsizetype index = d->animations.indexOf(animation);
199
if
(index == -1) {
200
qWarning(
"QAnimationGroup::remove: animation is not part of this group"
);
201
return
;
202
}
203
204
takeAnimation(index);
205
}
206
207
/*!
208
Returns the animation at \a index and removes it from the animation group.
209
210
\note The ownership of the animation is transferred to the caller.
211
212
\sa removeAnimation(), addAnimation(), insertAnimation(), indexOfAnimation()
213
*/
214
QAbstractAnimation *QAnimationGroup::takeAnimation(
int
index)
215
{
216
Q_D(QAnimationGroup);
217
if
(index < 0 || index >= d->animations.size()) {
218
qWarning(
"QAnimationGroup::takeAnimation: no animation at index %d"
, index);
219
return
nullptr
;
220
}
221
QAbstractAnimation *animation = d->animations.at(index);
222
QAbstractAnimationPrivate::get(animation)->group =
nullptr
;
223
// ### removing from list before doing setParent to avoid infinite recursion
224
// in ChildRemoved event
225
d->animations.removeAt(index);
226
animation->setParent(
nullptr
);
227
d->animationRemoved(index, animation);
228
return
animation;
229
}
230
231
/*!
232
Removes and deletes all animations in this animation group, and resets the current
233
time to 0.
234
235
\sa addAnimation(), removeAnimation()
236
*/
237
void
QAnimationGroup::clear()
238
{
239
Q_D(QAnimationGroup);
240
d->clear(
false
);
241
}
242
243
/*!
244
\reimp
245
*/
246
bool
QAnimationGroup::event(QEvent *event)
247
{
248
Q_D(QAnimationGroup);
249
if
(event->type() == QEvent::ChildAdded) {
250
QChildEvent *childEvent =
static_cast
<QChildEvent *>(event);
251
if
(QAbstractAnimation *a = qobject_cast<QAbstractAnimation *>(childEvent->child())) {
252
if
(a->group() !=
this
)
253
addAnimation(a);
254
}
255
}
else
if
(event->type() == QEvent::ChildRemoved) {
256
QChildEvent *childEvent =
static_cast
<QChildEvent *>(event);
257
// You can only rely on the child being a QObject because in the QEvent::ChildRemoved
258
// case it might be called from the destructor. Casting down to QAbstractAnimation then
259
// entails undefined behavior, so compare items as QObjects (which std::find does internally):
260
const
QList<QAbstractAnimation *>::const_iterator it
261
= std::find(d->animations.cbegin(), d->animations.cend(), childEvent->child());
262
if
(it != d->animations.cend())
263
takeAnimation(it - d->animations.cbegin());
264
}
265
return
QAbstractAnimation::event(event);
266
}
267
268
void
QAnimationGroupPrivate::clear(
bool
onDestruction)
269
{
270
const
QList<QAbstractAnimation *> animationsCopy = animations;
// taking a copy
271
animations.clear();
272
// Clearing backwards so the indices doesn't change while we remove animations.
273
for
(qsizetype i = animationsCopy.size() - 1; i >= 0; --i) {
274
QAbstractAnimation *animation = animationsCopy.at(i);
275
animation->setParent(
nullptr
);
276
QAbstractAnimationPrivate::get(animation)->group =
nullptr
;
277
// If we are in ~QAnimationGroup() it is not safe to called the virtual
278
// animationRemoved method, which can still be a method in a
279
// QAnimationGroupPrivate derived class that assumes q_ptr is still
280
// a valid derived class of QAnimationGroup.
281
if
(!onDestruction)
282
animationRemoved(i, animation);
283
delete
animation;
284
}
285
}
286
287
void
QAnimationGroupPrivate::animationRemoved(qsizetype index, QAbstractAnimation *)
288
{
289
Q_Q(QAnimationGroup);
290
Q_UNUSED(index);
291
if
(animations.isEmpty()) {
292
currentTime = 0;
293
q->stop();
294
}
295
}
296
297
QT_END_NAMESPACE
298
299
#
include
"moc_qanimationgroup.cpp"
qtbase
src
corelib
animation
qanimationgroup.cpp
Generated on
for Qt by
1.18.0