QskGestureFilterEvent introduced to allow adding gestures to foreign

controls using event filtering ( f.e QskDrawer needs this )
This commit is contained in:
Uwe Rathmann 2023-08-10 13:38:21 +02:00
parent c8316906d2
commit ac4f190733
5 changed files with 109 additions and 49 deletions

View File

@ -31,6 +31,20 @@ static inline void qskSendEventTo( QObject* object, QEvent::Type type )
QCoreApplication::sendEvent( object, &event ); 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 ) QskControl::QskControl( QQuickItem* parent )
: QskQuickItem( *( new QskControlPrivate() ), parent ) : QskQuickItem( *( new QskControlPrivate() ), parent )
{ {
@ -791,6 +805,33 @@ bool QskControl::event( QEvent* event )
break; 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: case QskEvent::Gesture:
{ {
gestureEvent( static_cast< QskGestureEvent* >( event ) ); 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 true;
return Inherited::event( event ); 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* ) bool QskControl::gestureFilter( const QQuickItem*, const QEvent* )

View File

@ -8,6 +8,7 @@
#include "QskLayoutMetrics.h" #include "QskLayoutMetrics.h"
#include "QskObjectTree.h" #include "QskObjectTree.h"
#include "QskWindow.h" #include "QskWindow.h"
#include "QskEvent.h"
static inline void qskSendEventTo( QObject* object, QEvent::Type type ) 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 ); 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& ); extern bool qskInheritLocale( QskWindow*, const QLocale& );
namespace namespace
@ -309,41 +301,6 @@ QSizeF QskControlPrivate::explicitSizeHint( Qt::SizeHint whichHint ) const
return QSizeF(); 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 ) bool QskControlPrivate::inheritLocale( QskControl* control, const QLocale& locale )
{ {
auto d = static_cast< QskControlPrivate* >( QQuickItemPrivate::get( control ) ); auto d = static_cast< QskControlPrivate* >( QQuickItemPrivate::get( control ) );

View File

@ -36,8 +36,6 @@ class QskControlPrivate : public QskQuickItemPrivate
void implicitSizeChanged() override final; void implicitSizeChanged() override final;
void layoutConstraintChanged() override final; void layoutConstraintChanged() override final;
bool maybeGesture( const QQuickItem*, const QEvent* );
QskPlacementPolicy::Policy placementPolicy( bool visible ) const noexcept; QskPlacementPolicy::Policy placementPolicy( bool visible ) const noexcept;
void setPlacementPolicy( bool visible, QskPlacementPolicy::Policy ); void setPlacementPolicy( bool visible, QskPlacementPolicy::Policy );

View File

@ -154,6 +154,28 @@ bool qskIsButtonPressKey( const QKeyEvent* event )
#endif #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 ) QskEvent::QskEvent( QskEvent::Type type )
: QEvent( static_cast< QEvent::Type >( type ) ) : QEvent( static_cast< QEvent::Type >( type ) )
{ {
@ -249,3 +271,19 @@ QskAnimatorEvent* QskAnimatorEvent::clone() const
{ {
return new QskAnimatorEvent( *this ); 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 );
}

View File

@ -47,6 +47,7 @@ class QSK_EXPORT QskEvent : public QEvent
PopupRemoved, PopupRemoved,
Gesture, Gesture,
GestureFilter,
Animator, Animator,
@ -118,6 +119,29 @@ class QSK_EXPORT QskPopupEvent : public QskEvent
QskPopup* m_popup; 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 class QSK_EXPORT QskGestureEvent : public QskEvent
{ {
public: public:
@ -178,4 +202,6 @@ QSK_EXPORT qreal qskWheelIncrement( const QWheelEvent* );
QSK_EXPORT bool qskIsStandardKeyInput( const QKeyEvent*, QKeySequence::StandardKey ); QSK_EXPORT bool qskIsStandardKeyInput( const QKeyEvent*, QKeySequence::StandardKey );
QSK_EXPORT bool qskIsButtonPressKey( const QKeyEvent* ); QSK_EXPORT bool qskIsButtonPressKey( const QKeyEvent* );
QSK_EXPORT bool qskIsTouchOrMouseEvent( QEvent::Type );
#endif #endif