From 6a3cc36e4ad2d9256f5ed2358b2dc5cf669f7984 Mon Sep 17 00:00:00 2001 From: Andreas Buhr Date: Mon, 7 Dec 2020 11:13:17 +0100 Subject: Port of QTimeLine to new property system The six properties duration, updateInterval, currentTime, direction, loopCount and easingCurve have been ported to the new property system and are now bindable. Drive-by renamed a local variable to avoid shadowing. Task-number: QTBUG-85520 Change-Id: Ibabf106f5200d2dd4329a1e1f96112eccc29d6b1 Reviewed-by: Sona Kurazyan Reviewed-by: Ivan Solovev Reviewed-by: Edward Welbourne --- src/corelib/tools/qtimeline.cpp | 140 ++++++++++++++++++++++++++++------------ src/corelib/tools/qtimeline.h | 20 ++++-- 2 files changed, 111 insertions(+), 49 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index 4609b258fc..8a01dbe685 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -39,6 +39,7 @@ #include "qtimeline.h" +#include #include #include #include @@ -50,31 +51,29 @@ class QTimeLinePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QTimeLine) public: - inline QTimeLinePrivate() - : easingCurve(QEasingCurve::InOutSine), - startTime(0), duration(1000), startFrame(0), endFrame(0), - updateInterval(1000 / 25), - totalLoopCount(1), currentLoopCount(0), currentTime(0), timerId(0), - direction(QTimeLine::Forward), - state(QTimeLine::NotRunning) - { } - QElapsedTimer timer; - QEasingCurve easingCurve; - - int startTime; - int duration; - int startFrame; - int endFrame; - int updateInterval; - int totalLoopCount; - int currentLoopCount; - - int currentTime; - int timerId; - - QTimeLine::Direction direction; - QTimeLine::State state; + Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QTimeLinePrivate, QEasingCurve, easingCurve, + QEasingCurve::InOutSine) + + int startTime = 0; + void setDuration(int duration) { q_func()->setDuration(duration); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QTimeLinePrivate, int, duration, + &QTimeLinePrivate::setDuration, 1000) + int startFrame = 0; + int endFrame = 0; + Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QTimeLinePrivate, int, updateInterval, 1000 / 25) + Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QTimeLinePrivate, int, loopCount, 1) + int currentLoopCount = 0; + + void setCurrentTimeForwardToQ(int time) { q_func()->setCurrentTime(time); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QTimeLinePrivate, int, currentTime, + &QTimeLinePrivate::setCurrentTimeForwardToQ, 0) + int timerId = 0; + + void setDirection(QTimeLine::Direction direction) { q_func()->setDirection(direction); } + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QTimeLinePrivate, QTimeLine::Direction, direction, + &QTimeLinePrivate::setDirection, QTimeLine::Forward) + QTimeLine::State state = QTimeLine::NotRunning; inline void setState(QTimeLine::State newState) { Q_Q(QTimeLine); @@ -91,34 +90,35 @@ public: void QTimeLinePrivate::setCurrentTime(int msecs) { Q_Q(QTimeLine); + currentTime.removeBindingUnlessInWrapper(); + auto previousCurrentTime = currentTime.value(); qreal lastValue = q->currentValue(); int lastFrame = q->currentFrame(); // Determine if we are looping. int elapsed = (direction == QTimeLine::Backward) ? (-msecs + duration) : msecs; - int loopCount = elapsed / duration; + int loopCountNow = elapsed / duration; - bool looping = (loopCount != currentLoopCount); + bool looping = (loopCountNow != currentLoopCount); #ifdef QTIMELINE_DEBUG - qDebug() << "QTimeLinePrivate::setCurrentTime:" << msecs << duration << "with loopCount" << loopCount - << "currentLoopCount" << currentLoopCount - << "looping" << looping; + qDebug() << "QTimeLinePrivate::setCurrentTime:" << msecs << duration << "with loopCountNow" + << loopCountNow << "currentLoopCount" << currentLoopCount << "looping" << looping; #endif if (looping) - currentLoopCount = loopCount; + currentLoopCount = loopCountNow; // Normalize msecs to be between 0 and duration, inclusive. - currentTime = elapsed % duration; - if (direction == QTimeLine::Backward) - currentTime = duration - currentTime; + currentTime.setValueBypassingBindings(elapsed % duration); + if (direction.value() == QTimeLine::Backward) + currentTime.setValueBypassingBindings(duration - currentTime); // Check if we have reached the end of loopcount. bool finished = false; - if (totalLoopCount && currentLoopCount >= totalLoopCount) { + if (loopCount && currentLoopCount >= loopCount) { finished = true; - currentTime = (direction == QTimeLine::Backward) ? 0 : duration; - currentLoopCount = totalLoopCount - 1; + currentTime.setValueBypassingBindings((direction == QTimeLine::Backward) ? 0 : duration); + currentLoopCount = loopCount - 1; } int currentFrame = q->frameForTime(currentTime); @@ -159,6 +159,13 @@ void QTimeLinePrivate::setCurrentTime(int msecs) q->stop(); emit q->finished(QTimeLine::QPrivateSignal()); } + if (currentTime.value() != previousCurrentTime) + currentTime.notify(); +} +QBindable QTimeLine::bindableCurrentTime() +{ + Q_D(QTimeLine); + return &d->currentTime; } /*! @@ -326,12 +333,19 @@ QTimeLine::State QTimeLine::state() const int QTimeLine::loopCount() const { Q_D(const QTimeLine); - return d->totalLoopCount; + return d->loopCount; } + void QTimeLine::setLoopCount(int count) { Q_D(QTimeLine); - d->totalLoopCount = count; + d->loopCount = count; +} + +QBindable QTimeLine::bindableLoopCount() +{ + Q_D(QTimeLine); + return &d->loopCount; } /*! @@ -343,6 +357,9 @@ void QTimeLine::setLoopCount(int count) timeline duration, or from the value of the duration and towards 0 after start() has been called. + Any binding of direction will be removed not only by setDirection(), + but also by toggleDirection(). + By default, this property is set to \l Forward. */ QTimeLine::Direction QTimeLine::direction() const @@ -353,9 +370,18 @@ QTimeLine::Direction QTimeLine::direction() const void QTimeLine::setDirection(Direction direction) { Q_D(QTimeLine); - d->direction = direction; + auto previousDirection = d->direction.value(); + d->direction.setValue(direction); d->startTime = d->currentTime; d->timer.start(); + if (previousDirection != d->direction.value()) + d->direction.notify(); +} + +QBindable QTimeLine::bindableDirection() +{ + Q_D(QTimeLine); + return &d->direction; } /*! @@ -382,7 +408,18 @@ void QTimeLine::setDuration(int duration) qWarning("QTimeLine::setDuration: cannot set duration <= 0"); return; } - d->duration = duration; + if (duration == d->duration) { + d->duration.removeBindingUnlessInWrapper(); + return; + } + d->duration.setValue(duration); + d->duration.notify(); +} + +QBindable QTimeLine::bindableDuration() +{ + Q_D(QTimeLine); + return &d->duration; } /*! @@ -472,6 +509,11 @@ void QTimeLine::setUpdateInterval(int interval) Q_D(QTimeLine); d->updateInterval = interval; } +QBindable QTimeLine::bindableUpdateInterval() +{ + Q_D(QTimeLine); + return &d->updateInterval; +} /*! \property QTimeLine::easingCurve @@ -496,6 +538,12 @@ void QTimeLine::setEasingCurve(const QEasingCurve &curve) d->easingCurve = curve; } +QBindable QTimeLine::bindableEasingCurve() +{ + Q_D(QTimeLine); + return &d->easingCurve; +} + /*! \property QTimeLine::currentTime \brief the current time of the time line. @@ -505,6 +553,10 @@ void QTimeLine::setEasingCurve(const QEasingCurve &curve) value that was current when stop() was called last, or the value set by setCurrentTime(). + \note You can bind other properties to currentTime, but it is not + recommended setting bindings to it. As animation progresses, the currentTime + is updated automatically, which cancels its bindings. + By default, this property contains a value of 0. */ int QTimeLine::currentTime() const @@ -571,10 +623,10 @@ int QTimeLine::frameForTime(int msec) const qreal QTimeLine::valueForTime(int msec) const { Q_D(const QTimeLine); - msec = qMin(qMax(msec, 0), d->duration); + msec = qBound(0, msec, d->duration.value()); - qreal value = msec / qreal(d->duration); - return d->easingCurve.valueForProgress(value); + qreal value = msec / qreal(d->duration.value()); + return d->easingCurve.value().valueForProgress(value); } /*! @@ -678,6 +730,8 @@ void QTimeLine::setPaused(bool paused) Toggles the direction of the timeline. If the direction was Forward, it becomes Backward, and vice verca. + Existing bindings of \l direction are removed. + \sa setDirection() */ void QTimeLine::toggleDirection() diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 193c372c6a..48a06f06df 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.h @@ -54,12 +54,14 @@ class QTimeLinePrivate; class Q_CORE_EXPORT QTimeLine : public QObject { Q_OBJECT - Q_PROPERTY(int duration READ duration WRITE setDuration) - Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval) - Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime) - Q_PROPERTY(Direction direction READ direction WRITE setDirection) - Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount) - Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve) + Q_PROPERTY(int duration READ duration WRITE setDuration BINDABLE bindableDuration) + Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval + BINDABLE bindableUpdateInterval) + Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime BINDABLE bindableCurrentTime) + Q_PROPERTY(Direction direction READ direction WRITE setDirection BINDABLE bindableDirection) + Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount BINDABLE bindableLoopCount) + Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve + BINDABLE bindableEasingCurve) public: enum State { NotRunning, @@ -78,12 +80,15 @@ public: int loopCount() const; void setLoopCount(int count); + QBindable bindableLoopCount(); Direction direction() const; void setDirection(Direction direction); + QBindable bindableDirection(); int duration() const; void setDuration(int duration); + QBindable bindableDuration(); int startFrame() const; void setStartFrame(int frame); @@ -93,11 +98,14 @@ public: int updateInterval() const; void setUpdateInterval(int interval); + QBindable bindableUpdateInterval(); QEasingCurve easingCurve() const; void setEasingCurve(const QEasingCurve &curve); + QBindable bindableEasingCurve(); int currentTime() const; + QBindable bindableCurrentTime(); int currentFrame() const; qreal currentValue() const; -- cgit v1.2.3