diff options
Diffstat (limited to 'src/quick/util')
29 files changed, 564 insertions, 551 deletions
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 206b92eb81..9de474ac36 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -1198,14 +1198,14 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti struct QQuickSetPropertyAnimationAction : public QAbstractAnimationAction { QQuickStateActions actions; - virtual void doAction() + void doAction() override { for (int ii = 0; ii < actions.count(); ++ii) { const QQuickStateAction &action = actions.at(ii); QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); } } - virtual void debugAction(QDebug d, int indentLevel) const { + void debugAction(QDebug d, int indentLevel) const override { QByteArray ind(indentLevel, ' '); for (int ii = 0; ii < actions.count(); ++ii) { const QQuickStateAction &action = actions.at(ii); diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h index 145f2656d2..e27871dcaa 100644 --- a/src/quick/util/qquickanimation_p.h +++ b/src/quick/util/qquickanimation_p.h @@ -114,8 +114,8 @@ public: void setDisableUserControl(); void setEnableUserControl(); bool userControlDisabled() const; - void classBegin(); - void componentComplete(); + void classBegin() override; + void componentComplete() override; virtual ThreadingModel threadingModel() const; @@ -150,7 +150,7 @@ public: private Q_SLOTS: void componentFinalized(); private: - virtual void setTarget(const QQmlProperty &); + void setTarget(const QQmlProperty &) override; void notifyRunningChanged(bool running); friend class QQuickBehavior; friend class QQuickBehaviorPrivate; @@ -179,7 +179,7 @@ protected: QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; }; class QQuickScriptActionPrivate; @@ -202,10 +202,10 @@ public: void setStateChangeScriptName(const QString &); protected: - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; }; class QQuickPropertyActionPrivate; @@ -247,10 +247,10 @@ Q_SIGNALS: void propertyChanged(); protected: - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; }; class QQuickPropertyAnimationPrivate; @@ -303,10 +303,10 @@ protected: QObject *defaultTarget = 0); QQuickPropertyAnimation(QQuickPropertyAnimationPrivate &dd, QObject *parent); - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; Q_SIGNALS: void durationChanged(int); void fromChanged(const QVariant &); @@ -438,11 +438,11 @@ public: virtual ~QQuickSequentialAnimation(); protected: - virtual ThreadingModel threadingModel() const; - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + ThreadingModel threadingModel() const override; + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; }; class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGroup @@ -455,11 +455,11 @@ public: virtual ~QQuickParallelAnimation(); protected: - virtual ThreadingModel threadingModel() const; - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + ThreadingModel threadingModel() const override; + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; }; diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index ea7bf62171..a7abc5a004 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -88,8 +88,8 @@ class QAnimationActionProxy : public QAbstractAnimationAction { public: QAnimationActionProxy(T *instance) : m_instance(instance) {} - virtual void doAction() { (m_instance->*method)(); } - virtual void debugAction(QDebug d, int indentLevel) const { (m_instance->*debugMethod)(d, indentLevel); } + void doAction() override { (m_instance->*method)(); } + void debugAction(QDebug d, int indentLevel) const override { (m_instance->*debugMethod)(d, indentLevel); } private: T *m_instance; }; @@ -104,13 +104,13 @@ public: QActionAnimation(QAbstractAnimationAction *action); ~QActionAnimation(); - virtual int duration() const; + int duration() const override; void setAnimAction(QAbstractAnimationAction *action); protected: - virtual void updateCurrentTime(int); - virtual void updateState(State newState, State oldState); - void debugAnimation(QDebug d) const; + void updateCurrentTime(int) override; + void updateState(State newState, State oldState) override; + void debugAnimation(QDebug d) const override; private: QAbstractAnimationAction *animAction; @@ -137,16 +137,16 @@ public: void setFromSourcedValue(bool *value) { fromSourced = value; } - int duration() const { return m_duration; } + int duration() const override { return m_duration; } void setDuration(int msecs) { m_duration = msecs; } QEasingCurve easingCurve() const { return easing; } void setEasingCurve(const QEasingCurve &curve) { easing = curve; } protected: - void updateCurrentTime(int currentTime); - void topLevelAnimationLoopChanged(); - void debugAnimation(QDebug d) const; + void updateCurrentTime(int currentTime) override; + void topLevelAnimationLoopChanged() override; + void debugAnimation(QDebug d) const override; private: QQuickBulkValueUpdater *animValue; @@ -162,9 +162,9 @@ class QTickAnimationProxy : public QAbstractAnimationJob Q_DISABLE_COPY(QTickAnimationProxy) public: QTickAnimationProxy(T *instance) : QAbstractAnimationJob(), m_instance(instance) {} - virtual int duration() const { return -1; } + int duration() const override { return -1; } protected: - virtual void updateCurrentTime(int msec) { (m_instance->*method)(msec); } + void updateCurrentTime(int msec) override { (m_instance->*method)(msec); } private: T *m_instance; @@ -192,7 +192,7 @@ public: int loopCount; void commence(); - virtual void animationFinished(QAbstractAnimationJob *); + void animationFinished(QAbstractAnimationJob *) override; QQmlProperty defaultProperty; @@ -309,9 +309,9 @@ public: QQuickAnimationPropertyUpdater() : interpolatorType(0), interpolator(0), prevInterpolatorType(0), reverse(false), fromSourced(false), fromDefined(false), wasDeleted(0) {} ~QQuickAnimationPropertyUpdater(); - void setValue(qreal v); + void setValue(qreal v) override; - void debugUpdater(QDebug d, int indentLevel) const; + void debugUpdater(QDebug d, int indentLevel) const override; QQuickStateActions actions; int interpolatorType; //for Number/ColorAnimation diff --git a/src/quick/util/qquickanimationcontroller.cpp b/src/quick/util/qquickanimationcontroller.cpp index 8b6968ad98..4bc2d6319e 100644 --- a/src/quick/util/qquickanimationcontroller.cpp +++ b/src/quick/util/qquickanimationcontroller.cpp @@ -50,8 +50,8 @@ class QQuickAnimationControllerPrivate : public QObjectPrivate, QAnimationJobCha public: QQuickAnimationControllerPrivate() : progress(0.0), animation(0), animationInstance(0), finalized(false) {} - virtual void animationFinished(QAbstractAnimationJob *job); - virtual void animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime); + void animationFinished(QAbstractAnimationJob *job) override; + void animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime) override; qreal progress; diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h index e37bb90a0a..43555ac1c1 100644 --- a/src/quick/util/qquickanimationcontroller_p.h +++ b/src/quick/util/qquickanimationcontroller_p.h @@ -78,8 +78,8 @@ public: QQuickAbstractAnimation *animation() const; void setAnimation(QQuickAbstractAnimation *animation); - void classBegin(); - void componentComplete() {} + void classBegin() override; + void componentComplete() override {} Q_SIGNALS: void progressChanged(); void animationChanged(); diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h index 0fc900c5ac..92c66299dc 100644 --- a/src/quick/util/qquickanimator_p.h +++ b/src/quick/util/qquickanimator_p.h @@ -86,13 +86,13 @@ public: void setFrom(qreal from); protected: - ThreadingModel threadingModel() const { return RenderThread; } + ThreadingModel threadingModel() const override { return RenderThread; } virtual QQuickAnimatorJob *createJob() const = 0; virtual QString propertyName() const = 0; QAbstractAnimationJob *transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection, - QObject *); + QObject *) override; QQuickAnimator(QQuickAnimatorPrivate &dd, QObject *parent = 0); QQuickAnimator(QObject *parent = 0); @@ -112,8 +112,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimator : public QQuickAnimator public: QQuickScaleAnimator(QObject *parent = 0); protected: - QQuickAnimatorJob *createJob() const; - QString propertyName() const { return QStringLiteral("scale"); } + QQuickAnimatorJob *createJob() const override; + QString propertyName() const override { return QStringLiteral("scale"); } }; class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator @@ -122,8 +122,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator public: QQuickXAnimator(QObject *parent = 0); protected: - QQuickAnimatorJob *createJob() const; - QString propertyName() const{ return QStringLiteral("x"); } + QQuickAnimatorJob *createJob() const override; + QString propertyName() const override { return QStringLiteral("x"); } }; class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator @@ -132,8 +132,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator public: QQuickYAnimator(QObject *parent = 0); protected: - QQuickAnimatorJob *createJob() const; - QString propertyName() const { return QStringLiteral("y"); } + QQuickAnimatorJob *createJob() const override; + QString propertyName() const override { return QStringLiteral("y"); } }; class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator @@ -142,8 +142,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator public: QQuickOpacityAnimator(QObject *parent = 0); protected: - QQuickAnimatorJob *createJob() const; - QString propertyName() const { return QStringLiteral("opacity"); } + QQuickAnimatorJob *createJob() const override; + QString propertyName() const override { return QStringLiteral("opacity"); } }; class QQuickRotationAnimatorPrivate; @@ -166,8 +166,8 @@ Q_SIGNALS: void directionChanged(RotationDirection dir); protected: - QQuickAnimatorJob *createJob() const; - QString propertyName() const { return QStringLiteral("rotation"); } + QQuickAnimatorJob *createJob() const override; + QString propertyName() const override { return QStringLiteral("rotation"); } }; #if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) @@ -188,8 +188,8 @@ Q_SIGNALS: void uniformChanged(const QString &); protected: - QQuickAnimatorJob *createJob() const; - QString propertyName() const; + QQuickAnimatorJob *createJob() const override; + QString propertyName() const override; }; #endif diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 6d8167413e..2f96c511c0 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -50,228 +51,116 @@ QT_BEGIN_NAMESPACE -QQuickAnimatorController::QQuickAnimatorController(QQuickWindow *window) - : m_window(window) - , m_nodesAreInvalid(false) -{ - m_guiEntity = new QQuickAnimatorControllerGuiThreadEntity(); - m_guiEntity->controller = this; - connect(window, SIGNAL(frameSwapped()), m_guiEntity, SLOT(frameSwapped())); -} - -void QQuickAnimatorControllerGuiThreadEntity::frameSwapped() +QQuickAnimatorController::~QQuickAnimatorController() { - if (!controller.isNull()) - controller->stopProxyJobs(); } -QQuickAnimatorController::~QQuickAnimatorController() +QQuickAnimatorController::QQuickAnimatorController(QQuickWindow *window) + : m_window(window) { - // The proxy job might already have been deleted, in which case we - // need to avoid calling functions on them. Then delete the job. - for (QAbstractAnimationJob *job : qAsConst(m_deleting)) { - m_starting.take(job); - m_stopping.take(job); - m_animatorRoots.take(job); - delete job; - } - - for (QQuickAnimatorProxyJob *proxy : qAsConst(m_animatorRoots)) - proxy->controllerWasDeleted(); - for (auto it = m_animatorRoots.keyBegin(), end = m_animatorRoots.keyEnd(); it != end; ++it) - delete *it; - - // Delete those who have been started, stopped and are now still - // pending for restart. - for (auto it = m_starting.keyBegin(), end = m_starting.keyEnd(); it != end; ++it) { - QAbstractAnimationJob *job = *it; - if (!m_animatorRoots.contains(job)) - delete job; - } - - delete m_guiEntity; } -static void qquickanimator_invalidate_node(QAbstractAnimationJob *job) +static void qquickanimator_invalidate_jobs(QAbstractAnimationJob *job) { if (job->isRenderThreadJob()) { - static_cast<QQuickAnimatorJob *>(job)->nodeWasDestroyed(); + static_cast<QQuickAnimatorJob *>(job)->invalidate(); } else if (job->isGroup()) { QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) - qquickanimator_invalidate_node(a); + qquickanimator_invalidate_jobs(a); } } void QQuickAnimatorController::windowNodesDestroyed() { - m_nodesAreInvalid = true; - for (QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *>::const_iterator it = m_animatorRoots.constBegin(); - it != m_animatorRoots.constEnd(); ++it) { - qquickanimator_invalidate_node(it.key()); + for (const QSharedPointer<QAbstractAnimationJob> &toStop : qAsConst(m_rootsPendingStop)) { + qquickanimator_invalidate_jobs(toStop.data()); + toStop->stop(); } -} + m_rootsPendingStop.clear(); -void QQuickAnimatorController::itemDestroyed(QObject *o) -{ - m_deletedSinceLastFrame << (QQuickItem *) o; + // Clear animation roots and iterate over a temporary to avoid that job->stop() + // modifies the m_animationRoots and messes with our iteration + const auto roots = m_animationRoots; + m_animationRoots.clear(); + for (const QSharedPointer<QAbstractAnimationJob> &job : roots) { + qquickanimator_invalidate_jobs(job.data()); + + // Stop it and add it to the list of pending start so it might get + // started later on. + job->stop(); + m_rootsPendingStart.insert(job); + } } void QQuickAnimatorController::advance() { bool running = false; - for (QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *>::const_iterator it = m_animatorRoots.constBegin(); - !running && it != m_animatorRoots.constEnd(); ++it) { - if (it.key()->isRunning()) + for (const QSharedPointer<QAbstractAnimationJob> &job : qAsConst(m_animationRoots)) { + if (job->isRunning()) { running = true; + break; + } } - // It was tempting to only run over the active animations, but we need to push - // the values for the transforms that finished in the last frame and those will - // have been removed already... - lock(); - for (QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *>::const_iterator it = m_transforms.constBegin(); - it != m_transforms.constEnd(); ++it) { - QQuickTransformAnimatorJob::Helper *xform = *it; - // Set to zero when the item was deleted in beforeNodeSync(). - if (!xform->item) - continue; - (*it)->apply(); - } - unlock(); + for (QQuickAnimatorJob *job : qAsConst(m_runningAnimators)) + job->commit(); if (running) m_window->update(); } -static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorController *c, bool attachListener) +static void qquickanimator_sync_before_start(QAbstractAnimationJob *job) { if (job->isRenderThreadJob()) { - QQuickAnimatorJob *j = static_cast<QQuickAnimatorJob *>(job); - // Note: since a QQuickAnimatorJob::m_target is a QPointer, - // if m_target is destroyed between the time it was set - // as the target of the animator job and before this step, - // (e.g a Loader being set inactive just after starting the animator) - // we are sure it will be NULL and won't be dangling around - if (!j->target()) { - return; - } else if (c->m_deletedSinceLastFrame.contains(j->target())) { - j->targetWasDeleted(); - } else { - if (attachListener) - j->addAnimationChangeListener(c, QAbstractAnimationJob::StateChange); - j->initialize(c); - } + static_cast<QQuickAnimatorJob *>(job)->preSync(); } else if (job->isGroup()) { QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) - qquick_initialize_helper(a, c, attachListener); + qquickanimator_sync_before_start(a); } } void QQuickAnimatorController::beforeNodeSync() { - for (QAbstractAnimationJob *job : qAsConst(m_deleting)) { - m_starting.take(job); - m_stopping.take(job); - m_animatorRoots.take(job); - job->stop(); - delete job; - } - m_deleting.clear(); + for (const QSharedPointer<QAbstractAnimationJob> &toStop : qAsConst(m_rootsPendingStop)) + toStop->stop(); + m_rootsPendingStop.clear(); - if (m_starting.size()) - m_window->update(); - for (QQuickAnimatorProxyJob *proxy : qAsConst(m_starting)) { - QAbstractAnimationJob *job = proxy->job(); - job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); - qquick_initialize_helper(job, this, true); - m_animatorRoots[job] = proxy; - job->start(); - proxy->startedByController(); - } - m_starting.clear(); - for (QQuickAnimatorProxyJob *proxy : qAsConst(m_stopping)) { - QAbstractAnimationJob *job = proxy->job(); - job->stop(); - } - m_stopping.clear(); - - // First sync after a window was hidden or otherwise invalidated. - // call initialize again to pick up new nodes.. - if (m_nodesAreInvalid) { - for (QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *>::const_iterator it = m_animatorRoots.constBegin(); - it != m_animatorRoots.constEnd(); ++it) { - qquick_initialize_helper(it.key(), this, false); - } - m_nodesAreInvalid = false; - } + for (QQuickAnimatorJob *job : qAsConst(m_runningAnimators)) + job->preSync(); - for (QQuickAnimatorJob *job : qAsConst(m_activeLeafAnimations)) { - if (!job->target()) - continue; - else if (m_deletedSinceLastFrame.contains(job->target())) - job->targetWasDeleted(); - else if (job->isTransform()) { - QQuickTransformAnimatorJob *xform = static_cast<QQuickTransformAnimatorJob *>(job); - xform->transformHelper()->sync(); - } - } - for (QQuickItem *wiped : qAsConst(m_deletedSinceLastFrame)) { - QQuickTransformAnimatorJob::Helper *helper = m_transforms.take(wiped); - // Helper will now already have been reset in all animators referencing it. - delete helper; - } + // Start pending jobs + for (const QSharedPointer<QAbstractAnimationJob> &job : qAsConst(m_rootsPendingStart)) { + Q_ASSERT(!job->isRunning()); - m_deletedSinceLastFrame.clear(); -} + // We want to make sure that presync is called before + // updateAnimationTime is called the very first time, so before + // starting a tree of jobs, we go through it and call preSync on all + // its animators. + qquickanimator_sync_before_start(job.data()); -void QQuickAnimatorController::afterNodeSync() -{ - for (QQuickAnimatorJob *job : qAsConst(m_activeLeafAnimations)) { - if (job->target()) - job->afterNodeSync(); + // The start the job.. + job->start(); + m_animationRoots.insert(job.data(), job); } -} + m_rootsPendingStart.clear(); -void QQuickAnimatorController::proxyWasDestroyed(QQuickAnimatorProxyJob *proxy) -{ - lock(); - m_proxiesToStop.remove(proxy); - unlock(); + // Issue an update directly on the window to force another render pass. + if (m_animationRoots.size()) + m_window->update(); } -void QQuickAnimatorController::stopProxyJobs() +void QQuickAnimatorController::afterNodeSync() { - // Need to make a copy under lock and then stop while unlocked. - // Stopping triggers writeBack which in turn may lock, so it needs - // to be outside the lock. It is also safe because deletion of - // proxies happens on the GUI thread, where this code is also executing. - lock(); - const QSet<QQuickAnimatorProxyJob *> jobs = m_proxiesToStop; - m_proxiesToStop.clear(); - unlock(); - for (QQuickAnimatorProxyJob *p : jobs) - p->stop(); + for (QQuickAnimatorJob *job : qAsConst(m_runningAnimators)) + job->postSync(); } void QQuickAnimatorController::animationFinished(QAbstractAnimationJob *job) { - /* We are currently on the render thread and m_deleting is primarily - * being written on the GUI Thread and read during sync. However, we don't - * need to lock here as this is a direct result of animationDriver->advance() - * which is already locked. For non-threaded render loops no locking is - * needed in any case. - */ - if (!m_deleting.contains(job)) { - QQuickAnimatorProxyJob *proxy = m_animatorRoots.value(job); - if (proxy) { - m_window->update(); - m_proxiesToStop << proxy; - } - // else already gone... - } + m_animationRoots.remove(job); } void QQuickAnimatorController::animationStateChanged(QAbstractAnimationJob *job, @@ -281,43 +170,52 @@ void QQuickAnimatorController::animationStateChanged(QAbstractAnimationJob *job, Q_ASSERT(job->isRenderThreadJob()); QQuickAnimatorJob *animator = static_cast<QQuickAnimatorJob *>(job); if (newState == QAbstractAnimationJob::Running) { - m_activeLeafAnimations << animator; - animator->setHasBeenRunning(true); + m_runningAnimators.insert(animator); } else if (oldState == QAbstractAnimationJob::Running) { - m_activeLeafAnimations.remove(animator); + animator->commit(); + m_runningAnimators.remove(animator); } } - void QQuickAnimatorController::requestSync() { // Force a "sync" pass as the newly started animation needs to sync properties from GUI. m_window->maybeUpdate(); } -// These functions are called on the GUI thread. -void QQuickAnimatorController::startJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job) +// All this is being executed on the GUI thread while the animator controller +// is locked. +void QQuickAnimatorController::start_helper(QAbstractAnimationJob *job) { - proxy->markJobManagedByController(); - m_starting[job] = proxy; - m_stopping.remove(job); - requestSync(); + if (job->isRenderThreadJob()) { + QQuickAnimatorJob *j = static_cast<QQuickAnimatorJob *>(job); + j->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + j->initialize(this); + } else if (job->isGroup()) { + QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); + for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) + start_helper(a); + } } -void QQuickAnimatorController::stopJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job) +// Called by the proxy when it is time to kick off an animation job +void QQuickAnimatorController::start(const QSharedPointer<QAbstractAnimationJob> &job) { - m_stopping[job] = proxy; - m_starting.remove(job); + m_rootsPendingStart.insert(job); + m_rootsPendingStop.remove(job); + job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); + start_helper(job.data()); requestSync(); } -void QQuickAnimatorController::deleteJob(QAbstractAnimationJob *job) + +// Called by the proxy when it is time to stop an animation job. +void QQuickAnimatorController::cancel(const QSharedPointer<QAbstractAnimationJob> &job) { - lock(); - m_deleting << job; - requestSync(); - unlock(); + m_rootsPendingStart.remove(job); + m_rootsPendingStop.insert(job); } + QT_END_NAMESPACE diff --git a/src/quick/util/qquickanimatorcontroller_p.h b/src/quick/util/qquickanimatorcontroller_p.h index 0a9902cc30..428a6700d4 100644 --- a/src/quick/util/qquickanimatorcontroller_p.h +++ b/src/quick/util/qquickanimatorcontroller_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -60,8 +61,6 @@ QT_BEGIN_NAMESPACE -class QQuickAnimatorControllerGuiThreadEntity; - class QQuickAnimatorController : public QObject, public QAnimationJobChangeListener { Q_OBJECT @@ -74,54 +73,37 @@ public: void beforeNodeSync(); void afterNodeSync(); - void animationFinished(QAbstractAnimationJob *job); - void animationStateChanged(QAbstractAnimationJob *job, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); + void animationFinished(QAbstractAnimationJob *job) override; + void animationStateChanged(QAbstractAnimationJob *job, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; void requestSync(); // These are called from the GUI thread (the proxy) - void startJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job); - void stopJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job); - void deleteJob(QAbstractAnimationJob *job); + void start(const QSharedPointer<QAbstractAnimationJob> &job); + void cancel(const QSharedPointer<QAbstractAnimationJob> &job); + bool isPendingStart(const QSharedPointer<QAbstractAnimationJob> &job) const { return m_rootsPendingStart.contains(job); } void lock() { m_mutex.lock(); } void unlock() { m_mutex.unlock(); } - void proxyWasDestroyed(QQuickAnimatorProxyJob *proxy); void stopProxyJobs(); void windowNodesDestroyed(); -public Q_SLOTS: - void itemDestroyed(QObject *); + QQuickWindow *window() const { return m_window; } -public: - // These are manipulated from the GUI thread and should only - // be updated during the sync() phase. - QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *> m_starting; - QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *> m_stopping; - QSet<QAbstractAnimationJob *> m_deleting; - - QHash<QAbstractAnimationJob *, QQuickAnimatorProxyJob *> m_animatorRoots; - QSet<QQuickAnimatorJob *> m_activeLeafAnimations; - QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> m_transforms; - QSet<QQuickItem *> m_deletedSinceLastFrame; - QQuickWindow *m_window; - QQuickAnimatorControllerGuiThreadEntity *m_guiEntity; - QSet<QQuickAnimatorProxyJob *> m_proxiesToStop; - QMutex m_mutex; +private: + void start_helper(QAbstractAnimationJob *job); + void cancel_helper(QAbstractAnimationJob *job); - bool m_nodesAreInvalid; -}; - -class QQuickAnimatorControllerGuiThreadEntity : public QObject -{ - Q_OBJECT public: - QPointer<QQuickAnimatorController> controller; + QSet<QQuickAnimatorJob * > m_runningAnimators; + QHash<QAbstractAnimationJob *, QSharedPointer<QAbstractAnimationJob> > m_animationRoots; + QSet<QSharedPointer<QAbstractAnimationJob> > m_rootsPendingStop; + QSet<QSharedPointer<QAbstractAnimationJob> > m_rootsPendingStart; -public Q_SLOTS: - void frameSwapped(); + QQuickWindow *m_window; + QMutex m_mutex; }; diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 1176cf1ff7..fa13e8519e 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -54,12 +55,42 @@ QT_BEGIN_NAMESPACE +struct QQuickTransformAnimatorHelperStore +{ + QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> store; + QMutex mutex; + + QQuickTransformAnimatorJob::Helper *acquire(QQuickItem *item) { + mutex.lock(); + QQuickTransformAnimatorJob::Helper *helper = store.value(item); + if (!helper) { + helper = new QQuickTransformAnimatorJob::Helper(); + helper->item = item; + store[item] = helper; + } else { + ++helper->ref; + } + mutex.unlock(); + return helper; + } + + void release(QQuickTransformAnimatorJob::Helper *helper) { + mutex.lock(); + if (--helper->ref == 0) { + store.remove(helper->item); + delete helper; + } + mutex.unlock(); + } +}; +Q_GLOBAL_STATIC(QQuickTransformAnimatorHelperStore, qquick_transform_animatorjob_helper_store); + QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObject *item) - : m_controller(0) - , m_job(job) + : m_controller(nullptr) , m_internalState(State_Stopped) - , m_jobManagedByController(false) { + m_job.reset(job); + m_isRenderThreadProxy = true; m_animation = qobject_cast<QQuickAbstractAnimation *>(item); @@ -87,57 +118,58 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje QQuickItem *item = qobject_cast<QQuickItem *>(ctx); if (item->window()) setWindow(item->window()); - - qmlobject_connect(item, QQuickItem, SIGNAL(windowChanged(QQuickWindow*)), this, QQuickAnimatorProxyJob, SLOT(windowChanged(QQuickWindow*))); + connect(item, &QQuickItem::windowChanged, this, &QQuickAnimatorProxyJob::windowChanged); } } QQuickAnimatorProxyJob::~QQuickAnimatorProxyJob() { - deleteJob(); - if (m_controller) - m_controller->proxyWasDestroyed(this); -} - -void QQuickAnimatorProxyJob::deleteJob() -{ - if (m_job) { - // If we have a controller, we might have posted the job to be started - // so delete it through the controller to clean up properly. - if (m_controller) - m_controller->deleteJob(m_job); - - // We explicitly delete the job if the animator controller has never touched - // it. If it has, it will have ownership as well. - else if (!m_jobManagedByController) - delete m_job; - m_job = 0; - } + if (m_job && m_controller) + m_controller->cancel(m_job); + m_job.reset(); } QObject *QQuickAnimatorProxyJob::findAnimationContext(QQuickAbstractAnimation *a) { QObject *p = a->parent(); - while (p != 0 && qobject_cast<QQuickWindow *>(p) == 0 && qobject_cast<QQuickItem *>(p) == 0) + while (p != nullptr && qobject_cast<QQuickWindow *>(p) == nullptr && qobject_cast<QQuickItem *>(p) == nullptr) p = p->parent(); return p; } void QQuickAnimatorProxyJob::updateCurrentTime(int) { + // We do a simple check here to see if the animator has run and stopped on + // the render thread. isPendingStart() will perform a check against jobs + // that have been scheduled for start, but that will not yet have entered + // the actual running state. + // Secondly, we make an unprotected read of the job's state to figure out + // if it is running, but this is ok, since we're only reading the state + // and if the render thread should happen to be writing it concurrently, + // we might get the wrong value for this update, but then we'll simply + // pick it up on the next iterationm when the job is stopped and render + // thread is no longer using it. + if (m_internalState == State_Running + && !m_controller->isPendingStart(m_job) + && !m_job->isRunning()) { + stop(); + } } void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) { if (m_state == Running) { m_internalState = State_Starting; - if (m_controller) - m_controller->startJob(this, m_job); + if (m_controller) { + m_internalState = State_Running; + m_controller->start(m_job); + } + } else if (newState == Stopped) { syncBackCurrentValues(); m_internalState = State_Stopped; if (m_controller) { - m_controller->stopJob(this, m_job); + m_controller->cancel(m_job); } } } @@ -154,69 +186,54 @@ void QQuickAnimatorProxyJob::windowChanged(QQuickWindow *window) setWindow(window); } -void QQuickAnimatorProxyJob::controllerWasDeleted() -{ - m_controller = 0; - m_job = 0; -} - void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window) { if (!window) { - stop(); - deleteJob(); - - // Upon leaving a window, we reset the controller. This means that - // animators will only enter the Starting phase and won't be making - // calls to QQuickAnimatorController::startjob(). - if (m_controller) - m_controller->proxyWasDestroyed(this); - m_controller = 0; + if (m_job && m_controller) + m_controller->cancel(m_job); + m_controller = nullptr; } else if (!m_controller && m_job) { m_controller = QQuickWindowPrivate::get(window)->animationController; if (window->isSceneGraphInitialized()) readyToAnimate(); else - connect(window, SIGNAL(sceneGraphInitialized()), this, SLOT(sceneGraphInitialized())); + connect(window, &QQuickWindow::sceneGraphInitialized, this, &QQuickAnimatorProxyJob::sceneGraphInitialized); } } void QQuickAnimatorProxyJob::sceneGraphInitialized() { + disconnect(m_controller->window(), &QQuickWindow::sceneGraphInitialized, this, &QQuickAnimatorProxyJob::sceneGraphInitialized); readyToAnimate(); - disconnect(this, SLOT(sceneGraphInitialized())); } void QQuickAnimatorProxyJob::readyToAnimate() { - if (m_internalState == State_Starting) - m_controller->startJob(this, m_job); -} - -void QQuickAnimatorProxyJob::startedByController() -{ - m_internalState = State_Running; + Q_ASSERT(m_controller); + if (m_internalState == State_Starting) { + m_internalState = State_Running; + m_controller->start(m_job); + } } static void qquick_syncback_helper(QAbstractAnimationJob *job) { if (job->isRenderThreadJob()) { - QQuickAnimatorJob *a = static_cast<QQuickAnimatorJob *>(job); - // Sync back only those jobs that actually have been running - if (a->controller() && a->hasBeenRunning()) - a->writeBack(); + static_cast<QQuickAnimatorJob *>(job)->writeBack(); + } else if (job->isGroup()) { QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job); for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling()) qquick_syncback_helper(a); } + } void QQuickAnimatorProxyJob::syncBackCurrentValues() { if (m_job) - qquick_syncback_helper(m_job); + qquick_syncback_helper(m_job.data()); } QQuickAnimatorJob::QQuickAnimatorJob() @@ -228,7 +245,6 @@ QQuickAnimatorJob::QQuickAnimatorJob() , m_duration(0) , m_isTransform(false) , m_isUniform(false) - , m_hasBeenRunning(false) { m_isRenderThreadJob = true; } @@ -244,13 +260,16 @@ qreal QQuickAnimatorJob::progress(int time) const { return m_easing.valueForProgress((m_duration == 0) ? qreal(1) : qreal(time) / qreal(m_duration)); } + qreal QQuickAnimatorJob::value() const { - qreal v; - m_controller->lock(); - v = m_value; - m_controller->unlock(); - return v; + qreal value = m_to; + if (m_controller) { + m_controller->lock(); + value = m_value; + m_controller->unlock(); + } + return value; } void QQuickAnimatorJob::setTarget(QQuickItem *target) @@ -263,62 +282,81 @@ void QQuickAnimatorJob::initialize(QQuickAnimatorController *controller) m_controller = controller; } -void QQuickAnimatorJob::targetWasDeleted() -{ - m_target = 0; - m_controller = 0; -} - QQuickTransformAnimatorJob::QQuickTransformAnimatorJob() - : m_helper(0) + : m_helper(nullptr) { m_isTransform = true; } QQuickTransformAnimatorJob::~QQuickTransformAnimatorJob() { - if (m_helper && --m_helper->ref == 0) { - // The only condition for not having a controller is when target was - // destroyed, in which case we have neither m_helper nor m_contorller. - Q_ASSERT(m_controller); - Q_ASSERT(m_helper->item); - m_controller->m_transforms.remove(m_helper->item); - delete m_helper; - } + if (m_helper) + qquick_transform_animatorjob_helper_store()->release(m_helper); } -void QQuickTransformAnimatorJob::initialize(QQuickAnimatorController *controller) +void QQuickTransformAnimatorJob::setTarget(QQuickItem *item) { - QQuickAnimatorJob::initialize(controller); + // In the extremely unlikely event that the target of an animator has been + // changed into a new item that sits in the exact same pointer address, we + // want to force syncing it again. + if (m_helper && m_target) + m_helper->wasSynced = false; + QQuickAnimatorJob::setTarget(item); +} - if (m_controller) { - bool newHelper = m_helper == 0; - m_helper = m_controller->m_transforms.value(m_target); - if (!m_helper) { - m_helper = new Helper(); - m_helper->item = m_target; - m_controller->m_transforms.insert(m_target, m_helper); - QObject::connect(m_target, SIGNAL(destroyed(QObject*)), m_controller, SLOT(itemDestroyed(QObject*)), Qt::DirectConnection); - } else { - if (newHelper) // only add reference the first time around.. - ++m_helper->ref; - // Make sure leftovers from previous runs are being used... - m_helper->wasSynced = false; - } - m_helper->sync(); +void QQuickTransformAnimatorJob::preSync() +{ + // If the target has changed or become null, release and reset the helper + if (m_helper && (m_helper->item != m_target || !m_target)) { + qquick_transform_animatorjob_helper_store()->release(m_helper); + m_helper = nullptr; } + + if (!m_target) + return; + + if (!m_helper) { + m_helper = qquick_transform_animatorjob_helper_store()->acquire(m_target); + + // This is a bit superfluous, but it ends up being simpler than the + // alternative. When an item happens to land on the same address as a + // previous item, that helper might not have been fully cleaned up by + // the time it gets taken back into use. As an alternative to storing + // connections to each and every item's QObject::destroyed() and + // having to clean those up afterwards, we simply sync all helpers on + // the first run. The sync is only done once for the run of an + // animation and it is a fairly light function (compared to storing + // potentially thousands of connections and managing their lifetime. + m_helper->wasSynced = false; + } + + m_helper->sync(); } -void QQuickTransformAnimatorJob::nodeWasDestroyed() +void QQuickTransformAnimatorJob::postSync() { - if (m_helper) - m_helper->node = 0; + Q_ASSERT((m_helper != nullptr) == (m_target != nullptr)); // If there is a target, there should also be a helper, ref: preSync + Q_ASSERT(!m_helper || m_helper->item == m_target); // If there is a helper, it should point to our target + + if (!m_target || !m_helper) { + invalidate(); + return; + } + + QQuickItemPrivate *d = QQuickItemPrivate::get(m_target); + if (d->extra.isAllocated() + && d->extra->layer + && d->extra->layer->enabled()) { + d = QQuickItemPrivate::get(d->extra->layer->m_effectSource); + } + + m_helper->node = d->itemNode(); } -void QQuickTransformAnimatorJob::targetWasDeleted() +void QQuickTransformAnimatorJob::invalidate() { - m_helper = 0; - QQuickAnimatorJob::targetWasDeleted(); + if (m_helper) + m_helper->node = nullptr; } void QQuickTransformAnimatorJob::Helper::sync() @@ -366,7 +404,7 @@ void QQuickTransformAnimatorJob::Helper::sync() } } -void QQuickTransformAnimatorJob::Helper::apply() +void QQuickTransformAnimatorJob::Helper::commit() { if (!wasChanged || !node) return; @@ -382,7 +420,11 @@ void QQuickTransformAnimatorJob::Helper::apply() wasChanged = false; } - +void QQuickTransformAnimatorJob::commit() +{ + if (m_helper) + m_helper->commit(); +} void QQuickXAnimatorJob::writeBack() { @@ -392,7 +434,8 @@ void QQuickXAnimatorJob::writeBack() void QQuickXAnimatorJob::updateCurrentTime(int time) { - if (!m_controller) + Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); + if (!m_helper) return; m_value = m_from + (m_to - m_from) * progress(time); @@ -408,7 +451,9 @@ void QQuickYAnimatorJob::writeBack() void QQuickYAnimatorJob::updateCurrentTime(int time) { - if (!m_controller) + Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); + + if (!m_helper) return; m_value = m_from + (m_to - m_from) * progress(time); @@ -416,14 +461,85 @@ void QQuickYAnimatorJob::updateCurrentTime(int time) m_helper->wasChanged = true; } +void QQuickScaleAnimatorJob::writeBack() +{ + if (m_target) + m_target->setScale(value()); +} + +void QQuickScaleAnimatorJob::updateCurrentTime(int time) +{ + Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); + + if (!m_helper) + return; + + m_value = m_from + (m_to - m_from) * progress(time); + m_helper->scale = m_value; + m_helper->wasChanged = true; +} + + +QQuickRotationAnimatorJob::QQuickRotationAnimatorJob() + : m_direction(QQuickRotationAnimator::Numerical) +{ +} + +extern QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress); +extern QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress); +extern QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress); + +void QQuickRotationAnimatorJob::updateCurrentTime(int time) +{ + Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); + + if (!m_helper) + return; + + float t = progress(time); + + switch (m_direction) { + case QQuickRotationAnimator::Clockwise: + m_value = _q_interpolateClockwiseRotation(m_from, m_to, t).toFloat(); + // The logic in _q_interpolateClockwise comes out a bit wrong + // for the case of X->0 where 0<X<360. It ends on 360 which it + // shouldn't. + if (t == 1) + m_value = m_to; + break; + case QQuickRotationAnimator::Counterclockwise: + m_value = _q_interpolateCounterclockwiseRotation(m_from, m_to, t).toFloat(); + break; + case QQuickRotationAnimator::Shortest: + m_value = _q_interpolateShortestRotation(m_from, m_to, t).toFloat(); + break; + case QQuickRotationAnimator::Numerical: + m_value = m_from + (m_to - m_from) * t; + break; + } + m_helper->rotation = m_value; + m_helper->wasChanged = true; +} + +void QQuickRotationAnimatorJob::writeBack() +{ + if (m_target) + m_target->setRotation(value()); +} + + QQuickOpacityAnimatorJob::QQuickOpacityAnimatorJob() - : m_opacityNode(0) + : m_opacityNode(nullptr) { } -void QQuickOpacityAnimatorJob::initialize(QQuickAnimatorController *controller) +void QQuickOpacityAnimatorJob::postSync() { - QQuickAnimatorJob::initialize(controller); + if (!m_target) { + invalidate(); + return; + } + QQuickItemPrivate *d = QQuickItemPrivate::get(m_target); #if QT_CONFIG(quick_shadereffect) if (d->extra.isAllocated() @@ -434,6 +550,7 @@ void QQuickOpacityAnimatorJob::initialize(QQuickAnimatorController *controller) #endif m_opacityNode = d->opacityNode(); + if (!m_opacityNode) { m_opacityNode = new QSGOpacityNode(); @@ -464,11 +581,12 @@ void QQuickOpacityAnimatorJob::initialize(QQuickAnimatorController *controller) d->extra.value().opacityNode = m_opacityNode; } + Q_ASSERT(m_opacityNode); } -void QQuickOpacityAnimatorJob::nodeWasDestroyed() +void QQuickOpacityAnimatorJob::invalidate() { - m_opacityNode = 0; + m_opacityNode = nullptr; } void QQuickOpacityAnimatorJob::writeBack() @@ -479,77 +597,19 @@ void QQuickOpacityAnimatorJob::writeBack() void QQuickOpacityAnimatorJob::updateCurrentTime(int time) { - if (!m_controller || !m_opacityNode) - return; + Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); - m_value = m_from + (m_to - m_from) * progress(time); - m_opacityNode->setOpacity(m_value); -} - -void QQuickScaleAnimatorJob::writeBack() -{ - if (m_target) - m_target->setScale(value()); -} - -void QQuickScaleAnimatorJob::updateCurrentTime(int time) -{ - if (!m_controller) + if (!m_opacityNode) return; m_value = m_from + (m_to - m_from) * progress(time); - m_helper->scale = m_value; - m_helper->wasChanged = true; -} - -QQuickRotationAnimatorJob::QQuickRotationAnimatorJob() - : m_direction(QQuickRotationAnimator::Numerical) -{ -} - -extern QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress); -extern QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress); -extern QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress); - -void QQuickRotationAnimatorJob::updateCurrentTime(int time) -{ - if (!m_controller) - return; - - float t = progress(time); - - switch (m_direction) { - case QQuickRotationAnimator::Clockwise: - m_value = _q_interpolateClockwiseRotation(m_from, m_to, t).toFloat(); - // The logic in _q_interpolateClockwise comes out a bit wrong - // for the case of X->0 where 0<X<360. It ends on 360 which it - // shouldn't. - if (t == 1) - m_value = m_to; - break; - case QQuickRotationAnimator::Counterclockwise: - m_value = _q_interpolateCounterclockwiseRotation(m_from, m_to, t).toFloat(); - break; - case QQuickRotationAnimator::Shortest: - m_value = _q_interpolateShortestRotation(m_from, m_to, t).toFloat(); - break; - case QQuickRotationAnimator::Numerical: - m_value = m_from + (m_to - m_from) * t; - break; - } - m_helper->rotation = m_value; - m_helper->wasChanged = true; + m_opacityNode->setOpacity(m_value); } -void QQuickRotationAnimatorJob::writeBack() -{ - if (m_target) - m_target->setRotation(value()); -} #if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) QQuickUniformAnimatorJob::QQuickUniformAnimatorJob() - : m_node(0) + : m_node(nullptr) , m_uniformIndex(-1) , m_uniformType(-1) { @@ -558,19 +618,24 @@ QQuickUniformAnimatorJob::QQuickUniformAnimatorJob() void QQuickUniformAnimatorJob::setTarget(QQuickItem *target) { - if (qobject_cast<QQuickOpenGLShaderEffect *>(target) != 0) + if (qobject_cast<QQuickOpenGLShaderEffect *>(target) != nullptr) m_target = target; } -void QQuickUniformAnimatorJob::nodeWasDestroyed() +void QQuickUniformAnimatorJob::invalidate() { - m_node = 0; + m_node = nullptr; m_uniformIndex = -1; m_uniformType = -1; } -void QQuickUniformAnimatorJob::afterNodeSync() +void QQuickUniformAnimatorJob::postSync() { + if (!m_target) { + invalidate(); + return; + } + m_node = static_cast<QQuickOpenGLShaderEffectNode *>(QQuickItemPrivate::get(m_target)->paintNode); if (m_node && m_uniformIndex == -1 && m_uniformType == -1) { diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 64e849d322..d7aaa988a9 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -80,25 +81,20 @@ public: QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObject *item); ~QQuickAnimatorProxyJob(); - int duration() const Q_DECL_OVERRIDE { return m_duration; } + int duration() const override { return m_duration; } - QAbstractAnimationJob *job() const { return m_job; } - - void startedByController(); - void controllerWasDeleted(); - void markJobManagedByController() { m_jobManagedByController = true; } + const QSharedPointer<QAbstractAnimationJob> &job() const { return m_job; } protected: - void updateCurrentTime(int) Q_DECL_OVERRIDE; - void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) Q_DECL_OVERRIDE; - void debugAnimation(QDebug d) const Q_DECL_OVERRIDE; + void updateCurrentTime(int) override; + void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; + void debugAnimation(QDebug d) const override; public Q_SLOTS: void windowChanged(QQuickWindow *window); void sceneGraphInitialized(); private: - void deleteJob(); void syncBackCurrentValues(); void readyToAnimate(); void setWindow(QQuickWindow *window); @@ -106,7 +102,7 @@ private: QPointer<QQuickAnimatorController> m_controller; QQuickAbstractAnimation *m_animation; - QAbstractAnimationJob *m_job; + QSharedPointer<QAbstractAnimationJob> m_job; int m_duration; enum InternalState { @@ -117,7 +113,6 @@ private: }; InternalState m_internalState; - bool m_jobManagedByController; }; class Q_QUICK_PRIVATE_EXPORT QQuickAnimatorJob : public QAbstractAnimationJob @@ -126,37 +121,53 @@ public: virtual void setTarget(QQuickItem *target); QQuickItem *target() const { return m_target; } - void setFrom(qreal scale) { m_from = scale; } + void setFrom(qreal from) { m_from = from; } qreal from() const { return m_from; } void setTo(qreal to) { m_to = to; } qreal to() const { return m_to; } void setDuration(int duration) { m_duration = duration; } - int duration() const Q_DECL_OVERRIDE { return m_duration; } + int duration() const override { return m_duration; } QEasingCurve easingCurve() const { return m_easing; } void setEasingCurve(const QEasingCurve &curve) { m_easing = curve; } - virtual void targetWasDeleted(); + // Initialize is called on the GUI thread just before it is started + // and taken over on the render thread. virtual void initialize(QQuickAnimatorController *controller); + + // Called on the render thread during SG shutdown. + virtual void invalidate() = 0; + + // Called on the GUI thread after a complete render thread animation job + // has been completed to write back a given animator's result to the + // source item. virtual void writeBack() = 0; - virtual void nodeWasDestroyed() = 0; - virtual void afterNodeSync() { } + + // Called before the SG sync on the render thread. The GUI thread is + // locked during this call. + virtual void preSync() { } + + // Called after the SG sync on the render thread. The GUI thread is + // locked during this call. + virtual void postSync() { } + + // Called after animations have ticked on the render thread. No locks are + // held at this time, so synchronization needs to be taken into account + // if applicable. + virtual void commit() { } bool isTransform() const { return m_isTransform; } bool isUniform() const { return m_isUniform; } - bool hasBeenRunning() const { return m_hasBeenRunning; } - void setHasBeenRunning(bool has) { m_hasBeenRunning = has; } - qreal value() const; QQuickAnimatorController *controller() const { return m_controller; } protected: QQuickAnimatorJob(); - void debugAnimation(QDebug d) const Q_DECL_OVERRIDE; + void debugAnimation(QDebug d) const override; qreal progress(int time) const; @@ -173,7 +184,6 @@ protected: uint m_isTransform : 1; uint m_isUniform : 1; - uint m_hasBeenRunning : 1; }; class QQuickTransformAnimatorJob : public QQuickAnimatorJob @@ -197,7 +207,7 @@ public: } void sync(); - void apply(); + void commit(); int ref; QQuickItem *item; @@ -217,13 +227,16 @@ public: }; ~QQuickTransformAnimatorJob(); - Helper *transformHelper() const { return m_helper; } + + void commit() override; + void preSync() override; + + void setTarget(QQuickItem *item) override; protected: QQuickTransformAnimatorJob(); - void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE; - void nodeWasDestroyed() Q_DECL_OVERRIDE; - void targetWasDeleted() Q_DECL_OVERRIDE; + void postSync() override; + void invalidate() override; Helper *m_helper; }; @@ -231,22 +244,22 @@ protected: class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimatorJob : public QQuickTransformAnimatorJob { public: - void updateCurrentTime(int time) Q_DECL_OVERRIDE; - void writeBack() Q_DECL_OVERRIDE; + void updateCurrentTime(int time) override; + void writeBack() override; }; class Q_QUICK_PRIVATE_EXPORT QQuickXAnimatorJob : public QQuickTransformAnimatorJob { public: - void updateCurrentTime(int time) Q_DECL_OVERRIDE; - void writeBack() Q_DECL_OVERRIDE; + void updateCurrentTime(int time) override; + void writeBack() override; }; class Q_QUICK_PRIVATE_EXPORT QQuickYAnimatorJob : public QQuickTransformAnimatorJob { public: - void updateCurrentTime(int time) Q_DECL_OVERRIDE; - void writeBack() Q_DECL_OVERRIDE; + void updateCurrentTime(int time) override; + void writeBack() override; }; class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimatorJob : public QQuickTransformAnimatorJob @@ -254,8 +267,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimatorJob : public QQuickTransformA public: QQuickRotationAnimatorJob(); - void updateCurrentTime(int time) Q_DECL_OVERRIDE; - void writeBack() Q_DECL_OVERRIDE; + void updateCurrentTime(int time) override; + void writeBack() override; void setDirection(QQuickRotationAnimator::RotationDirection direction) { m_direction = direction; } QQuickRotationAnimator::RotationDirection direction() const { return m_direction; } @@ -269,10 +282,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimatorJob : public QQuickAnimatorJob public: QQuickOpacityAnimatorJob(); - void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE; - void updateCurrentTime(int time) Q_DECL_OVERRIDE; - void writeBack() Q_DECL_OVERRIDE; - void nodeWasDestroyed() Q_DECL_OVERRIDE; + void invalidate() override; + void updateCurrentTime(int time) override; + void writeBack() override; + void postSync() override; private: QSGOpacityNode *m_opacityNode; @@ -283,16 +296,17 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimatorJob : public QQuickAnimatorJob public: QQuickUniformAnimatorJob(); - void setTarget(QQuickItem *target) Q_DECL_OVERRIDE; + void setTarget(QQuickItem *target) override; void setUniform(const QByteArray &uniform) { m_uniform = uniform; } QByteArray uniform() const { return m_uniform; } - void afterNodeSync() Q_DECL_OVERRIDE; + void postSync() override; + + void updateCurrentTime(int time) override; + void writeBack() override; - void updateCurrentTime(int time) Q_DECL_OVERRIDE; - void writeBack() Q_DECL_OVERRIDE; - void nodeWasDestroyed() Q_DECL_OVERRIDE; + void invalidate() override; private: QByteArray m_uniform; diff --git a/src/quick/util/qquickapplication.cpp b/src/quick/util/qquickapplication.cpp index 5c26b23ff7..5c89275c5a 100644 --- a/src/quick/util/qquickapplication.cpp +++ b/src/quick/util/qquickapplication.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "qquickapplication_p.h" - +#include <private/qquickscreen_p.h> #include <private/qobject_p.h> #include <private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> @@ -63,6 +63,12 @@ QQuickApplication::QQuickApplication(QObject *parent) this, SIGNAL(stateChanged(Qt::ApplicationState))); connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SIGNAL(activeChanged())); + connect(qApp, SIGNAL(applicationDisplayNameChanged()), + this, SIGNAL(displayNameChanged())); + + connect(qApp, &QGuiApplication::screenAdded, this, &QQuickApplication::updateScreens); + connect(qApp, &QGuiApplication::screenRemoved, this, &QQuickApplication::updateScreens); + updateScreens(); } } @@ -95,4 +101,42 @@ QFont QQuickApplication::font() const return QGuiApplication::font(); } +QString QQuickApplication::displayName() const +{ + return QGuiApplication::applicationDisplayName(); +} + +void QQuickApplication::setDisplayName(const QString &displayName) +{ + return QGuiApplication::setApplicationDisplayName(displayName); +} + +int screens_count(QQmlListProperty<QQuickScreenInfo> *prop) +{ + return static_cast<QVector<QQuickScreenInfo *> *>(prop->data)->count(); +} + +QQuickScreenInfo *screens_at(QQmlListProperty<QQuickScreenInfo> *prop, int idx) +{ + return static_cast<QVector<QQuickScreenInfo *> *>(prop->data)->at(idx); +} + +QQmlListProperty<QQuickScreenInfo> QQuickApplication::screens() +{ + return QQmlListProperty<QQuickScreenInfo>(this, + const_cast<QVector<QQuickScreenInfo *> *>(&m_screens), &screens_count, &screens_at); +} + +void QQuickApplication::updateScreens() +{ + const QList<QScreen *> screenList = QGuiApplication::screens(); + m_screens.resize(screenList.count()); + for (int i = 0; i < screenList.count(); ++i) { + if (!m_screens[i]) + m_screens[i] = new QQuickScreenInfo(this); + m_screens[i]->setWrappedScreen(screenList[i]); + } + emit screensChanged(); +} + QT_END_NAMESPACE diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h index 091cb094ed..8ee203f0da 100644 --- a/src/quick/util/qquickapplication_p.h +++ b/src/quick/util/qquickapplication_p.h @@ -56,10 +56,10 @@ #include <qqml.h> #include <QtQml/private/qqmlglobal_p.h> #include <private/qtquickglobal_p.h> +#include "../items/qquickscreen_p.h" QT_BEGIN_NAMESPACE - class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication { Q_OBJECT @@ -68,6 +68,8 @@ class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication Q_PROPERTY(bool supportsMultipleWindows READ supportsMultipleWindows CONSTANT) Q_PROPERTY(Qt::ApplicationState state READ state NOTIFY stateChanged) Q_PROPERTY(QFont font READ font CONSTANT) + Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged) + Q_PROPERTY(QQmlListProperty<QQuickScreenInfo> screens READ screens NOTIFY screensChanged) public: explicit QQuickApplication(QObject *parent = 0); @@ -77,14 +79,23 @@ public: bool supportsMultipleWindows() const; Qt::ApplicationState state() const; QFont font() const; + QQmlListProperty<QQuickScreenInfo> screens(); + QString displayName() const; + void setDisplayName(const QString &displayName); Q_SIGNALS: void activeChanged(); + void displayNameChanged(); void layoutDirectionChanged(); void stateChanged(Qt::ApplicationState state); + void screensChanged(); + +private Q_SLOTS: + void updateScreens(); private: Q_DISABLE_COPY(QQuickApplication) + QVector<QQuickScreenInfo *> m_screens; }; QT_END_NAMESPACE diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp index 1d3ee2c4be..9af1d41b29 100644 --- a/src/quick/util/qquickbehavior.cpp +++ b/src/quick/util/qquickbehavior.cpp @@ -60,7 +60,7 @@ public: QQuickBehaviorPrivate() : animation(0), animationInstance(0), enabled(true), finalized(false) , blockRunningChanged(false) {} - virtual void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); + void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; QQmlProperty property; QVariant targetValue; diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h index c3438d8c6d..b3fd2af400 100644 --- a/src/quick/util/qquickbehavior_p.h +++ b/src/quick/util/qquickbehavior_p.h @@ -75,8 +75,8 @@ public: QQuickBehavior(QObject *parent=0); ~QQuickBehavior(); - virtual void setTarget(const QQmlProperty &); - virtual void write(const QVariant &value); + void setTarget(const QQmlProperty &) override; + void write(const QVariant &value) override; QQuickAbstractAnimation *animation(); void setAnimation(QQuickAbstractAnimation *); diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h index d4719a7f5b..879c4d0fcc 100644 --- a/src/quick/util/qquickimageprovider.h +++ b/src/quick/util/qquickimageprovider.h @@ -90,8 +90,8 @@ public: QQuickImageProvider(ImageType type, Flags flags = Flags()); virtual ~QQuickImageProvider(); - ImageType imageType() const; - Flags flags() const; + ImageType imageType() const override; + Flags flags() const override; #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize, bool requestedAutoTransform); diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index 457f69d20f..06ad389b49 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -156,7 +156,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve public: QQuickPathLine(QObject *parent=0) : QQuickCurve(parent) {} - void addToPath(QPainterPath &path, const QQuickPathData &); + void addToPath(QPainterPath &path, const QQuickPathData &) override; }; class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve @@ -184,7 +184,7 @@ public: void setRelativeControlY(qreal y); bool hasRelativeControlY(); - void addToPath(QPainterPath &path, const QQuickPathData &); + void addToPath(QPainterPath &path, const QQuickPathData &) override; Q_SIGNALS: void controlXChanged(); @@ -242,7 +242,7 @@ public: void setRelativeControl2Y(qreal y); bool hasRelativeControl2Y(); - void addToPath(QPainterPath &path, const QQuickPathData &); + void addToPath(QPainterPath &path, const QQuickPathData &) override; Q_SIGNALS: void control1XChanged(); @@ -271,7 +271,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve public: QQuickPathCatmullRomCurve(QObject *parent=0) : QQuickCurve(parent) {} - void addToPath(QPainterPath &path, const QQuickPathData &); + void addToPath(QPainterPath &path, const QQuickPathData &) override; }; class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve @@ -301,7 +301,7 @@ public: ArcDirection direction() const; void setDirection(ArcDirection direction); - void addToPath(QPainterPath &path, const QQuickPathData &); + void addToPath(QPainterPath &path, const QQuickPathData &) override; Q_SIGNALS: void radiusXChanged(); @@ -326,7 +326,7 @@ public: QString path() const; void setPath(const QString &path); - void addToPath(QPainterPath &path, const QQuickPathData &); + void addToPath(QPainterPath &path, const QQuickPathData &) override; Q_SIGNALS: void pathChanged(); @@ -405,8 +405,8 @@ Q_SIGNALS: void startYChanged(); protected: - virtual void componentComplete(); - virtual void classBegin(); + void componentComplete() override; + void classBegin() override; void disconnectPathElements(); void connectPathElements(); void gatherAttributes(); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 96b88636fe..7dffc09ba5 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -177,7 +177,7 @@ class QQuickPixmapReaderThreadObject : public QObject { public: QQuickPixmapReaderThreadObject(QQuickPixmapReader *); void processJobs(); - virtual bool event(QEvent *e); + bool event(QEvent *e) override; private slots: void networkRequestDone(); void asyncResponseFinished(); @@ -891,7 +891,7 @@ public: void purgeCache(); protected: - virtual void timerEvent(QTimerEvent *); + void timerEvent(QTimerEvent *) override; public: QHash<QQuickPixmapKey, QQuickPixmapData *> m_cache; diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h index f53e847e00..623c826815 100644 --- a/src/quick/util/qquickpixmapcache_p.h +++ b/src/quick/util/qquickpixmapcache_p.h @@ -77,10 +77,10 @@ class QQuickDefaultTextureFactory : public QQuickTextureFactory Q_OBJECT public: QQuickDefaultTextureFactory(const QImage &i); - QSGTexture *createTexture(QQuickWindow *window) const; - QSize textureSize() const { return size; } - int textureByteCount() const { return size.width() * size.height() * 4; } - QImage image() const { return im; } + QSGTexture *createTexture(QQuickWindow *window) const override; + QSize textureSize() const override { return size; } + int textureByteCount() const override { return size.width() * size.height() * 4; } + QImage image() const override { return im; } private: QImage im; diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 37a910876e..4dfeb7cc4a 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -142,29 +142,29 @@ public: QQuickReplaceSignalHandler() {} ~QQuickReplaceSignalHandler() {} - virtual EventType type() const { return SignalHandler; } + EventType type() const override { return SignalHandler; } QQmlProperty property; QQmlBoundSignalExpressionPointer expression; QQmlBoundSignalExpressionPointer reverseExpression; QQmlBoundSignalExpressionPointer rewindExpression; - virtual void execute() { + void execute() override { QQmlPropertyPrivate::setSignalExpression(property, expression); } - virtual bool isReversable() { return true; } - virtual void reverse() { + bool isReversable() override { return true; } + void reverse() override { QQmlPropertyPrivate::setSignalExpression(property, reverseExpression); } - virtual void saveOriginals() { + void saveOriginals() override { saveCurrentValues(); reverseExpression = rewindExpression; } - virtual bool needsCopy() { return true; } - virtual void copyOriginals(QQuickStateActionEvent *other) + bool needsCopy() override { return true; } + void copyOriginals(QQuickStateActionEvent *other) override { QQuickReplaceSignalHandler *rsh = static_cast<QQuickReplaceSignalHandler*>(other); saveCurrentValues(); @@ -173,14 +173,14 @@ public: reverseExpression = rsh->reverseExpression; } - virtual void rewind() { + void rewind() override { QQmlPropertyPrivate::setSignalExpression(property, rewindExpression); } - virtual void saveCurrentValues() { + void saveCurrentValues() override { rewindExpression = QQmlPropertyPrivate::signalExpression(property); } - virtual bool override(QQuickStateActionEvent*other) { + bool override(QQuickStateActionEvent *other) override { if (other == this) return true; if (other->type() != type()) diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h index 0537750338..35b37e84cb 100644 --- a/src/quick/util/qquickpropertychanges_p.h +++ b/src/quick/util/qquickpropertychanges_p.h @@ -78,7 +78,7 @@ public: bool isExplicit() const; void setIsExplicit(bool); - virtual ActionList actions(); + ActionList actions() override; bool containsProperty(const QString &name) const; bool containsValue(const QString &name) const; @@ -103,8 +103,8 @@ public: void verifyList(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding); - virtual void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props); - virtual void applyBindings(QObject *obj, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings); + void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props) override; + void applyBindings(QObject *obj, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override; }; diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h index d640985b39..2f0e3bc0d8 100644 --- a/src/quick/util/qquicksmoothedanimation_p.h +++ b/src/quick/util/qquicksmoothedanimation_p.h @@ -79,8 +79,8 @@ public: ReversingMode reversingMode() const; void setReversingMode(ReversingMode); - virtual int duration() const; - virtual void setDuration(int); + int duration() const override; + void setDuration(int) override; qreal velocity() const; void setVelocity(qreal); @@ -88,10 +88,10 @@ public: int maximumEasingTime() const; void setMaximumEasingTime(int); - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; Q_SIGNALS: void velocityChanged(); void reversingModeChanged(); diff --git a/src/quick/util/qquicksmoothedanimation_p_p.h b/src/quick/util/qquicksmoothedanimation_p_p.h index 4a61599592..a415fdb55f 100644 --- a/src/quick/util/qquicksmoothedanimation_p_p.h +++ b/src/quick/util/qquicksmoothedanimation_p_p.h @@ -93,7 +93,7 @@ public: QQmlProperty target; - int duration() const; + int duration() const override; void restart(); void init(); @@ -101,9 +101,9 @@ public: void clearTemplate() { animationTemplate = 0; } protected: - virtual void updateCurrentTime(int); - virtual void updateState(QAbstractAnimationJob::State, QAbstractAnimationJob::State); - void debugAnimation(QDebug d) const; + void updateCurrentTime(int) override; + void updateState(QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; + void debugAnimation(QDebug d) const override; private: qreal easeFollow(qreal); diff --git a/src/quick/util/qquickspringanimation.cpp b/src/quick/util/qquickspringanimation.cpp index 294122150a..a9940959a0 100644 --- a/src/quick/util/qquickspringanimation.cpp +++ b/src/quick/util/qquickspringanimation.cpp @@ -61,7 +61,7 @@ public: QSpringAnimation(QQuickSpringAnimationPrivate * = 0); ~QSpringAnimation(); - int duration() const; + int duration() const override; void restart(); void init(); @@ -97,9 +97,9 @@ public: void clearTemplate() { animationTemplate = 0; } protected: - virtual void updateCurrentTime(int time); - virtual void updateState(QAbstractAnimationJob::State, QAbstractAnimationJob::State); - void debugAnimation(QDebug d) const; + void updateCurrentTime(int time) override; + void updateState(QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; + void debugAnimation(QDebug d) const override; private: QQuickSpringAnimationPrivate *animationTemplate; diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h index 141a2469d7..ffb2c41e6b 100644 --- a/src/quick/util/qquickspringanimation_p.h +++ b/src/quick/util/qquickspringanimation_p.h @@ -94,10 +94,10 @@ public: qreal modulus() const; void setModulus(qreal modulus); - virtual QAbstractAnimationJob* transition(QQuickStateActions &actions, + QAbstractAnimationJob* transition(QQuickStateActions &actions, QQmlProperties &modified, TransitionDirection direction, - QObject *defaultTarget = 0); + QObject *defaultTarget = 0) override; Q_SIGNALS: void modulusChanged(); diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h index 0c17b7c68c..a1315ae2ef 100644 --- a/src/quick/util/qquickstatechangescript_p.h +++ b/src/quick/util/qquickstatechangescript_p.h @@ -69,9 +69,9 @@ public: QQuickStateChangeScript(QObject *parent=0); ~QQuickStateChangeScript(); - virtual ActionList actions(); + ActionList actions() override; - virtual EventType type() const; + EventType type() const override; QQmlScriptString script() const; void setScript(const QQmlScriptString &); @@ -79,7 +79,7 @@ public: QString name() const; void setName(const QString &); - virtual void execute(); + void execute() override; }; diff --git a/src/quick/util/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h index 78508ac166..eebe3a9e56 100644 --- a/src/quick/util/qquickstategroup_p.h +++ b/src/quick/util/qquickstategroup_p.h @@ -81,8 +81,8 @@ public: QQuickState *findState(const QString &name) const; void removeState(QQuickState *state); - virtual void classBegin(); - virtual void componentComplete(); + void classBegin() override; + void componentComplete() override; Q_SIGNALS: void stateChanged(const QString &); diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp index 4139c87eda..ae8719341d 100644 --- a/src/quick/util/qquickstyledtext.cpp +++ b/src/quick/util/qquickstyledtext.cpp @@ -721,8 +721,7 @@ void QQuickStyledTextPrivate::parseImageAttributes(const QChar *&ch, const QStri QString padding(qFloor(imgWidth / spaceWidth), QChar::Nbsp); if (!trailingSpace) textOut += QLatin1Char(' '); - textOut += padding; - textOut += QLatin1Char(' '); + textOut += padding + QLatin1Char(' '); } QPair<QStringRef,QStringRef> QQuickStyledTextPrivate::parseAttribute(const QChar *&ch, const QString &textIn) diff --git a/src/quick/util/qquicktimeline_p_p.h b/src/quick/util/qquicktimeline_p_p.h index 552f194b79..ae1087487b 100644 --- a/src/quick/util/qquicktimeline_p_p.h +++ b/src/quick/util/qquicktimeline_p_p.h @@ -100,14 +100,14 @@ public: int time() const; - virtual int duration() const; + int duration() const override; Q_SIGNALS: void updated(); void completed(); protected: - virtual void updateCurrentTime(int); - void debugAnimation(QDebug d) const; + void updateCurrentTime(int) override; + void debugAnimation(QDebug d) const override; private: void remove(QQuickTimeLineObject *); @@ -181,7 +181,7 @@ public: Q_ASSERT(_class); } - virtual void setValue(qreal v) + void setValue(qreal v) override { QQuickTimeLineValue::setValue(v); if (_setFunctionReal) (_class->*_setFunctionReal)(v); diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index c8b5482c87..1d258d84bf 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -106,7 +106,7 @@ public: QQuickTransitionManager *manager; protected: - virtual void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); + void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; }; class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener @@ -134,7 +134,7 @@ public: bool reversible; bool enabled; protected: - virtual void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State); + void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty<QQuickAbstractAnimation> *list); |