You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
4.4 KiB
190 lines
4.4 KiB
/* This file is part of the KDE libraries
|
|
Copyright (C) 2005 Allan Sandfeld Jensen <kde@carewolf.com>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <qtimer.h>
|
|
#include <qevent.h>
|
|
#include <qapplication.h>
|
|
|
|
#include "kscrollview.h"
|
|
#include <kdebug.h>
|
|
#include <kconfig.h>
|
|
#include <kglobal.h>
|
|
|
|
struct KScrollView::KScrollViewPrivate {
|
|
KScrollViewPrivate() : dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false) {}
|
|
QTimer timer;
|
|
int dx;
|
|
int dy;
|
|
// Step size * 16 and residual to avoid huge difference between 1px/step and 2px/step
|
|
int ddx;
|
|
int ddy;
|
|
int rdx;
|
|
int rdy;
|
|
bool scrolling;
|
|
};
|
|
|
|
KScrollView::KScrollView( QWidget *parent, const char *name, Qt::WFlags f )
|
|
: QScrollView( parent, name, f )
|
|
{
|
|
d = new KScrollViewPrivate;
|
|
connect(&d->timer, SIGNAL(timeout()), this, SLOT(scrollTick()));
|
|
}
|
|
|
|
KScrollView::~KScrollView()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void KScrollView::scrollBy(int dx, int dy)
|
|
{
|
|
KConfigGroup cfg( KGlobal::config(), "KDE" );
|
|
if( !cfg.readBoolEntry( "SmoothScrolling", true )) {
|
|
QScrollView::scrollBy( dx, dy );
|
|
return;
|
|
}
|
|
// scrolling destination
|
|
int full_dx = d->dx + dx;
|
|
int full_dy = d->dy + dy;
|
|
|
|
// scrolling speed
|
|
int ddx = 0;
|
|
int ddy = 0;
|
|
|
|
int steps = SCROLL_TIME/SCROLL_TICK;
|
|
|
|
ddx = (full_dx*16)/steps;
|
|
ddy = (full_dy*16)/steps;
|
|
|
|
// don't go under 1px/step
|
|
if (ddx > 0 && ddx < 16) ddx = 16;
|
|
if (ddy > 0 && ddy < 16) ddy = 16;
|
|
if (ddx < 0 && ddx > -16) ddx = -16;
|
|
if (ddy < 0 && ddy > -16) ddy = -16;
|
|
|
|
d->dx = full_dx;
|
|
d->dy = full_dy;
|
|
d->ddx = ddx;
|
|
d->ddy = ddy;
|
|
|
|
if (!d->scrolling) {
|
|
scrollTick();
|
|
startScrolling();
|
|
}
|
|
}
|
|
/*
|
|
void KScrollView::scrollBy(int dx, int dy)
|
|
{
|
|
if (d->scrolling)
|
|
setContentsPos( d->x+dx, d->y+dy );
|
|
else
|
|
setContentsPos( contentsX() + dx, contentsY() + dy);
|
|
}
|
|
|
|
void KScrollView::setContentsPos(int x, int y)
|
|
{
|
|
if (x < 0) x = 0;
|
|
if (y < 0) y = 0;
|
|
|
|
int dx = x - contentsX();
|
|
int dy = y - contentsY();
|
|
|
|
// to large to smooth out
|
|
// if (dx > 1000 || dy > 1000) return QScrollView::setContentsPos(x,y);
|
|
|
|
// scrolling speed
|
|
int ddx = 0;
|
|
int ddy = 0;
|
|
|
|
int steps = SCROLL_TIME/SCROLL_TICK;
|
|
|
|
ddx = (dx*16)/steps;
|
|
ddy = (dy*16)/steps;
|
|
|
|
d->x = x;
|
|
d->y = y;
|
|
d->dx = dx;
|
|
d->dy = dy;
|
|
d->ddx = ddx;
|
|
d->ddy = ddy;
|
|
|
|
if (!d->scrolling) {
|
|
scrollTick();
|
|
startScrolling();
|
|
}
|
|
} */
|
|
|
|
void KScrollView::scrollTick() {
|
|
if (d->dx == 0 && d->dy == 0) {
|
|
stopScrolling();
|
|
return;
|
|
}
|
|
|
|
int tddx = d->ddx + d->rdx;
|
|
int tddy = d->ddy + d->rdy;
|
|
|
|
int ddx = tddx / 16;
|
|
int ddy = tddy / 16;
|
|
d->rdx = tddx % 16;
|
|
d->rdy = tddy % 16;
|
|
|
|
if (d->dx > 0 && ddx > d->dx) ddx = d->dx;
|
|
else
|
|
if (d->dx < 0 && ddx < d->dx) ddx = d->dx;
|
|
|
|
if (d->dy > 0 && ddy > d->dy) ddy = d->dy;
|
|
else
|
|
if (d->dy < 0 && ddy < d->dy) ddy = d->dy;
|
|
|
|
d->dx -= ddx;
|
|
d->dy -= ddy;
|
|
|
|
// QScrollView::setContentsPos( contentsX() + ddx, contentsY() + ddy);
|
|
QScrollView::scrollBy(ddx, ddy);
|
|
}
|
|
|
|
void KScrollView::startScrolling()
|
|
{
|
|
d->scrolling = true;
|
|
d->timer.start(SCROLL_TICK, false);
|
|
}
|
|
|
|
void KScrollView::stopScrolling()
|
|
{
|
|
d->timer.stop();
|
|
d->dx = d->dy = 0;
|
|
d->scrolling = false;
|
|
}
|
|
|
|
// Overloaded from QScrollView and QScrollBar
|
|
void KScrollView::wheelEvent( QWheelEvent *e )
|
|
{
|
|
int pageStep = verticalScrollBar()->pageStep();
|
|
int lineStep = verticalScrollBar()->lineStep();
|
|
int step = QMIN( QApplication::wheelScrollLines()*lineStep, pageStep );
|
|
if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
|
|
step = pageStep;
|
|
|
|
int dy = (e->delta()*step)/120;
|
|
scrollBy(0,-dy);
|
|
e->accept();
|
|
}
|
|
|
|
#include "kscrollview.moc"
|