diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index 0ea473d0..7aa7b64c 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -31,6 +31,20 @@ static inline void qskSendEventTo( QObject* object, QEvent::Type type ) QCoreApplication::sendEvent( object, &event ); } +static inline bool qskMaybeGesture( QQuickItem* item, + const QQuickItem* child, const QEvent* event ) +{ + if ( qskIsTouchOrMouseEvent( event->type() ) ) + { + QskGestureFilterEvent ev( child, event ); + QCoreApplication::sendEvent( item, &ev ); + + return ev.maybeGesture(); + } + + return false; +} + QskControl::QskControl( QQuickItem* parent ) : QskQuickItem( *( new QskControlPrivate() ), parent ) { @@ -791,6 +805,33 @@ bool QskControl::event( QEvent* event ) break; } + case QskEvent::GestureFilter: + { + /* + qskMaybeGesture is sending an event, so that it can be manipulated + by event filters. F.e QskDrawer wants to add a gesture to + some other control to initiate its appearance. + */ + + auto ev = static_cast< QskGestureFilterEvent* >( event ); + + if ( ev->event()->type() == QEvent::MouseButtonPress ) + { + auto mouseEvent = static_cast< const QMouseEvent* >( ev->event() ); + const auto pos = + mapFromItem( ev->item(), qskMousePosition( mouseEvent ) ); + + if ( !gestureRect().contains( pos ) ) + { + ev->setMaybeGesture( false ); + break; + } + } + + ev->setMaybeGesture( gestureFilter( ev->item(), ev->event() ) ); + + break; + } case QskEvent::Gesture: { gestureEvent( static_cast< QskGestureEvent* >( event ) ); @@ -798,15 +839,15 @@ bool QskControl::event( QEvent* event ) } } - if ( d_func()->maybeGesture( this, event ) ) + if ( qskMaybeGesture( this, this, event ) ) return true; return Inherited::event( event ); } -bool QskControl::childMouseEventFilter( QQuickItem* item, QEvent* event ) +bool QskControl::childMouseEventFilter( QQuickItem* child, QEvent* event ) { - return d_func()->maybeGesture( item, event ); + return qskMaybeGesture( this, child, event ); } bool QskControl::gestureFilter( const QQuickItem*, const QEvent* ) diff --git a/src/controls/QskControlPrivate.cpp b/src/controls/QskControlPrivate.cpp index 88e4747d..84cc755f 100644 --- a/src/controls/QskControlPrivate.cpp +++ b/src/controls/QskControlPrivate.cpp @@ -8,6 +8,7 @@ #include "QskLayoutMetrics.h" #include "QskObjectTree.h" #include "QskWindow.h" +#include "QskEvent.h" static inline void qskSendEventTo( QObject* object, QEvent::Type type ) { @@ -15,15 +16,6 @@ static inline void qskSendEventTo( QObject* object, QEvent::Type type ) QCoreApplication::sendEvent( object, &event ); } -static inline QPointF qskScenePosition( const QMouseEvent* event ) -{ -#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) - return event->scenePosition(); -#else - return event->windowPos(); -#endif -} - extern bool qskInheritLocale( QskWindow*, const QLocale& ); namespace @@ -309,41 +301,6 @@ QSizeF QskControlPrivate::explicitSizeHint( Qt::SizeHint whichHint ) const return QSizeF(); } -bool QskControlPrivate::maybeGesture( const QQuickItem* child, const QEvent* event ) -{ - Q_Q( QskControl ); - - switch ( event->type() ) - { - case QEvent::MouseButtonPress: - { - const auto mouseEvent = static_cast< const QMouseEvent* >( event ); - - auto pos = qskScenePosition( mouseEvent ); - pos = q->mapFromScene( pos ); - - if ( !q->gestureRect().contains( pos ) ) - return false; - - break; - } - - case QEvent::MouseMove: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::UngrabMouse: - case QEvent::TouchBegin: - case QEvent::TouchCancel: - case QEvent::TouchUpdate: - break; - - default: - return false; - } - - return q->gestureFilter( child, event ); -} - bool QskControlPrivate::inheritLocale( QskControl* control, const QLocale& locale ) { auto d = static_cast< QskControlPrivate* >( QQuickItemPrivate::get( control ) ); diff --git a/src/controls/QskControlPrivate.h b/src/controls/QskControlPrivate.h index 06815304..9a9dd09a 100644 --- a/src/controls/QskControlPrivate.h +++ b/src/controls/QskControlPrivate.h @@ -36,8 +36,6 @@ class QskControlPrivate : public QskQuickItemPrivate void implicitSizeChanged() override final; void layoutConstraintChanged() override final; - bool maybeGesture( const QQuickItem*, const QEvent* ); - QskPlacementPolicy::Policy placementPolicy( bool visible ) const noexcept; void setPlacementPolicy( bool visible, QskPlacementPolicy::Policy ); diff --git a/src/controls/QskEvent.cpp b/src/controls/QskEvent.cpp index e430e8b1..b3aeae87 100644 --- a/src/controls/QskEvent.cpp +++ b/src/controls/QskEvent.cpp @@ -154,6 +154,28 @@ bool qskIsButtonPressKey( const QKeyEvent* event ) #endif } +bool qskIsTouchOrMouseEvent( QEvent::Type type ) +{ + switch ( type ) + { + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::UngrabMouse: + + case QEvent::TouchBegin: + case QEvent::TouchCancel: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + + return true; + + default: + return false; + } +} + QskEvent::QskEvent( QskEvent::Type type ) : QEvent( static_cast< QEvent::Type >( type ) ) { @@ -249,3 +271,19 @@ QskAnimatorEvent* QskAnimatorEvent::clone() const { return new QskAnimatorEvent( *this ); } + +// -- QskGestureFilterEvent + +QskGestureFilterEvent::QskGestureFilterEvent( + const QQuickItem* item, const QEvent* event ) + : QskEvent( QskEvent::GestureFilter ) + , m_item( item ) + , m_event( event ) + , m_maybeGesture( false ) +{ +} + +QskGestureFilterEvent* QskGestureFilterEvent::clone() const +{ + return new QskGestureFilterEvent( *this ); +} diff --git a/src/controls/QskEvent.h b/src/controls/QskEvent.h index 3ba04c09..094090e9 100644 --- a/src/controls/QskEvent.h +++ b/src/controls/QskEvent.h @@ -47,6 +47,7 @@ class QSK_EXPORT QskEvent : public QEvent PopupRemoved, Gesture, + GestureFilter, Animator, @@ -118,6 +119,29 @@ class QSK_EXPORT QskPopupEvent : public QskEvent QskPopup* m_popup; }; +class QSK_EXPORT QskGestureFilterEvent : public QskEvent +{ + public: + QskGestureFilterEvent( const QQuickItem*, const QEvent* ); + + inline const QQuickItem* item() const { return m_item; } + inline const QEvent* event() const { return m_event; } + + inline void setMaybeGesture( bool on ) { m_maybeGesture = on; } + inline bool maybeGesture() const { return m_maybeGesture; } + + QskGestureFilterEvent* clone() const override; + + protected: + QSK_EVENT_DISABLE_COPY( QskGestureFilterEvent ) + + private: + const QQuickItem* m_item; + const QEvent* m_event; + + bool m_maybeGesture; +}; + class QSK_EXPORT QskGestureEvent : public QskEvent { public: @@ -178,4 +202,6 @@ QSK_EXPORT qreal qskWheelIncrement( const QWheelEvent* ); QSK_EXPORT bool qskIsStandardKeyInput( const QKeyEvent*, QKeySequence::StandardKey ); QSK_EXPORT bool qskIsButtonPressKey( const QKeyEvent* ); +QSK_EXPORT bool qskIsTouchOrMouseEvent( QEvent::Type ); + #endif