diff options
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 106 |
1 files changed, 85 insertions, 21 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index dac37e284b..f615e85e1b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2490,13 +2490,13 @@ QQuickItem *QQuickItemPrivate::nextTabChildItem(const QQuickItem *item, int star { if (!item) { qWarning() << "QQuickItemPrivate::nextTabChildItem called with null item."; - return Q_NULLPTR; + return nullptr; } const QList<QQuickItem *> &children = item->childItems(); const int count = children.count(); if (start < 0 || start >= count) { qWarning() << "QQuickItemPrivate::nextTabChildItem: Start index value out of range for item" << item; - return Q_NULLPTR; + return nullptr; } while (start < count) { QQuickItem *child = children.at(start); @@ -2504,14 +2504,14 @@ QQuickItem *QQuickItemPrivate::nextTabChildItem(const QQuickItem *item, int star return child; ++start; } - return Q_NULLPTR; + return nullptr; } QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int start) { if (!item) { qWarning() << "QQuickItemPrivate::prevTabChildItem called with null item."; - return Q_NULLPTR; + return nullptr; } const QList<QQuickItem *> &children = item->childItems(); const int count = children.count(); @@ -2519,7 +2519,7 @@ QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int star start = count - 1; if (start < 0 || start >= count) { qWarning() << "QQuickItemPrivate::prevTabChildItem: Start index value out of range for item" << item; - return Q_NULLPTR; + return nullptr; } while (start >= 0) { QQuickItem *child = children.at(start); @@ -2527,7 +2527,7 @@ QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int star return child; --start; } - return Q_NULLPTR; + return nullptr; } QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward) @@ -2567,8 +2567,8 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo QQuickItem *last = current; bool hasChildren = !current->childItems().isEmpty() && current->isEnabled() && current->isVisible(); - QQuickItem *firstChild = Q_NULLPTR; - QQuickItem *lastChild = Q_NULLPTR; + QQuickItem *firstChild = nullptr; + QQuickItem *lastChild = nullptr; if (hasChildren) { firstChild = nextTabChildItem(current, 0); if (!firstChild) @@ -2600,11 +2600,11 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo if (!current->childItems().isEmpty()) skip = true; // back to the parent - } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : Q_NULLPTR) { + } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : nullptr) { // we would evaluate the parent twice, thus we skip if (forward) { skip = true; - } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : Q_NULLPTR) { + } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : nullptr) { if (last != firstSibling || (parent->isFocusScope() && parent->activeFocusOnTab() && parent->hasActiveFocus())) skip = true; @@ -7577,9 +7577,75 @@ void QQuickItem::setKeepTouchGrab(bool keep) bool QQuickItem::contains(const QPointF &point) const { Q_D(const QQuickItem); - qreal x = point.x(); - qreal y = point.y(); - return x >= 0 && y >= 0 && x <= d->width && y <= d->height; + if (d->mask) { + bool res = false; + d->extra->maskContains.invoke(d->mask, + Qt::DirectConnection, + Q_RETURN_ARG(bool, res), + Q_ARG(QPointF, point)); + return res; + } else { + qreal x = point.x(); + qreal y = point.y(); + return x >= 0 && y >= 0 && x <= d->width && y <= d->height; + } +} + +/*! + \qmlproperty QObject * QtQuick::Item::containsMask + \since 5.11 + This property holds an optional mask for the Item to be used in the + QtQuick::Item::contains method. + QtQuick::Item::contains main use is currently to determine whether + an input event has landed into the item or not. + + By default the \l contains method will return true for any point + within the Item's bounding box. \c containsMask allows for a + more fine-grained control. For example, the developer could + define and use an AnotherItem element as containsMask, + which has a specialized contains method, like: + + \code + Item { id: item; containsMask: AnotherItem { id: anotherItem } } + \endcode + + \e{item}'s contains method would then return true only if + \e{anotherItem}'s contains implementation returns true. +*/ +QObject *QQuickItem::containsMask() const +{ + Q_D(const QQuickItem); + return d->mask.data(); +} + +void QQuickItem::setContainsMask(QObject *mask) +{ + Q_D(QQuickItem); + // an Item can't mask itself (to prevent infinite loop in contains()) + if (d->mask.data() == mask || mask == static_cast<QObject *>(this)) + return; + + QQuickItem *quickMask = qobject_cast<QQuickItem *>(d->mask); + if (quickMask) { + QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); + maskPrivate->registerAsContainsMask(this, false); // removed from use as my mask + } + + if (mask) { + int methodIndex = mask->metaObject()->indexOfMethod(QByteArrayLiteral("contains(QPointF)")); + if (methodIndex < 0) { + qmlWarning(this) << QStringLiteral("QQuickItem: Object set as mask does not have an invokable contains method, ignoring it."); + return; + } + d->extra.value().maskContains = mask->metaObject()->method(methodIndex); + } + d->mask = mask; + quickMask = qobject_cast<QQuickItem *>(mask); + if (quickMask) { + QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); + maskPrivate->registerAsContainsMask(this, true); // telling maskPrivate that "this" is using it as mask + } + emit containsMaskChanged(); } /*! @@ -8501,10 +8567,8 @@ void QQuickItemLayer::updateGeometry() QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource; Q_ASSERT(l); QRectF bounds = m_item->clipRect(); - l->setWidth(bounds.width()); - l->setHeight(bounds.height()); - l->setX(bounds.x() + m_item->x()); - l->setY(bounds.y() + m_item->y()); + l->setSize(bounds.size()); + l->setPosition(bounds.topLeft() + m_item->position()); } void QQuickItemLayer::updateMatrix() @@ -8558,25 +8622,25 @@ QAccessible::Role QQuickItemPrivate::accessibleRole() const namespace QV4 { namespace Heap { struct QQuickItemWrapper : public QObjectWrapper { + static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack); }; } } struct QQuickItemWrapper : public QV4::QObjectWrapper { V4_OBJECT2(QQuickItemWrapper, QV4::QObjectWrapper) - static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack); }; DEFINE_OBJECT_VTABLE(QQuickItemWrapper); -void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) +void QV4::Heap::QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) { - QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that); + QObjectWrapper *This = static_cast<QObjectWrapper *>(that); if (QQuickItem *item = static_cast<QQuickItem*>(This->object())) { for (QQuickItem *child : qAsConst(QQuickItemPrivate::get(item)->childItems)) QV4::QObjectWrapper::markWrapper(child, markStack); } - QV4::QObjectWrapper::markObjects(that, markStack); + QObjectWrapper::markObjects(that, markStack); } quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine) |