QskDrawer::interactive, gesture handling for closing

This commit is contained in:
Uwe Rathmann 2023-10-17 17:05:57 +02:00
parent 142995504b
commit a791867a3e
2 changed files with 73 additions and 28 deletions

View File

@ -26,6 +26,12 @@ QSK_QT_PRIVATE_END
*/ */
QSK_SUBCONTROL( QskDrawer, Panel ) QSK_SUBCONTROL( QskDrawer, Panel )
static inline qreal qskDefaultDragMargin()
{
// a skin hint ???
return QGuiApplication::styleHints()->startDragDistance();
}
static void qskCatchMouseEvents( QQuickItem* item ) static void qskCatchMouseEvents( QQuickItem* item )
{ {
#if 1 #if 1
@ -196,13 +202,17 @@ namespace
bool isAcceptedPos( const QPointF& pos ) const override bool isAcceptedPos( const QPointF& pos ) const override
{ {
auto drawer = qobject_cast< const QskDrawer* >( targetItem() ); auto drawer = qobject_cast< const QskDrawer* >( targetItem() );
if ( drawer->isFading() )
const auto dragMargin = drawer->dragMargin();
if ( dragMargin <= 0.0 )
return false; return false;
auto rect = qskItemRect( watchedItem() ); auto rect = qskItemRect( watchedItem() );
if ( !drawer->isOpen() )
{
const auto dragMargin = drawer->dragMargin();
if ( dragMargin <= 0.0 )
return false;
switch( drawer->edge() ) switch( drawer->edge() )
{ {
case Qt::LeftEdge: case Qt::LeftEdge:
@ -221,6 +231,7 @@ namespace
rect.setTop( rect.bottom() - dragMargin ); rect.setTop( rect.bottom() - dragMargin );
break; break;
} }
}
return rect.contains( pos ); return rect.contains( pos );
} }
@ -234,8 +245,7 @@ class QskDrawer::PrivateData
GestureRecognizer* gestureRecognizer = nullptr; GestureRecognizer* gestureRecognizer = nullptr;
GeometryListener* listener = nullptr; GeometryListener* listener = nullptr;
// a skin hint ??? qreal dragMargin = qskDefaultDragMargin();
qreal dragMargin = QGuiApplication::styleHints()->startDragDistance();
}; };
QskDrawer::QskDrawer( QQuickItem* parentItem ) QskDrawer::QskDrawer( QQuickItem* parentItem )
@ -247,6 +257,7 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
#endif #endif
setAutoLayoutChildren( true ); setAutoLayoutChildren( true );
setInteractive( true );
setPopupFlag( PopupFlag::CloseOnPressOutside, true ); setPopupFlag( PopupFlag::CloseOnPressOutside, true );
setFaderAspect( Panel | QskAspect::Position | QskAspect::Metric ); setFaderAspect( Panel | QskAspect::Position | QskAspect::Metric );
@ -258,13 +269,7 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
*/ */
setPlacementPolicy( QskPlacementPolicy::Ignore ); setPlacementPolicy( QskPlacementPolicy::Ignore );
if ( parentItem ) if ( parentItem )
{
m_data->listener = new GeometryListener( parentItem, this ); m_data->listener = new GeometryListener( parentItem, this );
qskCatchMouseEvents( parentItem );
}
m_data->gestureRecognizer = new GestureRecognizer( this );
connect( this, &QskPopup::openChanged, this, &QskDrawer::setFading ); connect( this, &QskPopup::openChanged, this, &QskDrawer::setFading );
@ -297,6 +302,32 @@ void QskDrawer::setEdge( Qt::Edge edge )
edgeChanged( edge ); edgeChanged( edge );
} }
void QskDrawer::setInteractive( bool on )
{
if ( on == isInteractive() )
return;
if ( on )
{
m_data->gestureRecognizer = new GestureRecognizer( this );
if ( parentItem() )
qskCatchMouseEvents( parentItem() );
}
else
{
// how to revert qskCatchMouseEvents properly ???
delete m_data->gestureRecognizer;
m_data->gestureRecognizer = nullptr;
}
Q_EMIT interactiveChanged( on );
}
bool QskDrawer::isInteractive() const
{
return m_data->gestureRecognizer != nullptr;
}
void QskDrawer::setDragMargin( qreal margin ) void QskDrawer::setDragMargin( qreal margin )
{ {
margin = std::max( margin, 0.0 ); margin = std::max( margin, 0.0 );
@ -308,6 +339,11 @@ void QskDrawer::setDragMargin( qreal margin )
} }
} }
void QskDrawer::resetDragMargin()
{
setDragMargin( qskDefaultDragMargin() );
}
qreal QskDrawer::dragMargin() const qreal QskDrawer::dragMargin() const
{ {
return m_data->dragMargin; return m_data->dragMargin;
@ -324,8 +360,9 @@ void QskDrawer::gestureEvent( QskGestureEvent* event )
const auto gesture = static_cast< const QskPanGesture* >( event->gesture().get() ); const auto gesture = static_cast< const QskPanGesture* >( event->gesture().get() );
if ( gesture->state() == QskGesture::Finished ) if ( gesture->state() == QskGesture::Finished )
{ {
if ( qskCheckDirection( m_data->edge, gesture ) ) const auto forwards = qskCheckDirection( m_data->edge, gesture );
open(); if ( forwards != isOpen() )
setOpen( forwards );
} }
return; return;
@ -355,7 +392,7 @@ void QskDrawer::itemChange( QQuickItem::ItemChange change,
{ {
case QQuickItem::ItemParentHasChanged: case QQuickItem::ItemParentHasChanged:
{ {
if ( parentItem() ) if ( parentItem() && isInteractive() )
qskCatchMouseEvents( parentItem() ); qskCatchMouseEvents( parentItem() );
Q_FALLTHROUGH(); Q_FALLTHROUGH();

View File

@ -18,7 +18,10 @@ class QSK_EXPORT QskDrawer : public QskPopup
Q_PROPERTY( Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged ) Q_PROPERTY( Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged )
Q_PROPERTY( qreal dragMargin READ dragMargin Q_PROPERTY( qreal dragMargin READ dragMargin
WRITE setDragMargin NOTIFY dragMarginChanged ) WRITE setDragMargin RESET resetDragMargin NOTIFY dragMarginChanged )
Q_PROPERTY( bool interactive READ isInteractive
WRITE setInteractive NOTIFY interactiveChanged )
public: public:
QSK_SUBCONTROLS( Panel ) QSK_SUBCONTROLS( Panel )
@ -29,7 +32,11 @@ class QSK_EXPORT QskDrawer : public QskPopup
void setEdge( Qt::Edge ); void setEdge( Qt::Edge );
Qt::Edge edge() const; Qt::Edge edge() const;
void setInteractive( bool );
bool isInteractive() const;
void setDragMargin( qreal ); void setDragMargin( qreal );
void resetDragMargin();
qreal dragMargin() const; qreal dragMargin() const;
QRectF layoutRectForSize( const QSizeF& ) const override; QRectF layoutRectForSize( const QSizeF& ) const override;
@ -37,6 +44,7 @@ class QSK_EXPORT QskDrawer : public QskPopup
Q_SIGNALS: Q_SIGNALS:
void edgeChanged( Qt::Edge ); void edgeChanged( Qt::Edge );
void dragMarginChanged( qreal ); void dragMarginChanged( qreal );
void interactiveChanged( bool );
protected: protected:
void itemChange( ItemChange, const ItemChangeData& ) override; void itemChange( ItemChange, const ItemChangeData& ) override;