From fefcd396a7f8e973e25ead66142ffd388eceb08d Mon Sep 17 00:00:00 2001 From: Zack Mak Date: Fri, 3 May 2024 00:37:54 +0800 Subject: [PATCH] Group page scroll into a single function Renamed wheelAccumulatedDelta to pageScrollDelta Use QTimer instead of timestamp for scroll idle timeout --- part/pageview.cpp | 116 +++++++++++++++++++++++++++------------------- part/pageview.h | 5 ++ 2 files changed, 74 insertions(+), 47 deletions(-) diff --git a/part/pageview.cpp b/part/pageview.cpp index 1f4534c33..85361f865 100644 --- a/part/pageview.cpp +++ b/part/pageview.cpp @@ -177,7 +177,6 @@ public: int lastSourceLocationViewportPageNumber = -1; double lastSourceLocationViewportNormalizedX = 0.0; double lastSourceLocationViewportNormalizedY = 0.0; - int wheelAccumulatedDelta = 0; // for everything except PgUp/PgDn and scroll to arbitrary locations const int baseShortScrollDuration = 100; @@ -218,6 +217,10 @@ public: QPoint dragScrollVector; QTimer dragScrollTimer; + // page scroll + int pageScrollDelta = 0; + QTimer pageScrollTimer; + // left click depress QTimer leftClickTimer; @@ -423,6 +426,8 @@ PageView::PageView(QWidget *parent, Okular::Document *document) connect(&d->dragScrollTimer, &QTimer::timeout, this, &PageView::slotDragScroll); + connect(&d->pageScrollTimer, &QTimer::timeout, this, &PageView::slotPageScroll); + d->leftClickTimer.setSingleShot(true); connect(&d->leftClickTimer, &QTimer::timeout, this, &PageView::slotShowSizeAllCursor); @@ -2184,6 +2189,56 @@ void PageView::continuousZoomEnd() updateCursor(); } +bool PageView::isPageScroll(int delta) +{ + bool pageScroll = false; + int vScroll = verticalScrollBar()->value(); + + d->pageScrollDelta += delta; + if (d->pageScrollTimer.isActive()) { + d->pageScrollTimer.stop(); + } + d->pageScrollTimer.setSingleShot(true); + d->pageScrollTimer.start(500); + + if (d->pageScrollDelta <= -QWheelEvent::DefaultDeltasPerStep && vScroll == verticalScrollBar()->maximum()) { + // go to next page + if ((int)d->document->currentPage() < d->items.count() - 1) { + // more optimized than document->setNextPage and then move view to top + Okular::DocumentViewport newViewport = d->document->viewport(); + newViewport.pageNumber += viewColumns(); + if (newViewport.pageNumber >= (int)d->items.count()) { + newViewport.pageNumber = d->items.count() - 1; + } + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedY = 0.0; + d->document->setViewport(newViewport); + d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar + d->pageScrollDelta = 0; + pageScroll = true; + } + } else if (d->pageScrollDelta >= QWheelEvent::DefaultDeltasPerStep && vScroll == verticalScrollBar()->minimum()) { + // go to prev page + if (d->document->currentPage() > 0) { + // more optimized than document->setPrevPage and then move view to bottom + Okular::DocumentViewport newViewport = d->document->viewport(); + newViewport.pageNumber -= viewColumns(); + if (newViewport.pageNumber < 0) { + newViewport.pageNumber = 0; + } + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedY = 1.0; + d->document->setViewport(newViewport); + d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar + d->pageScrollDelta = 0; + pageScroll = true; + } + } else if ((d->pageScrollDelta < 0 && vScroll == verticalScrollBar()->maximum()) || (d->pageScrollDelta > 0 && vScroll == verticalScrollBar()->minimum())) { + pageScroll = true; + } + return pageScroll; +} + void PageView::mouseMoveEvent(QMouseEvent *e) { d->previousMouseMovePos = e->globalPosition(); @@ -2314,7 +2369,7 @@ void PageView::mouseMoveEvent(QMouseEvent *e) void PageView::mousePressEvent(QMouseEvent *e) { - d->wheelAccumulatedDelta = 0; + d->pageScrollDelta = 0; // don't perform any mouse action when no document is shown if (d->items.isEmpty()) { @@ -2515,7 +2570,7 @@ void PageView::mousePressEvent(QMouseEvent *e) void PageView::mouseReleaseEvent(QMouseEvent *e) { - d->wheelAccumulatedDelta = 0; + d->pageScrollDelta = 0; // stop the drag scrolling d->dragScrollTimer.stop(); @@ -3164,7 +3219,7 @@ void PageView::guessTableDividers() void PageView::mouseDoubleClickEvent(QMouseEvent *e) { - d->wheelAccumulatedDelta = 0; + d->pageScrollDelta = 0; if (e->button() == Qt::LeftButton) { const QPoint eventPos = contentAreaPoint(e->pos()); @@ -3216,54 +3271,16 @@ void PageView::wheelEvent(QWheelEvent *e) return; } - int delta = e->angleDelta().y(), vScroll = verticalScrollBar()->value(); + int delta = e->angleDelta().y(); e->accept(); if ((e->modifiers() & Qt::ControlModifier) == Qt::ControlModifier) { continuousZoom(delta); } else { - bool scroll = true; - d->wheelAccumulatedDelta += delta; - + bool skipScroll = false; if (!getContinuousMode()) { - d->pageScrollTimestamp = e->timestamp(); - - if (d->wheelAccumulatedDelta <= -QWheelEvent::DefaultDeltasPerStep && vScroll == verticalScrollBar()->maximum()) { - // go to next page - if ((int)d->document->currentPage() < d->items.count() - 1) { - // more optimized than document->setNextPage and then move view to top - Okular::DocumentViewport newViewport = d->document->viewport(); - newViewport.pageNumber += viewColumns(); - if (newViewport.pageNumber >= (int)d->items.count()) { - newViewport.pageNumber = d->items.count() - 1; - } - newViewport.rePos.enabled = true; - newViewport.rePos.normalizedY = 0.0; - d->document->setViewport(newViewport); - d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar - d->wheelAccumulatedDelta = 0; - scroll = false; - } - } else if (d->wheelAccumulatedDelta >= QWheelEvent::DefaultDeltasPerStep && vScroll == verticalScrollBar()->minimum()) { - // go to prev page - if (d->document->currentPage() > 0) { - // more optimized than document->setPrevPage and then move view to bottom - Okular::DocumentViewport newViewport = d->document->viewport(); - newViewport.pageNumber -= viewColumns(); - if (newViewport.pageNumber < 0) { - newViewport.pageNumber = 0; - } - newViewport.rePos.enabled = true; - newViewport.rePos.normalizedY = 1.0; - d->document->setViewport(newViewport); - d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar - d->wheelAccumulatedDelta = 0; - scroll = false; - } - } else if ((d->wheelAccumulatedDelta < 0 && vScroll == verticalScrollBar()->maximum()) || (d->wheelAccumulatedDelta > 0 && vScroll == verticalScrollBar()->minimum())) { - scroll = false; - } + skipScroll = isPageScroll(delta); } - if (scroll) { + if (!skipScroll) { // When the shift key is held down, scroll ten times faster int multiplier = e->modifiers() & Qt::ShiftModifier ? 10 : 1; @@ -3278,7 +3295,7 @@ void PageView::wheelEvent(QWheelEvent *e) } else { d->scroller->scrollTo(d->scroller->finalPosition() - e->angleDelta() * multiplier, 0); } - d->wheelAccumulatedDelta = 0; + d->pageScrollDelta = 0; } } } @@ -4931,6 +4948,11 @@ void PageView::slotDragScroll() updateSelection(p); } +void PageView::slotPageScroll() +{ + d->pageScrollDelta = 0; +} + void PageView::slotShowWelcome() { // show initial welcome text diff --git a/part/pageview.h b/part/pageview.h index 8093e5d90..d6de9b82f 100644 --- a/part/pageview.h +++ b/part/pageview.h @@ -237,6 +237,9 @@ private: */ bool getContinuousMode() const; + // Hangle page scrolling in non-continuous mode + bool isPageScroll(int delta); + // Zoom around the point given as zoomCenter // zoomCenter is given in viewport coordinates // newZoom is the intended new zoom level. A value of 0.0 means: Don't change the current zoom level. @@ -259,6 +262,8 @@ private Q_SLOTS: void slotAutoScroll(); // activated by the dragScroll timer void slotDragScroll(); + // activated by the pageScroll timer + void slotPageScroll(); // show the welcome message void slotShowWelcome(); // activated by left click timer