aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r--src/quick/items/qquickitem.cpp106
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)