1// Copyright (C) 2016 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
4#ifndef QQUICKPATH_H
5#define QQUICKPATH_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qtquickglobal_p.h>
19
20QT_REQUIRE_CONFIG(quick_path);
21
22#include <qqml.h>
23
24#include <private/qqmlnullablevalue_p.h>
25#include <private/qlazilyallocated_p.h>
26#include <private/qbezier_p.h>
27#include <private/qtquickglobal_p.h>
28
29#include <QtCore/QObject>
30#include <QtCore/QHash>
31#include <QtGui/QPainterPath>
32#include <QtGui/QFont>
33
34QT_BEGIN_NAMESPACE
35
36class QQuickCurve;
37struct QQuickPathData
38{
39 int index;
40 QPointF endPoint;
41 QList<QQuickCurve*> curves;
42};
43
44class Q_QUICK_EXPORT QQuickPathElement : public QObject
45{
46 Q_OBJECT
47 QML_ANONYMOUS
48 QML_ADDED_IN_VERSION(2, 0)
49public:
50 QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {}
51Q_SIGNALS:
52 void changed();
53};
54
55class Q_QUICK_EXPORT QQuickPathAttribute : public QQuickPathElement
56{
57 Q_OBJECT
58
59 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
60 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
61 QML_NAMED_ELEMENT(PathAttribute)
62 QML_ADDED_IN_VERSION(2, 0)
63public:
64 QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {}
65
66
67 QString name() const;
68 void setName(const QString &name);
69
70 qreal value() const;
71 void setValue(qreal value);
72
73Q_SIGNALS:
74 void nameChanged();
75 void valueChanged();
76
77private:
78 QString _name;
79 qreal _value = 0;
80};
81
82class Q_QUICK_EXPORT QQuickCurve : public QQuickPathElement
83{
84 Q_OBJECT
85
86 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
87 Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
88 Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged)
89 Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged)
90 QML_ANONYMOUS
91 QML_ADDED_IN_VERSION(2, 0)
92public:
93 QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {}
94
95 qreal x() const;
96 void setX(qreal x);
97 bool hasX();
98
99 qreal y() const;
100 void setY(qreal y);
101 bool hasY();
102
103 qreal relativeX() const;
104 void setRelativeX(qreal x);
105 bool hasRelativeX();
106
107 qreal relativeY() const;
108 void setRelativeY(qreal y);
109 bool hasRelativeY();
110
111 virtual void addToPath(QPainterPath &, const QQuickPathData &) {}
112
113Q_SIGNALS:
114 void xChanged();
115 void yChanged();
116 void relativeXChanged();
117 void relativeYChanged();
118
119private:
120 QQmlNullableValue<qreal> _x;
121 QQmlNullableValue<qreal> _y;
122 QQmlNullableValue<qreal> _relativeX;
123 QQmlNullableValue<qreal> _relativeY;
124};
125
126class Q_QUICK_EXPORT QQuickPathLine : public QQuickCurve
127{
128 Q_OBJECT
129 QML_NAMED_ELEMENT(PathLine)
130 QML_ADDED_IN_VERSION(2, 0)
131public:
132 QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {}
133
134 void addToPath(QPainterPath &path, const QQuickPathData &) override;
135};
136
137class Q_QUICK_EXPORT QQuickPathMove : public QQuickCurve
138{
139 Q_OBJECT
140 QML_NAMED_ELEMENT(PathMove)
141 QML_ADDED_IN_VERSION(2, 9)
142public:
143 QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {}
144
145 void addToPath(QPainterPath &path, const QQuickPathData &) override;
146};
147
148class Q_QUICK_EXPORT QQuickPathQuad : public QQuickCurve
149{
150 Q_OBJECT
151
152 Q_PROPERTY(qreal controlX READ controlX WRITE setControlX NOTIFY controlXChanged)
153 Q_PROPERTY(qreal controlY READ controlY WRITE setControlY NOTIFY controlYChanged)
154 Q_PROPERTY(qreal relativeControlX READ relativeControlX WRITE setRelativeControlX NOTIFY relativeControlXChanged)
155 Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged)
156
157 QML_NAMED_ELEMENT(PathQuad)
158 QML_ADDED_IN_VERSION(2, 0)
159public:
160 QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {}
161
162 qreal controlX() const;
163 void setControlX(qreal x);
164
165 qreal controlY() const;
166 void setControlY(qreal y);
167
168 qreal relativeControlX() const;
169 void setRelativeControlX(qreal x);
170 bool hasRelativeControlX();
171
172 qreal relativeControlY() const;
173 void setRelativeControlY(qreal y);
174 bool hasRelativeControlY();
175
176 void addToPath(QPainterPath &path, const QQuickPathData &) override;
177
178Q_SIGNALS:
179 void controlXChanged();
180 void controlYChanged();
181 void relativeControlXChanged();
182 void relativeControlYChanged();
183
184private:
185 qreal _controlX = 0;
186 qreal _controlY = 0;
187 QQmlNullableValue<qreal> _relativeControlX;
188 QQmlNullableValue<qreal> _relativeControlY;
189};
190
191class Q_QUICK_EXPORT QQuickPathCubic : public QQuickCurve
192{
193 Q_OBJECT
194
195 Q_PROPERTY(qreal control1X READ control1X WRITE setControl1X NOTIFY control1XChanged)
196 Q_PROPERTY(qreal control1Y READ control1Y WRITE setControl1Y NOTIFY control1YChanged)
197 Q_PROPERTY(qreal control2X READ control2X WRITE setControl2X NOTIFY control2XChanged)
198 Q_PROPERTY(qreal control2Y READ control2Y WRITE setControl2Y NOTIFY control2YChanged)
199 Q_PROPERTY(qreal relativeControl1X READ relativeControl1X WRITE setRelativeControl1X NOTIFY relativeControl1XChanged)
200 Q_PROPERTY(qreal relativeControl1Y READ relativeControl1Y WRITE setRelativeControl1Y NOTIFY relativeControl1YChanged)
201 Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged)
202 Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged)
203 QML_NAMED_ELEMENT(PathCubic)
204 QML_ADDED_IN_VERSION(2, 0)
205public:
206 QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {}
207
208 qreal control1X() const;
209 void setControl1X(qreal x);
210
211 qreal control1Y() const;
212 void setControl1Y(qreal y);
213
214 qreal control2X() const;
215 void setControl2X(qreal x);
216
217 qreal control2Y() const;
218 void setControl2Y(qreal y);
219
220 qreal relativeControl1X() const;
221 void setRelativeControl1X(qreal x);
222 bool hasRelativeControl1X();
223
224 qreal relativeControl1Y() const;
225 void setRelativeControl1Y(qreal y);
226 bool hasRelativeControl1Y();
227
228 qreal relativeControl2X() const;
229 void setRelativeControl2X(qreal x);
230 bool hasRelativeControl2X();
231
232 qreal relativeControl2Y() const;
233 void setRelativeControl2Y(qreal y);
234 bool hasRelativeControl2Y();
235
236 void addToPath(QPainterPath &path, const QQuickPathData &) override;
237
238Q_SIGNALS:
239 void control1XChanged();
240 void control1YChanged();
241 void control2XChanged();
242 void control2YChanged();
243 void relativeControl1XChanged();
244 void relativeControl1YChanged();
245 void relativeControl2XChanged();
246 void relativeControl2YChanged();
247
248private:
249 qreal _control1X = 0;
250 qreal _control1Y = 0;
251 qreal _control2X = 0;
252 qreal _control2Y = 0;
253 QQmlNullableValue<qreal> _relativeControl1X;
254 QQmlNullableValue<qreal> _relativeControl1Y;
255 QQmlNullableValue<qreal> _relativeControl2X;
256 QQmlNullableValue<qreal> _relativeControl2Y;
257};
258
259class Q_QUICK_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve
260{
261 Q_OBJECT
262 QML_NAMED_ELEMENT(PathCurve)
263 QML_ADDED_IN_VERSION(2, 0)
264public:
265 QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {}
266
267 void addToPath(QPainterPath &path, const QQuickPathData &) override;
268};
269
270class Q_QUICK_EXPORT QQuickPathArc : public QQuickCurve
271{
272 Q_OBJECT
273 Q_PROPERTY(qreal radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged)
274 Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
275 Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged)
276 Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
277 Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION(2, 9))
278 QML_NAMED_ELEMENT(PathArc)
279 QML_ADDED_IN_VERSION(2, 0)
280
281public:
282 QQuickPathArc(QObject *parent=nullptr)
283 : QQuickCurve(parent) {}
284
285 enum ArcDirection { Clockwise, Counterclockwise };
286 Q_ENUM(ArcDirection)
287
288 qreal radiusX() const;
289 void setRadiusX(qreal);
290
291 qreal radiusY() const;
292 void setRadiusY(qreal);
293
294 bool useLargeArc() const;
295 void setUseLargeArc(bool);
296
297 ArcDirection direction() const;
298 void setDirection(ArcDirection direction);
299
300 qreal xAxisRotation() const;
301 void setXAxisRotation(qreal rotation);
302
303 void addToPath(QPainterPath &path, const QQuickPathData &) override;
304
305Q_SIGNALS:
306 void radiusXChanged();
307 void radiusYChanged();
308 void useLargeArcChanged();
309 void directionChanged();
310 Q_REVISION(2, 9) void xAxisRotationChanged();
311
312private:
313 qreal _radiusX = 0;
314 qreal _radiusY = 0;
315 bool _useLargeArc = false;
316 ArcDirection _direction = Clockwise;
317 qreal _xAxisRotation = 0;
318};
319
320class Q_QUICK_EXPORT QQuickPathAngleArc : public QQuickCurve
321{
322 Q_OBJECT
323 Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged)
324 Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged)
325 Q_PROPERTY(qreal radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged)
326 Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
327 Q_PROPERTY(qreal startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged)
328 Q_PROPERTY(qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY sweepAngleChanged)
329 Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged)
330
331 QML_NAMED_ELEMENT(PathAngleArc)
332 QML_ADDED_IN_VERSION(2, 11)
333
334public:
335 QQuickPathAngleArc(QObject *parent=nullptr)
336 : QQuickCurve(parent) {}
337
338 qreal centerX() const;
339 void setCenterX(qreal);
340
341 qreal centerY() const;
342 void setCenterY(qreal);
343
344 qreal radiusX() const;
345 void setRadiusX(qreal);
346
347 qreal radiusY() const;
348 void setRadiusY(qreal);
349
350 qreal startAngle() const;
351 void setStartAngle(qreal);
352
353 qreal sweepAngle() const;
354 void setSweepAngle(qreal);
355
356 bool moveToStart() const;
357 void setMoveToStart(bool);
358
359 void addToPath(QPainterPath &path, const QQuickPathData &) override;
360
361Q_SIGNALS:
362 void centerXChanged();
363 void centerYChanged();
364 void radiusXChanged();
365 void radiusYChanged();
366 void startAngleChanged();
367 void sweepAngleChanged();
368 void moveToStartChanged();
369
370private:
371 qreal _centerX = 0;
372 qreal _centerY = 0;
373 qreal _radiusX = 0;
374 qreal _radiusY = 0;
375 qreal _startAngle = 0;
376 qreal _sweepAngle = 0;
377 bool _moveToStart = true;
378};
379
380class Q_QUICK_EXPORT QQuickPathSvg : public QQuickCurve
381{
382 Q_OBJECT
383 Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
384 QML_NAMED_ELEMENT(PathSvg)
385 QML_ADDED_IN_VERSION(2, 0)
386public:
387 QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {}
388
389 QString path() const;
390 void setPath(const QString &path);
391
392 void addToPath(QPainterPath &path, const QQuickPathData &) override;
393
394Q_SIGNALS:
395 void pathChanged();
396
397private:
398 QString _path;
399};
400
401class Q_QUICK_EXPORT QQuickPathRectangle : public QQuickCurve
402{
403 Q_OBJECT
404
405 Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged FINAL)
406 Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged FINAL)
407 Q_PROPERTY(qreal strokeAdjustment READ strokeAdjustment WRITE setStrokeAdjustment NOTIFY strokeAdjustmentChanged FINAL)
408 Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged FINAL)
409 Q_PROPERTY(qreal topLeftRadius READ topLeftRadius WRITE setTopLeftRadius RESET resetTopLeftRadius NOTIFY topLeftRadiusChanged FINAL)
410 Q_PROPERTY(qreal topRightRadius READ topRightRadius WRITE setTopRightRadius NOTIFY topRightRadiusChanged RESET resetTopRightRadius FINAL)
411 Q_PROPERTY(qreal bottomLeftRadius READ bottomLeftRadius WRITE setBottomLeftRadius NOTIFY bottomLeftRadiusChanged RESET resetBottomLeftRadius FINAL)
412 Q_PROPERTY(qreal bottomRightRadius READ bottomRightRadius WRITE setBottomRightRadius NOTIFY bottomRightRadiusChanged RESET resetBottomRightRadius FINAL)
413
414 QML_NAMED_ELEMENT(PathRectangle)
415 QML_ADDED_IN_VERSION(6, 8)
416public:
417 QQuickPathRectangle(QObject *parent = nullptr) : QQuickCurve(parent) {}
418
419 qreal width() const;
420 void setWidth(qreal width);
421
422 qreal height() const;
423 void setHeight(qreal height);
424
425 qreal strokeAdjustment() const;
426 void setStrokeAdjustment(qreal newStrokeAdjustment);
427
428 qreal radius() const;
429 void setRadius(qreal newRadius);
430
431 qreal topLeftRadius() const { return cornerRadius(corner: Qt::TopLeftCorner); }
432 void setTopLeftRadius(qreal radius) { setCornerRadius(corner: Qt::TopLeftCorner, newCornerRadius: radius); }
433 void resetTopLeftRadius() { resetCornerRadius(corner: Qt::TopLeftCorner); }
434
435 qreal topRightRadius() const { return cornerRadius(corner: Qt::TopRightCorner); }
436 void setTopRightRadius(qreal radius) { setCornerRadius(corner: Qt::TopRightCorner, newCornerRadius: radius); }
437 void resetTopRightRadius() { resetCornerRadius(corner: Qt::TopRightCorner); }
438
439 qreal bottomLeftRadius() const { return cornerRadius(corner: Qt::BottomLeftCorner); }
440 void setBottomLeftRadius(qreal radius) { setCornerRadius(corner: Qt::BottomLeftCorner, newCornerRadius: radius); }
441 void resetBottomLeftRadius() { resetCornerRadius(corner: Qt::BottomLeftCorner); }
442
443 qreal bottomRightRadius() const { return cornerRadius(corner: Qt::BottomRightCorner); }
444 void setBottomRightRadius(qreal radius) { setCornerRadius(corner: Qt::BottomRightCorner, newCornerRadius: radius); }
445 void resetBottomRightRadius() { resetCornerRadius(corner: Qt::BottomRightCorner); }
446
447 qreal cornerRadius(Qt::Corner corner) const;
448 void setCornerRadius(Qt::Corner corner, qreal newCornerRadius);
449 void resetCornerRadius(Qt::Corner corner);
450
451 void addToPath(QPainterPath &path, const QQuickPathData &) override;
452
453Q_SIGNALS:
454 void widthChanged();
455 void heightChanged();
456 void strokeAdjustmentChanged();
457 void radiusChanged();
458 void topLeftRadiusChanged();
459 void topRightRadiusChanged();
460 void bottomLeftRadiusChanged();
461 void bottomRightRadiusChanged();
462
463private:
464 void emitCornerRadiusChanged(Qt::Corner corner);
465
466 qreal _width = 0;
467 qreal _height = 0;
468 qreal _strokeAdjustment = 0;
469 struct ExtraData
470 {
471 ExtraData() { std::fill_n(cornerRadii, 4, -1); }
472 qreal radius = 0;
473 qreal cornerRadii[4];
474 };
475 QLazilyAllocated<ExtraData> _extra;
476};
477
478class Q_QUICK_EXPORT QQuickPathPercent : public QQuickPathElement
479{
480 Q_OBJECT
481 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
482 QML_NAMED_ELEMENT(PathPercent)
483 QML_ADDED_IN_VERSION(2, 0)
484public:
485 QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {}
486
487 qreal value() const;
488 void setValue(qreal value);
489
490Q_SIGNALS:
491 void valueChanged();
492
493private:
494 qreal _value = 0;
495};
496
497class Q_QUICK_EXPORT QQuickPathPolyline : public QQuickCurve
498{
499 Q_OBJECT
500 Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
501 Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged)
502 QML_NAMED_ELEMENT(PathPolyline)
503 QML_ADDED_IN_VERSION(2, 14)
504public:
505 QQuickPathPolyline(QObject *parent=nullptr);
506
507 QVariant path() const;
508 void setPath(const QVariant &path);
509 void setPath(const QVector<QPointF> &path);
510 QPointF start() const;
511 void addToPath(QPainterPath &path, const QQuickPathData &data) override;
512
513Q_SIGNALS:
514 void pathChanged();
515 void startChanged();
516
517private:
518 QVector<QPointF> m_path;
519};
520
521class Q_QUICK_EXPORT QQuickPathMultiline : public QQuickCurve
522{
523 Q_OBJECT
524 Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
525 Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged)
526 QML_NAMED_ELEMENT(PathMultiline)
527 QML_ADDED_IN_VERSION(2, 14)
528public:
529 QQuickPathMultiline(QObject *parent=nullptr);
530
531 QVariant paths() const;
532 void setPaths(const QVariant &paths);
533 void setPaths(const QVector<QVector<QPointF>> &paths);
534 QPointF start() const;
535 void addToPath(QPainterPath &path, const QQuickPathData &) override;
536
537Q_SIGNALS:
538 void pathsChanged();
539 void startChanged();
540
541private:
542 QPointF absolute(const QPointF &relative) const;
543
544 QVector<QVector<QPointF>> m_paths;
545};
546
547struct QQuickCachedBezier
548{
549 QQuickCachedBezier() {}
550 QBezier bezier;
551 int element;
552 qreal bezLength;
553 qreal currLength;
554 qreal p;
555 bool isValid = false;
556};
557
558class QQuickPathPrivate;
559class Q_QUICK_EXPORT QQuickPath : public QObject, public QQmlParserStatus
560{
561 Q_OBJECT
562
563 Q_INTERFACES(QQmlParserStatus)
564 Q_PROPERTY(QQmlListProperty<QQuickPathElement> pathElements READ pathElements)
565 Q_PROPERTY(qreal startX READ startX WRITE setStartX NOTIFY startXChanged)
566 Q_PROPERTY(qreal startY READ startY WRITE setStartY NOTIFY startYChanged)
567 Q_PROPERTY(bool closed READ isClosed NOTIFY changed)
568 Q_PROPERTY(bool simplify READ simplify WRITE setSimplify NOTIFY simplifyChanged REVISION(6, 6) FINAL)
569 Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION(2, 14))
570 Q_CLASSINFO("DefaultProperty", "pathElements")
571 QML_NAMED_ELEMENT(Path)
572 QML_ADDED_IN_VERSION(2, 0)
573public:
574 QQuickPath(QObject *parent=nullptr);
575 ~QQuickPath() override;
576
577 QQmlListProperty<QQuickPathElement> pathElements();
578
579 qreal startX() const;
580 void setStartX(qreal x);
581 bool hasStartX() const;
582
583 qreal startY() const;
584 void setStartY(qreal y);
585 bool hasStartY() const;
586
587 bool isClosed() const;
588
589 QPainterPath path() const;
590 void setPath(const QPainterPath &path);
591
592 QStringList attributes() const;
593 qreal attributeAt(const QString &, qreal) const;
594 Q_REVISION(2, 14) Q_INVOKABLE QPointF pointAtPercent(qreal t) const;
595 QPointF sequentialPointAt(qreal p, qreal *angle = nullptr) const;
596 void invalidateSequentialHistory() const;
597
598 QSizeF scale() const;
599 void setScale(const QSizeF &scale);
600
601 bool simplify() const;
602 void setSimplify(bool s);
603
604 bool isAsynchronous() const;
605 void setAsynchronous(bool a);
606
607Q_SIGNALS:
608 void changed();
609 void startXChanged();
610 void startYChanged();
611 Q_REVISION(6, 6) void simplifyChanged();
612 Q_REVISION(2, 14) void scaleChanged();
613
614protected:
615 QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr);
616 void componentComplete() override;
617 void classBegin() override;
618 void disconnectPathElements();
619 void connectPathElements();
620 void gatherAttributes();
621
622 // pathElements property
623 static QQuickPathElement *pathElements_at(QQmlListProperty<QQuickPathElement> *, qsizetype);
624 static void pathElements_append(QQmlListProperty<QQuickPathElement> *, QQuickPathElement *);
625 static qsizetype pathElements_count(QQmlListProperty<QQuickPathElement> *);
626 static void pathElements_clear(QQmlListProperty<QQuickPathElement> *);
627
628private Q_SLOTS:
629 void processPath();
630
631private:
632 struct AttributePoint {
633 AttributePoint() {}
634 AttributePoint(const AttributePoint &other)
635 : percent(other.percent), scale(other.scale), origpercent(other.origpercent), values(other.values) {}
636 AttributePoint &operator=(const AttributePoint &other) {
637 percent = other.percent; scale = other.scale; origpercent = other.origpercent; values = other.values; return *this;
638 }
639 qreal percent = 0; //massaged percent along the painter path
640 qreal scale = 1;
641 qreal origpercent = 0; //'real' percent along the painter path
642 QHash<QString, qreal> values;
643 };
644
645 void doProcessPath();
646 void interpolate(int idx, const QString &name, qreal value);
647 void endpoint(const QString &name);
648 void createPointCache() const;
649
650 static void interpolate(QList<AttributePoint> &points, int idx, const QString &name, qreal value);
651 static void endpoint(QList<AttributePoint> &attributePoints, const QString &name);
652 static QPointF forwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr);
653 static QPointF backwardsPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr);
654
655private:
656 Q_DISABLE_COPY(QQuickPath)
657 Q_DECLARE_PRIVATE(QQuickPath)
658 friend class QQuickPathAnimationUpdater;
659
660public:
661 QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = nullptr);
662 QPainterPath createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed = nullptr);
663 static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr);
664};
665
666class Q_QUICK_EXPORT QQuickPathText : public QQuickPathElement
667{
668 Q_OBJECT
669 Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
670 Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
671 Q_PROPERTY(qreal width READ width NOTIFY changed)
672 Q_PROPERTY(qreal height READ height NOTIFY changed)
673 Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
674 Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
675 QML_NAMED_ELEMENT(PathText)
676 QML_ADDED_IN_VERSION(2, 15)
677public:
678 QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent)
679 {
680 connect(sender: this, signal: &QQuickPathText::xChanged, context: this, slot: &QQuickPathElement::changed);
681 connect(sender: this, signal: &QQuickPathText::yChanged, context: this, slot: &QQuickPathElement::changed);
682 connect(sender: this, signal: &QQuickPathText::textChanged, context: this, slot: &QQuickPathElement::changed);
683 connect(sender: this, signal: &QQuickPathText::fontChanged, context: this, slot: &QQuickPathElement::changed);
684
685 connect(sender: this, signal: &QQuickPathElement::changed, context: this, slot: &QQuickPathText::invalidate);
686 }
687
688 void addToPath(QPainterPath &path);
689
690 qreal x() const { return _x; }
691 qreal y() const { return _y; }
692 QString text() const { return _text; }
693 QFont font() const { return _font; }
694
695 void setX(qreal x)
696 {
697 if (qFuzzyCompare(p1: _x, p2: x))
698 return;
699
700 _x = x;
701 Q_EMIT xChanged();
702 }
703
704 void setY(qreal y)
705 {
706 if (qFuzzyCompare(p1: _y, p2: y))
707 return;
708
709 _y = y;
710 Q_EMIT yChanged();
711 }
712
713 void setText(const QString &text)
714 {
715 if (text == _text)
716 return;
717
718 _text = text;
719 Q_EMIT textChanged();
720 }
721
722 void setFont(const QFont &font)
723 {
724 if (font == _font)
725 return;
726
727 _font = font;
728 Q_EMIT fontChanged();
729 }
730
731 qreal width() const
732 {
733 updatePath();
734 return _path.boundingRect().width();
735 }
736
737 qreal height() const
738 {
739 updatePath();
740 return _path.boundingRect().height();
741 }
742
743Q_SIGNALS:
744 void xChanged();
745 void yChanged();
746 void textChanged();
747 void fontChanged();
748
749private Q_SLOTS:
750 void invalidate()
751 {
752 _path.clear();
753 }
754
755private:
756 void updatePath() const;
757
758 QString _text;
759 qreal _x = qreal(0.0);
760 qreal _y = qreal(0.0);
761 QFont _font;
762
763 mutable QPainterPath _path;
764};
765
766QT_END_NAMESPACE
767
768#endif // QQUICKPATH_H
769

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtdeclarative/src/quick/util/qquickpath_p.h