From 6dc319155a282cd274a93887c5b83c8ed8b82d90 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 16 Aug 2019 05:51:02 +0200 Subject: Enable PathPolyline to take a QPolygonF or QVector path If a C++ model object can make a vector of points available directly, and it is bound to a PathPolyline's path to provide the view layer, it's a waste of time to convert it to a QVariantList and back again. Changing the type of the property to QVariant instead of QVariantList enables an extensible set of supported types. Task-number: QTBUG-77929 Change-Id: I2453b59e047ec3310070e943f6934c9ddcd1ffaa Reviewed-by: Paolo Angelelli --- src/quick/util/qquickpath.cpp | 40 +++++++++++++++++++++++++--------------- src/quick/util/qquickpath_p.h | 6 +++--- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index d246ee7910..6d4e469e44 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -2397,32 +2397,42 @@ void QQuickPathPercent::setValue(qreal value) \qmlproperty list QtQuick::PathPolyline::path This property defines the vertices of the polyline. + + It can be a JS array of points constructed with \c Qt.point(), + a QList or QVector of QPointF, or QPolygonF. + If you are binding this to a custom property in some C++ object, + QPolygonF is the most appropriate type to use. */ QQuickPathPolyline::QQuickPathPolyline(QObject *parent) : QQuickCurve(parent) { } -QVariantList QQuickPathPolyline::path() const +QVariant QQuickPathPolyline::path() const { - QVariantList res; - for (int i = 0; i < m_path.length(); ++i) { - const QPointF &c = m_path.at(i); - res.append(QVariant::fromValue(c)); - } - - return res; + return QVariant::fromValue(m_path); } -void QQuickPathPolyline::setPath(const QVariantList &path) +void QQuickPathPolyline::setPath(const QVariant &path) { - QVector pathList; - for (int i = 0; i < path.length(); ++i) { - const QPointF c = path.at(i).toPointF(); - pathList.append(c); + if (path.type() == QVariant::PolygonF) { + setPath(path.value()); + } else if (path.canConvert>()) { + setPath(path.value>()); + } else if (path.canConvert()) { + // This handles cases other than QPolygonF or QVector, such as + // QList, QVector, QVariantList of QPointF, QVariantList of QPoint. + QVector pathList; + QVariantList vl = path.value(); + // If path is a QJSValue, e.g. coming from a JS array of Qt.point() in QML, + // then path.value() is inefficient. + // TODO We should be able to iterate over path.value() eventually + for (const QVariant &v : vl) + pathList.append(v.toPointF()); + setPath(pathList); + } else { + qWarning() << "PathPolyline: path of type" << path.type() << "not supported"; } - - setPath(pathList); } void QQuickPathPolyline::setPath(const QVector &path) diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index 92607a6c1e..e37a2e2dce 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -428,12 +428,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve { Q_OBJECT Q_PROPERTY(QPointF start READ start NOTIFY startChanged) - Q_PROPERTY(QVariantList path READ path WRITE setPath NOTIFY pathChanged) + Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged) public: QQuickPathPolyline(QObject *parent=nullptr); - QVariantList path() const; - void setPath(const QVariantList &path); + QVariant path() const; + void setPath(const QVariant &path); void setPath(const QVector &path); QPointF start() const; void addToPath(QPainterPath &path, const QQuickPathData &data) override; -- cgit v1.2.3