| /**************************************************************************** |
| ** |
| ** Copyright (C) 2019 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of Qt Quick Designer Components. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 or (at your option) any later version |
| ** approved by the KDE Free Qt Foundation. The licenses are as published by |
| ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qquicktimeline_p.h" |
| |
| #include <QtCore/qmath.h> |
| #include <QtGui/qpainter.h> |
| #include <QtQuick/private/qquickitem_p.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| class QQuickTimelinePrivate : public QObjectPrivate |
| { |
| Q_DECLARE_PUBLIC(QQuickTimeline) |
| public: |
| QQuickTimelinePrivate() : enabled(false), componentComplete(false) |
| { |
| } |
| |
| qreal startFrame = 0; |
| qreal endFrame = 0; |
| qreal currentFrame = 0; |
| |
| bool enabled:1; |
| bool componentComplete:1; |
| |
| protected: |
| void init(); |
| void disable(); |
| |
| static void append_keyframe(QQmlListProperty<QQuickKeyframeGroup> *list, QQuickKeyframeGroup *a); |
| static int keyframe_count(QQmlListProperty<QQuickKeyframeGroup> *list); |
| static QQuickKeyframeGroup* keyframe_at(QQmlListProperty<QQuickKeyframeGroup> *list, int pos); |
| static void clear_keyframes(QQmlListProperty<QQuickKeyframeGroup> *list); |
| |
| static void append_animation(QQmlListProperty<QQuickTimelineAnimation> *list, QQuickTimelineAnimation *a); |
| static int animation_count(QQmlListProperty<QQuickTimelineAnimation> *list); |
| static QQuickTimelineAnimation* animation_at(QQmlListProperty<QQuickTimelineAnimation> *list, int pos); |
| static void clear_animations(QQmlListProperty<QQuickTimelineAnimation> *list); |
| |
| QList<QQuickKeyframeGroup *> keyframeGroups; |
| QList<QQuickTimelineAnimation *> animations; |
| }; |
| |
| void QQuickTimelinePrivate::init() |
| { |
| for (auto keyFrames : keyframeGroups) { |
| keyFrames->init(); |
| keyFrames->setProperty(currentFrame); |
| } |
| } |
| |
| void QQuickTimelinePrivate::disable() |
| { |
| for (auto keyFrames : keyframeGroups) |
| keyFrames->resetDefaultValue(); |
| } |
| |
| void QQuickTimelinePrivate::append_keyframe(QQmlListProperty<QQuickKeyframeGroup> *list, QQuickKeyframeGroup *a) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| q->d_func()->keyframeGroups.append(a); |
| } |
| |
| int QQuickTimelinePrivate::keyframe_count(QQmlListProperty<QQuickKeyframeGroup> *list) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| return q->d_func()->keyframeGroups.count(); |
| } |
| |
| QQuickKeyframeGroup* QQuickTimelinePrivate::keyframe_at(QQmlListProperty<QQuickKeyframeGroup> *list, int pos) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| return q->d_func()->keyframeGroups.at(pos); |
| } |
| |
| void QQuickTimelinePrivate::clear_keyframes(QQmlListProperty<QQuickKeyframeGroup> *list) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| while (q->d_func()->keyframeGroups.count()) { |
| QQuickKeyframeGroup *firstKeyframe = q->d_func()->keyframeGroups.at(0); |
| q->d_func()->keyframeGroups.removeAll(firstKeyframe); |
| } |
| } |
| |
| void QQuickTimelinePrivate::append_animation(QQmlListProperty<QQuickTimelineAnimation> *list, QQuickTimelineAnimation *a) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| a->setTargetObject(q); |
| q->d_func()->animations.append(a); |
| } |
| |
| int QQuickTimelinePrivate::animation_count(QQmlListProperty<QQuickTimelineAnimation> *list) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| return q->d_func()->animations.count(); |
| } |
| |
| QQuickTimelineAnimation* QQuickTimelinePrivate::animation_at(QQmlListProperty<QQuickTimelineAnimation> *list, int pos) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| return q->d_func()->animations.at(pos); |
| } |
| |
| void QQuickTimelinePrivate::clear_animations(QQmlListProperty<QQuickTimelineAnimation> *list) |
| { |
| auto q = static_cast<QQuickTimeline *>(list->object); |
| while (q->d_func()->animations.count()) { |
| QQuickTimelineAnimation *firstAnimation = q->d_func()->animations.at(0); |
| q->d_func()->animations.removeAll(firstAnimation); |
| } |
| } |
| |
| /*! |
| \qmltype Timeline |
| \inherits QObject |
| \instantiates QQuickTimeline |
| \inqmlmodule QtQuick.Timeline |
| \ingroup qtqmltypes |
| |
| \brief A timeline. |
| |
| Specifies a timeline with a range of keyframes that contain values for the |
| properties of an object. The timeline allows specifying the values of items |
| depending on keyframes and their easing curves. |
| |
| A timeline can be either used for animations or to control the behavior of |
| items. |
| |
| For example, it is possible to create a progress bar where the current frame |
| reflects the progress. |
| */ |
| |
| /*! |
| \qmlproperty double Timeline::startFrame |
| |
| The start of the timeline. |
| */ |
| |
| /*! |
| \qmlproperty double Timeline::endFrame |
| |
| The end of the timeline. |
| */ |
| |
| /*! |
| \qmlproperty double Timeline::currentFrame |
| |
| The current keyframe on the timeline. The current keyframe can be animated |
| or a binding can be attached to it. Using bindings allows controlling |
| the behavior of components. |
| */ |
| |
| /*! |
| \qmlproperty list Timeline::keyframes |
| \readonly |
| |
| This property contains the keyframe groups attached to the timeline. |
| Each keyframe group contains a list of keyframes for a specific item |
| and property. |
| */ |
| |
| /*! |
| \qmlproperty list Timeline::animations |
| \readonly |
| |
| A list of animations attached to the timeline. |
| */ |
| |
| /*! |
| \qmlproperty bool Timeline::enabled |
| |
| Whether the timeline is enabled. |
| |
| When the timeline is disabled, all items will have their regular values. |
| When the timeline is enabled, the values of items are determined by the |
| current frame and the keyframes. |
| |
| Only one timeline should be active at a particular time. |
| */ |
| |
| QQuickTimeline::QQuickTimeline(QObject *parent) : QObject(*(new QQuickTimelinePrivate), parent) |
| { |
| } |
| |
| QQmlListProperty<QQuickKeyframeGroup> QQuickTimeline::keyframeGroups() |
| { |
| Q_D(QQuickTimeline); |
| |
| return { this, &d->keyframeGroups, QQuickTimelinePrivate::append_keyframe, |
| QQuickTimelinePrivate::keyframe_count, |
| QQuickTimelinePrivate::keyframe_at, |
| QQuickTimelinePrivate::clear_keyframes }; |
| } |
| |
| QQmlListProperty<QQuickTimelineAnimation> QQuickTimeline::animations() |
| { |
| Q_D(QQuickTimeline); |
| |
| return { this, &d->animations, QQuickTimelinePrivate::append_animation, |
| QQuickTimelinePrivate::animation_count, |
| QQuickTimelinePrivate::animation_at, |
| QQuickTimelinePrivate::clear_animations }; |
| } |
| |
| bool QQuickTimeline::enabled() const |
| { |
| Q_D(const QQuickTimeline); |
| return d->enabled; |
| } |
| |
| void QQuickTimeline::setEnabled(bool b) |
| { |
| Q_D(QQuickTimeline); |
| if (d->enabled == b) |
| return; |
| d->enabled = b; |
| |
| if (d->componentComplete) { |
| if (b) |
| init(); |
| else |
| reset(); |
| } |
| |
| emit enabledChanged(); |
| } |
| |
| qreal QQuickTimeline::startFrame() const |
| { |
| Q_D(const QQuickTimeline); |
| return d->startFrame; |
| } |
| |
| void QQuickTimeline::setStartFrame(qreal frame) |
| { |
| Q_D(QQuickTimeline); |
| if (d->startFrame == frame) |
| return; |
| d->startFrame = frame; |
| emit startFrameChanged(); |
| } |
| |
| qreal QQuickTimeline::endFrame() const |
| { |
| Q_D(const QQuickTimeline); |
| return d->endFrame; |
| } |
| |
| void QQuickTimeline::setEndFrame(qreal frame) |
| { |
| Q_D(QQuickTimeline); |
| if (d->endFrame == frame) |
| return; |
| d->endFrame = frame; |
| emit endFrameChanged(); |
| } |
| |
| qreal QQuickTimeline::currentFrame() const |
| { |
| Q_D(const QQuickTimeline); |
| return d->currentFrame; |
| } |
| |
| void QQuickTimeline::setCurrentFrame(qreal frame) |
| { |
| Q_D(QQuickTimeline); |
| if (d->currentFrame == frame) |
| return; |
| d->currentFrame = frame; |
| |
| reevaulate(); |
| |
| emit currentFrameChanged(); |
| } |
| |
| void QQuickTimeline::reevaulate() |
| { |
| Q_D(QQuickTimeline); |
| |
| if (d->componentComplete && d->enabled) |
| for (auto keyFrames : d->keyframeGroups) |
| keyFrames->setProperty(d->currentFrame); |
| } |
| |
| void QQuickTimeline::init() |
| { |
| Q_D(QQuickTimeline); |
| |
| if (d->componentComplete) |
| d->init(); |
| } |
| |
| void QQuickTimeline::reset() |
| { |
| Q_D(QQuickTimeline); |
| |
| if (d->componentComplete) |
| d->disable(); |
| } |
| |
| QList<QQuickTimelineAnimation *> QQuickTimeline::getAnimations() const |
| { |
| Q_D(const QQuickTimeline); |
| |
| return d->animations; |
| } |
| |
| void QQuickTimeline::classBegin() |
| { |
| Q_D(QQuickTimeline); |
| d->componentComplete = false; |
| } |
| |
| void QQuickTimeline::componentComplete() |
| { |
| Q_D(QQuickTimeline); |
| d->componentComplete = true; |
| |
| if (d->enabled) |
| init(); |
| } |
| |
| QT_END_NAMESPACE |