diff --git a/src/controls/QskBoundedInput.cpp b/src/controls/QskBoundedInput.cpp index 2269c3a2..b55ec4dd 100644 --- a/src/controls/QskBoundedInput.cpp +++ b/src/controls/QskBoundedInput.cpp @@ -6,6 +6,7 @@ #include "QskBoundedInput.h" #include "QskFunctions.h" #include "QskIntervalF.h" +#include "QskEvent.h" #include @@ -200,19 +201,13 @@ void QskBoundedInput::keyPressEvent( QKeyEvent* event ) void QskBoundedInput::wheelEvent( QWheelEvent* event ) { - if ( isReadOnly() ) + if ( !isReadOnly() ) + { + increment( qskWheelSteps( event ) * m_stepSize ); return; + } -#if QT_VERSION < 0x050e00 - const int wheelDelta = event->delta(); -#else - const auto delta = event->angleDelta(); - const int wheelDelta = ( qAbs( delta.x() ) > qAbs( delta.y() ) ) - ? delta.x() : delta.y(); -#endif - - const int steps = wheelDelta / QWheelEvent::DefaultDeltasPerStep; - increment( steps * m_stepSize ); + Inherited::wheelEvent( event ); } #endif diff --git a/src/controls/QskEvent.cpp b/src/controls/QskEvent.cpp index 22ae0a56..347c3967 100644 --- a/src/controls/QskEvent.cpp +++ b/src/controls/QskEvent.cpp @@ -63,6 +63,17 @@ QPointF qskMouseScenePosition( const QMouseEvent* event ) #endif } +QPointF qskHoverPosition( const QHoverEvent* event ) +{ +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) + return event->position(); +#else + return event->posF(); +#endif +} + +#ifndef QT_NO_WHEELEVENT + QPointF qskWheelPosition( const QWheelEvent* event ) { #if QT_VERSION >= QT_VERSION_CHECK( 5, 14, 0 ) @@ -72,15 +83,60 @@ QPointF qskWheelPosition( const QWheelEvent* event ) #endif } -QPointF qskHoverPosition( const QHoverEvent* event ) -{ -#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) - return event->position(); -#else - return event->posF(); #endif + +#ifndef QT_NO_WHEELEVENT + +qreal qskWheelSteps( const QWheelEvent* event, int orientation ) +{ + qreal delta = 0.0; + + // what about event->pixelDelta() + auto aDelta = event->angleDelta(); + +#if QT_VERSION >= QT_VERSION_CHECK( 5, 7, 0 ) + if ( event->inverted() ) + aDelta.setY( -aDelta.y() ); +#endif + + switch( orientation ) + { + case Qt::Horizontal: + delta = aDelta.x(); + break; + + case Qt::Vertical: + delta = aDelta.y(); + break; + + default: + delta = aDelta.y() ? aDelta.y() : aDelta.x(); + } + + return delta / QWheelEvent::DefaultDeltasPerStep; } +#endif + +#ifndef QT_NO_WHEELEVENT + +QPointF qskScrollIncrement( const QWheelEvent* event ) +{ + QPointF increment = event->pixelDelta(); + + if ( increment.isNull() ) + { + increment = event->angleDelta() / QWheelEvent::DefaultDeltasPerStep; + + constexpr qreal stepSize = 20.0; // how to find this value ??? + increment *= stepSize; + } + + return increment; +} + +#endif + QskEvent::QskEvent( QskEvent::Type type ) : QEvent( static_cast< QEvent::Type >( type ) ) { diff --git a/src/controls/QskEvent.h b/src/controls/QskEvent.h index 721953fe..2ebe81be 100644 --- a/src/controls/QskEvent.h +++ b/src/controls/QskEvent.h @@ -138,7 +138,16 @@ QSK_EXPORT int qskFocusChainIncrement( const QEvent* ); // some helper to work around Qt version incompatibilities QSK_EXPORT QPointF qskMouseScenePosition( const QMouseEvent* ); QSK_EXPORT QPointF qskMousePosition( const QMouseEvent* ); -QSK_EXPORT QPointF qskWheelPosition( const QWheelEvent* ); QSK_EXPORT QPointF qskHoverPosition( const QHoverEvent* ); +#ifndef QT_NO_WHEELEVENT + +QSK_EXPORT QPointF qskWheelPosition( const QWheelEvent* ); +QSK_EXPORT qreal qskWheelSteps( + const QWheelEvent*, int orientation = 0 ); + +QSK_EXPORT QPointF qskScrollIncrement( const QWheelEvent* ); + +#endif + #endif diff --git a/src/controls/QskInputGrabber.cpp b/src/controls/QskInputGrabber.cpp index e85d8922..f5d5d224 100644 --- a/src/controls/QskInputGrabber.cpp +++ b/src/controls/QskInputGrabber.cpp @@ -156,12 +156,14 @@ bool QskInputGrabber::event( QEvent* event ) doBlock = isBlocking( qskMousePosition( mouseEvent ) ); break; } +#ifndef QT_NO_WHEELEVENT case QEvent::Wheel: { const auto wheelEvent = static_cast< QWheelEvent* >( event ); doBlock = isBlocking( qskWheelPosition( wheelEvent ) ); break; } +#endif case QEvent::HoverEnter: case QEvent::HoverLeave: { diff --git a/src/controls/QskMenu.cpp b/src/controls/QskMenu.cpp index 7dc0feb2..eeb75849 100644 --- a/src/controls/QskMenu.cpp +++ b/src/controls/QskMenu.cpp @@ -233,18 +233,16 @@ void QskMenu::keyReleaseEvent( QKeyEvent* ) } } +#ifndef QT_NO_WHEELEVENT + void QskMenu::wheelEvent( QWheelEvent* event ) { -#if QT_VERSION < 0x050e00 - const int delta = event->delta(); -#else - const int delta = event->angleDelta().y(); -#endif - - // we ignore the step count and use its direction only - traverse( delta < 0 ? 1 : -1 ); + const auto steps = qskWheelSteps( event ); + traverse( -steps ); } +#endif + void QskMenu::traverse( int steps ) { if ( count() == 0 || ( steps % count() == 0 ) ) diff --git a/src/controls/QskMenu.h b/src/controls/QskMenu.h index fcacc858..b9dbf598 100644 --- a/src/controls/QskMenu.h +++ b/src/controls/QskMenu.h @@ -83,7 +83,10 @@ class QSK_EXPORT QskMenu : public QskPopup protected: void keyPressEvent( QKeyEvent* ) override; void keyReleaseEvent( QKeyEvent* ) override; + +#ifndef QT_NO_WHEELEVENT void wheelEvent( QWheelEvent* ) override; +#endif void mousePressEvent( QMouseEvent* ) override; void mouseReleaseEvent( QMouseEvent* ) override; diff --git a/src/controls/QskPageIndicator.cpp b/src/controls/QskPageIndicator.cpp index 2e377615..3b9a8071 100644 --- a/src/controls/QskPageIndicator.cpp +++ b/src/controls/QskPageIndicator.cpp @@ -12,18 +12,6 @@ QSK_SUBCONTROL( QskPageIndicator, Bullet ) QSK_SYSTEM_STATE( QskPageIndicator, Selected, QskAspect::FirstSystemState << 1 ) -static void qskSetMouseAccepted( QskPageIndicator* indicator, bool on ) -{ - auto buttons = indicator->acceptedMouseButtons(); - - if ( on ) - buttons |= Qt::LeftButton; - else - buttons &= ~Qt::LeftButton; - - indicator->setAcceptedMouseButtons( buttons ); -} - static int qskKeyIncrement( const QskPageIndicator* indicator, const QKeyEvent* event ) { @@ -63,7 +51,6 @@ class QskPageIndicator::PrivateData public: PrivateData( int count ) : count( count ) - , interactive( false ) , orientation( Qt::Horizontal ) { } @@ -72,8 +59,6 @@ class QskPageIndicator::PrivateData int pressedIndex = -1; int count; - - bool interactive : 1; Qt::Orientation orientation : 2; }; @@ -122,29 +107,6 @@ void QskPageIndicator::setOrientation( Qt::Orientation orientation ) } } -bool QskPageIndicator::isInteractive() const -{ - return m_data->interactive; -} - -void QskPageIndicator::setInteractive( bool on ) -{ - if ( on == m_data->interactive ) - return; - - m_data->interactive = on; - - qskSetMouseAccepted( this, on ); - setWheelEnabled( on ); - setFocusPolicy( on ? Qt::StrongFocus : Qt::NoFocus ); - - // being interactive might have an impact on its representation - resetImplicitSize(); - update(); - - Q_EMIT interactiveChanged( on ); -} - void QskPageIndicator::setCount( int count ) { if ( count != m_data->count ) @@ -209,6 +171,13 @@ void QskPageIndicator::mousePressEvent( QMouseEvent* event ) { if ( event->button() == Qt::LeftButton ) { + /* + The bullets are usually small and therefore hard to click - with + touch input almost impossible. It might be better to + increment in direction of the mouse position ? + + A swipe gesture might make more sense, TODO ... + */ const auto pos = qskMousePosition( event ); m_data->pressedIndex = indexAtPosition( pos ); @@ -218,6 +187,11 @@ void QskPageIndicator::mousePressEvent( QMouseEvent* event ) return Inherited::mousePressEvent( event ); } +void QskPageIndicator::mouseUngrabEvent() +{ + m_data->pressedIndex = -1; +} + void QskPageIndicator::mouseReleaseEvent( QMouseEvent* event ) { if ( event->button() == Qt::LeftButton ) @@ -242,40 +216,41 @@ void QskPageIndicator::keyPressEvent( QKeyEvent* event ) { if ( const int increment = qskKeyIncrement( this, event ) ) { - if ( const auto n = m_data->count ) - { - int index = m_data->currentIndex; - if ( index < 0 && increment < 0 ) - index = n; - - // do we need an cycling on/off attribute, TODO ... - - index = ( index + increment ) % n; - if ( index < 0 ) - index += n; - - Q_EMIT pageRequested( index ); - } - + incrementRequested( increment ); return; } Inherited::keyPressEvent( event ); } +#ifndef QT_NO_WHEELEVENT + void QskPageIndicator::wheelEvent( QWheelEvent* event ) { -#if QT_VERSION < 0x050e00 - const int delta = event->delta(); -#else - const auto angleDelta = event->angleDelta(); + incrementRequested( qskWheelSteps( event ) ); +} - const int delta = ( orientation() == Qt::Horizontal ) - ? angleDelta.x() : angleDelta.y(); #endif - Q_UNUSED( delta ) - // TODO ... +void QskPageIndicator::incrementRequested( int offset ) +{ + const auto n = m_data->count; + + if ( offset == 0 || n == 0 ) + return; + + int index = m_data->currentIndex; + if ( index < 0 && offset < 0 ) + index = n; + + // do we need a cycling on/off attribute, TODO ... + + index = ( index + offset ) % n; + if ( index < 0 ) + index += n; + + if ( index != m_data->currentIndex ) + Q_EMIT pageRequested( index ); } #include "moc_QskPageIndicator.cpp" diff --git a/src/controls/QskPageIndicator.h b/src/controls/QskPageIndicator.h index 85dc7f4a..f6266625 100644 --- a/src/controls/QskPageIndicator.h +++ b/src/controls/QskPageIndicator.h @@ -18,9 +18,6 @@ class QSK_EXPORT QskPageIndicator : public QskControl Q_PROPERTY( qreal currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL ) - Q_PROPERTY( bool interactive READ isInteractive - WRITE setInteractive NOTIFY interactiveChanged FINAL ) - Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL ) @@ -63,12 +60,18 @@ class QSK_EXPORT QskPageIndicator : public QskControl protected: void mousePressEvent( QMouseEvent* e ) override; + void mouseUngrabEvent() override; void mouseReleaseEvent( QMouseEvent* e ) override; void keyPressEvent( QKeyEvent* ) override; + +#ifndef QT_NO_WHEELEVENT void wheelEvent( QWheelEvent* ) override; +#endif private: + void incrementRequested( int ); + class PrivateData; std::unique_ptr< PrivateData > m_data; }; diff --git a/src/controls/QskScrollBox.cpp b/src/controls/QskScrollBox.cpp index 1c3901d2..67df2be4 100644 --- a/src/controls/QskScrollBox.cpp +++ b/src/controls/QskScrollBox.cpp @@ -400,40 +400,14 @@ void QskScrollBox::gestureEvent( QskGestureEvent* event ) #ifndef QT_NO_WHEELEVENT -QPointF QskScrollBox::scrollOffset( const QWheelEvent* event ) const -{ -#if QT_VERSION < 0x050e00 - const auto pos = event->posF(); -#else - const auto pos = event->position(); -#endif - if ( viewContentsRect().contains( pos ) ) - { - /* - Not sure if that code makes sense, but I don't have an input device - that generates wheel events in both directions. TODO ... - */ - return event->angleDelta(); - } - - return QPointF(); -} - void QskScrollBox::wheelEvent( QWheelEvent* event ) { - QPointF offset = scrollOffset( event ); - - if ( !offset.isNull() ) + const auto pos = qskWheelPosition( event ); + if ( viewContentsRect().contains( pos ) ) { - constexpr qreal stepSize = 20.0; // how to find this value - offset *= stepSize / QWheelEvent::DefaultDeltasPerStep; - -#if QT_VERSION >= QT_VERSION_CHECK( 5, 7, 0 ) - if ( event->inverted() ) - offset = -offset; -#endif - - setScrollPos( m_data->scrollPos - offset ); + const auto offset = qskScrollIncrement( event ); + if ( !offset.isNull() ) + setScrollPos( m_data->scrollPos - offset ); } } diff --git a/src/controls/QskScrollBox.h b/src/controls/QskScrollBox.h index 73fd0a64..01b878a8 100644 --- a/src/controls/QskScrollBox.h +++ b/src/controls/QskScrollBox.h @@ -68,7 +68,6 @@ class QSK_EXPORT QskScrollBox : public QskControl #ifndef QT_NO_WHEELEVENT void wheelEvent( QWheelEvent* ) override; - virtual QPointF scrollOffset( const QWheelEvent* ) const; #endif bool gestureFilter( QQuickItem*, QEvent* ) override; diff --git a/src/controls/QskScrollView.cpp b/src/controls/QskScrollView.cpp index 1363ad1f..392a42f4 100644 --- a/src/controls/QskScrollView.cpp +++ b/src/controls/QskScrollView.cpp @@ -209,34 +209,40 @@ void QskScrollView::mouseReleaseEvent( QMouseEvent* event ) #ifndef QT_NO_WHEELEVENT -QPointF QskScrollView::scrollOffset( const QWheelEvent* event ) const +void QskScrollView::wheelEvent( QWheelEvent* event ) { QPointF offset; - const auto wheelPos = qskWheelPosition( event ); + const auto pos = qskWheelPosition( event ); -#if QT_VERSION < QT_VERSION_CHECK( 5, 14, 0 ) - const auto wheelDelta = event->delta(); -#else - const QPoint delta = event->angleDelta(); - const int wheelDelta = ( qAbs( delta.x() ) > qAbs( delta.y() ) ) - ? delta.x() : delta.y(); + if ( subControlRect( VerticalScrollBar ).contains( pos ) ) + { + const auto increment = qskScrollIncrement( event ); + offset.setY( increment.y() ); + } + else if ( subControlRect( HorizontalScrollBar ).contains( pos ) ) + { + const auto increment = qskScrollIncrement( event ); + + qreal dx = increment.x(); + if ( dx == 0 ) + { + dx = increment.y(); + +#if QT_VERSION >= QT_VERSION_CHECK( 5, 7, 0 ) + if ( event->inverted() ) + dx = -dx; #endif - - if ( subControlRect( VerticalScrollBar ).contains( wheelPos ) ) - { - offset.setY( wheelDelta ); + } + offset.setX( dx ); } - else if ( subControlRect( HorizontalScrollBar ).contains( wheelPos ) ) + else if ( viewContentsRect().contains( pos ) ) { - offset.setX( wheelDelta ); - } - else - { - offset = Inherited::scrollOffset( event ); + offset = qskScrollIncrement( event ); } - return offset; + if ( !offset.isNull() ) + setScrollPos( scrollPos() - offset ); } #endif diff --git a/src/controls/QskScrollView.h b/src/controls/QskScrollView.h index 551a6db7..05d32495 100644 --- a/src/controls/QskScrollView.h +++ b/src/controls/QskScrollView.h @@ -53,7 +53,7 @@ class QSK_EXPORT QskScrollView : public QskScrollBox void mouseReleaseEvent( QMouseEvent* ) override; #ifndef QT_NO_WHEELEVENT - QPointF scrollOffset( const QWheelEvent* ) const override; + void wheelEvent( QWheelEvent* ) override; #endif private: