diff options
| author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2025-04-24 13:27:41 +0200 |
|---|---|---|
| committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2025-05-19 16:39:28 +0200 |
| commit | 38b0fe294957d6e6c352ca652a662a6dd014d539 (patch) | |
| tree | 530ed666988934fcc5f823920c6170c88a3002eb /src/quickvectorimage/helpers/qquicktransformgroup.cpp | |
| parent | 61149d18225fdcbadc92aa84778436b86e1b9feb (diff) | |
Support replace animations
SVG has a feature where a set of animations on the transform
can be set to either replace or append to previous animations,
but only while the animation set is active.
In order to support this, we introduce a helper class called
TransformGroup which can contain a set of parallel animations
and have them override the others.
Change-Id: I28be7d120527b1f2d1e3dbf5c5de94094c766363
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/quickvectorimage/helpers/qquicktransformgroup.cpp')
| -rw-r--r-- | src/quickvectorimage/helpers/qquicktransformgroup.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/quickvectorimage/helpers/qquicktransformgroup.cpp b/src/quickvectorimage/helpers/qquicktransformgroup.cpp new file mode 100644 index 0000000000..20a59ff41e --- /dev/null +++ b/src/quickvectorimage/helpers/qquicktransformgroup.cpp @@ -0,0 +1,134 @@ +// Copyright (C) 2025 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 "qquicktransformgroup_p.h" +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype TransformGroup + \inqmlmodule QtQuick.VectorImage.Helpers + \brief Provides specialization for sequences of transforms. + + This type allows specific specializations for sequences of transform operations required + for VectorImage. +*/ + +namespace { + +class DummyQuickItem : public QQuickItem +{ +public: + DummyQuickItem(QQuickTransformGroup *group) : m_group(group) {} + + virtual void itemChange(ItemChange ic, const ItemChangeData &) override + { + if (ic == ItemTransformHasChanged) + m_group->triggerUpdate(); + } + +private: + QQuickTransformGroup *m_group = nullptr; +}; + +} + +QQuickTransformGroup::QQuickTransformGroup(QObject *parent) + : QQuickTransform(parent) +{ + m_dummyItem = new DummyQuickItem(this); +} + +QQuickTransformGroup::~QQuickTransformGroup() +{ + delete m_dummyItem; +} + +void QQuickTransformGroup::activateOverride(QQuickTransform *xform) +{ + m_transformFlags[xform] |= Override; + update(); +} + +void QQuickTransformGroup::triggerUpdate() +{ + update(); +} + +void QQuickTransformGroup::deactivateOverride(QQuickTransform *xform) +{ + m_transformFlags[xform] &= ~Override; + update(); +} + +void QQuickTransformGroup::deactivate(QQuickTransform *xform) +{ + m_transformFlags[xform] |= Disabled; + update(); +} + +void QQuickTransformGroup::applyTo(QMatrix4x4 *matrix) const +{ + QVarLengthArray<QQuickTransform *, 8> activeTransforms; + for (QQuickTransform *xform : m_transforms) { + int flags = m_transformFlags.value(xform); + if (!(flags & Disabled)) { + activeTransforms.append(xform); + if (flags & Override) + break; + } + } + + // Apply in reverse order + for (auto it = activeTransforms.crbegin(); it != activeTransforms.crend(); ++it) + (*it)->applyTo(matrix); +} + +QQmlListProperty<QQuickTransform> QQuickTransformGroup::transformSequence() +{ + return QQmlListProperty<QQuickTransform>(this, + nullptr, + transformSequence_append, + transformSequence_count, + transformSequence_at, + transformSequence_clear); +} + +void QQuickTransformGroup::transformSequence_append(QQmlListProperty<QQuickTransform> *prop, + QQuickTransform *transform) +{ + if (!transform) + return; + + QQuickTransformGroup *that = static_cast<QQuickTransformGroup *>(prop->object); + that->m_transforms.append(transform); + that->update(); + + transform->appendToItem(that->m_dummyItem); +} + +QQuickTransform *QQuickTransformGroup::transformSequence_at(QQmlListProperty<QQuickTransform> *prop, + qsizetype idx) +{ + QQuickTransformGroup *that = static_cast<QQuickTransformGroup *>(prop->object); + if (idx < 0 || idx >= that->m_transforms.size()) + return nullptr; + else + return that->m_transforms.at(idx); +} + +void QQuickTransformGroup::transformSequence_clear(QQmlListProperty<QQuickTransform> *prop) +{ + QQuickTransformGroup *that = static_cast<QQuickTransformGroup *>(prop->object); + that->m_transforms.clear(); + that->update(); +} + +qsizetype QQuickTransformGroup::transformSequence_count(QQmlListProperty<QQuickTransform> *prop) +{ + QQuickTransformGroup *that = static_cast<QQuickTransformGroup *>(prop->object); + return that->m_transforms.size(); +} + +QT_END_NAMESPACE |
