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

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