diff options
Diffstat (limited to 'src/corelib/animation/qvariantanimation.cpp')
-rw-r--r-- | src/corelib/animation/qvariantanimation.cpp | 108 |
1 files changed, 47 insertions, 61 deletions
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index efe1675fe5..b4d47aae8f 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or 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.GPL2 and 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qvariantanimation.h" #include "qvariantanimation_p.h" @@ -192,7 +156,7 @@ void QVariantAnimationPrivate::convertValues(int t) { auto type = QMetaType(t); //this ensures that all the keyValues are of type t - for (int i = 0; i < keyValues.count(); ++i) { + for (int i = 0; i < keyValues.size(); ++i) { QVariantAnimation::KeyValue &pair = keyValues[i]; pair.second.convert(type); } @@ -226,11 +190,12 @@ void QVariantAnimationPrivate::updateInterpolator() void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) { // can't interpolate if we don't have at least 2 values - if ((keyValues.count() + (defaultStartEndValue.isValid() ? 1 : 0)) < 2) + if ((keyValues.size() + (defaultStartEndValue.isValid() ? 1 : 0)) < 2) return; const qreal endProgress = (direction == QAbstractAnimation::Forward) ? qreal(1) : qreal(0); - const qreal progress = easing.valueForProgress(((duration == 0) ? endProgress : qreal(currentTime) / qreal(duration))); + const qreal progress = easing.value().valueForProgress( + duration == 0 ? endProgress : qreal(currentTime) / qreal(duration)); //0 and 1 are still the boundaries if (force || (currentInterval.start.first > 0 && progress < currentInterval.start.first) @@ -238,27 +203,27 @@ void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) //let's update currentInterval QVariantAnimation::KeyValues::const_iterator it = std::lower_bound(keyValues.constBegin(), keyValues.constEnd(), - qMakePair(progress, QVariant()), + std::pair{progress, QVariant{}}, animationValueLessThan); if (it == keyValues.constBegin()) { //the item pointed to by it is the start element in the range - if (it->first == 0 && keyValues.count() > 1) { + if (it->first == 0 && keyValues.size() > 1) { currentInterval.start = *it; currentInterval.end = *(it+1); } else { - currentInterval.start = qMakePair(qreal(0), defaultStartEndValue); + currentInterval.start = {qreal(0), defaultStartEndValue}; currentInterval.end = *it; } } else if (it == keyValues.constEnd()) { --it; //position the iterator on the last item - if (it->first == 1 && keyValues.count() > 1) { + if (it->first == 1 && keyValues.size() > 1) { //we have an end value (item with progress = 1) currentInterval.start = *(it-1); currentInterval.end = *it; } else { //we use the default end value here currentInterval.start = *it; - currentInterval.end = qMakePair(qreal(1), defaultStartEndValue); + currentInterval.end = {qreal(1), defaultStartEndValue}; } } else { currentInterval.start = *(it-1); @@ -277,14 +242,16 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) const qreal startProgress = currentInterval.start.first; const qreal endProgress = currentInterval.end.first; - const qreal localProgress = (progress - startProgress) / (endProgress - startProgress); + const qreal localProgress = + qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below + /* else */ : (progress - startProgress) / (endProgress - startProgress); QVariant ret = q->interpolated(currentInterval.start.second, currentInterval.end.second, localProgress); qSwap(currentValue, ret); q->updateCurrentValue(currentValue); - static QBasicAtomicInt changedSignalIndex = Q_BASIC_ATOMIC_INITIALIZER(0); + Q_CONSTINIT static QBasicAtomicInt changedSignalIndex = Q_BASIC_ATOMIC_INITIALIZER(0); if (!changedSignalIndex.loadRelaxed()) { //we keep the mask so that we emit valueChanged only when needed (for performance reasons) changedSignalIndex.testAndSetRelaxed(0, signalIndex("valueChanged(QVariant)")); @@ -297,9 +264,10 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) QVariant QVariantAnimationPrivate::valueAt(qreal step) const { - QVariantAnimation::KeyValues::const_iterator result = - std::lower_bound(keyValues.constBegin(), keyValues.constEnd(), qMakePair(step, QVariant()), animationValueLessThan); - if (result != keyValues.constEnd() && !animationValueLessThan(qMakePair(step, QVariant()), *result)) + const auto sought = std::pair{step, QVariant()}; + const auto result = std::lower_bound(keyValues.cbegin(), keyValues.cend(), sought, + animationValueLessThan); + if (result != keyValues.cend() && !animationValueLessThan(sought, *result)) return result->second; return QVariant(); @@ -386,13 +354,23 @@ QEasingCurve QVariantAnimation::easingCurve() const void QVariantAnimation::setEasingCurve(const QEasingCurve &easing) { Q_D(QVariantAnimation); - d->easing = easing; + d->easing.removeBindingUnlessInWrapper(); + const bool valueChanged = easing != d->easing.valueBypassingBindings(); + d->easing.setValueBypassingBindings(easing); d->recalculateCurrentInterval(); + if (valueChanged) + d->easing.notify(); +} + +QBindable<QEasingCurve> QVariantAnimation::bindableEasingCurve() +{ + Q_D(QVariantAnimation); + return &d->easing; } typedef QList<QVariantAnimation::Interpolator> QInterpolatorVector; Q_GLOBAL_STATIC(QInterpolatorVector, registeredInterpolators) -static QBasicMutex registeredInterpolatorsMutex; +Q_CONSTINIT static QBasicMutex registeredInterpolatorsMutex; /*! \fn template <typename T> void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) @@ -429,8 +407,8 @@ void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator fun // to continue causes the app to crash on exit with a SEGV if (interpolators) { const auto locker = qt_scoped_lock(registeredInterpolatorsMutex); - if (int(interpolationType) >= interpolators->count()) - interpolators->resize(int(interpolationType) + 1); + if (interpolationType >= interpolators->size()) + interpolators->resize(interpolationType + 1); interpolators->replace(interpolationType, func); } } @@ -447,7 +425,7 @@ QVariantAnimation::Interpolator QVariantAnimationPrivate::getInterpolator(int in QInterpolatorVector *interpolators = registeredInterpolators(); const auto locker = qt_scoped_lock(registeredInterpolatorsMutex); QVariantAnimation::Interpolator ret = nullptr; - if (interpolationType < interpolators->count()) { + if (interpolationType < interpolators->size()) { ret = interpolators->at(interpolationType); if (ret) return ret; } @@ -506,10 +484,18 @@ void QVariantAnimation::setDuration(int msecs) qWarning("QVariantAnimation::setDuration: cannot set a negative duration"); return; } - if (d->duration == msecs) - return; - d->duration = msecs; - d->recalculateCurrentInterval(); + d->duration.removeBindingUnlessInWrapper(); + if (d->duration.valueBypassingBindings() != msecs) { + d->duration.setValueBypassingBindings(msecs); + d->recalculateCurrentInterval(); + d->duration.notify(); + } +} + +QBindable<int> QVariantAnimation::bindableDuration() +{ + Q_D(QVariantAnimation); + return &d->duration; } /*! @@ -567,7 +553,7 @@ QVariant QVariantAnimation::keyValueAt(qreal step) const /*! \typedef QVariantAnimation::KeyValue - This is a typedef for QPair<qreal, QVariant>. + This is a typedef for std::pair<qreal, QVariant>. */ /*! \typedef QVariantAnimation::KeyValues |