More fun with auto scrolling

Koos Vriezen koos.vriezen at xs4all.nl
Wed Jul 10 23:12:39 BST 2002


Hi,

The attached patch is just a trial for auto scrolling. It works only with
scrolling down. The cursor down key starts auto scrolling. Pressing it
again, accelerated the scrolling. Holding the key long enough for auto
repeat, enables normal scrolling.
The up key decelerates scrolling, until it stops and normal up
scrolling is enabled.

I found that scrolling is smoother if not for each pixel line a
renderer()->print is called, but fill the whole paintbuffer and copy each
time a line out of it. This is not perfect, it will mess up the view a bit
(eg. when increasing font sizes) but its quite harmless.

Can't wait to read tomorrows lwn's 'All in one big page' ;)

Regards,

Koos Vriezen
-------------- next part --------------
Index: khtmlview.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtmlview.cpp,v
retrieving revision 1.474
diff -u -3 -p -r1.474 khtmlview.cpp
--- khtmlview.cpp	2002/06/25 02:28:04	1.474
+++ khtmlview.cpp	2002/07/10 22:11:18
@@ -98,6 +98,7 @@ public:
         prevScrollbarVisible = true;
 	timerId = 0;
         repaintTimerId = 0;
+        scrollTimerId = 0;
         complete = false;
 	tooltip = 0;
     }
@@ -139,6 +140,7 @@ public:
 	scrollingSelf = false;
 	timerId = 0;
         repaintTimerId = 0;
+        scrollTimerId = 0;
         complete = false;
         firstRelayout = true;
         layoutSchedulingEnabled = true;
@@ -174,6 +176,10 @@ public:
     int timerId;
 
     int repaintTimerId;
+    int scrollTimerId;
+    int scrollLine;
+    QRect scrollRect;
+    int scrollBy;
     bool complete;
     bool firstRelayout;
     bool layoutSchedulingEnabled;
@@ -326,26 +332,39 @@ void KHTMLView::drawContents( QPainter *
     if ( d->paintBuffer->width() < visibleWidth() )
         d->paintBuffer->resize(visibleWidth(),PAINT_BUFFER_HEIGHT);
 
-    int py=0;
-    while (py < eh) {
-        int ph = eh-py < PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
-        d->tp->begin(d->paintBuffer);
-        d->tp->translate(-ex, -ey-py);
-        d->tp->fillRect(ex, ey+py, ew, ph, palette().normal().brush(QColorGroup::Base));
-        m_part->xmlDocImpl()->renderer()->print(d->tp, ex, ey+py, ew, ph, 0, 0);
+    if (d->scrollTimerId && d->scrollLine && d->scrollRect.contains(QRect(ex, ey, ew, eh)) && d->scrollLine + eh < PAINT_BUFFER_HEIGHT && ex == d->scrollRect.x()) {
+        p->drawPixmap(ex, ey, *d->paintBuffer, 0, d->scrollLine, ew, eh);
+        d->scrollLine += eh;
+        // kdDebug( 6000 ) << "drawContents using cache" << endl;
+    }
+    else {
+        int py=0;
+        while (py < eh) {
+            int ph = eh-py < PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
+            int pvh = ph;
+            if (pvh < PAINT_BUFFER_HEIGHT && d->scrollTimerId && ey + eh == contentsY() + visibleHeight()) {
+                pvh = PAINT_BUFFER_HEIGHT;
+                d->scrollRect = QRect(ex, ey, ew, PAINT_BUFFER_HEIGHT);
+                d->scrollLine = eh;
+                // kdDebug( 6000 ) << "drawContents make cache" << endl;
+            }
+            d->tp->begin(d->paintBuffer);
+            d->tp->translate(-ex, -ey-py);
+            d->tp->fillRect(ex, ey+py, ew, pvh, palette().normal().brush(QColorGroup::Base));
+            m_part->xmlDocImpl()->renderer()->print(d->tp, ex, ey+py, ew, pvh, 0, 0);
 #ifdef BOX_DEBUG
-	if (m_part->xmlDocImpl()->focusNode())
-	{
-	    d->tp->setBrush(Qt::NoBrush);
-	    d->tp->drawRect(m_part->xmlDocImpl()->focusNode()->getRect());
-	}
+            if (m_part->xmlDocImpl()->focusNode())
+            {
+                d->tp->setBrush(Qt::NoBrush);
+                d->tp->drawRect(m_part->xmlDocImpl()->focusNode()->getRect());
+            }
 #endif
-        d->tp->end();
+            d->tp->end();
 
-        p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph);
-        py += PAINT_BUFFER_HEIGHT;
+            p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph);
+            py += PAINT_BUFFER_HEIGHT;
+        }
     }
-
     khtml::DrawContentsEvent event( p, ex, ey, ew, eh );
     QApplication::sendEvent( m_part, &event );
 
@@ -636,8 +655,19 @@ void KHTMLView::keyPressEvent( QKeyEvent
         case Key_J:
             if ( d->vmode == QScrollView::AlwaysOff )
                 _ke->accept();
-            else
+            else if (_ke->isAutoRepeat()) {
+                if (d->scrollTimerId) {
+                    killTimer(d->scrollTimerId);
+                    d->scrollTimerId = 0;
+                }
                 scrollBy( 0, 10 );
+            } else if (!d->scrollTimerId) {
+                d->scrollLine = 0;
+                d->scrollBy = 1;
+                scrollBy( 0, d->scrollBy );
+                d->scrollTimerId = startTimer(30);
+            } else if (d->scrollBy < 10)
+                d->scrollBy++;
             break;
 
         case Key_Space:
@@ -652,7 +682,12 @@ void KHTMLView::keyPressEvent( QKeyEvent
         case Key_K:
             if ( d->vmode == QScrollView::AlwaysOff )
                 _ke->accept();
-            else
+            else if (d->scrollTimerId) {
+                if (--d->scrollBy <= 0) {
+                    killTimer(d->scrollTimerId);
+                    d->scrollTimerId = 0;
+                }
+            } else
                 scrollBy( 0, -10 );
             break;
 
@@ -1445,6 +1480,15 @@ void KHTMLView::slotScrollBarMoved()
 void KHTMLView::timerEvent ( QTimerEvent *e )
 {
 //    kdDebug() << "timer event " << e->timerId() << endl;
+    if (e->timerId() == d->scrollTimerId) {
+        if (contentsY() + visibleHeight () >= contentsHeight() || d->scrollBy <= 0) {
+            kdDebug() << "timer event killing timer" << endl;
+            killTimer(d->scrollTimerId);
+            d->scrollTimerId = 0;
+        } else
+            scrollBy( 0, d->scrollBy );
+        return;
+    }
     if (e->timerId()==d->timerId)
     {
         d->firstRelayout = false;


More information about the kfm-devel mailing list