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 | |
20 | QT_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 | |
34 | QT_BEGIN_NAMESPACE |
35 | |
36 | class QQuickCurve; |
37 | struct QQuickPathData |
38 | { |
39 | int index; |
40 | QPointF endPoint; |
41 | QList<QQuickCurve*> curves; |
42 | }; |
43 | |
44 | class Q_QUICK_EXPORT QQuickPathElement : public QObject |
45 | { |
46 | Q_OBJECT |
47 | QML_ANONYMOUS |
48 | QML_ADDED_IN_VERSION(2, 0) |
49 | public: |
50 | QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {} |
51 | Q_SIGNALS: |
52 | void changed(); |
53 | }; |
54 | |
55 | class 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) |
63 | public: |
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 | |
73 | Q_SIGNALS: |
74 | void nameChanged(); |
75 | void valueChanged(); |
76 | |
77 | private: |
78 | QString _name; |
79 | qreal _value = 0; |
80 | }; |
81 | |
82 | class 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) |
92 | public: |
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 | |
113 | Q_SIGNALS: |
114 | void xChanged(); |
115 | void yChanged(); |
116 | void relativeXChanged(); |
117 | void relativeYChanged(); |
118 | |
119 | private: |
120 | QQmlNullableValue<qreal> _x; |
121 | QQmlNullableValue<qreal> _y; |
122 | QQmlNullableValue<qreal> _relativeX; |
123 | QQmlNullableValue<qreal> _relativeY; |
124 | }; |
125 | |
126 | class Q_QUICK_EXPORT QQuickPathLine : public QQuickCurve |
127 | { |
128 | Q_OBJECT |
129 | QML_NAMED_ELEMENT(PathLine) |
130 | QML_ADDED_IN_VERSION(2, 0) |
131 | public: |
132 | QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {} |
133 | |
134 | void addToPath(QPainterPath &path, const QQuickPathData &) override; |
135 | }; |
136 | |
137 | class Q_QUICK_EXPORT QQuickPathMove : public QQuickCurve |
138 | { |
139 | Q_OBJECT |
140 | QML_NAMED_ELEMENT(PathMove) |
141 | QML_ADDED_IN_VERSION(2, 9) |
142 | public: |
143 | QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {} |
144 | |
145 | void addToPath(QPainterPath &path, const QQuickPathData &) override; |
146 | }; |
147 | |
148 | class 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) |
159 | public: |
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 | |
178 | Q_SIGNALS: |
179 | void controlXChanged(); |
180 | void controlYChanged(); |
181 | void relativeControlXChanged(); |
182 | void relativeControlYChanged(); |
183 | |
184 | private: |
185 | qreal _controlX = 0; |
186 | qreal _controlY = 0; |
187 | QQmlNullableValue<qreal> _relativeControlX; |
188 | QQmlNullableValue<qreal> _relativeControlY; |
189 | }; |
190 | |
191 | class 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) |
205 | public: |
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 | |
238 | Q_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 | |
248 | private: |
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 | |
259 | class Q_QUICK_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve |
260 | { |
261 | Q_OBJECT |
262 | QML_NAMED_ELEMENT(PathCurve) |
263 | QML_ADDED_IN_VERSION(2, 0) |
264 | public: |
265 | QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {} |
266 | |
267 | void addToPath(QPainterPath &path, const QQuickPathData &) override; |
268 | }; |
269 | |
270 | class 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 | |
281 | public: |
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 | |
305 | Q_SIGNALS: |
306 | void radiusXChanged(); |
307 | void radiusYChanged(); |
308 | void useLargeArcChanged(); |
309 | void directionChanged(); |
310 | Q_REVISION(2, 9) void xAxisRotationChanged(); |
311 | |
312 | private: |
313 | qreal _radiusX = 0; |
314 | qreal _radiusY = 0; |
315 | bool _useLargeArc = false; |
316 | ArcDirection _direction = Clockwise; |
317 | qreal _xAxisRotation = 0; |
318 | }; |
319 | |
320 | class 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 | |
334 | public: |
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 | |
361 | Q_SIGNALS: |
362 | void centerXChanged(); |
363 | void centerYChanged(); |
364 | void radiusXChanged(); |
365 | void radiusYChanged(); |
366 | void startAngleChanged(); |
367 | void sweepAngleChanged(); |
368 | void moveToStartChanged(); |
369 | |
370 | private: |
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 | |
380 | class 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) |
386 | public: |
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 | |
394 | Q_SIGNALS: |
395 | void pathChanged(); |
396 | |
397 | private: |
398 | QString _path; |
399 | }; |
400 | |
401 | class 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) |
416 | public: |
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 | |
453 | Q_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 | |
463 | private: |
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 | |
478 | class 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) |
484 | public: |
485 | QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {} |
486 | |
487 | qreal value() const; |
488 | void setValue(qreal value); |
489 | |
490 | Q_SIGNALS: |
491 | void valueChanged(); |
492 | |
493 | private: |
494 | qreal _value = 0; |
495 | }; |
496 | |
497 | class 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) |
504 | public: |
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 | |
513 | Q_SIGNALS: |
514 | void pathChanged(); |
515 | void startChanged(); |
516 | |
517 | private: |
518 | QVector<QPointF> m_path; |
519 | }; |
520 | |
521 | class 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) |
528 | public: |
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 | |
537 | Q_SIGNALS: |
538 | void pathsChanged(); |
539 | void startChanged(); |
540 | |
541 | private: |
542 | QPointF absolute(const QPointF &relative) const; |
543 | |
544 | QVector<QVector<QPointF>> m_paths; |
545 | }; |
546 | |
547 | struct 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 | |
558 | class QQuickPathPrivate; |
559 | class 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) |
573 | public: |
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 | |
607 | Q_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 | |
614 | protected: |
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 | |
628 | private Q_SLOTS: |
629 | void processPath(); |
630 | |
631 | private: |
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 | |
655 | private: |
656 | Q_DISABLE_COPY(QQuickPath) |
657 | Q_DECLARE_PRIVATE(QQuickPath) |
658 | friend class QQuickPathAnimationUpdater; |
659 | |
660 | public: |
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 | |
666 | class 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) |
677 | public: |
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 | |
743 | Q_SIGNALS: |
744 | void xChanged(); |
745 | void yChanged(); |
746 | void textChanged(); |
747 | void fontChanged(); |
748 | |
749 | private Q_SLOTS: |
750 | void invalidate() |
751 | { |
752 | _path.clear(); |
753 | } |
754 | |
755 | private: |
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 | |
766 | QT_END_NAMESPACE |
767 | |
768 | #endif // QQUICKPATH_H |
769 |
Definitions
- QQuickPathData
- QQuickPathElement
- QQuickPathElement
- QQuickPathAttribute
- QQuickPathAttribute
- QQuickCurve
- QQuickCurve
- addToPath
- QQuickPathLine
- QQuickPathLine
- QQuickPathMove
- QQuickPathMove
- QQuickPathQuad
- QQuickPathQuad
- QQuickPathCubic
- QQuickPathCubic
- QQuickPathCatmullRomCurve
- QQuickPathCatmullRomCurve
- QQuickPathArc
- QQuickPathArc
- ArcDirection
- QQuickPathAngleArc
- QQuickPathAngleArc
- QQuickPathSvg
- QQuickPathSvg
- QQuickPathRectangle
- QQuickPathRectangle
- topLeftRadius
- setTopLeftRadius
- resetTopLeftRadius
- topRightRadius
- setTopRightRadius
- resetTopRightRadius
- bottomLeftRadius
- setBottomLeftRadius
- resetBottomLeftRadius
- bottomRightRadius
- setBottomRightRadius
- resetBottomRightRadius
- ExtraData
- ExtraData
- QQuickPathPercent
- QQuickPathPercent
- QQuickPathPolyline
- QQuickPathMultiline
- QQuickCachedBezier
- QQuickCachedBezier
- QQuickPath
- AttributePoint
- AttributePoint
- AttributePoint
- operator=
- QQuickPath
- QQuickPathText
- QQuickPathText
- x
- y
- text
- font
- setX
- setY
- setText
- setFont
- width
- height
Learn Advanced QML with KDAB
Find out more