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
qgraphicsitemanimation.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 QGraphicsItemAnimation
7
\brief The QGraphicsItemAnimation class provides simple animation
8
support for QGraphicsItem.
9
\since 4.2
10
\ingroup graphicsview-api
11
\inmodule QtWidgets
12
\deprecated
13
14
The QGraphicsItemAnimation class animates a QGraphicsItem. You can
15
schedule changes to the item's transformation matrix at
16
specified steps. The QGraphicsItemAnimation class has a
17
current step value. When this value changes the transformations
18
scheduled at that step are performed. The current step of the
19
animation is set with the \c setStep() function.
20
21
QGraphicsItemAnimation will do a simple linear interpolation
22
between the nearest adjacent scheduled changes to calculate the
23
matrix. For instance, if you set the position of an item at values
24
0.0 and 1.0, the animation will show the item moving in a straight
25
line between these positions. The same is true for scaling and
26
rotation.
27
28
It is usual to use the class with a QTimeLine. The timeline's
29
\l{QTimeLine::}{valueChanged()} signal is then connected to the
30
\c setStep() slot. For example, you can set up an item for rotation
31
by calling \c setRotationAt() for different step values.
32
The animations timeline is set with the setTimeLine() function.
33
34
An example animation with a timeline follows:
35
36
\snippet timeline/main.cpp 0
37
38
Note that steps lie between 0.0 and 1.0. It may be necessary to use
39
\l{QTimeLine::}{setUpdateInterval()}. The default update interval
40
is 40 ms. A scheduled transformation cannot be removed when set,
41
so scheduling several transformations of the same kind (e.g.,
42
rotations) at the same step is not recommended.
43
44
\sa QTimeLine, {Graphics View Framework}
45
*/
46
47
#
include
"qgraphicsitemanimation.h"
48
49
#
include
"qgraphicsitem.h"
50
51
#
include
<
QtCore
/
qtimeline
.
h
>
52
#
include
<
QtCore
/
qpoint
.
h
>
53
#
include
<
QtCore
/
qpointer
.
h
>
54
55
#
include
<
algorithm
>
56
57
QT_BEGIN_NAMESPACE
58
59
static
inline
bool
check_step_valid
(qreal step,
const
char
*method)
60
{
61
if
(!(step >= 0 && step <= 1)) {
62
qWarning(
"QGraphicsItemAnimation::%s: invalid step = %f"
, method, step);
63
return
false
;
64
}
65
return
true
;
66
}
67
68
class
QGraphicsItemAnimationPrivate
69
{
70
public
:
71
inline
QGraphicsItemAnimationPrivate
()
72
:
q
(
nullptr
),
timeLine
(
nullptr
),
item
(
nullptr
),
step
(0)
73
{ }
74
75
QGraphicsItemAnimation
*
q
;
76
77
QPointer
<
QTimeLine
>
timeLine
;
78
QGraphicsItem *
item
;
79
80
QPointF
startPos
;
81
QTransform
startTransform
;
82
83
qreal
step
;
84
85
struct
Pair
{
86
bool
operator
<(
const
Pair
&other)
const
87
{
return
step < other.step; }
88
bool
operator
==(
const
Pair
&other)
const
89
{
return
step == other.step; }
90
qreal
step
;
91
qreal
value
;
92
};
93
QList
<
Pair
>
xPosition
;
94
QList
<
Pair
>
yPosition
;
95
QList
<
Pair
>
rotation
;
96
QList
<
Pair
>
verticalScale
;
97
QList
<
Pair
>
horizontalScale
;
98
QList
<
Pair
>
verticalShear
;
99
QList
<
Pair
>
horizontalShear
;
100
QList
<
Pair
>
xTranslation
;
101
QList
<
Pair
>
yTranslation
;
102
103
qreal
linearValueForStep
(qreal step,
const
QList<Pair> &source, qreal defaultValue = 0);
104
void
insertUniquePair
(qreal step, qreal value, QList<Pair> *binList,
const
char
*method);
105
};
106
Q_DECLARE_TYPEINFO
(
QGraphicsItemAnimationPrivate
::
Pair
,
Q_PRIMITIVE_TYPE
);
107
108
qreal
QGraphicsItemAnimationPrivate
::
linearValueForStep
(qreal step,
const
QList<Pair> &source,
109
qreal defaultValue)
110
{
111
if
(source.isEmpty())
112
return
defaultValue;
113
step = qMin<qreal>(qMax<qreal>(step, 0), 1);
114
115
if
(step == 1)
116
return
source.back().value;
117
118
qreal stepBefore = 0;
119
qreal stepAfter = 1;
120
qreal valueBefore = source.front().step == 0 ? source.front().value : defaultValue;
121
qreal valueAfter = source.back().value;
122
123
// Find the closest step and value before the given step.
124
for
(
int
i = 0; i < source.size() && step >= source[i].step; ++i) {
125
stepBefore = source[i].step;
126
valueBefore = source[i].value;
127
}
128
129
// Find the closest step and value after the given step.
130
for
(
int
i = source.size() - 1; i >= 0 && step < source[i].step; --i) {
131
stepAfter = source[i].step;
132
valueAfter = source[i].value;
133
}
134
135
// Do a simple linear interpolation.
136
return
valueBefore + (valueAfter - valueBefore) * ((step - stepBefore) / (stepAfter - stepBefore));
137
}
138
139
void
QGraphicsItemAnimationPrivate
::
insertUniquePair
(qreal step, qreal value, QList<Pair> *binList,
140
const
char
*method)
141
{
142
if
(!check_step_valid(step, method))
143
return
;
144
145
const
Pair
pair = { step, value };
146
147
const
QList<Pair>::iterator result =
std
::lower_bound(binList->begin(), binList->end(), pair);
148
if
(result == binList->end() || pair < *result)
149
binList->insert(result, pair);
150
else
151
result->value = value;
152
}
153
154
/*!
155
Constructs an animation object with the given \a parent.
156
*/
157
QGraphicsItemAnimation::QGraphicsItemAnimation(QObject *parent)
158
: QObject(parent), d(
new
QGraphicsItemAnimationPrivate)
159
{
160
d->q =
this
;
161
}
162
163
/*!
164
Destroys the animation object.
165
*/
166
QGraphicsItemAnimation::~QGraphicsItemAnimation()
167
{
168
delete
d;
169
}
170
171
/*!
172
Returns the item on which the animation object operates.
173
174
\sa setItem()
175
*/
176
QGraphicsItem *QGraphicsItemAnimation::item()
const
177
{
178
return
d->item;
179
}
180
181
/*!
182
Sets the specified \a item to be used in the animation.
183
184
\sa item()
185
*/
186
void
QGraphicsItemAnimation::setItem(QGraphicsItem *item)
187
{
188
d->item = item;
189
d->startPos = d->item->pos();
190
}
191
192
/*!
193
Returns the timeline object used to control the rate at which the animation
194
occurs.
195
196
\sa setTimeLine()
197
*/
198
QTimeLine *QGraphicsItemAnimation::timeLine()
const
199
{
200
return
d->timeLine;
201
}
202
203
/*!
204
Sets the timeline object used to control the rate of animation to the \a timeLine
205
specified.
206
207
\sa timeLine()
208
*/
209
void
QGraphicsItemAnimation::setTimeLine(QTimeLine *timeLine)
210
{
211
if
(d->timeLine == timeLine)
212
return
;
213
if
(d->timeLine)
214
delete
d->timeLine;
215
if
(!timeLine)
216
return
;
217
d->timeLine = timeLine;
218
connect(timeLine, SIGNAL(valueChanged(qreal)),
this
, SLOT(setStep(qreal)));
219
}
220
221
/*!
222
Returns the position of the item at the given \a step value.
223
224
\sa setPosAt()
225
*/
226
QPointF QGraphicsItemAnimation::posAt(qreal step)
const
227
{
228
check_step_valid(step,
"posAt"
);
229
return
QPointF(d->linearValueForStep(step, d->xPosition, d->startPos.x()),
230
d->linearValueForStep(step, d->yPosition, d->startPos.y()));
231
}
232
233
/*!
234
\fn void QGraphicsItemAnimation::setPosAt(qreal step, const QPointF &point)
235
236
Sets the position of the item at the given \a step value to the \a point specified.
237
238
\sa posAt()
239
*/
240
void
QGraphicsItemAnimation::setPosAt(qreal step,
const
QPointF &pos)
241
{
242
d->insertUniquePair(step, pos.x(), &d->xPosition,
"setPosAt"
);
243
d->insertUniquePair(step, pos.y(), &d->yPosition,
"setPosAt"
);
244
}
245
246
/*!
247
Returns all explicitly inserted positions.
248
249
\sa posAt(), setPosAt()
250
*/
251
QList<std::pair<qreal, QPointF> > QGraphicsItemAnimation::posList()
const
252
{
253
QList<std::pair<qreal, QPointF>> list;
254
const
int
xPosCount = d->xPosition.size();
255
list.reserve(xPosCount);
256
for
(
int
i = 0; i < xPosCount; ++i)
257
list.emplace_back(d->xPosition.at(i).step,
258
QPointF(d->xPosition.at(i).value, d->yPosition.at(i).value));
259
260
return
list;
261
}
262
263
/*!
264
Returns the transform used for the item at the specified \a step value.
265
266
\since 5.14
267
*/
268
QTransform QGraphicsItemAnimation::transformAt(qreal step)
const
269
{
270
check_step_valid(step,
"transformAt"
);
271
272
QTransform transform;
273
if
(!d->rotation.isEmpty())
274
transform.rotate(rotationAt(step));
275
if
(!d->verticalScale.isEmpty())
276
transform.scale(horizontalScaleAt(step), verticalScaleAt(step));
277
if
(!d->verticalShear.isEmpty())
278
transform.shear(horizontalShearAt(step), verticalShearAt(step));
279
if
(!d->xTranslation.isEmpty())
280
transform.translate(xTranslationAt(step), yTranslationAt(step));
281
return
transform;
282
}
283
284
/*!
285
Returns the angle at which the item is rotated at the specified \a step value.
286
287
\sa setRotationAt()
288
*/
289
qreal QGraphicsItemAnimation::rotationAt(qreal step)
const
290
{
291
check_step_valid(step,
"rotationAt"
);
292
return
d->linearValueForStep(step, d->rotation);
293
}
294
295
/*!
296
Sets the rotation of the item at the given \a step value to the \a angle specified.
297
298
\sa rotationAt()
299
*/
300
void
QGraphicsItemAnimation::setRotationAt(qreal step, qreal angle)
301
{
302
d->insertUniquePair(step, angle, &d->rotation,
"setRotationAt"
);
303
}
304
305
/*!
306
Returns all explicitly inserted rotations.
307
308
\sa rotationAt(), setRotationAt()
309
*/
310
QList<std::pair<qreal, qreal> > QGraphicsItemAnimation::rotationList()
const
311
{
312
QList<std::pair<qreal, qreal>> list;
313
const
int
numRotations = d->rotation.size();
314
list.reserve(numRotations);
315
for
(
int
i = 0; i < numRotations; ++i)
316
list.emplace_back(d->rotation.at(i).step, d->rotation.at(i).value);
317
318
return
list;
319
}
320
321
/*!
322
Returns the horizontal translation of the item at the specified \a step value.
323
324
\sa setTranslationAt()
325
*/
326
qreal QGraphicsItemAnimation::xTranslationAt(qreal step)
const
327
{
328
check_step_valid(step,
"xTranslationAt"
);
329
return
d->linearValueForStep(step, d->xTranslation);
330
}
331
332
/*!
333
Returns the vertical translation of the item at the specified \a step value.
334
335
\sa setTranslationAt()
336
*/
337
qreal QGraphicsItemAnimation::yTranslationAt(qreal step)
const
338
{
339
check_step_valid(step,
"yTranslationAt"
);
340
return
d->linearValueForStep(step, d->yTranslation);
341
}
342
343
/*!
344
Sets the translation of the item at the given \a step value using the horizontal
345
and vertical coordinates specified by \a dx and \a dy.
346
347
\sa xTranslationAt(), yTranslationAt()
348
*/
349
void
QGraphicsItemAnimation::setTranslationAt(qreal step, qreal dx, qreal dy)
350
{
351
d->insertUniquePair(step, dx, &d->xTranslation,
"setTranslationAt"
);
352
d->insertUniquePair(step, dy, &d->yTranslation,
"setTranslationAt"
);
353
}
354
355
/*!
356
Returns all explicitly inserted translations.
357
358
\sa xTranslationAt(), yTranslationAt(), setTranslationAt()
359
*/
360
QList<std::pair<qreal, QPointF> > QGraphicsItemAnimation::translationList()
const
361
{
362
QList<std::pair<qreal, QPointF>> list;
363
const
int
numTranslations = d->xTranslation.size();
364
list.reserve(numTranslations);
365
for
(
int
i = 0; i < numTranslations; ++i)
366
list.emplace_back(d->xTranslation.at(i).step,
367
QPointF(d->xTranslation.at(i).value, d->yTranslation.at(i).value));
368
369
return
list;
370
}
371
372
/*!
373
Returns the vertical scale for the item at the specified \a step value.
374
375
\sa setScaleAt()
376
*/
377
qreal QGraphicsItemAnimation::verticalScaleAt(qreal step)
const
378
{
379
check_step_valid(step,
"verticalScaleAt"
);
380
381
return
d->linearValueForStep(step, d->verticalScale, 1);
382
}
383
384
/*!
385
Returns the horizontal scale for the item at the specified \a step value.
386
387
\sa setScaleAt()
388
*/
389
qreal QGraphicsItemAnimation::horizontalScaleAt(qreal step)
const
390
{
391
check_step_valid(step,
"horizontalScaleAt"
);
392
return
d->linearValueForStep(step, d->horizontalScale, 1);
393
}
394
395
/*!
396
Sets the scale of the item at the given \a step value using the horizontal and
397
vertical scale factors specified by \a sx and \a sy.
398
399
\sa verticalScaleAt(), horizontalScaleAt()
400
*/
401
void
QGraphicsItemAnimation::setScaleAt(qreal step, qreal sx, qreal sy)
402
{
403
d->insertUniquePair(step, sx, &d->horizontalScale,
"setScaleAt"
);
404
d->insertUniquePair(step, sy, &d->verticalScale,
"setScaleAt"
);
405
}
406
407
/*!
408
Returns all explicitly inserted scales.
409
410
\sa verticalScaleAt(), horizontalScaleAt(), setScaleAt()
411
*/
412
QList<std::pair<qreal, QPointF> > QGraphicsItemAnimation::scaleList()
const
413
{
414
QList<std::pair<qreal, QPointF>> list;
415
const
int
numScales = d->horizontalScale.size();
416
list.reserve(numScales);
417
for
(
int
i = 0; i < numScales; ++i)
418
list.emplace_back(d->horizontalScale.at(i).step,
419
QPointF(d->horizontalScale.at(i).value,
420
d->verticalScale.at(i).value));
421
422
return
list;
423
}
424
425
/*!
426
Returns the vertical shear for the item at the specified \a step value.
427
428
\sa setShearAt()
429
*/
430
qreal QGraphicsItemAnimation::verticalShearAt(qreal step)
const
431
{
432
check_step_valid(step,
"verticalShearAt"
);
433
return
d->linearValueForStep(step, d->verticalShear, 0);
434
}
435
436
/*!
437
Returns the horizontal shear for the item at the specified \a step value.
438
439
\sa setShearAt()
440
*/
441
qreal QGraphicsItemAnimation::horizontalShearAt(qreal step)
const
442
{
443
check_step_valid(step,
"horizontalShearAt"
);
444
return
d->linearValueForStep(step, d->horizontalShear, 0);
445
}
446
447
/*!
448
Sets the shear of the item at the given \a step value using the horizontal and
449
vertical shear factors specified by \a sh and \a sv.
450
451
\sa verticalShearAt(), horizontalShearAt()
452
*/
453
void
QGraphicsItemAnimation::setShearAt(qreal step, qreal sh, qreal sv)
454
{
455
d->insertUniquePair(step, sh, &d->horizontalShear,
"setShearAt"
);
456
d->insertUniquePair(step, sv, &d->verticalShear,
"setShearAt"
);
457
}
458
459
/*!
460
Returns all explicitly inserted shears.
461
462
\sa verticalShearAt(), horizontalShearAt(), setShearAt()
463
*/
464
QList<std::pair<qreal, QPointF> > QGraphicsItemAnimation::shearList()
const
465
{
466
QList<std::pair<qreal, QPointF>> list;
467
const
int
numShears = d->horizontalShear.size();
468
list.reserve(numShears);
469
for
(
int
i = 0; i < numShears; ++i)
470
list.emplace_back(d->horizontalShear.at(i).step,
471
QPointF(d->horizontalShear.at(i).value,
472
d->verticalShear.at(i).value));
473
474
return
list;
475
}
476
477
/*!
478
Clears the scheduled transformations used for the animation, but
479
retains the item and timeline.
480
*/
481
void
QGraphicsItemAnimation::clear()
482
{
483
d->xPosition.clear();
484
d->yPosition.clear();
485
d->rotation.clear();
486
d->verticalScale.clear();
487
d->horizontalScale.clear();
488
d->verticalShear.clear();
489
d->horizontalShear.clear();
490
d->xTranslation.clear();
491
d->yTranslation.clear();
492
}
493
494
/*!
495
\fn void QGraphicsItemAnimation::setStep(qreal step)
496
497
Sets the current \a step value for the animation, causing the
498
transformations scheduled at this step to be performed.
499
*/
500
void
QGraphicsItemAnimation::setStep(qreal step)
501
{
502
if
(!check_step_valid(step,
"setStep"
))
503
return
;
504
505
beforeAnimationStep(step);
506
507
d->step = step;
508
if
(d->item) {
509
if
(!d->xPosition.isEmpty() || !d->yPosition.isEmpty())
510
d->item->setPos(posAt(step));
511
if
(!d->rotation.isEmpty()
512
|| !d->verticalScale.isEmpty()
513
|| !d->horizontalScale.isEmpty()
514
|| !d->verticalShear.isEmpty()
515
|| !d->horizontalShear.isEmpty()
516
|| !d->xTranslation.isEmpty()
517
|| !d->yTranslation.isEmpty()) {
518
d->item->setTransform(d->startTransform * transformAt(step));
519
}
520
}
521
522
afterAnimationStep(step);
523
}
524
525
/*!
526
\fn void QGraphicsItemAnimation::beforeAnimationStep(qreal step)
527
528
This method is meant to be overridden by subclassed that needs to
529
execute additional code before a new step takes place. The
530
animation \a step is provided for use in cases where the action
531
depends on its value.
532
*/
533
void
QGraphicsItemAnimation::beforeAnimationStep(qreal step)
534
{
535
Q_UNUSED(step);
536
}
537
538
/*!
539
\fn void QGraphicsItemAnimation::afterAnimationStep(qreal step)
540
541
This method is meant to be overridden in subclasses that need to
542
execute additional code after a new step has taken place. The
543
animation \a step is provided for use in cases where the action
544
depends on its value.
545
*/
546
void
QGraphicsItemAnimation::afterAnimationStep(qreal step)
547
{
548
Q_UNUSED(step);
549
}
550
551
QT_END_NAMESPACE
552
553
#
include
"moc_qgraphicsitemanimation.cpp"
QGraphicsItemAnimationPrivate
Definition
qgraphicsitemanimation.cpp:69
QGraphicsItemAnimationPrivate::xPosition
QList< Pair > xPosition
Definition
qgraphicsitemanimation.cpp:93
QGraphicsItemAnimationPrivate::timeLine
QPointer< QTimeLine > timeLine
Definition
qgraphicsitemanimation.cpp:77
QGraphicsItemAnimationPrivate::insertUniquePair
void insertUniquePair(qreal step, qreal value, QList< Pair > *binList, const char *method)
Definition
qgraphicsitemanimation.cpp:139
QGraphicsItemAnimationPrivate::yPosition
QList< Pair > yPosition
Definition
qgraphicsitemanimation.cpp:94
QGraphicsItemAnimationPrivate::horizontalScale
QList< Pair > horizontalScale
Definition
qgraphicsitemanimation.cpp:97
QGraphicsItemAnimationPrivate::step
qreal step
Definition
qgraphicsitemanimation.cpp:83
QGraphicsItemAnimationPrivate::verticalShear
QList< Pair > verticalShear
Definition
qgraphicsitemanimation.cpp:98
QGraphicsItemAnimationPrivate::horizontalShear
QList< Pair > horizontalShear
Definition
qgraphicsitemanimation.cpp:99
QGraphicsItemAnimationPrivate::yTranslation
QList< Pair > yTranslation
Definition
qgraphicsitemanimation.cpp:101
QGraphicsItemAnimationPrivate::startTransform
QTransform startTransform
Definition
qgraphicsitemanimation.cpp:81
QGraphicsItemAnimationPrivate::item
QGraphicsItem * item
Definition
qgraphicsitemanimation.cpp:78
QGraphicsItemAnimationPrivate::verticalScale
QList< Pair > verticalScale
Definition
qgraphicsitemanimation.cpp:96
QGraphicsItemAnimationPrivate::rotation
QList< Pair > rotation
Definition
qgraphicsitemanimation.cpp:95
QGraphicsItemAnimationPrivate::linearValueForStep
qreal linearValueForStep(qreal step, const QList< Pair > &source, qreal defaultValue=0)
Definition
qgraphicsitemanimation.cpp:108
QGraphicsItemAnimationPrivate::QGraphicsItemAnimationPrivate
QGraphicsItemAnimationPrivate()
Definition
qgraphicsitemanimation.cpp:71
QGraphicsItemAnimationPrivate::xTranslation
QList< Pair > xTranslation
Definition
qgraphicsitemanimation.cpp:100
QGraphicsItemAnimationPrivate::q
QGraphicsItemAnimation * q
Definition
qgraphicsitemanimation.cpp:75
QGraphicsItemAnimationPrivate::startPos
QPointF startPos
Definition
qgraphicsitemanimation.cpp:80
QPointF
\inmodule QtCore\reentrant
Definition
qpoint.h:232
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
check_step_valid
static QT_BEGIN_NAMESPACE bool check_step_valid(qreal step, const char *method)
Definition
qgraphicsitemanimation.cpp:59
Q_DECLARE_TYPEINFO
Q_DECLARE_TYPEINFO(QGraphicsItemAnimationPrivate::Pair, Q_PRIMITIVE_TYPE)
QGraphicsItemAnimationPrivate::Pair
Definition
qgraphicsitemanimation.cpp:85
QGraphicsItemAnimationPrivate::Pair::operator==
bool operator==(const Pair &other) const
Definition
qgraphicsitemanimation.cpp:88
QGraphicsItemAnimationPrivate::Pair::value
qreal value
Definition
qgraphicsitemanimation.cpp:91
QGraphicsItemAnimationPrivate::Pair::step
qreal step
Definition
qgraphicsitemanimation.cpp:90
QGraphicsItemAnimationPrivate::Pair::operator<
bool operator<(const Pair &other) const
Definition
qgraphicsitemanimation.cpp:86
qtbase
src
widgets
graphicsview
qgraphicsitemanimation.cpp
Generated on
for Qt by
1.18.0