Issue #112: smooth scrolling

This commit is contained in:
Jakub Melka 2023-12-10 13:07:06 +01:00
parent 0b579c828f
commit 4340b3dbaa
3 changed files with 75 additions and 3 deletions

View File

@ -24,7 +24,6 @@ jobs:
uses: actions/cache@v3
with:
path: |
./vcpkg/buildtrees
./vcpkg/downloads
./vcpkg/packages
key: ${{ runner.os }}-vcpkg-v2-${{ hashFiles('**/vcpkg.json') }}

View File

@ -266,6 +266,8 @@ PDFDrawWidgetBase<BaseWidget>::PDFDrawWidgetBase(PDFWidget* widget, QWidget* par
{
this->setFocusPolicy(Qt::StrongFocus);
this->setMouseTracking(true);
QObject::connect(&m_autoScrollTimer, &QTimer::timeout, this, &PDFDrawWidgetBase::onAutoScrollTimeout);
}
template<typename BaseWidget>
@ -308,6 +310,13 @@ void PDFDrawWidgetBase<BaseWidget>::performMouseOperation(QPoint currentMousePos
break;
}
case MouseOperation::AutoScroll:
{
m_lastMousePosition = currentMousePosition;
onAutoScrollTimeout();
break;
}
default:
Q_ASSERT(false);
}
@ -407,6 +416,26 @@ void PDFDrawWidgetBase<BaseWidget>::mousePressEvent(QMouseEvent* event)
m_lastMousePosition = event->pos();
}
if (event->button() == Qt::MiddleButton)
{
if (m_mouseOperation == MouseOperation::AutoScroll)
{
m_mouseOperation = MouseOperation::None;
m_autoScrollTimer.stop();
m_autoScrollLastElapsedTimer.restart();
m_autoScrollOffset = QPointF(0.0, 0.0);
}
else
{
m_mouseOperation = MouseOperation::AutoScroll;
m_autoScrollMousePosition = event->pos();
m_autoScrollLastElapsedTimer.restart();
m_autoScrollOffset = QPointF(0.0, 0.0);
m_lastMousePosition = event->pos();
m_autoScrollTimer.start();
}
}
updateCursor();
event->accept();
}
@ -440,13 +469,20 @@ void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
break;
case MouseOperation::Translate:
{
if (event->button() != Qt::MiddleButton)
{
m_mouseOperation = MouseOperation::None;
}
break;
}
case MouseOperation::AutoScroll:
break;
default:
Q_ASSERT(false);
break;
}
updateCursor();
@ -496,6 +532,10 @@ void PDFDrawWidgetBase<BaseWidget>::updateCursor()
cursor = QCursor(Qt::ClosedHandCursor);
break;
case MouseOperation::AutoScroll:
cursor = QCursor(Qt::SizeAllCursor);
break;
default:
Q_ASSERT(false);
break;
@ -512,6 +552,31 @@ void PDFDrawWidgetBase<BaseWidget>::updateCursor()
}
}
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::onAutoScrollTimeout()
{
if (m_mouseOperation != MouseOperation::AutoScroll)
{
return;
}
QPointF offset = m_autoScrollMousePosition - m_lastMousePosition;
QPointF scrollOffset = m_autoScrollOffset;
qreal secondsElapsed = qreal(m_autoScrollLastElapsedTimer.nsecsElapsed()) * 0.000000001;
m_autoScrollLastElapsedTimer.restart();
scrollOffset += offset * secondsElapsed;
int scrollX = qFloor(scrollOffset.x());
int scrollY = qFloor(scrollOffset.y());
scrollOffset -= QPointF(scrollX, scrollY);
m_autoScrollOffset = scrollOffset;
PDFDrawWidgetProxy* proxy = m_widget->getDrawWidgetProxy();
proxy->scrollByPixels(QPoint(scrollX, scrollY));
}
template<typename BaseWidget>
void PDFDrawWidgetBase<BaseWidget>::wheelEvent(QWheelEvent* event)
{

View File

@ -24,6 +24,8 @@
#include <QWidget>
#include <QScrollBar>
#include <QTimer>
#include <QElapsedTimer>
#ifdef PDF4QT_ENABLE_OPENGL
#include <QOpenGLWidget>
@ -161,6 +163,7 @@ protected:
private:
void updateCursor();
void onAutoScrollTimeout();
template<typename Event, void(IDrawWidgetInputInterface::* Function)(QWidget*, Event*)>
bool processEvent(Event* event);
@ -168,7 +171,8 @@ private:
enum class MouseOperation
{
None,
Translate
Translate,
AutoScroll
};
/// Performs the mouse operation (under the current mouse position)
@ -177,7 +181,11 @@ private:
PDFWidget* m_widget;
QPoint m_lastMousePosition;
QPoint m_autoScrollMousePosition;
MouseOperation m_mouseOperation;
QTimer m_autoScrollTimer;
QPointF m_autoScrollOffset;
QElapsedTimer m_autoScrollLastElapsedTimer;
};
class PDFDrawWidget : public PDFDrawWidgetBase<QWidget>