aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickitem.cpp
diff options
context:
space:
mode:
authorAlbert Astals Cid <albert.astals.cid@kdab.com>2020-01-15 10:45:30 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-01-24 13:55:16 +0000
commit702f94960896f6f7b73d3dbf4e675e42e2d54d2d (patch)
tree8ca847e6099039b3e1fc6e813f3e3b042b94018c /src/quick/items/qquickitem.cpp
parent906a235c9d37f0e813f814d61fa342ffa09b9f6d (diff)
Make QtQuick::Item::mapFrom/ToItem also accept point and rect
[ChangeLog][QtQuick][Item] Item.mapToItem() and mapFromItem() now work with QPointF and QRectF types as well as with raw numbers. Change-Id: Ifeb5c36e1bc5a283df4e11c8cf2af960de3f287b Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r--src/quick/items/qquickitem.cpp194
1 files changed, 104 insertions, 90 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 59684d15a8..03cdeb5bef 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -74,6 +74,7 @@
#include <private/qv4object_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qdebug_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
#if QT_CONFIG(cursor)
# include <QtGui/qcursor.h>
@@ -4475,9 +4476,94 @@ void QQuickItem::polish()
}
}
+static bool unwrapMapFromToFromItemArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning,
+ QQuickItem **itemObj, qreal *x, qreal *y, qreal *w, qreal *h, bool *isRect)
+{
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ if (args->length() != 2 && args->length() != 3 && args->length() != 5) {
+ v4->throwTypeError();
+ return false;
+ }
+
+ QV4::Scope scope(v4);
+ QV4::ScopedValue item(scope, (*args)[0]);
+
+ *itemObj = nullptr;
+ if (!item->isNull()) {
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
+ if (qobjectWrapper)
+ *itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
+ }
+
+ if (!(*itemObj) && !item->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << " given argument \"" << item->toQStringNoThrow()
+ << "\" which is neither null nor an Item";
+ v4->throwTypeError();
+ return false;
+ }
+
+ *isRect = false;
+
+ if (args->length() == 2) {
+ QV4::ScopedValue sv(scope, (*args)[1]);
+ if (sv->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is neither a point nor a rect";
+ v4->throwTypeError();
+ return false;
+ }
+ const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
+ const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
+ if (v.canConvert<QPointF>()) {
+ const QPointF p = v.toPointF();
+ *x = p.x();
+ *y = p.y();
+ } else if (v.canConvert<QRectF>()) {
+ const QRectF r = v.toRectF();
+ *x = r.x();
+ *y = r.y();
+ *w = r.width();
+ *h = r.height();
+ *isRect = true;
+ } else {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is neither a point nor a rect";
+ v4->throwTypeError();
+ return false;
+ }
+ } else {
+ QV4::ScopedValue vx(scope, (*args)[1]);
+ QV4::ScopedValue vy(scope, (*args)[2]);
+
+ if (!vx->isNumber() || !vy->isNumber()) {
+ v4->throwTypeError();
+ return false;
+ }
+
+ *x = vx->asDouble();
+ *y = vy->asDouble();
+
+ if (args->length() > 3) {
+ QV4::ScopedValue vw(scope, (*args)[3]);
+ QV4::ScopedValue vh(scope, (*args)[4]);
+ if (!vw->isNumber() || !vh->isNumber()) {
+ v4->throwTypeError();
+ return false;
+ }
+ *w = vw->asDouble();
+ *h = vh->asDouble();
+ *isRect = true;
+ }
+ }
+
+ return true;
+}
+
/*!
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y)
+ \qmlmethod object QtQuick::Item::mapFromItem(Item item, point p)
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height)
+ \qmlmethod object QtQuick::Item::mapFromItem(Item item, rect r)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
item's coordinate system, to this item's coordinate system, and returns a \l point or \l rect
@@ -4487,6 +4573,8 @@ void QQuickItem::polish()
If \a item is a \c null value, this maps the point or rect from the coordinate system of
the root QML view.
+
+ The versions accepting point and rect are since Qt 5.15.
*/
/*!
\internal
@@ -4494,55 +4582,16 @@ void QQuickItem::polish()
void QQuickItem::mapFromItem(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 3 && args->length() != 5) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue item(scope, (*args)[0]);
-
- QQuickItem *itemObj = nullptr;
- if (!item->isNull()) {
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
- if (qobjectWrapper)
- itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
- }
-
- if (!itemObj && !item->isNull()) {
- qmlWarning(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow()
- << "\" which is neither null nor an Item";
- v4->throwTypeError();
- return;
- }
- QV4::ScopedValue vx(scope, (*args)[1]);
- QV4::ScopedValue vy(scope, (*args)[2]);
-
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
+ qreal x, y, w, h;
+ bool isRect;
+ QQuickItem *itemObj;
+ if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapFromItem()"), &itemObj, &x, &y, &w, &h, &isRect))
return;
- }
-
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
-
- QVariant result;
- if (args->length() > 3) {
- QV4::ScopedValue vw(scope, (*args)[3]);
- QV4::ScopedValue vh(scope, (*args)[4]);
- if (!vw->isNumber() || !vh->isNumber()) {
- v4->throwTypeError();
- return;
- }
- qreal w = vw->asDouble();
- qreal h = vh->asDouble();
-
- result = mapRectFromItem(itemObj, QRectF(x, y, w, h));
- } else {
- result = mapFromItem(itemObj, QPointF(x, y));
- }
+ const QVariant result = isRect ? QVariant(mapRectFromItem(itemObj, QRectF(x, y, w, h)))
+ : QVariant(mapFromItem(itemObj, QPointF(x, y)));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
args->setReturnValue(rv.asReturnedValue());
@@ -4567,7 +4616,9 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
/*!
\qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y)
+ \qmlmethod object QtQuick::Item::mapToItem(Item item, point p)
\qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y, real width, real height)
+ \qmlmethod object QtQuick::Item::mapToItem(Item item, rect r)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
item's coordinate system, to \a item's coordinate system, and returns a \l point or \l rect
@@ -4577,6 +4628,8 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
If \a item is a \c null value, this maps the point or rect to the coordinate system of the
root QML view.
+
+ The versions accepting point and rect are since Qt 5.15.
*/
/*!
\internal
@@ -4584,55 +4637,16 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
void QQuickItem::mapToItem(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 3 && args->length() != 5) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue item(scope, (*args)[0]);
-
- QQuickItem *itemObj = nullptr;
- if (!item->isNull()) {
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
- if (qobjectWrapper)
- itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
- }
-
- if (!itemObj && !item->isNull()) {
- qmlWarning(this) << "mapToItem() given argument \"" << item->toQStringNoThrow()
- << "\" which is neither null nor an Item";
- v4->throwTypeError();
- return;
- }
- QV4::ScopedValue vx(scope, (*args)[1]);
- QV4::ScopedValue vy(scope, (*args)[2]);
-
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
+ qreal x, y, w, h;
+ bool isRect;
+ QQuickItem *itemObj;
+ if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapToItem()"), &itemObj, &x, &y, &w, &h, &isRect))
return;
- }
-
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
-
- QVariant result;
- if (args->length() > 3) {
- QV4::ScopedValue vw(scope, (*args)[3]);
- QV4::ScopedValue vh(scope, (*args)[4]);
- if (!vw->isNumber() || !vh->isNumber()) {
- v4->throwTypeError();
- return;
- }
- qreal w = vw->asDouble();
- qreal h = vh->asDouble();
-
- result = mapRectToItem(itemObj, QRectF(x, y, w, h));
- } else {
- result = mapToItem(itemObj, QPointF(x, y));
- }
+ const QVariant result = isRect ? QVariant(mapRectToItem(itemObj, QRectF(x, y, w, h)))
+ : QVariant(mapToItem(itemObj, QPointF(x, y)));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
args->setReturnValue(rv.asReturnedValue());