From 1c44804600ad3dbeb60d1f5209ce9cf937d30ab3 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 16 Jan 2020 13:45:15 +0100 Subject: Add PointerHandler.cursorShape property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, QQuickItemPrivate::setHasCursorInChild() was unable to check the QQuickItemPrivate::hasCursor variable, because the function argument hasCursor was shadowing that, even though the comment "nope! sorry, I have a cursor myself" hints that the intention was to check that. So this change exposed a problem there, and we have to fix that too, in order to keep the tst_qquickwindow::cursor() test passing. [ChangeLog][Event Handlers] Pointer Handlers now have a cursorShape property to set the cursor when the handler is active and the mouse is hovering, and restore to the previous cursor when the mouse leaves. Fixes: QTBUG-68073 Change-Id: Ib5c66bd59c4691c4210ee5465e1c95e7bdcf5ae1 Reviewed-by: Jan Arve Sæther --- src/quick/handlers/qquickhoverhandler.cpp | 51 ++++++++++++++++ src/quick/handlers/qquickpointerhandler.cpp | 84 ++++++++++++++++++++++++++- src/quick/handlers/qquickpointerhandler_p.h | 13 +++++ src/quick/handlers/qquickpointerhandler_p_p.h | 2 + 4 files changed, 149 insertions(+), 1 deletion(-) (limited to 'src/quick/handlers') diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp index 79cb288af8..1216eda477 100644 --- a/src/quick/handlers/qquickhoverhandler.cpp +++ b/src/quick/handlers/qquickhoverhandler.cpp @@ -64,6 +64,9 @@ Q_LOGGING_CATEGORY(lcHoverHandler, "qt.quick.handler.hover") properties can be used to narrow the behavior to detect hovering of specific kinds of devices or while holding a modifier key. + The \l cursorShape property allows changing the cursor whenever + \l hovered changes to \c true. + \sa MouseArea, PointHandler */ @@ -125,4 +128,52 @@ void QQuickHoverHandler::setHovered(bool hovered) } } +/*! + \since 5.15 + \qmlproperty Qt::CursorShape QtQuick::HoverHandler::cursorShape + This property holds the cursor shape that will appear whenever + \l hovered is \c true and no other handler is overriding it. + + The available cursor shapes are: + \list + \li Qt.ArrowCursor + \li Qt.UpArrowCursor + \li Qt.CrossCursor + \li Qt.WaitCursor + \li Qt.IBeamCursor + \li Qt.SizeVerCursor + \li Qt.SizeHorCursor + \li Qt.SizeBDiagCursor + \li Qt.SizeFDiagCursor + \li Qt.SizeAllCursor + \li Qt.BlankCursor + \li Qt.SplitVCursor + \li Qt.SplitHCursor + \li Qt.PointingHandCursor + \li Qt.ForbiddenCursor + \li Qt.WhatsThisCursor + \li Qt.BusyCursor + \li Qt.OpenHandCursor + \li Qt.ClosedHandCursor + \li Qt.DragCopyCursor + \li Qt.DragMoveCursor + \li Qt.DragLinkCursor + \endlist + + The default value of this property is not set, which allows any active + handler on the same \l parentItem to determine the cursor shape. + This property can be reset to the initial condition by setting it to + \c undefined. + + If any handler with defined \c cursorShape is + \l {PointerHandler::active}{active}, that cursor will appear. + Else if the HoverHandler has a defined \c cursorShape, that cursor will appear. + Otherwise, the \l {QQuickItem::cursor()}{cursor} of \l parentItem will appear. + + \note When this property has not been set, or has been set to \c undefined, + if you read the value it will return \c Qt.ArrowCursor. + + \sa Qt::CursorShape, QQuickItem::cursor() +*/ + QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index c498c96454..adb753e000 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -51,7 +51,6 @@ Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active") \qmltype PointerHandler \qmlabstract \since 5.10 - \preliminary \instantiates QQuickPointerHandler \inqmlmodule QtQuick \brief Abstract handler for pointer events. @@ -153,6 +152,87 @@ void QQuickPointerHandler::resetDragThreshold() emit dragThresholdChanged(); } +/*! + \since 5.15 + \qmlproperty Qt::CursorShape PointerHandler::cursorShape + This property holds the cursor shape that will appear whenever the mouse is + hovering over the \l parentItem while \l active is \c true. + + The available cursor shapes are: + \list + \li Qt.ArrowCursor + \li Qt.UpArrowCursor + \li Qt.CrossCursor + \li Qt.WaitCursor + \li Qt.IBeamCursor + \li Qt.SizeVerCursor + \li Qt.SizeHorCursor + \li Qt.SizeBDiagCursor + \li Qt.SizeFDiagCursor + \li Qt.SizeAllCursor + \li Qt.BlankCursor + \li Qt.SplitVCursor + \li Qt.SplitHCursor + \li Qt.PointingHandCursor + \li Qt.ForbiddenCursor + \li Qt.WhatsThisCursor + \li Qt.BusyCursor + \li Qt.OpenHandCursor + \li Qt.ClosedHandCursor + \li Qt.DragCopyCursor + \li Qt.DragMoveCursor + \li Qt.DragLinkCursor + \endlist + + The default value is not set, which allows the \l {QQuickItem::cursor()}{cursor} + of \l parentItem to appear. This property can be reset to the same initial + condition by setting it to undefined. + + \note When this property has not been set, or has been set to \c undefined, + if you read the value it will return \c Qt.ArrowCursor. + + \sa Qt::CursorShape, QQuickItem::cursor(), HoverHandler::cursorShape +*/ +#if QT_CONFIG(cursor) +Qt::CursorShape QQuickPointerHandler::cursorShape() const +{ + Q_D(const QQuickPointerHandler); + return d->cursorShape; +} + +void QQuickPointerHandler::setCursorShape(Qt::CursorShape shape) +{ + Q_D(QQuickPointerHandler); + if (d->cursorSet && shape == d->cursorShape) + return; + d->cursorShape = shape; + d->cursorSet = true; + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem()); + itemPriv->hasCursorHandler = true; + itemPriv->setHasCursorInChild(true); + emit cursorShapeChanged(); +} + +void QQuickPointerHandler::resetCursorShape() +{ + Q_D(QQuickPointerHandler); + if (!d->cursorSet) + return; + d->cursorShape = Qt::ArrowCursor; + d->cursorSet = false; + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem()); + itemPriv->hasCursorHandler = false; + itemPriv->setHasCursorInChild(itemPriv->hasCursor); + emit cursorShapeChanged(); +} + +bool QQuickPointerHandler::isCursorShapeExplicitlySet() const +{ + Q_D(const QQuickPointerHandler); + return d->cursorSet; +} +#endif + /*! Notification that the grab has changed in some way which is relevant to this handler. The \a grabber (subject) will be the Input Handler whose state is changing, @@ -597,11 +677,13 @@ QQuickPointerHandlerPrivate::QQuickPointerHandlerPrivate() : grabPermissions(QQuickPointerHandler::CanTakeOverFromItems | QQuickPointerHandler::CanTakeOverFromHandlersOfDifferentType | QQuickPointerHandler::ApprovesTakeOverByAnything) + , cursorShape(Qt::ArrowCursor) , enabled(true) , active(false) , targetExplicitlySet(false) , hadKeepMouseGrab(false) , hadKeepTouchGrab(false) + , cursorSet(false) { } diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h index 34ae9ce2c2..7262f4bcd3 100644 --- a/src/quick/handlers/qquickpointerhandler_p.h +++ b/src/quick/handlers/qquickpointerhandler_p.h @@ -72,6 +72,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP 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 15) +#if QT_CONFIG(cursor) + Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION 15) +#endif QML_NAMED_ELEMENT(PointerHandler) QML_UNCREATABLE("PointerHandler is an abstract base class.") @@ -119,6 +122,13 @@ public: void setDragThreshold(int t); void resetDragThreshold(); +#if QT_CONFIG(cursor) + Qt::CursorShape cursorShape() const; + void setCursorShape(Qt::CursorShape shape); + void resetCursorShape(); + bool isCursorShapeExplicitlySet() const; +#endif + Q_SIGNALS: void enabledChanged(); void activeChanged(); @@ -128,6 +138,9 @@ Q_SIGNALS: void grabChanged(QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point); void grabPermissionChanged(); void canceled(QQuickEventPoint *point); +#if QT_CONFIG(cursor) + Q_REVISION(15) void cursorShapeChanged(); +#endif protected: QQuickPointerHandler(QQuickPointerHandlerPrivate &dd, QQuickItem *parent); diff --git a/src/quick/handlers/qquickpointerhandler_p_p.h b/src/quick/handlers/qquickpointerhandler_p_p.h index 5727b1ef55..db053fb6b4 100644 --- a/src/quick/handlers/qquickpointerhandler_p_p.h +++ b/src/quick/handlers/qquickpointerhandler_p_p.h @@ -79,11 +79,13 @@ public: qreal m_margin = 0; qint16 dragThreshold = -1; // -1 means use the platform default uint8_t grabPermissions : 8; + Qt::CursorShape cursorShape : 6; bool enabled : 1; bool active : 1; bool targetExplicitlySet : 1; bool hadKeepMouseGrab : 1; // some handlers override target()->setKeepMouseGrab(); this remembers previous state bool hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state + bool cursorSet : 1; }; QT_END_NAMESPACE -- cgit v1.2.3