Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickpathinterpolated.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <private/qquicksvgparser_p.h>
6
8
9Q_STATIC_LOGGING_CATEGORY(lcPath, "qt.quick.shapes.path")
10
11/*!
12 \qmltype PathInterpolated
13 \nativetype QQuickPathInterpolated
14 \inqmlmodule QtQuick.VectorImage.Helpers
15 \brief Defines a path as an interpolated value between two of the paths in a list.
16 \since 6.11
17
18 This item provides a simple way to specify an interpolated path. This is useful for displaying
19 animated paths, where one path is gradually morphed into the next.
20
21 The interpolation end points are specified in the \l svgPaths list property, using the same
22 syntax as the PathSvg item. Based on the \l factor property, the resulting path will be an
23 interpolation between path \e n and \e n+1 in the list, where \e n is the integer part of the
24 factor. The fractional part determines the interpolation weight between the two.
25
26 \sa Path, PathSvg
27*/
28
29QQuickPathInterpolated::QQuickPathInterpolated(QObject *parent) : QQuickCurve{ parent }
30{
31 connect(this, &QQuickPathInterpolated::factorChanged, this, &QQuickPathElement::changed);
32 connect(this, &QQuickPathInterpolated::svgPathsChanged, this, &QQuickPathElement::changed);
33}
34
35/*!
36 \qmlproperty real QtQuick.VectorImage.Helpers::PathInterpolated::factor
37
38 This property holds the interpolation factor. The effective value is clamped to \e{[0,
39 svgPaths.size - 1]}.
40*/
41
42qreal QQuickPathInterpolated::factor() const
43{
44 return m_factor;
45}
46
47void QQuickPathInterpolated::setFactor(qreal newFactor)
48{
49 if (qFuzzyCompare(m_factor, newFactor) || !qIsFinite(newFactor))
50 return;
51 m_factor = newFactor;
52 emit factorChanged();
53}
54
55/*!
56 \qmlproperty stringlist QtQuick.VectorImage.Helpers::PathInterpolated::svgPaths
57
58 This property holds a list of paths, specified as SVG text strings in the manner of \l PathSvg.
59
60 The generation of an interpolated value between two of the paths in the list depends on them
61 having the same number and types of path elements. The resulting path has the same elements,
62 with coordinates linearly interpolated between the two source paths.
63*/
64
65QStringList QQuickPathInterpolated::svgPaths() const
66{
67 return m_svgPaths;
68}
69
70void QQuickPathInterpolated::setSvgPaths(const QStringList &newSvgPaths)
71{
72 if (m_svgPaths == newSvgPaths)
73 return;
74 m_svgPaths = newSvgPaths;
75 m_dirty = true;
76 emit svgPathsChanged();
77}
78
79void QQuickPathInterpolated::addToPath(QPainterPath &path, const QQuickPathData &)
80{
81 const qsizetype pathCount = m_svgPaths.size();
82 if (m_dirty) {
83 m_paths.clear();
84 m_paths.resize(pathCount);
85 for (qsizetype i = 0; i < pathCount; i++) {
86 if (!QQuickSvgParser::parsePathDataFast(m_svgPaths.at(i), m_paths[i]))
87 qCDebug(lcPath) << "Syntax error in svg path no." << i;
88 }
89 m_dirty = false;
90 }
91 Q_ASSERT(m_paths.size() == pathCount);
92
93 if (m_paths.isEmpty())
94 return;
95
96 QPainterPath res;
97 qreal factorIntValue = 0;
98 const qreal f = std::modf(m_factor, &factorIntValue);
99 const qsizetype pathIdx = qsizetype(qBound(qreal(0), factorIntValue, qreal(pathCount - 1)));
100
101 if (m_paths.size() == 1 || (pathIdx == 0 && f <= 0)) {
102 res = m_paths.first();
103 } else {
104 res = m_paths.at(pathIdx);
105 if ((pathIdx < pathCount - 1) && f > 0) {
106 const QPainterPath &p0 = m_paths.at(pathIdx);
107 const QPainterPath &p1 = m_paths.at(pathIdx + 1);
108 if (p0.elementCount() == p1.elementCount()) {
109 for (qsizetype i = 0; i < p0.elementCount(); i++) {
110 QPainterPath::Element e0 = p0.elementAt(i);
111 QPainterPath::Element e1 = p1.elementAt(i);
112 if (e0.type != e1.type) {
113 qCDebug(lcPath) << "Differing elements in svg path no." << i;
114 break;
115 }
116 QPointF cp = QPointF(e0) + f * (QPointF(e1) - QPointF(e0));
117 res.setElementPositionAt(i, cp.x(), cp.y());
118 }
119 } else {
120 qCDebug(lcPath) << "Differing element count in svg path no." << pathIdx + 1;
121 }
122 }
123 }
124 path.addPath(res);
125}
126
127QT_END_NAMESPACE
Combined button and popup list for selecting options.