From b94c146ef02f7e966251bb78cd124367c73e7d1d Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Wed, 30 Jun 2010 18:36:49 +0200 Subject: Implement KHTML smooth scrolling for rekonq --- src/rekonq.kcfg | 3 + src/settings/settings_appearance.ui | 17 ++++- src/webview.cpp | 124 +++++++++++++++++++++++++++++++++++- src/webview.h | 17 +++++ 4 files changed, 158 insertions(+), 3 deletions(-) diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg index 1d6139ac..33a07751 100644 --- a/src/rekonq.kcfg +++ b/src/rekonq.kcfg @@ -73,6 +73,9 @@ true + + true + diff --git a/src/settings/settings_appearance.ui b/src/settings/settings_appearance.ui index 7ec23484..f7dd4747 100644 --- a/src/settings/settings_appearance.ui +++ b/src/settings/settings_appearance.ui @@ -6,8 +6,8 @@ 0 0 - 351 - 455 + 364 + 457 @@ -241,6 +241,19 @@ + + + + Scroll pages with an eye candy effect + + + Enable smooth scrolling + + + true + + + diff --git a/src/webview.cpp b/src/webview.cpp index 188216f8..31ab70c8 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -32,6 +32,8 @@ // Auto Includes #include "rekonq.h" +#include + // Local Includes #include "mainwindow.h" #include "mainview.h" @@ -73,6 +75,13 @@ WebView::WebView(QWidget* parent) , _HScrollSpeed(0) , _canEnableAutoScroll(true) , _isAutoScrollEnabled(false) + , smoothScroller(0) + , nbSteps(0) + , timer(new QTimer(this)) + , nbTicks(0) + , time(new QTime()) + , smoothScrolling(false) + , dy(0) { WebPage *page = new WebPage(this); setPage(page); @@ -105,6 +114,8 @@ WebView::WebView(QWidget* parent) // scrolling timer connect(_scrollTimer, SIGNAL(timeout()), this, SLOT(scrollFrameChanged())); _scrollTimer->setInterval(100); + timer->setInterval(16); + connect(timer, SIGNAL(timeout()), this, SLOT(scrollTick())); } @@ -119,6 +130,12 @@ WebView::~WebView() QString path = WebSnap::imagePathFromUrl(p->mainFrame()->url().toString()); QFile::remove(path); preview.save(path); + + if (smoothScrolling) + stopScrolling(); + + delete timer; + delete time; } @@ -525,9 +542,13 @@ void WebView::keyPressEvent(QKeyEvent *event) } + + + void WebView::wheelEvent(QWheelEvent *event) { - KWebView::wheelEvent(event); + if (!ReKonfig::smoothScrolling()) + KWebView::wheelEvent(event); // Sync with the zoom slider if (event->modifiers() == Qt::ControlModifier) @@ -545,6 +566,23 @@ void WebView::wheelEvent(QWheelEvent *event) emit zoomChanged((qreal)newFactor / 10); } + else if ( ReKonfig::smoothScrolling() ) + { + int numDegrees = event->delta() / 8; + int numSteps = numDegrees / 15; + + if ((numSteps > 0) != !bas) + stopScrolling(); + + if (numSteps > 0) + bas = false; + else + bas = true; + + setupSmoothScrolling( 100); + + return; + } } @@ -577,3 +615,87 @@ void WebView::scrollFrameChanged() if (x == 0 || x == page()->currentFrame()->scrollBarMaximum(Qt::Horizontal)) _HScrollSpeed = 0; } + +// Scroll chat to bottom +void WebView::setupSmoothScrolling(int posY) +{ + int ddy = qMax(steps ? abs(dy)/steps : 0,3); + + dy += posY; + + if (dy <= 0) + { + stopScrolling(); + return; + } + + steps = 8; + + if (dy / steps < ddy) + { + // Don't move slower than average 4px/step in minimum one direction + // This means fewer than normal steps + steps = (abs(dy)+ddy-1)/ddy; + if (steps < 1) + steps = 1; + } + + time->start(); + if (!smoothScrolling) + { + smoothScrolling = true; + timer->start(); + scrollTick(); + } +} + + +void WebView::scrollTick() +{ + if (dy == 0) + { + stopScrolling(); + return; + } + + if (steps < 1) + steps = 1; + + int takesteps = time->restart() / 16; + int scroll_y = 0; + + if (takesteps < 1) + takesteps = 1; + + if (takesteps > steps) + takesteps = steps; + + for(int i = 0; i < takesteps; i++) + { + int ddy = (dy / (steps+1)) * 2; + + // limit step to requested scrolling distance + if (abs(ddy) > abs(dy)) ddy = dy; + + // update remaining scroll + dy -= ddy; + scroll_y += ddy; + steps--; + } + + + + //page()->mainFrame()->setScrollPosition( QPoint( 0, frame ) ); + if (bas) + page()->mainFrame()->setScrollPosition( QPoint( 0, page()->mainFrame()->scrollPosition().y() + scroll_y ) ); + else + page()->mainFrame()->setScrollPosition( QPoint( 0, page()->mainFrame()->scrollPosition().y() - scroll_y ) ); +} + + +void WebView::stopScrolling() +{ + timer->stop(); + dy = 0; + smoothScrolling = false; +} diff --git a/src/webview.h b/src/webview.h index a4ba676c..cc5508cb 100644 --- a/src/webview.h +++ b/src/webview.h @@ -32,6 +32,8 @@ // Rekonq Includes #include "rekonq_defines.h" +#include + // KDE Includes #include @@ -71,6 +73,11 @@ private slots: void inspect(); void scrollFrameChanged(); + void scrollTick(); + + void setupSmoothScrolling(int posY); + + void stopScrolling(); signals: void loadUrl(const KUrl &, const Rekonq::OpenType &); @@ -85,6 +92,16 @@ private: int _HScrollSpeed; bool _canEnableAutoScroll; bool _isAutoScrollEnabled; + + QTimeLine *smoothScroller; + QTimer *timer; + int nbSteps; + int nbTicks; + bool bas; + QTime *time; + bool smoothScrolling; + int dy; + int steps; }; #endif -- cgit v1.2.1