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 <QtGui/private/qguisvg_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 std::optional<QPainterPath> qpath = QGuiSvg::parsePath(m_svgPaths.at(i));
87 if (qpath)
88 m_paths[i] = qpath.value();
89 else
90 qCDebug(lcPath) << "Syntax error in svg path no." << i;
91 }
92 m_dirty = false;
93 }
94 Q_ASSERT(m_paths.size() == pathCount);
95
96 if (m_paths.isEmpty())
97 return;
98
99 QPainterPath res;
100 qreal factorIntValue = 0;
101 const qreal f = std::modf(m_factor, &factorIntValue);
102 const qsizetype pathIdx = qsizetype(qBound(qreal(0), factorIntValue, qreal(pathCount - 1)));
103
104 if (m_paths.size() == 1 || (pathIdx == 0 && f <= 0)) {
105 res = m_paths.first();
106 } else {
107 res = m_paths.at(pathIdx);
108 if ((pathIdx < pathCount - 1) && f > 0) {
109 const QPainterPath &p0 = m_paths.at(pathIdx);
110 const QPainterPath &p1 = m_paths.at(pathIdx + 1);
111 if (p0.elementCount() == p1.elementCount()) {
112 for (qsizetype i = 0; i < p0.elementCount(); i++) {
113 QPainterPath::Element e0 = p0.elementAt(i);
114 QPainterPath::Element e1 = p1.elementAt(i);
115 if (e0.type != e1.type) {
116 qCDebug(lcPath) << "Differing elements in svg path no." << i;
117 break;
118 }
119 QPointF cp = QPointF(e0) + f * (QPointF(e1) - QPointF(e0));
120 res.setElementPositionAt(i, cp.x(), cp.y());
121 }
122 } else {
123 qCDebug(lcPath) << "Differing element count in svg path no." << pathIdx + 1;
124 }
125 }
126 }
127 path.addPath(res);
128}
129
130QT_END_NAMESPACE
Combined button and popup list for selecting options.