From bf2c2b981e3a6ea1187826645da4fab75723222c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 10 Aug 2023 19:54:06 +0200 Subject: [PATCH] QskSwipeView improvements --- examples/layouts/SwipeViewPage.cpp | 1 + src/controls/QskSwipeView.cpp | 70 ++++++++++++++++++++++++------ src/controls/QskSwipeView.h | 30 ++++++++++++- 3 files changed, 87 insertions(+), 14 deletions(-) diff --git a/examples/layouts/SwipeViewPage.cpp b/examples/layouts/SwipeViewPage.cpp index 012e1951..9ce05c65 100644 --- a/examples/layouts/SwipeViewPage.cpp +++ b/examples/layouts/SwipeViewPage.cpp @@ -23,6 +23,7 @@ class SwipeView : public QskSwipeView setBackgroundColor( Qt::white ); setDefaultAlignment( Qt::AlignCenter ); + setOrientation( Qt::Horizontal ); addRectangle( "Gold" ); addRectangle( "SeaGreen" ); diff --git a/src/controls/QskSwipeView.cpp b/src/controls/QskSwipeView.cpp index 3994c6c7..8e712a16 100644 --- a/src/controls/QskSwipeView.cpp +++ b/src/controls/QskSwipeView.cpp @@ -9,6 +9,7 @@ #include "QskGesture.h" #include "QskPanGestureRecognizer.h" #include "QskStackBoxAnimator.h" +#include "QskPlatform.h" class QskSwipeView::PrivateData { @@ -30,11 +31,11 @@ QskSwipeView::QskSwipeView( QQuickItem* parent ) recognizer.setWatchedItem( this ); - // should be skin hints + // should be skin hints, TODO recognizer.setOrientations( Qt::Horizontal ); - recognizer.setMinDistance( 50 ); recognizer.setTimeout( 100 ); + resetSwipeDistance(); resetDuration(); } @@ -42,13 +43,38 @@ QskSwipeView::~QskSwipeView() { } -QskAspect::Subcontrol QskSwipeView::effectiveSubcontrol( - QskAspect::Subcontrol subControl ) const +void QskSwipeView::setOrientation( Qt::Orientation orientation ) { - if ( subControl == QskBox::Panel ) - return QskSwipeView::Panel; + if ( orientation != this->orientation() ) + { + m_data->panRecognizer.setOrientations( orientation ); + Q_EMIT orientationChanged( orientation ); + } +} - return Inherited::effectiveSubcontrol( subControl ); +Qt::Orientation QskSwipeView::orientation() const +{ + return ( m_data->panRecognizer.orientations() == Qt::Vertical ) + ? Qt::Vertical : Qt::Horizontal; +} + +int QskSwipeView::swipeDistance() const +{ + return m_data->panRecognizer.minDistance(); +} + +void QskSwipeView::setSwipeDistance( int distance ) +{ + const auto oldDistance = m_data->panRecognizer.minDistance(); + m_data->panRecognizer.setMinDistance( distance ); + + if ( oldDistance != m_data->panRecognizer.minDistance() ) + Q_EMIT swipeDistanceChanged( m_data->panRecognizer.minDistance() ); +} + +void QskSwipeView::resetSwipeDistance() +{ + setSwipeDistance( qRound( qskDpToPixels( 40 ) ) ); } int QskSwipeView::duration() const @@ -58,12 +84,16 @@ int QskSwipeView::duration() const void QskSwipeView::setDuration( int duration ) { - m_data->duration = duration; + if ( duration != m_data->duration ) + { + m_data->duration = duration; + Q_EMIT durationChanged( duration ); + } } void QskSwipeView::resetDuration() { - m_data->duration = 500; + setDuration( 500 ); } bool QskSwipeView::gestureFilter( const QQuickItem* item, const QEvent* event ) @@ -94,16 +124,20 @@ void QskSwipeView::gestureEvent( QskGestureEvent* event ) if ( animator == nullptr ) { animator = new QskStackBoxAnimator1( this ); - animator->setOrientation( Qt::Horizontal ); + animator->setOrientation( orientation() ); } animator->setDuration( m_data->duration ); QskStackBox::setAnimator( animator ); - const auto direction = ( ( gesture->angle() < 90.0 ) || ( gesture->angle() > 270.0 ) ) - ? Qsk::LeftToRight : Qsk::RightToLeft; + bool forwards; - auto newIndex = ( direction == Qsk::LeftToRight ) ? currentIndex() - 1 : currentIndex() + 1; + if ( orientation() == Qt::Horizontal ) + forwards = gesture->angle() >= 90.0 && gesture->angle() <= 270.0; + else + forwards = gesture->angle() >= 180.0; + + auto newIndex = forwards ? currentIndex() + 1 : currentIndex() - 1; if( newIndex < 0 ) newIndex += itemCount(); @@ -117,4 +151,14 @@ void QskSwipeView::gestureEvent( QskGestureEvent* event ) Inherited::gestureEvent( event ); } +QskAspect::Subcontrol QskSwipeView::effectiveSubcontrol( + QskAspect::Subcontrol subControl ) const +{ + if ( subControl == QskBox::Panel ) + return QskSwipeView::Panel; + + return Inherited::effectiveSubcontrol( subControl ); +} + + #include "moc_QskSwipeView.cpp" diff --git a/src/controls/QskSwipeView.h b/src/controls/QskSwipeView.h index bebb976d..868a6d4b 100644 --- a/src/controls/QskSwipeView.h +++ b/src/controls/QskSwipeView.h @@ -12,7 +12,14 @@ class QSK_EXPORT QskSwipeView : public QskStackBox { Q_OBJECT - Q_PROPERTY( int duration READ duration WRITE setDuration RESET resetDuration ) + Q_PROPERTY( int duration READ duration + WRITE setDuration RESET resetDuration NOTIFY durationChanged ) + + Q_PROPERTY( int swipeDistance READ swipeDistance + WRITE setSwipeDistance RESET resetSwipeDistance NOTIFY swipeDistanceChanged ) + + Q_PROPERTY( Qt::Orientation orientation READ orientation + WRITE setOrientation NOTIFY orientationChanged ) using Inherited = QskStackBox; @@ -22,12 +29,33 @@ class QSK_EXPORT QskSwipeView : public QskStackBox QskSwipeView( QQuickItem* parent = nullptr ); ~QskSwipeView() override; + void setOrientation( Qt::Orientation ); + Qt::Orientation orientation() const; + + // Duration is the time ( in ms ) used for changing between pages + int duration() const; void setDuration( int ); void resetDuration(); + /* + Even if called "swipe view" we use a pan - no swipe - gesture. + ( = pages are moved before the gesture has been confirmed ) + + The swipe distance is the minimum distance in pixels of the pan gesture + */ + + int swipeDistance() const; + void setSwipeDistance( int ); + void resetSwipeDistance(); + QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol ) const; + Q_SIGNALS: + void orientationChanged( Qt::Orientation ); + void durationChanged( int ); + void swipeDistanceChanged( int ); + protected: bool gestureFilter( const QQuickItem*, const QEvent* ) override; void gestureEvent( QskGestureEvent* ) override;