wheel scrolling improved

This commit is contained in:
Uwe Rathmann 2022-01-12 13:29:42 +01:00
parent e310c3c9bb
commit acbb5d1c0b
4 changed files with 85 additions and 21 deletions

View File

@ -6,6 +6,14 @@
#include "QskListView.h"
#include "QskAspect.h"
#include "QskColorFilter.h"
#include "QskEvent.h"
#if QT_VERSION >= QT_VERSION_CHECK( 5, 9, 0 )
#include <qguiapplication.h>
#include <qstylehints.h>
#endif
#include <qmath.h>
QSK_SUBCONTROL( QskListView, Cell )
QSK_SUBCONTROL( QskListView, Text )
@ -263,6 +271,58 @@ void QskListView::mouseReleaseEvent( QMouseEvent* event )
Inherited::mouseReleaseEvent( event );
}
#ifndef QT_NO_WHEELEVENT
QPointF QskListView::scrollOffset( const QWheelEvent* event ) const
{
QPointF offset;
const auto pos = qskWheelPosition( event );
if ( subControlRect( VerticalScrollBar ).contains( pos ) )
{
const auto steps = qskWheelSteps( event );
offset.setY( steps );
}
else if ( subControlRect( HorizontalScrollBar ).contains( pos ) )
{
const auto steps = qskWheelSteps( event );
offset.setX( steps );
}
else if ( viewContentsRect().contains( pos ) )
{
offset = event->angleDelta() / QWheelEvent::DefaultDeltasPerStep;
}
if ( offset.x() != 0.0 )
{
offset.rx() *= viewContentsRect().width(); // pagewise
}
else if ( offset.y() != 0.0 )
{
const auto viewHeight = viewContentsRect().height();
const qreal rowHeight = this->rowHeight();
int numLines = 3;
#if QT_VERSION >= QT_VERSION_CHECK( 5, 9, 0 )
numLines = QGuiApplication::styleHints()->wheelScrollLines();
#endif
qreal dy = numLines * rowHeight;
if ( event->modifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ) )
dy = qMax( dy, viewHeight );
// we should align to row boundaries. TODO ...
offset.setY( offset.y() * dy );
}
// using the animated scrollTo instead ?
return offset;
}
#endif
void QskListView::updateScrollableSize()
{
const double h = rowCount() * rowHeight();

View File

@ -89,6 +89,10 @@ class QSK_EXPORT QskListView : public QskScrollView
void mousePressEvent( QMouseEvent* ) override;
void mouseReleaseEvent( QMouseEvent* ) override;
#ifndef QT_NO_WHEELEVENT
virtual QPointF scrollOffset( const QWheelEvent* ) const override;
#endif
void updateScrollableSize();
void componentComplete() override;

View File

@ -405,15 +405,16 @@ QPointF QskScrollBox::scrollOffset( const QWheelEvent* event ) const
QPointF offset;
const auto pos = qskWheelPosition( event );
if ( viewContentsRect().contains( pos ) )
const auto viewRect = viewContentsRect();
if ( viewRect.contains( pos ) )
{
offset = event->pixelDelta();
if ( offset.isNull() )
{
offset = event->angleDelta() / QWheelEvent::DefaultDeltasPerStep;
offset *= 20.0; // how to find such a value ???
}
offset.rx() *= viewRect.width();
offset.ry() *= viewRect.height();
}
return offset;

View File

@ -8,9 +8,6 @@
#include "QskBoxBorderMetrics.h"
#include "QskEvent.h"
#include <qguiapplication.h>
#include <qstylehints.h>
QSK_SUBCONTROL( QskScrollView, Panel )
QSK_SUBCONTROL( QskScrollView, Viewport )
QSK_SUBCONTROL( QskScrollView, HorizontalScrollBar )
@ -21,15 +18,6 @@ QSK_SUBCONTROL( QskScrollView, VerticalScrollHandle )
QSK_SYSTEM_STATE( QskScrollView, VerticalHandlePressed, QskAspect::FirstSystemState << 1 )
QSK_SYSTEM_STATE( QskScrollView, HorizontalHandlePressed, QskAspect::FirstSystemState << 2 )
static int qskScrollLines()
{
#if QT_VERSION >= QT_VERSION_CHECK( 5, 9, 0 )
return QGuiApplication::styleHints()->wheelScrollLines();
#else
return 3;
#endif
}
class QskScrollView::PrivateData
{
public:
@ -226,20 +214,31 @@ QPointF QskScrollView::scrollOffset( const QWheelEvent* event ) const
QPointF offset;
const auto pos = qskWheelPosition( event );
const auto viewRect = viewContentsRect();
if ( subControlRect( VerticalScrollBar ).contains( pos ) )
{
const auto steps = qskWheelSteps( event );
offset.setY( steps * qskScrollLines() );
offset.setY( steps );
}
else if ( subControlRect( HorizontalScrollBar ).contains( pos ) )
{
const auto steps = qskWheelSteps( event );
offset.setX( steps * qskScrollLines() );
offset.setX( steps );
}
else
else if ( viewRect.contains( pos ) )
{
offset = Inherited::scrollOffset( event );
offset = event->pixelDelta();
if ( offset.isNull() )
offset = event->angleDelta() / QWheelEvent::DefaultDeltasPerStep;
}
if ( !offset.isNull() )
{
const auto vs = viewRect.size() / 3.0;
offset.rx() *= vs.width();
offset.ry() *= vs.height();
}
return offset;