418void QQuickRectangle::setGradient(
const QJSValue &gradient)
420 Q_D(QQuickRectangle);
421 if (d->gradient.equals(gradient))
424 static int updatedSignalIdx = QMetaMethod::fromSignal(&QQuickGradient::updated).methodIndex();
425 if (d->doUpdateSlotIdx < 0)
426 d->doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot(
"doUpdate()");
428 if (
auto oldGradient = qobject_cast<QQuickGradient*>(d->gradient.toQObject()))
429 QMetaObject::disconnect(oldGradient, updatedSignalIdx,
this, d->doUpdateSlotIdx);
431 if (gradient.isQObject()) {
432 if (
auto newGradient = qobject_cast<QQuickGradient*>(gradient.toQObject())) {
433 d->gradient = gradient;
434 QMetaObject::connect(newGradient, updatedSignalIdx,
this, d->doUpdateSlotIdx);
436 qmlWarning(
this) <<
"Can't assign "
437 << QQmlMetaType::prettyTypeName(gradient.toQObject()) <<
" to gradient property";
438 d->gradient = QJSValue();
440 }
else if (gradient.isNumber() || gradient.isString()) {
441 static const QMetaEnum gradientPresetMetaEnum = QMetaEnum::fromType<QGradient::Preset>();
442 Q_ASSERT(gradientPresetMetaEnum.isValid());
450 if (gradient.isNumber()) {
451 const auto preset = QGradient::Preset(gradient.toInt());
452 if (preset != QGradient::NumPresets && gradientPresetMetaEnum.valueToKey(preset))
453 result = QGradient(preset);
454 }
else if (gradient.isString()) {
455 const auto presetName = gradient.toString();
456 if (presetName != QLatin1String(
"NumPresets")) {
458 const auto presetInt = gradientPresetMetaEnum.keyToValue(qPrintable(presetName), &ok);
460 result = QGradient(QGradient::Preset(presetInt));
464 if (result.type() != QGradient::NoGradient) {
465 d->gradient = gradient;
467 qmlWarning(
this) <<
"No such gradient preset '" << gradient.toString() <<
"'";
468 d->gradient = QJSValue();
470 }
else if (gradient.isNull() || gradient.isUndefined()) {
471 d->gradient = gradient;
473 qmlWarning(
this) <<
"Unknown gradient type. Expected int, string, or Gradient";
474 d->gradient = QJSValue();
502void QQuickRectangle::setRadius(qreal radius)
504 Q_D(QQuickRectangle);
505 if (d->radius == radius)
509 d->maybeSetImplicitAntialiasing();
512 emit radiusChanged();
514 if (d->extraRectangle.isAllocated()) {
515 if (!d->extraRectangle->isTopLeftRadiusSet)
516 emit topLeftRadiusChanged();
517 if (!d->extraRectangle->isTopRightRadiusSet)
518 emit topRightRadiusChanged();
519 if (!d->extraRectangle->isBottomLeftRadiusSet)
520 emit bottomLeftRadiusChanged();
521 if (!d->extraRectangle->isBottomRightRadiusSet)
522 emit bottomRightRadiusChanged();
524 emit topLeftRadiusChanged();
525 emit topRightRadiusChanged();
526 emit bottomLeftRadiusChanged();
527 emit bottomRightRadiusChanged();
774QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
777 Q_D(QQuickRectangle);
779 if (width() <= 0 || height() <= 0
780 || (d->gradient.isUndefined() && d->color.alpha() == 0 && (!d->pen || d->pen->width() == 0 || d->pen->color().alpha() == 0))) {
785 QSGInternalRectangleNode *rectangle =
static_cast<QSGInternalRectangleNode *>(oldNode);
786 if (!rectangle) rectangle = d->sceneGraphContext()->createInternalRectangleNode();
788 rectangle->setRect(QRectF(0, 0, width(), height()));
789 rectangle->setColor(d->color);
791 if (d->pen && d->pen->isValid()) {
792 rectangle->setPenColor(d->pen->color());
793 qreal penWidth = d->pen->width();
794 if (d->pen->pixelAligned()) {
795 qreal dpr = d->effectiveDevicePixelRatio();
796 penWidth = qRound(penWidth * dpr) / dpr;
798 rectangle->setPenWidth(penWidth);
799 rectangle->setAligned(
false);
801 rectangle->setPenWidth(0);
804 rectangle->setRadius(d->radius);
805 if (d->extraRectangle.isAllocated()) {
806 const auto &extra = d->extraRectangle.value();
807 if (extra.isTopLeftRadiusSet)
808 rectangle->setTopLeftRadius(extra.topLeftRadius);
810 rectangle->resetTopLeftRadius();
811 if (extra.isTopRightRadiusSet)
812 rectangle->setTopRightRadius(extra.topRightRadius);
814 rectangle->resetTopRightRadius();
815 if (extra.isBottomLeftRadiusSet)
816 rectangle->setBottomLeftRadius(extra.bottomLeftRadius);
818 rectangle->resetBottomLeftRadius();
819 if (extra.isBottomRightRadiusSet)
820 rectangle->setBottomRightRadius(extra.bottomRightRadius);
822 rectangle->resetBottomRightRadius();
824 rectangle->resetTopLeftRadius();
825 rectangle->resetTopRightRadius();
826 rectangle->resetBottomLeftRadius();
827 rectangle->resetBottomRightRadius();
829 rectangle->setAntialiasing(antialiasing());
831 QGradientStops stops;
832 bool vertical =
true;
833 if (d->gradient.isQObject()) {
834 auto gradient = qobject_cast<QQuickGradient*>(d->gradient.toQObject());
836 stops = gradient->gradientStops();
837 vertical = gradient->orientation() == QQuickGradient::Vertical;
838 }
else if (d->gradient.isNumber() || d->gradient.isString()) {
839 QGradient preset(d->gradient.toVariant().value<QGradient::Preset>());
840 if (preset.type() == QGradient::LinearGradient) {
841 auto linearGradient =
static_cast<QLinearGradient&>(preset);
842 const QPointF start = linearGradient.start();
843 const QPointF end = linearGradient.finalStop();
844 vertical = qAbs(start.y() - end.y()) >= qAbs(start.x() - end.x());
845 stops = linearGradient.stops();
846 if ((vertical && start.y() > end.y()) || (!vertical && start.x() > end.x())) {
849 QGradientStops reverseStops;
850 for (
auto it = stops.rbegin(); it != stops.rend(); ++it) {
852 stop.first = 1 - stop.first;
853 reverseStops.append(stop);
855 stops = reverseStops;
859 rectangle->setGradientStops(stops);
860 rectangle->setGradientVertical(vertical);