diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2018-06-27 16:16:19 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-10 04:33:05 +0000 |
commit | 1771d298f33543a3fe47decfe0fff10609b01ab1 (patch) | |
tree | 2f19e74f00c458a7a31afa6fe9ce21abba20f61a /src | |
parent | ffbf089addcaab3e132f5dbb0685c1a46bd6d1ab (diff) |
Teach Rectangle's gradient property to accept QGradient::Preset
Change-Id: Id640b596c1d8d52221f2f2be8807d6e245971bdc
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/doc/snippets/qml/rectangle/rectangle-gradient.qml | 12 | ||||
-rw-r--r-- | src/quick/items/qquickrectangle.cpp | 87 | ||||
-rw-r--r-- | src/quick/items/qquickrectangle_p.h | 7 | ||||
-rw-r--r-- | src/quick/items/qquickrectangle_p_p.h | 2 |
4 files changed, 88 insertions, 20 deletions
diff --git a/src/quick/doc/snippets/qml/rectangle/rectangle-gradient.qml b/src/quick/doc/snippets/qml/rectangle/rectangle-gradient.qml index 031bee960d..e52a0ce0ef 100644 --- a/src/quick/doc/snippets/qml/rectangle/rectangle-gradient.qml +++ b/src/quick/doc/snippets/qml/rectangle/rectangle-gradient.qml @@ -80,5 +80,17 @@ Rectangle { } } //! [rectangles] + +//! [presets] +Rectangle { + y: 0; width: 80; height: 80 + gradient: Gradient.NightFade +} + +Rectangle { + y: 0; width: 80; height: 80 + gradient: "NightFade" +} +//! [presets] } } diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index ab8203d0a8..5e217dcd0c 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -40,9 +40,13 @@ #include "qquickrectangle_p.h" #include "qquickrectangle_p_p.h" +#include <QtQml/qqmlinfo.h> + #include <QtQuick/private/qsgcontext_p.h> #include <private/qsgadaptationlayer_p.h> +#include <private/qqmlmetatype_p.h> + #include <QtGui/qpixmapcache.h> #include <QtCore/qmath.h> #include <QtCore/qmetaobject.h> @@ -393,7 +397,7 @@ QQuickPen *QQuickRectangle::border() } /*! - \qmlproperty Gradient QtQuick::Rectangle::gradient + \qmlproperty any QtQuick::Rectangle::gradient The gradient to use to fill the rectangle. @@ -407,37 +411,66 @@ QQuickPen *QQuickRectangle::border() \snippet qml/rectangle/rectangle-gradient.qml rectangles \clearfloat + The property also accepts gradient presets from QGradient::Preset. Note however + that due to Rectangle only supporting simple vertical or horizontal gradients, + any preset with an unsupported angle will revert to the closest representation. + + \snippet qml/rectangle/rectangle-gradient.qml presets + \clearfloat + If both a gradient and a color are specified, the gradient will be used. \sa Gradient, color */ -QQuickGradient *QQuickRectangle::gradient() const +QJSValue QQuickRectangle::gradient() const { Q_D(const QQuickRectangle); return d->gradient; } -void QQuickRectangle::setGradient(QQuickGradient *gradient) +void QQuickRectangle::setGradient(const QJSValue &gradient) { Q_D(QQuickRectangle); - if (d->gradient == gradient) + if (d->gradient.equals(gradient)) return; - static int updatedSignalIdx = -1; - if (updatedSignalIdx < 0) - updatedSignalIdx = QMetaMethod::fromSignal(&QQuickGradient::updated).methodIndex(); + + static int updatedSignalIdx = QMetaMethod::fromSignal(&QQuickGradient::updated).methodIndex(); if (d->doUpdateSlotIdx < 0) d->doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot("doUpdate()"); - if (d->gradient) - QMetaObject::disconnect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx); - d->gradient = gradient; - if (d->gradient) - QMetaObject::connect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx); + + if (auto oldGradient = qobject_cast<QQuickGradient*>(d->gradient.toQObject())) + QMetaObject::disconnect(oldGradient, updatedSignalIdx, this, d->doUpdateSlotIdx); + + if (gradient.isQObject()) { + if (auto newGradient = qobject_cast<QQuickGradient*>(gradient.toQObject())) { + d->gradient = gradient; + QMetaObject::connect(newGradient, updatedSignalIdx, this, d->doUpdateSlotIdx); + } else { + qmlWarning(this) << "Can't assign " + << QQmlMetaType::prettyTypeName(gradient.toQObject()) << " to gradient property"; + d->gradient = QJSValue(); + } + } else if (gradient.isNumber() || gradient.isString()) { + QGradient preset(gradient.toVariant().value<QGradient::Preset>()); + if (preset.type() != QGradient::NoGradient) { + d->gradient = gradient; + } else { + qmlWarning(this) << "No such gradient preset '" << gradient.toString() << "'"; + d->gradient = QJSValue(); + } + } else if (gradient.isNull() || gradient.isUndefined()) { + d->gradient = gradient; + } else { + qmlWarning(this) << "Unknown gradient type. Expected int, string, or Gradient"; + d->gradient = QJSValue(); + } + update(); } void QQuickRectangle::resetGradient() { - setGradient(nullptr); + setGradient(QJSValue()); } /*! @@ -534,9 +567,31 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData QGradientStops stops; bool vertical = true; - if (d->gradient) { - stops = d->gradient->gradientStops(); - vertical = d->gradient->orientation() == QQuickGradient::Vertical; + if (d->gradient.isQObject()) { + auto gradient = qobject_cast<QQuickGradient*>(d->gradient.toQObject()); + Q_ASSERT(gradient); + stops = gradient->gradientStops(); + vertical = gradient->orientation() == QQuickGradient::Vertical; + } else if (d->gradient.isNumber() || d->gradient.isString()) { + QGradient preset(d->gradient.toVariant().value<QGradient::Preset>()); + if (preset.type() == QGradient::LinearGradient) { + auto linearGradient = static_cast<QLinearGradient&>(preset); + const QPointF start = linearGradient.start(); + const QPointF end = linearGradient.finalStop(); + vertical = qAbs(start.y() - end.y()) >= qAbs(start.x() - end.x()); + stops = linearGradient.stops(); + if ((vertical && start.y() > end.y()) || (!vertical && start.x() > end.x())) { + // QSGInternalRectangleNode doesn't support stops in the wrong order, + // so we need to manually reverse them here. + QGradientStops reverseStops; + for (auto it = stops.rbegin(); it != stops.rend(); ++it) { + auto stop = *it; + stop.first = 1 - stop.first; + reverseStops.append(stop); + } + stops = reverseStops; + } + } } rectangle->setGradientStops(stops); rectangle->setGradientVertical(vertical); diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index ddafaafb28..d56a03d22d 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -122,6 +122,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION 12) Q_CLASSINFO("DefaultProperty", "stops") + Q_ENUMS(QGradient::Preset) public: QQuickGradient(QObject *parent=nullptr); ~QQuickGradient() override; @@ -157,7 +158,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - Q_PROPERTY(QQuickGradient *gradient READ gradient WRITE setGradient RESET resetGradient) + Q_PROPERTY(QJSValue gradient READ gradient WRITE setGradient RESET resetGradient) Q_PROPERTY(QQuickPen * border READ border CONSTANT) Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) public: @@ -168,8 +169,8 @@ public: QQuickPen *border(); - QQuickGradient *gradient() const; - void setGradient(QQuickGradient *gradient); + QJSValue gradient() const; + void setGradient(const QJSValue &gradient); void resetGradient(); qreal radius() const; diff --git a/src/quick/items/qquickrectangle_p_p.h b/src/quick/items/qquickrectangle_p_p.h index 3c1aaf7661..c7c5293f9b 100644 --- a/src/quick/items/qquickrectangle_p_p.h +++ b/src/quick/items/qquickrectangle_p_p.h @@ -73,7 +73,7 @@ public: } QColor color; - QQuickGradient *gradient; + QJSValue gradient; QQuickPen *pen; qreal radius; static int doUpdateSlotIdx; |