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
qquickrectangleshape.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
6
8
9/*!
10 \class QQuickRectangleShape
11 \inmodule QtQuickShapes
12 \internal
13*/
14
15Q_STATIC_LOGGING_CATEGORY(lcCalculateIndependentRadii, "qt.quick.shapes.designhelpers.rectangleshape.calculateindependentradii")
16Q_STATIC_LOGGING_CATEGORY(lcUpdatePolish, "qt.quick.shapes.designhelpers.rectangleshape.updatepolish")
17Q_STATIC_LOGGING_CATEGORY(lcMaybeUpdateElements, "qt.quick.shapes.designhelpers.rectangleshape.maybeupdateelements")
18
19void QQuickRectangleShapePrivate::setTopLeftRadius(int topLeftRadius,
20 QQml::PropertyUtils::State propertyState)
21{
22 Q_Q(QQuickRectangleShape);
23 const int oldEffectiveTopLeftRadius = q->topLeftRadius();
24 explicitTopLeftRadius = isExplicitlySet(propertyState);
25 this->topLeftRadius = topLeftRadius;
26
27 if (q->topLeftRadius() == oldEffectiveTopLeftRadius)
28 return;
29
30 q->polish();
31 emit q->topLeftRadiusChanged();
32}
33
34void QQuickRectangleShapePrivate::setTopRightRadius(int topRightRadius,
35 QQml::PropertyUtils::State propertyState)
36{
37 Q_Q(QQuickRectangleShape);
38 const int oldEffectiveTopRightRadius = q->topRightRadius();
39 explicitTopRightRadius = isExplicitlySet(propertyState);
40 this->topRightRadius = topRightRadius;
41
42 if (q->topRightRadius() == oldEffectiveTopRightRadius)
43 return;
44
45 q->polish();
46 emit q->topRightRadiusChanged();
47}
48
49void QQuickRectangleShapePrivate::setBottomLeftRadius(int bottomLeftRadius,
50 QQml::PropertyUtils::State propertyState)
51{
52 Q_Q(QQuickRectangleShape);
53 const int oldEffectiveBottomLeftRadius = q->bottomLeftRadius();
54 explicitBottomLeftRadius = isExplicitlySet(propertyState);
55 this->bottomLeftRadius = bottomLeftRadius;
56
57 if (q->bottomLeftRadius() == oldEffectiveBottomLeftRadius)
58 return;
59
60 q->polish();
61 emit q->bottomLeftRadiusChanged();
62}
63
64void QQuickRectangleShapePrivate::setBottomRightRadius(int bottomRightRadius,
65 QQml::PropertyUtils::State propertyState)
66{
67 Q_Q(QQuickRectangleShape);
68 const int oldEffectiveBottomRightRadius = q->bottomRightRadius();
69 explicitBottomRightRadius = isExplicitlySet(propertyState);
70 this->bottomRightRadius = bottomRightRadius;
71
72 if (q->bottomRightRadius() == oldEffectiveBottomRightRadius)
73 return;
74
75 q->polish();
76 emit q->bottomRightRadiusChanged();
77}
78
79void QQuickRectangleShapePrivate::setTopLeftBevel(bool topLeftBevel,
80 QQml::PropertyUtils::State propertyState)
81{
82 Q_Q(QQuickRectangleShape);
83 const bool oldTopLeftBevel = q->hasTopLeftBevel();
84 explicitTopLeftBevel = isExplicitlySet(propertyState);
85 this->topLeftBevel = topLeftBevel;
86
87 if (q->hasTopLeftBevel() == oldTopLeftBevel)
88 return;
89
90 q->polish();
91 emit q->topLeftBevelChanged();
92}
93
94void QQuickRectangleShapePrivate::setTopRightBevel(bool topRightBevel,
95 QQml::PropertyUtils::State propertyState)
96{
97 Q_Q(QQuickRectangleShape);
98 const bool oldTopRightBevel = q->hasTopRightBevel();
99 explicitTopRightBevel = isExplicitlySet(propertyState);
100 this->topRightBevel = topRightBevel;
101
102 if (q->hasTopRightBevel() == oldTopRightBevel)
103 return;
104
105 q->polish();
106 emit q->topRightBevelChanged();
107}
108
109void QQuickRectangleShapePrivate::setBottomLeftBevel(bool bottomLeftBevel,
110 QQml::PropertyUtils::State propertyState)
111{
112 Q_Q(QQuickRectangleShape);
113 const bool oldBottomLeftBevel = q->hasBottomLeftBevel();
114 explicitBottomLeftBevel = isExplicitlySet(propertyState);
115 this->bottomLeftBevel = bottomLeftBevel;
116
117 if (q->hasBottomLeftBevel() == oldBottomLeftBevel)
118 return;
119
120 q->polish();
121 emit q->bottomLeftBevelChanged();
122}
123
124void QQuickRectangleShapePrivate::setBottomRightBevel(bool bottomRightBevel,
125 QQml::PropertyUtils::State propertyState)
126{
127 Q_Q(QQuickRectangleShape);
128 const bool oldBottomRightBevel = q->hasBottomRightBevel();
129 explicitBottomRightBevel = isExplicitlySet(propertyState);
130 this->bottomRightBevel = bottomRightBevel;
131
132 if (q->hasBottomRightBevel() == oldBottomRightBevel)
133 return;
134
135 q->polish();
136 emit q->bottomRightBevelChanged();
137}
138
139template <typename T>
140T *createElement(QQuickShapePath *shapePath, const char *objectName)
141{
142 auto *element = new T(shapePath);
143 element->setObjectName(objectName);
144 return element;
145}
146
147/*!
148 \internal
149
150 Constructs and append the individual path elements to the ShapePath.
151*/
152void QQuickRectangleShapePrivate::maybeUpdateElements()
153{
154 if (!componentComplete)
155 return;
156
157 auto *shapePathPrivate = QQuickShapePathPrivate::get(shapePath);
158
159 // We need to delete the elements since we create them ourselves.
160 qCDebug(lcMaybeUpdateElements).nospace() << "maybeUpdateElements called on "
161 // Avoid printing the QQuickItem as it results in assertion failure in QQuickItemLayer::componentComplete.
162 << static_cast<void *>(q_func()) << "; deleting and clearing path elements";
163 shapePathPrivate->clearPathElements(QQuickPathPrivate::DeleteElementPolicy::Delete);
164
165 static const QQuickPathPrivate::ProcessPathPolicy DontProcessPath
166 = QQuickPathPrivate::ProcessPathPolicy::DontProcess;
167
168 // We avoid rendering issues (QDS-14861) by rotating the start position
169 // clockwise until the first visible edge after a hidden edge was found.
170 // Set the start position (startIndex) to that edge and continue the construction of
171 // the border item from there.
172 const std::array visibleEdges = {drawTop, drawRight, drawBottom, drawLeft };
173 int startIndex = 0;
174 for (int currentEdge = static_cast<int>(Edge::Top); currentEdge < static_cast<int>(Edge::NEdges); ++currentEdge) {
175 const int previousEdge = (currentEdge + 3) % 4;
176 if (!visibleEdges[previousEdge] && visibleEdges[currentEdge]) {
177 startIndex = currentEdge;
178 break;
179 }
180 }
181
182 firstVisibleEdge = static_cast<Edge>(startIndex);
183 qCDebug(lcMaybeUpdateElements) << "firstVisibleEdge:" << startIndex; // (Can't print the enum itself)
184
185 for (int i = 0; i < 4; i++) {
186 const int currentEdge = (startIndex + i) % 4;
187 const int nextEdge = (startIndex + i + 1) % 4;
188
189 switch (static_cast<Edge>(currentEdge)) {
190 case Edge::Top:
191 if (visibleEdges[currentEdge]) {
192 topPathLine = createElement<QQuickPathLine>(shapePath, "topPathLine");
193 shapePathPrivate->appendPathElement(topPathLine, DontProcessPath);
194 topPathMove = nullptr;
195 } else {
196 topPathLine = nullptr;
197 topPathMove = createElement<QQuickPathMove>(shapePath, "topPathMove");
198 shapePathPrivate->appendPathElement(topPathMove, DontProcessPath);
199 }
200
201 // Top right corner
202 if (visibleEdges[currentEdge] && visibleEdges[nextEdge]) {
203 topRightPathArc = createElement<QQuickPathArc>(shapePath, "topRightPathArc");
204 shapePathPrivate->appendPathElement(topRightPathArc, DontProcessPath);
205 } else {
206 topRightPathArc = nullptr;
207 }
208 break;
209 case Edge::Right:
210 if (visibleEdges[currentEdge]) {
211 rightPathLine = createElement<QQuickPathLine>(shapePath, "rightPathLine");
212 shapePathPrivate->appendPathElement(rightPathLine, DontProcessPath);
213 rightPathMove = nullptr;
214 } else {
215 rightPathLine = nullptr;
216 rightPathMove = createElement<QQuickPathMove>(shapePath, "rightPathMove");
217 shapePathPrivate->appendPathElement(rightPathMove, DontProcessPath);
218 }
219
220 // Bottom right corner
221 if (visibleEdges[currentEdge] && visibleEdges[nextEdge]) {
222 bottomRightPathArc = createElement<QQuickPathArc>(shapePath, "bottomRightPathArc");
223 shapePathPrivate->appendPathElement(bottomRightPathArc, DontProcessPath);
224 } else {
225 bottomRightPathArc = nullptr;
226 }
227 break;
228 case Edge::Bottom:
229 if (visibleEdges[currentEdge]) {
230 bottomPathLine = createElement<QQuickPathLine>(shapePath, "bottomPathLine");
231 shapePathPrivate->appendPathElement(bottomPathLine, DontProcessPath);
232 bottomPathMove = nullptr;
233 } else {
234 bottomPathLine = nullptr;
235 bottomPathMove = createElement<QQuickPathMove>(shapePath, "bottomPathMove");
236 shapePathPrivate->appendPathElement(bottomPathMove, DontProcessPath);
237 }
238
239 // Bottom left corner
240 if (visibleEdges[currentEdge] && visibleEdges[nextEdge]) {
241 bottomLeftPathArc = createElement<QQuickPathArc>(shapePath, "bottomLeftPathArc");
242 shapePathPrivate->appendPathElement(bottomLeftPathArc, DontProcessPath);
243 } else {
244 bottomLeftPathArc = nullptr;
245 }
246 break;
247 case Edge::Left:
248 if (visibleEdges[currentEdge]) {
249 leftPathLine = createElement<QQuickPathLine>(shapePath, "leftPathLine");
250 shapePathPrivate->appendPathElement(leftPathLine, DontProcessPath);
251 } else {
252 leftPathLine = nullptr;
253 // There isn't a leftPathMove because it will only be applicable for the case where
254 // there is only a top and bottom edge (the only configuration where a
255 // left-path-move could be needed), and if that is the case, it must start with the
256 // top edge, and must end at the left edge, so there is never need to move the path
257 // at the last (left in this case) edge.
258 }
259
260 // Top left corner
261 if (visibleEdges[currentEdge] && visibleEdges[nextEdge]) {
262 topLeftPathArc = createElement<QQuickPathArc>(shapePath, "topLeftPathArc");
263 shapePathPrivate->appendPathElement(topLeftPathArc, DontProcessPath);
264 } else {
265 topLeftPathArc = nullptr;
266 }
267 break;
268 case Edge::NEdges:
269 Q_UNREACHABLE();
270 }
271 }
272
273 qCDebug(lcMaybeUpdateElements) << "about to process path";
274 shapePath->processPath();
275 qCDebug(lcMaybeUpdateElements) << "about to call _q_shapePathChanged (i.e. polish and update implicit size)";
276 _q_shapePathChanged();
277}
278
279void QQuickRectangleShapePrivate::calculateIndependentRadii()
280{
281 Q_Q(const QQuickRectangleShape);
282 const qreal rectWidth = width.valueBypassingBindings();
283 const qreal rectHeight = height.valueBypassingBindings();
284 const int minDimension = qMin(rectWidth, rectHeight);
285 const int maxRadius = minDimension / 2;
286 const int topLeftRadius = q->topLeftRadius();
287 const int topRightRadius = q->topRightRadius();
288 const int bottomRightRadius = q->bottomRightRadius();
289 const int bottomLeftRadius = q->bottomLeftRadius();
290 const bool mixed = !(radius == topLeftRadius
291 && radius == topRightRadius
292 && radius == bottomLeftRadius
293 && radius == bottomRightRadius);
294
295 // Uniform radii
296 if (!mixed) {
297 effectiveTopLeftRadius = qMin(topLeftRadius, maxRadius);
298 effectiveTopRightRadius = qMin(topRightRadius, maxRadius);
299 effectiveBottomRightRadius = qMin(bottomRightRadius, maxRadius);
300 effectiveBottomLeftRadius = qMin(bottomLeftRadius, maxRadius);
301 qCDebug(lcCalculateIndependentRadii) << "calculateIndependentRadii: using uniform radii of" << radius
302 << "width" << rectWidth
303 << "height" << rectHeight
304 << "minDimension" << minDimension
305 << "tlr" << topLeftRadius
306 << "etlr" << effectiveTopLeftRadius
307 << "trr" << topRightRadius
308 << "etrr" << effectiveTopRightRadius
309 << "blr" << bottomLeftRadius
310 << "eblr" << effectiveBottomLeftRadius
311 << "brr" << bottomRightRadius
312 << "ebrr" << effectiveBottomRightRadius;
313 return;
314 }
315
316 // Mixed radii
317 qreal topLeftRadiusMin = qMin(minDimension, topLeftRadius);
318 qreal topRightRadiusMin = qMin(minDimension, topRightRadius);
319 qreal bottomLeftRadiusMin = qMin(minDimension, bottomLeftRadius);
320 qreal bottomRightRadiusMin = qMin(minDimension, bottomRightRadius);
321
322 // Top radii
323 const qreal topRadii = topLeftRadius + topRightRadius;
324
325 if (topRadii > rectWidth) {
326 const qreal topLeftRadiusFactor = topLeftRadius / topRadii;
327 const qreal tlr = qRound(rectWidth * topLeftRadiusFactor);
328
329 topLeftRadiusMin = qMin(topLeftRadiusMin, tlr);
330 topRightRadiusMin = qMin(topRightRadiusMin, rectWidth - tlr);
331 }
332
333 // Right radii
334 const qreal rightRadii = topRightRadius + bottomRightRadius;
335
336 if (rightRadii > rectHeight) {
337 const qreal topRightRadiusFactor = topRightRadius / rightRadii;
338 const qreal trr = qRound(rectHeight * topRightRadiusFactor);
339
340 topRightRadiusMin = qMin(topRightRadiusMin, trr);
341 bottomRightRadiusMin = qMin(bottomRightRadiusMin, rectHeight - trr);
342 }
343
344 // Bottom radii
345 const qreal bottomRadii = bottomRightRadius + bottomLeftRadius;
346
347 if (bottomRadii > rectWidth) {
348 const qreal bottomRightRadiusFactor = bottomRightRadius / bottomRadii;
349 const qreal brr = qRound(rectWidth * bottomRightRadiusFactor);
350
351 bottomRightRadiusMin = qMin(bottomRightRadiusMin, brr);
352 bottomLeftRadiusMin = qMin(bottomLeftRadiusMin, rectWidth - brr);
353 }
354
355 // Left radii
356 const qreal leftRadii = bottomLeftRadius + topLeftRadius;
357
358 if (leftRadii > rectHeight) {
359 const qreal bottomLeftRadiusFactor = bottomLeftRadius / leftRadii;
360 const qreal blr = qRound(rectHeight * bottomLeftRadiusFactor);
361
362 bottomLeftRadiusMin = qMin(bottomLeftRadiusMin, blr);
363 topLeftRadiusMin = qMin(topLeftRadiusMin, rectHeight - blr);
364 }
365
366 effectiveTopLeftRadius = topLeftRadiusMin;
367 effectiveTopRightRadius = topRightRadiusMin;
368 effectiveBottomLeftRadius = bottomLeftRadiusMin;
369 effectiveBottomRightRadius = bottomRightRadiusMin;
370
371 qCDebug(lcCalculateIndependentRadii) << "calculateIndependentRadii:"
372 << "width" << rectWidth
373 << "height" << rectHeight
374 << "borderMode" << borderMode
375 << "strokeWidth" << shapePath->strokeWidth()
376 << "minDimension" << minDimension
377 << "tlr" << topLeftRadius
378 << "etlr" << effectiveTopLeftRadius
379 << "trr" << topRightRadius
380 << "etrr" << effectiveTopRightRadius
381 << "blr" << bottomLeftRadius
382 << "eblr" << effectiveBottomLeftRadius
383 << "brr" << bottomRightRadius
384 << "ebrr" << effectiveBottomRightRadius
385 << "borderOffset" << borderOffset
386 << "startX" << shapePath->startX()
387 << "startY" << shapePath->startY();
388}
389
390/*!
391 \qmltype RectangleShape
392 \inqmlmodule QtQuick.Shapes.DesignHelpers
393 \brief A filled rectangle with an optional border.
394 \since QtQuick 6.10
395
396 RectangleShape is used to fill areas with solid color or gradients and to
397 provide a rectangular border.
398
399 Each Rectangle item is painted using either a solid fill color, specified
400 using the \l fillColor property, or a gradient, defined using one of the \l
401 ShapeGradient subtypes and set using the \l gradient property. If both a
402 color and a gradient are specified, the gradient is used.
403
404 An optional border can be added to a rectangle with its own color and
405 thickness by setting the \l strokeColor and \l strokeWidth properties.
406 Setting the color to \c transparent creates a border without a fill color.
407
408 Rounded rectangles can be drawn using the \l radius property. The radius
409 can also be specified separately for each corner. Additionally, \l bevel
410 can be applied on any corner to cut it off sharply.
411
412 RectangleShape's default value for \l {QtQuick.Shapes::Shape::preferredRendererType} is
413 \c Shape.CurveRenderer.
414
415 \section1 Example Usage
416
417 \snippet rectangleshape-bevel.qml rectangleShape
418
419 \image pathrectangle-bevel.png
420*/
421
422QQuickRectangleShape::QQuickRectangleShape(QQuickItem *parent)
423 : QQuickShape(*(new QQuickRectangleShapePrivate), parent)
424{
425 Q_D(QQuickRectangleShape);
426
427 // Create the ShapePath.
428 d->shapePath = new QQuickShapePath(this);
429 d->shapePath->setObjectName("rectangleShapeShapePath");
430 d->shapePath->setStrokeWidth(1);
431 d->shapePath->setStrokeColor(QColorConstants::Black);
432 d->shapePath->setFillColor(QColorConstants::White);
433 d->shapePath->setJoinStyle(QQuickShapePath::BevelJoin);
434 // Don't make it asynchronous, as it results in brief periods of incorrect rendering.
435
436 connect(d->shapePath, &QQuickShapePath::strokeColorChanged, this, &QQuickRectangleShape::strokeColorChanged);
437 connect(d->shapePath, &QQuickShapePath::strokeWidthChanged, this, &QQuickRectangleShape::strokeWidthChanged);
438 connect(d->shapePath, &QQuickShapePath::fillColorChanged, this, &QQuickRectangleShape::fillColorChanged);
439 connect(d->shapePath, &QQuickShapePath::joinStyleChanged, this, &QQuickRectangleShape::joinStyleChanged);
440 connect(d->shapePath, &QQuickShapePath::capStyleChanged, this, &QQuickRectangleShape::capStyleChanged);
441 connect(d->shapePath, &QQuickShapePath::strokeStyleChanged, this, &QQuickRectangleShape::strokeStyleChanged);
442 connect(d->shapePath, &QQuickShapePath::dashOffsetChanged, this, &QQuickRectangleShape::dashOffsetChanged);
443 connect(d->shapePath, &QQuickShapePath::dashPatternChanged, this, &QQuickRectangleShape::dashPatternChanged);
444 // QQuickShapePath has no change signal for fillGradient.
445
446 // Add the path as a child of us.
447 // The individual path elements will be added to the shape path in maybeUpdateElements().
448 // Do what vpe_append in qquickshape.cpp does except without the overhead of the QQmlListProperty stuff.
449 d->sp.append(d->shapePath);
450 // Similar, but for QQuickItemPrivate::data_append...
451 d->shapePath->setParent(this);
452 // ... which calls QQuickItemPrivate::resources_append.
453 d->extra.value().resourcesList.append(d->shapePath);
454
455 setWidth(200);
456 setHeight(200);
457 setPreferredRendererType(CurveRenderer);
458
459 // QQuickShape::componentComplete sets up the connections to each path.
460 // It also calls _q_shapePathChanged, which will call polish (for our updatePolish).
461}
462
463QQuickRectangleShape::~QQuickRectangleShape()
464{
465}
466
467/*!
468 \since 6.11
469 \qmlproperty bool QtQuick.Shapes.DesignHelpers::RectangleShape::drawTop
470
471 This property holds whether the top border is drawn.
472
473 The default value is \c true.
474*/
475bool QQuickRectangleShape::drawTop() const
476{
477 Q_D(const QQuickRectangleShape);
478 return d->drawTop;
479}
480
481void QQuickRectangleShape::setDrawTop(bool drawTop)
482{
483 Q_D(QQuickRectangleShape);
484 if (drawTop == d->drawTop)
485 return;
486
487 d->drawTop = drawTop;
488 d->maybeUpdateElements();
489 emit drawTopChanged();
490}
491
492void QQuickRectangleShape::resetDrawTop()
493{
494 setDrawTop(QQuickRectangleShapePrivate::defaultDrawEdge);
495}
496
497/*!
498 \since 6.11
499 \qmlproperty bool QtQuick.Shapes.DesignHelpers::RectangleShape::drawRight
500
501 This property holds whether the right border is drawn.
502
503 The default value is \c true.
504*/
505bool QQuickRectangleShape::drawRight() const
506{
507 Q_D(const QQuickRectangleShape);
508 return d->drawRight;
509}
510
511void QQuickRectangleShape::setDrawRight(bool drawRight)
512{
513 Q_D(QQuickRectangleShape);
514 if (drawRight == d->drawRight)
515 return;
516
517 d->drawRight = drawRight;
518 d->maybeUpdateElements();
519 emit drawRightChanged();
520}
521
522void QQuickRectangleShape::resetDrawRight()
523{
524 setDrawRight(QQuickRectangleShapePrivate::defaultDrawEdge);
525}
526
527/*!
528 \since 6.11
529 \qmlproperty bool QtQuick.Shapes.DesignHelpers::RectangleShape::drawBottom
530
531 This property holds whether the bottom border is drawn.
532
533 The default value is \c true.
534*/
535bool QQuickRectangleShape::drawBottom() const
536{
537 Q_D(const QQuickRectangleShape);
538 return d->drawBottom;
539}
540
541void QQuickRectangleShape::setDrawBottom(bool drawBottom)
542{
543 Q_D(QQuickRectangleShape);
544 if (drawBottom == d->drawBottom)
545 return;
546
547 d->drawBottom = drawBottom;
548 d->maybeUpdateElements();
549 emit drawBottomChanged();
550}
551
552void QQuickRectangleShape::resetDrawBottom()
553{
554 setDrawBottom(QQuickRectangleShapePrivate::defaultDrawEdge);
555}
556
557/*!
558 \since 6.11
559 \qmlproperty bool QtQuick.Shapes.DesignHelpers::RectangleShape::drawLeft
560
561 This property holds whether the left border is drawn.
562
563 The default value is \c true.
564*/
565bool QQuickRectangleShape::drawLeft() const
566{
567 Q_D(const QQuickRectangleShape);
568 return d->drawLeft;
569}
570
571void QQuickRectangleShape::setDrawLeft(bool drawLeft)
572{
573 Q_D(QQuickRectangleShape);
574 if (drawLeft == d->drawLeft)
575 return;
576
577 d->drawLeft = drawLeft;
578 d->maybeUpdateElements();
579 emit drawLeftChanged();
580}
581
582void QQuickRectangleShape::resetDrawLeft()
583{
584 setDrawLeft(QQuickRectangleShapePrivate::defaultDrawEdge);
585}
586
587/*!
588 \include pathrectangle.qdocinc {radius-property}
589 {QtQuick.Shapes.DesignHelpers::RectangleShape}
590
591 The default value is \c 10.
592*/
593
594int QQuickRectangleShape::radius() const
595{
596 Q_D(const QQuickRectangleShape);
597 return d->radius;
598}
599
600void QQuickRectangleShape::setRadius(int radius)
601{
602 Q_D(QQuickRectangleShape);
603 if (radius == d->radius)
604 return;
605
606 const int oldTopLeftRadius = topLeftRadius();
607 const int oldTopRightRadius = topRightRadius();
608 const int oldBottomRightRadius = bottomRightRadius();
609 const int oldBottomLeftRadius = bottomLeftRadius();
610
611 d->radius = radius;
612 polish();
613 emit radiusChanged();
614 if (topLeftRadius() != oldTopLeftRadius)
615 emit topLeftRadiusChanged();
616 if (topRightRadius() != oldTopRightRadius)
617 emit topRightRadiusChanged();
618 if (bottomRightRadius() != oldBottomRightRadius)
619 emit bottomRightRadiusChanged();
620 if (bottomLeftRadius() != oldBottomLeftRadius)
621 emit bottomLeftRadiusChanged();
622}
623
624void QQuickRectangleShape::resetRadius()
625{
626 setRadius(QQuickRectangleShapePrivate::defaultRadius);
627}
628
629/*!
630 \include pathrectangle.qdocinc {radius-properties}
631 {QtQuick.Shapes.DesignHelpers::RectangleShape} {rectangleshape.qml} {rectangleShape}
632*/
633
634int QQuickRectangleShape::topLeftRadius() const
635{
636 Q_D(const QQuickRectangleShape);
637 return d->explicitTopLeftRadius ? d->topLeftRadius : d->radius;
638}
639
640void QQuickRectangleShape::setTopLeftRadius(int topLeftRadius)
641{
642 Q_D(QQuickRectangleShape);
643 d->setTopLeftRadius(topLeftRadius, QQml::PropertyUtils::State::ExplicitlySet);
644}
645
646void QQuickRectangleShape::resetTopLeftRadius()
647{
648 Q_D(QQuickRectangleShape);
649 d->setTopLeftRadius(QQuickRectangleShapePrivate::defaultRadius,
650 QQml::PropertyUtils::State::ImplicitlySet);
651}
652
653int QQuickRectangleShape::topRightRadius() const
654{
655 Q_D(const QQuickRectangleShape);
656 return d->explicitTopRightRadius ? d->topRightRadius : d->radius;
657}
658
659void QQuickRectangleShape::setTopRightRadius(int topRightRadius)
660{
661 Q_D(QQuickRectangleShape);
662 d->setTopRightRadius(topRightRadius, QQml::PropertyUtils::State::ExplicitlySet);
663}
664
665void QQuickRectangleShape::resetTopRightRadius()
666{
667 Q_D(QQuickRectangleShape);
668 d->setTopRightRadius(QQuickRectangleShapePrivate::defaultRadius,
669 QQml::PropertyUtils::State::ImplicitlySet);
670}
671
672int QQuickRectangleShape::bottomLeftRadius() const
673{
674 Q_D(const QQuickRectangleShape);
675 return d->explicitBottomLeftRadius ? d->bottomLeftRadius : d->radius;
676}
677
678void QQuickRectangleShape::setBottomLeftRadius(int bottomLeftRadius)
679{
680 Q_D(QQuickRectangleShape);
681 d->setBottomLeftRadius(bottomLeftRadius, QQml::PropertyUtils::State::ExplicitlySet);
682}
683
684void QQuickRectangleShape::resetBottomLeftRadius()
685{
686 Q_D(QQuickRectangleShape);
687 d->setBottomLeftRadius(QQuickRectangleShapePrivate::defaultRadius,
688 QQml::PropertyUtils::State::ImplicitlySet);
689}
690
691int QQuickRectangleShape::bottomRightRadius() const
692{
693 Q_D(const QQuickRectangleShape);
694 return d->explicitBottomRightRadius ? d->bottomRightRadius : d->radius;
695}
696
697void QQuickRectangleShape::setBottomRightRadius(int bottomRightRadius)
698{
699 Q_D(QQuickRectangleShape);
700 d->setBottomRightRadius(bottomRightRadius, QQml::PropertyUtils::State::ExplicitlySet);
701}
702
703void QQuickRectangleShape::resetBottomRightRadius()
704{
705 Q_D(QQuickRectangleShape);
706 d->setBottomRightRadius(QQuickRectangleShapePrivate::defaultRadius,
707 QQml::PropertyUtils::State::ImplicitlySet);
708}
709
710/*!
711 \include pathrectangle.qdocinc {bevel-property}
712 {QtQuick.Shapes.DesignHelpers::RectangleShape}
713 {rectangleshape-bevel.qml}{rectangleShape}
714*/
715
716bool QQuickRectangleShape::hasBevel() const
717{
718 Q_D(const QQuickRectangleShape);
719 return d->bevel;
720}
721
722void QQuickRectangleShape::setBevel(bool bevel)
723{
724 Q_D(QQuickRectangleShape);
725 if (bevel == d->bevel)
726 return;
727
728 const bool oldTopLeftBevel = hasTopLeftBevel();
729 const bool oldTopRightBevel = hasTopRightBevel();
730 const bool oldBottomRightBevel = hasBottomRightBevel();
731 const bool oldBottomLeftBevel = hasBottomLeftBevel();
732
733 d->bevel = bevel;
734 polish();
735 emit bevelChanged();
736 if (hasTopLeftBevel() != oldTopLeftBevel)
737 emit topLeftBevelChanged();
738 if (hasTopRightBevel() != oldTopRightBevel)
739 emit topRightBevelChanged();
740 if (hasBottomRightBevel() != oldBottomRightBevel)
741 emit bottomRightBevelChanged();
742 if (hasBottomLeftBevel() != oldBottomLeftBevel)
743 emit bottomLeftBevelChanged();
744}
745
746void QQuickRectangleShape::resetBevel()
747{
748 setBevel(false);
749}
750
751/*!
752 \include pathrectangle.qdocinc {bevel-properties}
753 {QtQuick.Shapes.DesignHelpers::RectangleShape}
754 {rectangleshape.qml} {rectangleShape}
755*/
756
757bool QQuickRectangleShape::hasTopLeftBevel() const
758{
759 Q_D(const QQuickRectangleShape);
760 return d->explicitTopLeftBevel ? d->topLeftBevel : d->bevel;
761}
762
763void QQuickRectangleShape::setTopLeftBevel(bool topLeftBevel)
764{
765 Q_D(QQuickRectangleShape);
766 d->setTopLeftBevel(topLeftBevel, QQml::PropertyUtils::State::ExplicitlySet);
767}
768
769void QQuickRectangleShape::resetTopLeftBevel()
770{
771 Q_D(QQuickRectangleShape);
772 d->setTopLeftBevel(QQuickRectangleShapePrivate::defaultBevel,
773 QQml::PropertyUtils::State::ImplicitlySet);
774}
775
776bool QQuickRectangleShape::hasTopRightBevel() const
777{
778 Q_D(const QQuickRectangleShape);
779 return d->explicitTopRightBevel ? d->topRightBevel : d->bevel;
780}
781
782void QQuickRectangleShape::setTopRightBevel(bool topRightBevel)
783{
784 Q_D(QQuickRectangleShape);
785 d->setTopRightBevel(topRightBevel, QQml::PropertyUtils::State::ExplicitlySet);
786}
787
788void QQuickRectangleShape::resetTopRightBevel()
789{
790 Q_D(QQuickRectangleShape);
791 d->setTopRightBevel(QQuickRectangleShapePrivate::defaultBevel,
792 QQml::PropertyUtils::State::ImplicitlySet);
793}
794
795bool QQuickRectangleShape::hasBottomLeftBevel() const
796{
797 Q_D(const QQuickRectangleShape);
798 return d->explicitBottomLeftBevel ? d->bottomLeftBevel : d->bevel;
799}
800
801void QQuickRectangleShape::setBottomLeftBevel(bool bottomLeftBevel)
802{
803 Q_D(QQuickRectangleShape);
804 d->setBottomLeftBevel(bottomLeftBevel, QQml::PropertyUtils::State::ExplicitlySet);
805}
806
807void QQuickRectangleShape::resetBottomLeftBevel()
808{
809 Q_D(QQuickRectangleShape);
810 d->setBottomLeftBevel(QQuickRectangleShapePrivate::defaultBevel,
811 QQml::PropertyUtils::State::ImplicitlySet);
812}
813
814bool QQuickRectangleShape::hasBottomRightBevel() const
815{
816 Q_D(const QQuickRectangleShape);
817 return d->explicitBottomRightBevel ? d->bottomRightBevel : d->bevel;
818}
819
820void QQuickRectangleShape::setBottomRightBevel(bool bottomRightBevel)
821{
822 Q_D(QQuickRectangleShape);
823 d->setBottomRightBevel(bottomRightBevel, QQml::PropertyUtils::State::ExplicitlySet);
824}
825
826void QQuickRectangleShape::resetBottomRightBevel()
827{
828 Q_D(QQuickRectangleShape);
829 d->setBottomRightBevel(QQuickRectangleShapePrivate::defaultBevel,
830 QQml::PropertyUtils::State::ImplicitlySet);
831}
832
833/*!
834 \qmlproperty color QtQuick.Shapes.DesignHelpers::RectangleShape::strokeColor
835
836 This property holds the stroking color.
837
838 When set to \c transparent, no stroking occurs.
839
840 The default value is \c "black".
841*/
842
843QColor QQuickRectangleShape::strokeColor() const
844{
845 Q_D(const QQuickRectangleShape);
846 return d->shapePath->strokeColor();
847}
848
849void QQuickRectangleShape::setStrokeColor(const QColor &color)
850{
851 Q_D(QQuickRectangleShape);
852 d->shapePath->setStrokeColor(color);
853}
854
855/*!
856 \qmlproperty real QtQuick.Shapes.DesignHelpers::RectangleShape::strokeWidth
857
858 This property holds the stroke width.
859
860 When set to a negative value, no stroking occurs.
861
862 The default value is \c 1.
863*/
864
865qreal QQuickRectangleShape::strokeWidth() const
866{
867 Q_D(const QQuickRectangleShape);
868 return d->shapePath->strokeWidth();
869}
870
871void QQuickRectangleShape::setStrokeWidth(qreal width)
872{
873 Q_D(QQuickRectangleShape);
874 d->shapePath->setStrokeWidth(width);
875}
876
877/*!
878 \qmlproperty color QtQuick.Shapes.DesignHelpers::RectangleShape::fillColor
879
880 This property holds the fill color.
881
882 When set to \c transparent, no filling occurs.
883
884 The default value is \c "white".
885
886 \note If either \l fillGradient is set to something other than \c null, it
887 will be used instead of \c fillColor.
888*/
889
890QColor QQuickRectangleShape::fillColor() const
891{
892 Q_D(const QQuickRectangleShape);
893 return d->shapePath->fillColor();
894}
895
896void QQuickRectangleShape::setFillColor(const QColor &color)
897{
898 Q_D(QQuickRectangleShape);
899 d->shapePath->setFillColor(color);
900}
901
902/*!
903 \include shapepath.qdocinc {fillRule-property} {QtQuick.Shapes.DesignHelpers::RectangleShape}
904*/
905
906QQuickShapePath::FillRule QQuickRectangleShape::fillRule() const
907{
908 Q_D(const QQuickRectangleShape);
909 return d->shapePath->fillRule();
910}
911
912void QQuickRectangleShape::setFillRule(QQuickShapePath::FillRule fillRule)
913{
914 Q_D(QQuickRectangleShape);
915 d->shapePath->setFillRule(fillRule);
916}
917
918/*!
919 \include shapepath.qdocinc {joinStyle-property} {QtQuick.Shapes.DesignHelpers::RectangleShape}
920*/
921
922QQuickShapePath::JoinStyle QQuickRectangleShape::joinStyle() const
923{
924 Q_D(const QQuickRectangleShape);
925 return d->shapePath->joinStyle();
926}
927
928void QQuickRectangleShape::setJoinStyle(QQuickShapePath::JoinStyle style)
929{
930 Q_D(QQuickRectangleShape);
931 d->shapePath->setJoinStyle(style);
932}
933
934int QQuickRectangleShape::miterLimit() const
935{
936 Q_D(const QQuickRectangleShape);
937 return d->shapePath->miterLimit();
938}
939
940void QQuickRectangleShape::setMiterLimit(int limit)
941{
942 Q_D(QQuickRectangleShape);
943 d->shapePath->setMiterLimit(limit);
944}
945
946/*!
947 \include shapepath.qdocinc {capStyle-property} {QtQuick.Shapes.DesignHelpers::RectangleShape}
948*/
949
950QQuickShapePath::CapStyle QQuickRectangleShape::capStyle() const
951{
952 Q_D(const QQuickRectangleShape);
953 return d->shapePath->capStyle();
954}
955
956void QQuickRectangleShape::setCapStyle(QQuickShapePath::CapStyle style)
957{
958 Q_D(QQuickRectangleShape);
959 d->shapePath->setCapStyle(style);
960}
961
962/*!
963 \include shapepath.qdocinc {strokeStyle-property} {QtQuick.Shapes.DesignHelpers::RectangleShape}
964*/
965
966QQuickShapePath::StrokeStyle QQuickRectangleShape::strokeStyle() const
967{
968 Q_D(const QQuickRectangleShape);
969 return d->shapePath->strokeStyle();
970}
971
972void QQuickRectangleShape::setStrokeStyle(QQuickShapePath::StrokeStyle style)
973{
974 Q_D(QQuickRectangleShape);
975 d->shapePath->setStrokeStyle(style);
976}
977
978/*!
979 \include shapepath.qdocinc {dashOffset-property} {QtQuick.Shapes.DesignHelpers::RectangleShape}
980*/
981
982qreal QQuickRectangleShape::dashOffset() const
983{
984 Q_D(const QQuickRectangleShape);
985 return d->shapePath->dashOffset();
986}
987
988void QQuickRectangleShape::setDashOffset(qreal offset)
989{
990 Q_D(QQuickRectangleShape);
991 d->shapePath->setDashOffset(offset);
992}
993
994/*!
995 \include shapepath.qdocinc {dashPattern-property} {QtQuick.Shapes.DesignHelpers::RectangleShape}
996*/
997
998QList<qreal> QQuickRectangleShape::dashPattern() const
999{
1000 Q_D(const QQuickRectangleShape);
1001 return d->shapePath->dashPattern();
1002}
1003
1004void QQuickRectangleShape::setDashPattern(const QList<qreal> &array)
1005{
1006 Q_D(QQuickRectangleShape);
1007 d->shapePath->setDashPattern(array);
1008}
1009
1010/*!
1011 \qmlproperty ShapeGradient QtQuick.Shapes.DesignHelpers::RectangleShape::fillGradient
1012
1013 The fillGradient of the rectangle fill color.
1014
1015 By default, no fillGradient is enabled and the value is null. In this case, the
1016 fill uses a solid color based on the value of \l fillColor.
1017
1018 When set, \l fillColor is ignored and filling is done using one of the
1019 \l ShapeGradient subtypes.
1020
1021 \note The \l Gradient type cannot be used here. Rather, prefer using one of
1022 the advanced subtypes, like \l LinearGradient.
1023*/
1024QQuickShapeGradient *QQuickRectangleShape::fillGradient() const
1025{
1026 Q_D(const QQuickRectangleShape);
1027 return d->shapePath->fillGradient();
1028}
1029
1030void QQuickRectangleShape::setFillGradient(QQuickShapeGradient *fillGradient)
1031{
1032 Q_D(QQuickRectangleShape);
1033 d->shapePath->setFillGradient(fillGradient);
1034}
1035
1036void QQuickRectangleShape::resetFillGradient()
1037{
1038 setFillGradient(nullptr);
1039}
1040
1041/*!
1042 \qmlproperty enumeration QtQuick.Shapes.DesignHelpers::RectangleShape::borderMode
1043
1044 The \l borderMode property determines where the border is drawn along the
1045 edge of the rectangle.
1046
1047 \value RectangleShape.Inside
1048 The border is drawn along the inside edge of the item and does not
1049 affect the item width.
1050
1051 This is the default value.
1052 \value RectangleShape.Middle
1053 The border is drawn over the edge of the item and does not
1054 affect the item width.
1055 \value RectangleShape.Outside
1056 The border is drawn along the outside edge of the item and increases
1057 the item width by the value of \l strokeWidth.
1058
1059 \sa strokeWidth
1060*/
1061QQuickRectangleShape::BorderMode QQuickRectangleShape::borderMode() const
1062{
1063 Q_D(const QQuickRectangleShape);
1064 return d->borderMode;
1065}
1066
1067void QQuickRectangleShape::setBorderMode(BorderMode borderMode)
1068{
1069 Q_D(QQuickRectangleShape);
1070 if (borderMode == d->borderMode)
1071 return;
1072
1073 d->borderMode = borderMode;
1074 polish();
1075 emit borderModeChanged();
1076}
1077
1078void QQuickRectangleShape::resetBorderMode()
1079{
1080 setBorderMode(BorderMode::Inside);
1081}
1082
1083void QQuickRectangleShape::componentComplete()
1084{
1085 Q_D(QQuickRectangleShape);
1086 d->componentComplete = true;
1087 // Do this before componentComplete(), because we need the elements to be
1088 // present in order for the connections to them to be made.
1089 d->maybeUpdateElements();
1090 QQuickShape::componentComplete();
1091}
1092
1093void QQuickRectangleShape::itemChange(ItemChange change, const ItemChangeData &value)
1094{
1095 Q_D(QQuickRectangleShape);
1096 d->maybeUpdateElements();
1097
1098 QQuickItem::itemChange(change, value);
1099}
1100
1101void QQuickRectangleShape::updatePolish()
1102{
1103 Q_D(QQuickRectangleShape);
1104 const qreal rectWidth = d->width.valueBypassingBindings();
1105 const qreal rectHeight = d->height.valueBypassingBindings();
1106
1107 d->calculateIndependentRadii();
1108
1109 switch (d->borderMode) {
1110 case QQuickRectangleShape::BorderMode::Inside:
1111 d->borderOffset = d->shapePath->strokeWidth() * 0.5;
1112 break;
1113 case QQuickRectangleShape::BorderMode::Middle:
1114 d->borderOffset = 0;
1115 break;
1116 case QQuickRectangleShape::BorderMode::Outside:
1117 d->borderOffset = -d->shapePath->strokeWidth() * 0.5;
1118 break;
1119 }
1120
1121 switch (d->borderMode) {
1122 case QQuickRectangleShape::BorderMode::Outside:
1123 d->borderRadiusAdjustment = d->shapePath->strokeWidth() * 0.5;
1124 break;
1125 case QQuickRectangleShape::BorderMode::Middle:
1126 d->borderRadiusAdjustment = d->shapePath->strokeWidth();
1127 break;
1128 default:
1129 d->borderRadiusAdjustment = 0;
1130 break;
1131 }
1132
1133 switch (d->firstVisibleEdge) {
1134 case QQuickRectangleShapePrivate::Edge::Top:
1135 d->shapePath->setStartX(d->effectiveTopLeftRadius + d->borderOffset + d->borderRadiusAdjustment);
1136 d->shapePath->setStartY(d->borderOffset);
1137 break;
1138 case QQuickRectangleShapePrivate::Edge::Right:
1139 d->shapePath->setStartX(rectWidth - d->borderOffset);
1140 d->shapePath->setStartY(d->effectiveTopRightRadius + d->borderOffset + d->borderRadiusAdjustment);
1141 break;
1142 case QQuickRectangleShapePrivate::Edge::Bottom:
1143 d->shapePath->setStartX(rectWidth - d->effectiveBottomRightRadius - d->borderOffset - d->borderRadiusAdjustment);
1144 d->shapePath->setStartY(rectHeight - d->borderOffset);
1145 break;
1146 case QQuickRectangleShapePrivate::Edge::Left:
1147 d->shapePath->setStartX(d->borderOffset);
1148 d->shapePath->setStartY(rectHeight - d->effectiveBottomLeftRadius - d->borderOffset - d->borderRadiusAdjustment);
1149 break;
1150 default:
1151 Q_UNREACHABLE();
1152 }
1153
1154 if (d->topPathLine) {
1155 d->topPathLine->setX(rectWidth - d->effectiveTopRightRadius - d->borderOffset - d->borderRadiusAdjustment);
1156 d->topPathLine->setY(d->borderOffset);
1157 } else {
1158 d->topPathMove->setX(rectWidth - d->borderOffset);
1159 d->topPathMove->setY(d->effectiveTopRightRadius + d->borderOffset + d->borderRadiusAdjustment);
1160 }
1161
1162 if (d->topRightPathArc) {
1163 d->topRightPathArc->setX(rectWidth - d->borderOffset);
1164 d->topRightPathArc->setY(d->effectiveTopRightRadius + d->borderOffset + d->borderRadiusAdjustment);
1165 const bool topRightBevel = hasTopRightBevel();
1166 d->topRightPathArc->setRadiusX(topRightBevel ? 50000 : d->effectiveTopRightRadius + d->borderRadiusAdjustment);
1167 d->topRightPathArc->setRadiusY(topRightBevel ? 50000 : d->effectiveTopRightRadius + d->borderRadiusAdjustment);
1168 }
1169
1170 if (d->rightPathLine) {
1171 d->rightPathLine->setX(rectWidth - d->borderOffset);
1172 d->rightPathLine->setY(rectHeight - d->effectiveBottomRightRadius - d->borderOffset - d->borderRadiusAdjustment);
1173 } else {
1174 d->rightPathMove->setX(rectWidth - d->effectiveBottomRightRadius - d->borderOffset - d->borderRadiusAdjustment);
1175 d->rightPathMove->setY(rectHeight - d->borderOffset);
1176 }
1177
1178 if (d->bottomRightPathArc) {
1179 d->bottomRightPathArc->setX(rectWidth - d->effectiveBottomRightRadius - d->borderOffset - d->borderRadiusAdjustment);
1180 d->bottomRightPathArc->setY(rectHeight - d->borderOffset);
1181 const bool bottomRightBevel = hasBottomRightBevel();
1182 d->bottomRightPathArc->setRadiusX(bottomRightBevel ? 50000 : d->effectiveBottomRightRadius + d->borderRadiusAdjustment);
1183 d->bottomRightPathArc->setRadiusY(bottomRightBevel ? 50000 : d->effectiveBottomRightRadius + d->borderRadiusAdjustment);
1184 }
1185
1186 if (d->bottomPathLine) {
1187 d->bottomPathLine->setX(d->effectiveBottomLeftRadius + d->borderOffset + d->borderRadiusAdjustment);
1188 d->bottomPathLine->setY(rectHeight - d->borderOffset);
1189 } else {
1190 d->bottomPathMove->setX(d->borderOffset);
1191 d->bottomPathMove->setY(rectHeight - d->effectiveBottomLeftRadius - d->borderOffset - d->borderRadiusAdjustment);
1192 }
1193
1194 if (d->bottomLeftPathArc) {
1195 d->bottomLeftPathArc->setX(d->borderOffset);
1196 d->bottomLeftPathArc->setY(rectHeight - d->effectiveBottomLeftRadius - d->borderOffset - d->borderRadiusAdjustment);
1197 const bool bottomLeftBevel = hasBottomLeftBevel();
1198 d->bottomLeftPathArc->setRadiusX(bottomLeftBevel ? 50000 : d->effectiveBottomLeftRadius + d->borderRadiusAdjustment);
1199 d->bottomLeftPathArc->setRadiusY(bottomLeftBevel ? 50000 : d->effectiveBottomLeftRadius + d->borderRadiusAdjustment);
1200 }
1201
1202 if (d->leftPathLine) {
1203 d->leftPathLine->setX(d->borderOffset);
1204 d->leftPathLine->setY(d->effectiveTopLeftRadius + d->borderOffset + d->borderRadiusAdjustment);
1205 }
1206
1207 if (d->topLeftPathArc) {
1208 d->topLeftPathArc->setX(d->effectiveTopLeftRadius + d->borderOffset + d->borderRadiusAdjustment);
1209 d->topLeftPathArc->setY(d->borderOffset);
1210 const bool topLeftBevel = hasTopLeftBevel();
1211 d->topLeftPathArc->setRadiusX(topLeftBevel ? 50000 : d->effectiveTopLeftRadius + d->borderRadiusAdjustment);
1212 d->topLeftPathArc->setRadiusY(topLeftBevel ? 50000 : d->effectiveTopLeftRadius + d->borderRadiusAdjustment);
1213 }
1214
1215 // This does stuff with each path, so we want to call it after we've made our own changes.
1216 QQuickShape::updatePolish();
1217
1218 qCDebug(lcUpdatePolish) << "updatePolish:"
1219 << "width" << rectWidth
1220 << "height" << rectHeight
1221 << "borderMode" << d->borderMode
1222 << "strokeWidth" << d->shapePath->strokeWidth()
1223 << "etlr" << d->effectiveTopLeftRadius
1224 << "etrr" << d->effectiveTopRightRadius
1225 << "eblr" << d->effectiveBottomLeftRadius
1226 << "ebrr" << d->effectiveBottomRightRadius
1227 << "borderOffset" << d->borderOffset
1228 << "startX" << d->shapePath->startX()
1229 << "startY" << d->shapePath->startY();
1230}
1231
1232QT_END_NAMESPACE
1233
1234#include "moc_qquickrectangleshape_p.cpp"
Combined button and popup list for selecting options.
T * createElement(QQuickShapePath *shapePath, const char *objectName)