diff options
-rw-r--r-- | src/quick/items/qquickitem.cpp | 139 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem/data/contains.qml | 26 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem/tst_qquickitem.cpp | 45 |
3 files changed, 133 insertions, 77 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 7ab2faf052..4d1bb696fa 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4113,8 +4113,8 @@ void QQuickItem::polish() \qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height) 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 an object with \c x and - \c y (and optionally \c width and \c height) properties matching the mapped coordinate. + item's coordinate system, to this item's coordinate system, and returns a \l point or \rect + matching the mapped coordinate. If \a item is a \c null value, this maps the point or rect from the coordinate system of the root QML view. @@ -4124,50 +4124,43 @@ void QQuickItem::polish() */ void QQuickItem::mapFromItem(QQmlV4Function *args) const { - if (args->length() != 0) { - QV4::ExecutionEngine *v4 = args->v4engine(); - QV4::Scope scope(v4); - QV4::ScopedValue item(scope, (*args)[0]); - - QQuickItem *itemObj = 0; - 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()) { - qmlInfo(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow() - << "\" which is neither null nor an Item"; - return; - } + if (args->length() == 0) + return; - QV4::ScopedObject rv(scope, v4->newObject()); - args->setReturnValue(rv.asReturnedValue()); + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + QV4::ScopedValue item(scope, (*args)[0]); - QV4::ScopedString s(scope); - QV4::ScopedValue v(scope); + QQuickItem *itemObj = 0; + if (!item->isNull()) { + QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>()); + if (qobjectWrapper) + itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object()); + } - qreal x = (args->length() > 1) ? (v = (*args)[1])->asDouble() : 0; - qreal y = (args->length() > 2) ? (v = (*args)[2])->asDouble() : 0; + if (!itemObj && !item->isNull()) { + qmlInfo(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow() + << "\" which is neither null nor an Item"; + return; + } - if (args->length() > 3) { - qreal w = (v = (*args)[3])->asDouble(); - qreal h = (args->length() > 4) ? (v = (*args)[4])->asDouble() : 0; + QV4::ScopedValue v(scope); - QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h)); + qreal x = (args->length() > 1) ? (v = (*args)[1])->asDouble() : 0; + qreal y = (args->length() > 2) ? (v = (*args)[2])->asDouble() : 0; - rv->put((s = v4->newString(QStringLiteral("x"))), (v = QV4::Primitive::fromDouble(r.x()))); - rv->put((s = v4->newString(QStringLiteral("y"))), (v = QV4::Primitive::fromDouble(r.y()))); - rv->put((s = v4->newString(QStringLiteral("width"))), (v = QV4::Primitive::fromDouble(r.width()))); - rv->put((s = v4->newString(QStringLiteral("height"))), (v = QV4::Primitive::fromDouble(r.height()))); - } else { - QPointF p = mapFromItem(itemObj, QPointF(x, y)); + QVariant result; - rv->put((s = v4->newString(QStringLiteral("x"))), (v = QV4::Primitive::fromDouble(p.x()))); - rv->put((s = v4->newString(QStringLiteral("y"))), (v = QV4::Primitive::fromDouble(p.y()))); - } + if (args->length() > 3) { + qreal w = (v = (*args)[3])->asDouble(); + qreal h = (args->length() > 4) ? (v = (*args)[4])->asDouble() : 0; + result = mapRectFromItem(itemObj, QRectF(x, y, w, h)); + } else { + result = mapFromItem(itemObj, QPointF(x, y)); } + + QV4::ScopedObject rv(scope, v4->fromVariant(result)); + args->setReturnValue(rv.asReturnedValue()); } /*! @@ -4192,8 +4185,8 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const \qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y, real width, real height) 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 an object with \c x and - \c y (and optionally \c width and \c height) properties matching the mapped coordinate. + item's coordinate system, to \a item's coordinate system, and returns a \l point or \l rect + matching the mapped coordinate. If \a item is a \c null value, this maps the point or rect to the coordinate system of the root QML view. @@ -4203,51 +4196,43 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const */ void QQuickItem::mapToItem(QQmlV4Function *args) const { - if (args->length() != 0) { - QV4::ExecutionEngine *v4 = args->v4engine(); - QV4::Scope scope(v4); - QV4::ScopedValue item(scope, (*args)[0]); - - QQuickItem *itemObj = 0; - 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()) { - qmlInfo(this) << "mapToItem() given argument \"" << item->toQStringNoThrow() - << "\" which is neither null nor an Item"; - return; - } - - QV4::ScopedObject rv(scope, v4->newObject()); - args->setReturnValue(rv.asReturnedValue()); + if (args->length() == 0) + return; - QV4::ScopedValue v(scope); + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + QV4::ScopedValue item(scope, (*args)[0]); - qreal x = (args->length() > 1) ? (v = (*args)[1])->asDouble() : 0; - qreal y = (args->length() > 2) ? (v = (*args)[2])->asDouble() : 0; + QQuickItem *itemObj = 0; + if (!item->isNull()) { + QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>()); + if (qobjectWrapper) + itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object()); + } - QV4::ScopedString s(scope); + if (!itemObj && !item->isNull()) { + qmlInfo(this) << "mapToItem() given argument \"" << item->toQStringNoThrow() + << "\" which is neither null nor an Item"; + return; + } - if (args->length() > 3) { - qreal w = (v = (*args)[3])->asDouble(); - qreal h = (args->length() > 4) ? (v = (*args)[4])->asDouble() : 0; + QV4::ScopedValue v(scope); + QVariant result; - QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h)); + qreal x = (args->length() > 1) ? (v = (*args)[1])->asDouble() : 0; + qreal y = (args->length() > 2) ? (v = (*args)[2])->asDouble() : 0; - rv->put((s = v4->newString(QStringLiteral("x"))), (v = QV4::Primitive::fromDouble(r.x()))); - rv->put((s = v4->newString(QStringLiteral("y"))), (v = QV4::Primitive::fromDouble(r.y()))); - rv->put((s = v4->newString(QStringLiteral("width"))), (v = QV4::Primitive::fromDouble(r.width()))); - rv->put((s = v4->newString(QStringLiteral("height"))), (v = QV4::Primitive::fromDouble(r.height()))); - } else { - QPointF p = mapToItem(itemObj, QPointF(x, y)); + if (args->length() > 3) { + qreal w = (v = (*args)[3])->asDouble(); + qreal h = (args->length() > 4) ? (v = (*args)[4])->asDouble() : 0; - rv->put((s = v4->newString(QStringLiteral("x"))), (v = QV4::Primitive::fromDouble(p.x()))); - rv->put((s = v4->newString(QStringLiteral("y"))), (v = QV4::Primitive::fromDouble(p.y()))); - } + result = mapRectToItem(itemObj, QRectF(x, y, w, h)); + } else { + result = mapToItem(itemObj, QPointF(x, y)); } + + QV4::ScopedObject rv(scope, v4->fromVariant(result)); + args->setReturnValue(rv.asReturnedValue()); } /*! diff --git a/tests/auto/quick/qquickitem/data/contains.qml b/tests/auto/quick/qquickitem/data/contains.qml new file mode 100644 index 0000000000..72fd8bdc91 --- /dev/null +++ b/tests/auto/quick/qquickitem/data/contains.qml @@ -0,0 +1,26 @@ +import QtQuick 2.3 + +Item { + id: root + width: 300 + height: 300 + + function childContainsViaMapToItem(x, y) { + var childLocalPos = root.mapToItem(child, x, y); + return child.contains(childLocalPos); + } + + function childContainsViaMapFromItem(x, y) { + var childLocalPos = child.mapFromItem(root, x, y); + return child.contains(childLocalPos); + } + + Item { + id: child + x: 50 + y: 50 + width: 50 + height: 50 + } +} + diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 832cbab971..c79af91747 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -169,6 +169,9 @@ private slots: void objectChildTransform(); + void contains_data(); + void contains(); + private: enum PaintOrderOp { @@ -1927,6 +1930,48 @@ void tst_qquickitem::objectChildTransform() // Shouldn't crash. } +void tst_qquickitem::contains_data() +{ + QTest::addColumn<int>("x"); + QTest::addColumn<int>("y"); + QTest::addColumn<bool>("contains"); + + QTest::newRow("(0, 0) = false") << 0 << 0 << false; + QTest::newRow("(50, 0) = false") << 50 << 0 << false; + QTest::newRow("(0, 50) = false") << 0 << 50 << false; + QTest::newRow("(50, 50) = true") << 50 << 50 << true; + QTest::newRow("(100, 100) = true") << 100 << 100 << true; + QTest::newRow("(150, 150) = false") << 150 << 150 << false; +} + +void tst_qquickitem::contains() +{ + // Tests that contains works, but also checks that mapToItem/mapFromItem + // return the correct type (point or rect, not a JS object with those properties), + // as this is a common combination of calls. + + QFETCH(int, x); + QFETCH(int, y); + QFETCH(bool, contains); + + QQuickView view; + view.setSource(testFileUrl("contains.qml")); + + QQuickItem *root = qobject_cast<QQuickItem*>(view.rootObject()); + QVERIFY(root); + + QVariant result = false; + QVERIFY(QMetaObject::invokeMethod(root, "childContainsViaMapToItem", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, qreal(x)), Q_ARG(QVariant, qreal(y)))); + QCOMPARE(result.toBool(), contains); + + result = false; + QVERIFY(QMetaObject::invokeMethod(root, "childContainsViaMapFromItem", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, qreal(x)), Q_ARG(QVariant, qreal(y)))); + QCOMPARE(result.toBool(), contains); +} + + QTEST_MAIN(tst_qquickitem) #include "tst_qquickitem.moc" |