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(-) (limited to 'src') 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 From 79eed28893b39a1db2b170e414382822bc5bda9a Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Fri, 2 Jul 2010 16:34:34 +0200 Subject: Code cleanup --- src/webview.cpp | 167 +++++++++++++++++++++++++++----------------------------- src/webview.h | 22 ++++---- 2 files changed, 90 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/webview.cpp b/src/webview.cpp index 31ab70c8..70a432c7 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -32,8 +32,6 @@ // Auto Includes #include "rekonq.h" -#include - // Local Includes #include "mainwindow.h" #include "mainview.h" @@ -52,7 +50,6 @@ // Qt Includes #include - #include #include #include @@ -70,18 +67,14 @@ WebView::WebView(QWidget* parent) : KWebView(parent, false) , _mousePos(QPoint(0, 0)) - , _scrollTimer(new QTimer(this)) + , _autoScrollTimer(new QTimer(this)) , _VScrollSpeed(0) , _HScrollSpeed(0) , _canEnableAutoScroll(true) , _isAutoScrollEnabled(false) - , smoothScroller(0) - , nbSteps(0) - , timer(new QTimer(this)) - , nbTicks(0) - , time(new QTime()) - , smoothScrolling(false) - , dy(0) + , _smoothScrollTimer(new QTimer(this)) + , _smoothScrolling(false) + , _dy(0) { WebPage *page = new WebPage(this); setPage(page); @@ -111,17 +104,24 @@ WebView::WebView(QWidget* parent) connect(this, SIGNAL(loadUrl(const KUrl &, const Rekonq::OpenType &)), Application::instance(), SLOT(loadUrl(const KUrl &, const Rekonq::OpenType &))); - // scrolling timer - connect(_scrollTimer, SIGNAL(timeout()), this, SLOT(scrollFrameChanged())); - _scrollTimer->setInterval(100); - timer->setInterval(16); - connect(timer, SIGNAL(timeout()), this, SLOT(scrollTick())); + // Auto scroll timer + connect(_autoScrollTimer, SIGNAL(timeout()), this, SLOT(scrollFrameChanged())); + _autoScrollTimer->setInterval(100); + + // Smooth scroll timer + connect(_smoothScrollTimer, SIGNAL(timeout()), this, SLOT(scrollTick())); + _smoothScrollTimer->setInterval(16); } WebView::~WebView() { - delete _scrollTimer; + delete _autoScrollTimer; + + if (_smoothScrolling) + stopScrolling(); + delete _smoothScrollTimer; + disconnect(); WebPage* p = page(); @@ -130,12 +130,6 @@ WebView::~WebView() QString path = WebSnap::imagePathFromUrl(p->mainFrame()->url().toString()); QFile::remove(path); preview.save(path); - - if (smoothScrolling) - stopScrolling(); - - delete timer; - delete time; } @@ -355,7 +349,7 @@ void WebView::mousePressEvent(QMouseEvent *event) setCursor(Qt::ArrowCursor); _VScrollSpeed = 0; _HScrollSpeed = 0; - _scrollTimer->stop(); + _autoScrollTimer->stop(); _isAutoScrollEnabled = false; return; } @@ -398,8 +392,8 @@ void WebView::mouseMoveEvent(QMouseEvent *event) QPoint r = _mousePos - _clickPos; _HScrollSpeed = r.x() / 2; // you are too fast.. _VScrollSpeed = r.y() / 2; - if (!_scrollTimer->isActive()) - _scrollTimer->start(); + if (!_autoScrollTimer->isActive()) + _autoScrollTimer->start(); return; } @@ -498,43 +492,43 @@ void WebView::keyPressEvent(QKeyEvent *event) if (event->key() == Qt::Key_Up) { _VScrollSpeed--; - if (!_scrollTimer->isActive()) - _scrollTimer->start(); + if (!_autoScrollTimer->isActive()) + _autoScrollTimer->start(); return; } if (event->key() == Qt::Key_Down) { _VScrollSpeed++; - if (!_scrollTimer->isActive()) - _scrollTimer->start(); + if (!_autoScrollTimer->isActive()) + _autoScrollTimer->start(); return; } if (event->key() == Qt::Key_Right) { _HScrollSpeed++; - if (!_scrollTimer->isActive()) - _scrollTimer->start(); + if (!_autoScrollTimer->isActive()) + _autoScrollTimer->start(); return; } if (event->key() == Qt::Key_Left) { _HScrollSpeed--; - if (!_scrollTimer->isActive()) - _scrollTimer->start(); + if (!_autoScrollTimer->isActive()) + _autoScrollTimer->start(); return; } - if (_scrollTimer->isActive()) + if (_autoScrollTimer->isActive()) { - _scrollTimer->stop(); + _autoScrollTimer->stop(); } else { if (_VScrollSpeed || _HScrollSpeed) - _scrollTimer->start(); + _autoScrollTimer->start(); } } @@ -571,15 +565,15 @@ void WebView::wheelEvent(QWheelEvent *event) int numDegrees = event->delta() / 8; int numSteps = numDegrees / 15; - if ((numSteps > 0) != !bas) + if ((numSteps > 0) != !_scrollBottom) stopScrolling(); if (numSteps > 0) - bas = false; + _scrollBottom = false; else - bas = true; + _scrollBottom = true; - setupSmoothScrolling( 100); + setupSmoothScrolling(100); return; } @@ -616,77 +610,74 @@ void WebView::scrollFrameChanged() _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(); - } + int ddy = qMax(_smoothScrollSteps ? abs(_dy)/_smoothScrollSteps : 0,3); + + _dy += posY; + + if (_dy <= 0) + { + stopScrolling(); + return; + } + + _smoothScrollSteps = 8; + + if (_dy / _smoothScrollSteps < ddy) + { + _smoothScrollSteps = (abs(_dy)+ddy-1)/ddy; + if (_smoothScrollSteps < 1) + _smoothScrollSteps = 1; + } + + _smoothScrollTime.start(); + + if (!_smoothScrolling) + { + _smoothScrolling = true; + _smoothScrollTimer->start(); + scrollTick(); + } } void WebView::scrollTick() { - if (dy == 0) + if (_dy == 0) { stopScrolling(); return; } - if (steps < 1) - steps = 1; + if (_smoothScrollSteps < 1) + _smoothScrollSteps = 1; - int takesteps = time->restart() / 16; + int takesteps = _smoothScrollTime.restart() / 16; int scroll_y = 0; if (takesteps < 1) takesteps = 1; - if (takesteps > steps) - takesteps = steps; + if (takesteps > _smoothScrollSteps) + takesteps = _smoothScrollSteps; for(int i = 0; i < takesteps; i++) { - int ddy = (dy / (steps+1)) * 2; + int ddy = (_dy / (_smoothScrollSteps+1)) * 2; // limit step to requested scrolling distance - if (abs(ddy) > abs(dy)) ddy = dy; + if (abs(ddy) > abs(_dy)) + ddy = _dy; // update remaining scroll - dy -= ddy; + _dy -= ddy; scroll_y += ddy; - steps--; - } - - + _smoothScrollSteps--; + } - //page()->mainFrame()->setScrollPosition( QPoint( 0, frame ) ); - if (bas) + if (_scrollBottom) page()->mainFrame()->setScrollPosition( QPoint( 0, page()->mainFrame()->scrollPosition().y() + scroll_y ) ); else page()->mainFrame()->setScrollPosition( QPoint( 0, page()->mainFrame()->scrollPosition().y() - scroll_y ) ); @@ -695,7 +686,7 @@ void WebView::scrollTick() void WebView::stopScrolling() { - timer->stop(); - dy = 0; - smoothScrolling = false; + _smoothScrollTimer->stop(); + _dy = 0; + _smoothScrolling = false; } diff --git a/src/webview.h b/src/webview.h index cc5508cb..b17940c7 100644 --- a/src/webview.h +++ b/src/webview.h @@ -32,7 +32,8 @@ // Rekonq Includes #include "rekonq_defines.h" -#include +//Qt Includes +#include // KDE Includes #include @@ -87,21 +88,20 @@ private: QPoint _mousePos; QPoint _clickPos; - QTimer *_scrollTimer; + // Auto Scroll + QTimer *_autoScrollTimer; int _VScrollSpeed; int _HScrollSpeed; bool _canEnableAutoScroll; bool _isAutoScrollEnabled; - QTimeLine *smoothScroller; - QTimer *timer; - int nbSteps; - int nbTicks; - bool bas; - QTime *time; - bool smoothScrolling; - int dy; - int steps; + // Smooth Scroll + QTimer *_smoothScrollTimer; + QTime _smoothScrollTime; + bool _scrollBottom; + bool _smoothScrolling; + int _dy; + int _smoothScrollSteps; }; #endif -- cgit v1.2.1 From 48448943317f89762559fe26d3a1701c6be0a9f2 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Sun, 8 Aug 2010 20:59:41 +0200 Subject: - Use default scrolling for editable contents - Smooth scrolling now follows QApplication::wheelScrollLines() but with a factor --- src/webview.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/webview.cpp b/src/webview.cpp index 70a432c7..35af8005 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -541,7 +541,7 @@ void WebView::keyPressEvent(QKeyEvent *event) void WebView::wheelEvent(QWheelEvent *event) { - if (!ReKonfig::smoothScrolling()) + if (!ReKonfig::smoothScrolling() || page()->currentFrame()->hitTestContent(event->pos()).isContentEditable()) KWebView::wheelEvent(event); // Sync with the zoom slider @@ -560,7 +560,7 @@ void WebView::wheelEvent(QWheelEvent *event) emit zoomChanged((qreal)newFactor / 10); } - else if ( ReKonfig::smoothScrolling() ) + else if ( ReKonfig::smoothScrolling() && !this->page()->currentFrame()->hitTestContent(event->pos()).isContentEditable()) { int numDegrees = event->delta() / 8; int numSteps = numDegrees / 15; @@ -573,7 +573,7 @@ void WebView::wheelEvent(QWheelEvent *event) else _scrollBottom = true; - setupSmoothScrolling(100); + setupSmoothScrolling(QApplication::wheelScrollLines() * 25); return; } -- cgit v1.2.1 From a033b7264d21299927a0fdc9e22ff28bee4fa42c Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Sun, 8 Aug 2010 21:07:00 +0200 Subject: Increase spped --- src/webview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/webview.cpp b/src/webview.cpp index 35af8005..dfa35dfd 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -573,7 +573,7 @@ void WebView::wheelEvent(QWheelEvent *event) else _scrollBottom = true; - setupSmoothScrolling(QApplication::wheelScrollLines() * 25); + setupSmoothScrolling(QApplication::wheelScrollLines() * 33); return; } -- cgit v1.2.1 From 4bf40ac2a07bd68305df486f6558e6dd9d26f9e2 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Tue, 10 Aug 2010 12:19:10 +0200 Subject: Fix the factor --- src/webview.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/webview.cpp b/src/webview.cpp index dfa35dfd..ebf13588 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -560,7 +560,7 @@ void WebView::wheelEvent(QWheelEvent *event) emit zoomChanged((qreal)newFactor / 10); } - else if ( ReKonfig::smoothScrolling() && !this->page()->currentFrame()->hitTestContent(event->pos()).isContentEditable()) + else if ( ReKonfig::smoothScrolling() && !page()->currentFrame()->hitTestContent(event->pos()).isContentEditable()) { int numDegrees = event->delta() / 8; int numSteps = numDegrees / 15; @@ -573,9 +573,8 @@ void WebView::wheelEvent(QWheelEvent *event) else _scrollBottom = true; - setupSmoothScrolling(QApplication::wheelScrollLines() * 33); - return; + setupSmoothScrolling(QApplication::wheelScrollLines() * abs(numSteps) * 20); } } -- cgit v1.2.1