aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickvectorimage/helpers/qquicktransformgroup.cpp
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2025-04-24 13:27:41 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2025-05-19 16:39:28 +0200
commit38b0fe294957d6e6c352ca652a662a6dd014d539 (patch)
tree530ed666988934fcc5f823920c6170c88a3002eb /src/quickvectorimage/helpers/qquicktransformgroup.cpp
parent61149d18225fdcbadc92aa84778436b86e1b9feb (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.cpp134
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