1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquicktimeline_p.h"
5
6#include <QtCore/qmath.h>
7#include <QtGui/qpainter.h>
8
9QT_BEGIN_NAMESPACE
10
11class QQuickTimelinePrivate : public QObjectPrivate
12{
13 Q_DECLARE_PUBLIC(QQuickTimeline)
14public:
15 QQuickTimelinePrivate() : enabled(false), componentComplete(false)
16 {
17 }
18
19 qreal startFrame = 0;
20 qreal endFrame = 0;
21 qreal currentFrame = 0;
22
23 bool enabled:1;
24 bool componentComplete:1;
25
26protected:
27 void init();
28 void disable();
29
30 static void append_keyframe(QQmlListProperty<QQuickKeyframeGroup> *list, QQuickKeyframeGroup *a);
31 static qsizetype keyframe_count(QQmlListProperty<QQuickKeyframeGroup> *list);
32 static QQuickKeyframeGroup* keyframe_at(QQmlListProperty<QQuickKeyframeGroup> *list, qsizetype pos);
33 static void clear_keyframes(QQmlListProperty<QQuickKeyframeGroup> *list);
34
35 static void append_animation(QQmlListProperty<QQuickTimelineAnimation> *list, QQuickTimelineAnimation *a);
36 static qsizetype animation_count(QQmlListProperty<QQuickTimelineAnimation> *list);
37 static QQuickTimelineAnimation* animation_at(QQmlListProperty<QQuickTimelineAnimation> *list, qsizetype pos);
38 static void clear_animations(QQmlListProperty<QQuickTimelineAnimation> *list);
39
40 QList<QQuickKeyframeGroup *> keyframeGroups;
41 QList<QQuickTimelineAnimation *> animations;
42};
43
44void QQuickTimelinePrivate::init()
45{
46 for (auto keyFrames : keyframeGroups) {
47 keyFrames->init();
48 keyFrames->setProperty(currentFrame);
49 }
50}
51
52void QQuickTimelinePrivate::disable()
53{
54 for (auto keyFrames : keyframeGroups)
55 keyFrames->resetDefaultValue();
56}
57
58void QQuickTimelinePrivate::append_keyframe(QQmlListProperty<QQuickKeyframeGroup> *list, QQuickKeyframeGroup *a)
59{
60 auto q = static_cast<QQuickTimeline *>(list->object);
61 q->d_func()->keyframeGroups.append(t: a);
62}
63
64qsizetype QQuickTimelinePrivate::keyframe_count(QQmlListProperty<QQuickKeyframeGroup> *list)
65{
66 auto q = static_cast<QQuickTimeline *>(list->object);
67 return q->d_func()->keyframeGroups.size();
68}
69
70QQuickKeyframeGroup* QQuickTimelinePrivate::keyframe_at(QQmlListProperty<QQuickKeyframeGroup> *list, qsizetype pos)
71{
72 auto q = static_cast<QQuickTimeline *>(list->object);
73 return q->d_func()->keyframeGroups.at(i: pos);
74}
75
76void QQuickTimelinePrivate::clear_keyframes(QQmlListProperty<QQuickKeyframeGroup> *list)
77{
78 auto q = static_cast<QQuickTimeline *>(list->object);
79 while (q->d_func()->keyframeGroups.size()) {
80 QQuickKeyframeGroup *firstKeyframe = q->d_func()->keyframeGroups.at(i: 0);
81 q->d_func()->keyframeGroups.removeAll(t: firstKeyframe);
82 }
83}
84
85void QQuickTimelinePrivate::append_animation(QQmlListProperty<QQuickTimelineAnimation> *list, QQuickTimelineAnimation *a)
86{
87 auto q = static_cast<QQuickTimeline *>(list->object);
88 a->setTargetObject(q);
89 q->d_func()->animations.append(t: a);
90}
91
92qsizetype QQuickTimelinePrivate::animation_count(QQmlListProperty<QQuickTimelineAnimation> *list)
93{
94 auto q = static_cast<QQuickTimeline *>(list->object);
95 return q->d_func()->animations.size();
96}
97
98QQuickTimelineAnimation* QQuickTimelinePrivate::animation_at(QQmlListProperty<QQuickTimelineAnimation> *list, qsizetype pos)
99{
100 auto q = static_cast<QQuickTimeline *>(list->object);
101 return q->d_func()->animations.at(i: pos);
102}
103
104void QQuickTimelinePrivate::clear_animations(QQmlListProperty<QQuickTimelineAnimation> *list)
105{
106 auto q = static_cast<QQuickTimeline *>(list->object);
107 while (q->d_func()->animations.size()) {
108 QQuickTimelineAnimation *firstAnimation = q->d_func()->animations.at(i: 0);
109 q->d_func()->animations.removeAll(t: firstAnimation);
110 }
111}
112
113/*!
114 \qmltype Timeline
115 \inherits QtObject
116 \nativetype QQuickTimeline
117 \inqmlmodule QtQuick.Timeline
118 \ingroup qtqmltypes
119
120 \brief A timeline.
121
122 Specifies a timeline with a range of keyframes that contain values for the
123 properties of an object. The timeline allows specifying the values of items
124 depending on keyframes and their easing curves.
125
126 A timeline can be either used for animations or to control the behavior of
127 items.
128
129 For example, it is possible to create a progress bar where the current frame
130 reflects the progress.
131*/
132
133/*!
134 \qmlproperty double Timeline::startFrame
135
136 The start of the timeline.
137*/
138
139/*!
140 \qmlproperty double Timeline::endFrame
141
142 The end of the timeline.
143*/
144
145/*!
146 \qmlproperty double Timeline::currentFrame
147
148 The current keyframe on the timeline. The current keyframe can be animated
149 or a binding can be attached to it. Using bindings allows controlling
150 the behavior of components.
151*/
152
153/*!
154 \qmlproperty list Timeline::keyframes
155 \readonly
156
157 This property contains the keyframe groups attached to the timeline.
158 Each keyframe group contains a list of keyframes for a specific item
159 and property.
160*/
161
162/*!
163 \qmlproperty list Timeline::animations
164 \readonly
165
166 A list of animations attached to the timeline.
167*/
168
169/*!
170 \qmlproperty bool Timeline::enabled
171
172 Whether the timeline is enabled.
173
174 When the timeline is disabled, all items will have their regular values.
175 When the timeline is enabled, the values of items are determined by the
176 current frame and the keyframes.
177
178 Only one timeline should be active at a particular time.
179*/
180
181QQuickTimeline::QQuickTimeline(QObject *parent) : QObject(*(new QQuickTimelinePrivate), parent)
182{
183}
184
185QQmlListProperty<QQuickKeyframeGroup> QQuickTimeline::keyframeGroups()
186{
187 Q_D(QQuickTimeline);
188
189 return { this, &d->keyframeGroups, QQuickTimelinePrivate::append_keyframe,
190 QQuickTimelinePrivate::keyframe_count,
191 QQuickTimelinePrivate::keyframe_at,
192 QQuickTimelinePrivate::clear_keyframes };
193}
194
195QQmlListProperty<QQuickTimelineAnimation> QQuickTimeline::animations()
196{
197 Q_D(QQuickTimeline);
198
199 return { this, &d->animations, QQuickTimelinePrivate::append_animation,
200 QQuickTimelinePrivate::animation_count,
201 QQuickTimelinePrivate::animation_at,
202 QQuickTimelinePrivate::clear_animations };
203}
204
205bool QQuickTimeline::enabled() const
206{
207 Q_D(const QQuickTimeline);
208 return d->enabled;
209}
210
211void QQuickTimeline::setEnabled(bool b)
212{
213 Q_D(QQuickTimeline);
214 if (d->enabled == b)
215 return;
216 d->enabled = b;
217
218 if (d->componentComplete) {
219 if (b)
220 init();
221 else
222 reset();
223 }
224
225 emit enabledChanged();
226}
227
228qreal QQuickTimeline::startFrame() const
229{
230 Q_D(const QQuickTimeline);
231 return d->startFrame;
232}
233
234void QQuickTimeline::setStartFrame(qreal frame)
235{
236 Q_D(QQuickTimeline);
237 if (d->startFrame == frame)
238 return;
239 d->startFrame = frame;
240 emit startFrameChanged();
241}
242
243qreal QQuickTimeline::endFrame() const
244{
245 Q_D(const QQuickTimeline);
246 return d->endFrame;
247}
248
249void QQuickTimeline::setEndFrame(qreal frame)
250{
251 Q_D(QQuickTimeline);
252 if (d->endFrame == frame)
253 return;
254 d->endFrame = frame;
255 emit endFrameChanged();
256}
257
258qreal QQuickTimeline::currentFrame() const
259{
260 Q_D(const QQuickTimeline);
261 return d->currentFrame;
262}
263
264void QQuickTimeline::setCurrentFrame(qreal frame)
265{
266 Q_D(QQuickTimeline);
267 if (d->currentFrame == frame)
268 return;
269 d->currentFrame = frame;
270
271 reevaluate();
272
273 emit currentFrameChanged();
274}
275
276void QQuickTimeline::reevaluate()
277{
278 Q_D(QQuickTimeline);
279
280 if (d->componentComplete && d->enabled)
281 for (auto keyFrames : d->keyframeGroups)
282 keyFrames->setProperty(d->currentFrame);
283}
284
285void QQuickTimeline::init()
286{
287 Q_D(QQuickTimeline);
288
289 if (d->componentComplete)
290 d->init();
291}
292
293void QQuickTimeline::reset()
294{
295 Q_D(QQuickTimeline);
296
297 if (d->componentComplete)
298 d->disable();
299}
300
301QList<QQuickTimelineAnimation *> QQuickTimeline::getAnimations() const
302{
303 Q_D(const QQuickTimeline);
304
305 return d->animations;
306}
307
308void QQuickTimeline::classBegin()
309{
310 Q_D(QQuickTimeline);
311 d->componentComplete = false;
312}
313
314void QQuickTimeline::componentComplete()
315{
316 Q_D(QQuickTimeline);
317 d->componentComplete = true;
318
319 if (d->enabled)
320 init();
321}
322
323QT_END_NAMESPACE
324

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtquicktimeline/src/timeline/qquicktimeline.cpp