// 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 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 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 QQuickTransformGroup::transformSequence() { return QQmlListProperty(this, nullptr, transformSequence_append, transformSequence_count, transformSequence_at, transformSequence_clear); } void QQuickTransformGroup::transformSequence_append(QQmlListProperty *prop, QQuickTransform *transform) { if (!transform) return; QQuickTransformGroup *that = static_cast(prop->object); that->m_transforms.append(transform); that->update(); transform->appendToItem(that->m_dummyItem); } QQuickTransform *QQuickTransformGroup::transformSequence_at(QQmlListProperty *prop, qsizetype idx) { QQuickTransformGroup *that = static_cast(prop->object); if (idx < 0 || idx >= that->m_transforms.size()) return nullptr; else return that->m_transforms.at(idx); } void QQuickTransformGroup::transformSequence_clear(QQmlListProperty *prop) { QQuickTransformGroup *that = static_cast(prop->object); that->m_transforms.clear(); that->update(); } qsizetype QQuickTransformGroup::transformSequence_count(QQmlListProperty *prop) { QQuickTransformGroup *that = static_cast(prop->object); return that->m_transforms.size(); } QT_END_NAMESPACE