diff options
| author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-12-09 08:06:18 +0100 |
|---|---|---|
| committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-12-10 06:51:59 +0100 |
| commit | e58cb58b44a0381592cd0e6eb0da3d3d6f1c5ccc (patch) | |
| tree | 27ce55d00f38360501842b6f06a647f0c93045a6 /src | |
| parent | af356e3bc87f8029026d1eaa345f7197c0705ffa (diff) | |
Allow reparenting Pointer Handlers
[ChangeLog][Event Handlers] The parent property of any Pointer Handler
is now settable.
Fixes: QTBUG-84730
Task-number: QTBUG-85926
Task-number: QTBUG-17286
Change-Id: Id738dd783de1acfbef9b5be203025040b0913008
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/quick/handlers/qquickpointerhandler.cpp | 16 | ||||
| -rw-r--r-- | src/quick/handlers/qquickpointerhandler_p.h | 4 | ||||
| -rw-r--r-- | src/quick/items/qquickitem.cpp | 22 | ||||
| -rw-r--r-- | src/quick/items/qquickitem_p.h | 2 |
4 files changed, 39 insertions, 5 deletions
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 4777f31b4b..2f38fe8973 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcPointerHandlerDispatch, "qt.quick.handler.dispatch") Q_LOGGING_CATEGORY(lcPointerHandlerGrab, "qt.quick.handler.grab") Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active") +Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent) /*! \qmltype PointerHandler @@ -626,6 +627,20 @@ QQuickItem *QQuickPointerHandler::parentItem() const return qmlobject_cast<QQuickItem *>(QObject::parent()); } +void QQuickPointerHandler::setParentItem(QQuickItem *p) +{ + if (QObject::parent() == p) + return; + + qCDebug(lcHandlerParent) << "reparenting handler" << this << ":" << parent() << "->" << p; + if (auto *oldParent = static_cast<QQuickItem *>(QObject::parent())) + QQuickItemPrivate::get(oldParent)->removePointerHandler(this); + setParent(p); + if (p) + QQuickItemPrivate::get(p)->addPointerHandler(this); + emit parentChanged(); +} + QQuickItem *QQuickPointerHandler::target() const { Q_D(const QQuickPointerHandler); @@ -725,7 +740,6 @@ void QQuickPointerHandler::handlePointerEventImpl(QPointerEvent *event) } /*! - \readonly \qmlproperty Item QtQuick::PointerHandler::parent The \l Item which is the scope of the handler; the Item in which it was declared. diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h index 125c8eb401..3f1b02ef62 100644 --- a/src/quick/handlers/qquickpointerhandler_p.h +++ b/src/quick/handlers/qquickpointerhandler_p.h @@ -68,7 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool active READ active NOTIFY activeChanged) Q_PROPERTY(QQuickItem * target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT) + Q_PROPERTY(QQuickItem * parent READ parentItem WRITE setParentItem NOTIFY parentChanged) Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged) Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged) Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION(2, 15)) @@ -110,6 +110,7 @@ public: void setTarget(QQuickItem *target); QQuickItem * parentItem() const; + void setParentItem(QQuickItem *p); void handlePointerEvent(QPointerEvent *event); @@ -142,6 +143,7 @@ Q_SIGNALS: #if QT_CONFIG(cursor) Q_REVISION(2, 15) void cursorShapeChanged(); #endif + Q_REVISION(6, 3) void parentChanged(); protected: QQuickPointerHandler(QQuickPointerHandlerPrivate &dd, QQuickItem *parent); diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index e4b7e18ae5..67572c231d 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7718,8 +7718,10 @@ void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons) d->extra.setTag(d->extra.tag().setFlag(QQuickItemPrivate::LeftMouseButtonAccepted, buttons & Qt::LeftButton)); buttons &= ~Qt::LeftButton; - if (buttons || d->extra.isAllocated()) - d->extra.value().acceptedMouseButtons = buttons; + if (buttons || d->extra.isAllocated()) { + d->extra.value().acceptedMouseButtonsWithoutHandlers = buttons; + d->extra.value().acceptedMouseButtons = d->extra->pointerHandlers.isEmpty() ? buttons : Qt::AllButtons; + } } /*! @@ -8960,10 +8962,11 @@ bool QQuickItemPrivate::hasHoverHandlers() const void QQuickItemPrivate::addPointerHandler(QQuickPointerHandler *h) { + Q_ASSERT(h); Q_Q(QQuickItem); // Accept all buttons, and leave filtering to pointerEvent() and/or user JS, // because there can be multiple handlers... - q->setAcceptedMouseButtons(Qt::AllButtons); + extra.value().acceptedMouseButtons = Qt::AllButtons; auto &handlers = extra.value().pointerHandlers; if (!handlers.contains(h)) handlers.prepend(h); @@ -8976,6 +8979,19 @@ void QQuickItemPrivate::addPointerHandler(QQuickPointerHandler *h) } } +void QQuickItemPrivate::removePointerHandler(QQuickPointerHandler *h) +{ + Q_ASSERT(h); + Q_Q(QQuickItem); + auto &handlers = extra.value().pointerHandlers; + handlers.removeOne(h); + auto &res = extra.value().resourcesList; + res.removeOne(h); + QObject::disconnect(h, &QObject::destroyed, q, nullptr); + if (handlers.isEmpty()) + extra.value().acceptedMouseButtons = extra.value().acceptedMouseButtonsWithoutHandlers; +} + #if QT_CONFIG(quick_shadereffect) QQuickItemLayer::QQuickItemLayer(QQuickItem *item) : m_item(item) diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 6be15c4f3a..933019b3c6 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -286,6 +286,7 @@ public: bool hasPointerHandlers() const; bool hasHoverHandlers() const; virtual void addPointerHandler(QQuickPointerHandler *h); + virtual void removePointerHandler(QQuickPointerHandler *h); // data property static void data_append(QQmlListProperty<QObject> *, QObject *); @@ -430,6 +431,7 @@ public: // extremely common to set acceptedMouseButtons to LeftButton, but very // rare to use any of the other buttons. Qt::MouseButtons acceptedMouseButtons; + Qt::MouseButtons acceptedMouseButtonsWithoutHandlers; QQuickItem::TransformOrigin origin:5; uint transparentForPositioner : 1; |
