smooth scrolling comment
Koos Vriezen
koos.vriezen at xs4all.nl
Wed Jul 31 16:09:29 BST 2002
On Tue, 30 Jul 2002, Koos Vriezen wrote:
> On Tue, 30 Jul 2002, Hetz Ben Hamo wrote:
>
> > 1. In order to stop the scrolling - only the up key stops. Why not any key?
> > I'm pretty sure end user would be pissed to find that they can't stop smooth
> > scrolling unless they find that arrow up stops it.
>
> That wouldn't be to difficult to implement. Personaly I like the
> combination of auto scrolling and PgUp/PgDown to quickly scan news sites.
> But for other, non-scrolling keys, yes why not.
>
> > 2. Is there going to be also a smooth scrolling upwards and sideways please?
> > it will help a lot with large tables..
>
> Scrolling up, wouldn't be hard to implement. Scrolling right/left needs
> imo some changes in paintBuffer, an extra vertical or rotation by
> drawPixmap. However the usefulness, compared to scrolling down, is a lot
> less.
Well for completing this auto scroller thing, here a patch that does the
above.
I've added a 10 by visualHeight vertical paintBuffer for smooth horizontal
scrolling. Besides that, the patch is quite boring.
Regards,
Koos Vriezen
-------------- next part --------------
Index: khtmlview.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtmlview.cpp,v
retrieving revision 1.478
diff -u -3 -p -r1.478 khtmlview.cpp
--- khtmlview.cpp 2002/07/30 15:36:48 1.478
+++ khtmlview.cpp 2002/07/31 15:10:24
@@ -60,6 +60,10 @@
#define PAINT_BUFFER_HEIGHT 128
+#define NEWSCROLLTIMER(x) \
+{ kdDebug() << "timer event killing timer" << endl; \
+ killTimer(d->scrollTimerId); d->scrollTimerId = (x); }
+
using namespace DOM;
using namespace khtml;
class KHTMLToolTip;
@@ -94,6 +98,7 @@ public:
reset();
tp=0;
paintBuffer=0;
+ vertPaintBuffer=0;
formCompletions=0;
prevScrollbarVisible = true;
timerId = 0;
@@ -107,6 +112,7 @@ public:
delete formCompletions;
delete tp; tp = 0;
delete paintBuffer; paintBuffer =0;
+ delete vertPaintBuffer;
if (underMouse)
underMouse->deref();
delete tooltip;
@@ -149,6 +155,7 @@ public:
QPainter *tp;
QPixmap *paintBuffer;
+ QPixmap *vertPaintBuffer;
NodeImpl *underMouse;
// the node that was selected when enter was pressed
@@ -179,6 +186,7 @@ public:
int scrollTimerId;
int scrollTiming;
int scrollBy;
+ enum { ScrollLeft, ScrollRight, ScrollUp, ScrollDown } scrollDirection;
bool complete;
bool firstRelayout;
bool layoutSchedulingEnabled;
@@ -249,6 +257,8 @@ KHTMLView::~KHTMLView()
void KHTMLView::init()
{
if(!d->paintBuffer) d->paintBuffer = new QPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT);
+ if(!d->vertPaintBuffer)
+ d->vertPaintBuffer = new QPixmap(10, PAINT_BUFFER_HEIGHT);
if(!d->tp) d->tp = new QPainter();
setFocusPolicy(QWidget::StrongFocus);
@@ -327,28 +337,40 @@ void KHTMLView::drawContents( QPainter *
if(!m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
p->fillRect(ex, ey, ew, eh, palette().normal().brush(QColorGroup::Base));
return;
+ }
+ if (eh > PAINT_BUFFER_HEIGHT && ew <= 10) {
+ if ( d->vertPaintBuffer->height() < visibleHeight() )
+ d->vertPaintBuffer->resize(10, visibleHeight());
+ d->tp->begin(d->vertPaintBuffer);
+ d->tp->translate(-ex, -ey);
+ d->tp->fillRect(ex, ey, ew, eh, palette().normal().brush(QColorGroup::Base));
+ m_part->xmlDocImpl()->renderer()->print(d->tp, ex, ey, ew, eh, 0, 0);
+ d->tp->end();
+ p->drawPixmap(ex, ey, *d->vertPaintBuffer, 0, 0, ew, eh);
}
- if ( d->paintBuffer->width() < visibleWidth() )
- d->paintBuffer->resize(visibleWidth(),PAINT_BUFFER_HEIGHT);
+ else {
+ 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);
+ 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);
#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 );
@@ -623,7 +645,9 @@ void KHTMLView::keyPressEvent( QKeyEvent
}
int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
- static int timings [][2] = { {100,1}, {50,1}, {30,1}, {20,1}, {20,2}, {20,4}, {20,6}, {0,0} };
+ static const struct { int msec, pixels; } timings [] = {
+ {100,1}, {50,1}, {30,1}, {20,1}, {20,2}, {20,4}, {20,6}, {0,0}
+ };
if (_ke->state() & Qt::ShiftButton)
switch(_ke->key())
{
@@ -636,31 +660,89 @@ void KHTMLView::keyPressEvent( QKeyEvent
case Key_Down:
case Key_J:
- if (!d->scrollTimerId) {
+ if (!d->scrollTimerId ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollLeft ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollRight) {
d->scrollTiming = 2;
- d->scrollBy = timings[d->scrollTiming][1];
+ d->scrollBy = timings[d->scrollTiming].pixels;
+ d->scrollDirection = KHTMLViewPrivate::ScrollDown;
scrollBy( 0, d->scrollBy );
- d->scrollTimerId = startTimer(timings[d->scrollTiming][0]);
- } else if (timings[d->scrollTiming+1][0]) {
- d->scrollBy = timings[++d->scrollTiming][1];
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollDown &&
+ timings[d->scrollTiming+1].msec) {
+ d->scrollBy = timings[++d->scrollTiming].pixels;
scrollBy( 0, d->scrollBy );
- killTimer(d->scrollTimerId);
- d->scrollTimerId = startTimer(timings[d->scrollTiming][0]);
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollUp) {
+ if (d->scrollTiming)
+ d->scrollBy = timings[--d->scrollTiming].pixels;
+ else
+ d->scrollDirection = KHTMLViewPrivate::ScrollDown;
}
+ NEWSCROLLTIMER(startTimer(timings[d->scrollTiming].msec));
break;
case Key_Up:
case Key_K:
- if (d->scrollTimerId)
- if (d->scrollTiming) {
- d->scrollBy = timings[--d->scrollTiming][1];
- killTimer(d->scrollTimerId);
- d->scrollTimerId = startTimer(timings[d->scrollTiming][0]);
- } else {
- killTimer(d->scrollTimerId);
- d->scrollTimerId = 0;
- }
+ if (!d->scrollTimerId ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollLeft ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollRight) {
+ d->scrollTiming = 2;
+ d->scrollBy = timings[d->scrollTiming].pixels;
+ d->scrollDirection = KHTMLViewPrivate::ScrollUp;
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollUp &&
+ timings[d->scrollTiming+1].msec) {
+ d->scrollBy = timings[++d->scrollTiming].pixels;
+ scrollBy( 0, -d->scrollBy );
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollDown) {
+ if (d->scrollTiming)
+ d->scrollBy = timings[--d->scrollTiming].pixels;
+ else
+ d->scrollDirection = KHTMLViewPrivate::ScrollUp;
+ }
+ NEWSCROLLTIMER(startTimer(timings[d->scrollTiming].msec));
+ break;
+
+ case Key_Left:
+ case Key_H:
+ if (!d->scrollTimerId ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollUp ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollDown) {
+ d->scrollTiming = 2;
+ d->scrollBy = timings[d->scrollTiming].pixels;
+ d->scrollDirection = KHTMLViewPrivate::ScrollLeft;
+ scrollBy( -d->scrollBy, 0 );
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollLeft &&
+ timings[d->scrollTiming+1].msec) {
+ d->scrollBy = timings[++d->scrollTiming].pixels;
+ scrollBy( -d->scrollBy, 0 );
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollRight) {
+ if (d->scrollTiming)
+ d->scrollBy = timings[--d->scrollTiming].pixels;
+ else
+ d->scrollDirection = KHTMLViewPrivate::ScrollLeft;
+ }
+ NEWSCROLLTIMER(startTimer(timings[d->scrollTiming].msec));
+ break;
+ case Key_Right:
+ case Key_L:
+ if (!d->scrollTimerId ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollUp ||
+ d->scrollDirection == KHTMLViewPrivate::ScrollDown) {
+ d->scrollTiming = 2;
+ d->scrollBy = timings[d->scrollTiming].pixels;
+ d->scrollDirection = KHTMLViewPrivate::ScrollRight;
+ scrollBy( d->scrollBy, 0 );
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollRight &&
+ timings[d->scrollTiming+1].msec) {
+ d->scrollBy = timings[++d->scrollTiming].pixels;
+ scrollBy( d->scrollBy, 0 );
+ } else if (d->scrollDirection == KHTMLViewPrivate::ScrollLeft) {
+ if (d->scrollTiming)
+ d->scrollBy = timings[--d->scrollTiming].pixels;
+ else
+ d->scrollDirection = KHTMLViewPrivate::ScrollRight;
+ }
+ NEWSCROLLTIMER(startTimer(timings[d->scrollTiming].msec));
break;
}
else
@@ -692,10 +774,8 @@ void KHTMLView::keyPressEvent( QKeyEvent
if ( d->vmode == QScrollView::AlwaysOff )
_ke->accept();
else {
- if (d->scrollTimerId) {
- killTimer(d->scrollTimerId);
- d->scrollTimerId = 0;
- }
+ if (d->scrollTimerId)
+ NEWSCROLLTIMER(0);
scrollBy( 0, -10 );
}
break;
@@ -710,15 +790,21 @@ void KHTMLView::keyPressEvent( QKeyEvent
case Key_L:
if ( d->hmode == QScrollView::AlwaysOff )
_ke->accept();
- else
+ else {
+ if (d->scrollTimerId)
+ NEWSCROLLTIMER(0);
scrollBy( 10, 0 );
+ }
break;
case Key_Left:
case Key_H:
if ( d->hmode == QScrollView::AlwaysOff )
_ke->accept();
- else
+ else {
+ if (d->scrollTimerId)
+ NEWSCROLLTIMER(0);
scrollBy( -10, 0 );
+ }
break;
case Key_Enter:
case Key_Return:
@@ -744,7 +830,15 @@ void KHTMLView::keyPressEvent( QKeyEvent
else
setContentsPos( 0, contentsHeight() - visibleHeight() );
break;
+ case Key_Shift:
+ // what are you doing here?
+ _ke->ignore();
+ return;
default:
+ if (d->scrollTimerId) {
+ killTimer(d->scrollTimerId);
+ d->scrollTimerId = 0;
+ }
_ke->ignore();
return;
}
@@ -1512,12 +1606,32 @@ void KHTMLView::timerEvent ( QTimerEvent
{
// kdDebug() << "timer event " << e->timerId() << endl;
if (e->timerId() == d->scrollTimerId) {
- if (contentsY() + visibleHeight () >= contentsHeight()) {
- kdDebug() << "timer event killing timer" << endl;
- killTimer(d->scrollTimerId);
- d->scrollTimerId = 0;
- } else
- scrollBy( 0, d->scrollBy );
+ switch (d->scrollDirection) {
+ case KHTMLViewPrivate::ScrollDown:
+ if (contentsY() + visibleHeight () >= contentsHeight())
+ NEWSCROLLTIMER(0)
+ else
+ scrollBy( 0, d->scrollBy );
+ break;
+ case KHTMLViewPrivate::ScrollUp:
+ if (contentsY() <= 0)
+ NEWSCROLLTIMER(0)
+ else
+ scrollBy( 0, -d->scrollBy );
+ break;
+ case KHTMLViewPrivate::ScrollRight:
+ if (contentsX() + visibleWidth () >= contentsWidth())
+ NEWSCROLLTIMER(0)
+ else
+ scrollBy( d->scrollBy, 0 );
+ break;
+ case KHTMLViewPrivate::ScrollLeft:
+ if (contentsX() <= 0)
+ NEWSCROLLTIMER(0)
+ else
+ scrollBy( -d->scrollBy, 0 );
+ break;
+ }
return;
}
if (e->timerId()==d->timerId)
More information about the kfm-devel
mailing list