wheel event handling improved
This commit is contained in:
parent
911847da11
commit
e67cccc088
@ -6,6 +6,7 @@
|
||||
#include "QskBoundedInput.h"
|
||||
#include "QskFunctions.h"
|
||||
#include "QskIntervalF.h"
|
||||
#include "QskEvent.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -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
|
||||
|
@ -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 ) )
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
{
|
||||
|
@ -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 ) )
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user