From 4340b3dbaa2a01ffc20da61a83d2cae46df01c16 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sun, 10 Dec 2023 13:07:06 +0100 Subject: [PATCH 1/2] Issue #112: smooth scrolling --- .github/workflows/ci.yml | 1 - Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp | 67 +++++++++++++++++++++- Pdf4QtLibWidgets/sources/pdfdrawwidget.h | 10 +++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6365bf9..205be7d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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') }} diff --git a/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp b/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp index ee3f8e3..c064eb8 100644 --- a/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp +++ b/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp @@ -266,6 +266,8 @@ PDFDrawWidgetBase::PDFDrawWidgetBase(PDFWidget* widget, QWidget* par { this->setFocusPolicy(Qt::StrongFocus); this->setMouseTracking(true); + + QObject::connect(&m_autoScrollTimer, &QTimer::timeout, this, &PDFDrawWidgetBase::onAutoScrollTimeout); } template @@ -308,6 +310,13 @@ void PDFDrawWidgetBase::performMouseOperation(QPoint currentMousePos break; } + case MouseOperation::AutoScroll: + { + m_lastMousePosition = currentMousePosition; + onAutoScrollTimeout(); + break; + } + default: Q_ASSERT(false); } @@ -407,6 +416,26 @@ void PDFDrawWidgetBase::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(); } @@ -441,12 +470,19 @@ void PDFDrawWidgetBase::mouseReleaseEvent(QMouseEvent* event) case MouseOperation::Translate: { - m_mouseOperation = MouseOperation::None; + 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::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::updateCursor() } } +template +void PDFDrawWidgetBase::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 void PDFDrawWidgetBase::wheelEvent(QWheelEvent* event) { diff --git a/Pdf4QtLibWidgets/sources/pdfdrawwidget.h b/Pdf4QtLibWidgets/sources/pdfdrawwidget.h index db867b1..69310f3 100644 --- a/Pdf4QtLibWidgets/sources/pdfdrawwidget.h +++ b/Pdf4QtLibWidgets/sources/pdfdrawwidget.h @@ -24,6 +24,8 @@ #include #include +#include +#include #ifdef PDF4QT_ENABLE_OPENGL #include @@ -161,6 +163,7 @@ protected: private: void updateCursor(); + void onAutoScrollTimeout(); template 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 From 2c0b462075880d16d66a9f550ac880f03fbb35b9 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sun, 10 Dec 2023 13:55:35 +0100 Subject: [PATCH 2/2] Issue #112: Interval fix --- Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp b/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp index c064eb8..27c0233 100644 --- a/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp +++ b/Pdf4QtLibWidgets/sources/pdfdrawwidget.cpp @@ -432,6 +432,7 @@ void PDFDrawWidgetBase::mousePressEvent(QMouseEvent* event) m_autoScrollLastElapsedTimer.restart(); m_autoScrollOffset = QPointF(0.0, 0.0); m_lastMousePosition = event->pos(); + m_autoScrollTimer.setInterval(10); m_autoScrollTimer.start(); } }