summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Engels <ralf.engels@nokia.com>2010-05-28 19:34:05 +0200
committerRalf Engels <ralf.engels@nokia.com>2010-05-28 19:34:05 +0200
commit7f241982bf395fa703d8c0c91fa4e7e25085cca3 (patch)
tree5926284f010477c4dcb704e9a6877adbef049e6b
parentd16e7a55988277e34492f6ded8e7b197d26e99e0 (diff)
Revert "Using scrollevents"
This reverts commit 536b3fb03ace6d49697d0cda19368133672de778.
-rw-r--r--scroller/qflickgesture.cpp21
-rw-r--r--scroller/qkineticscroller.cpp161
-rw-r--r--scroller/qkineticscroller.h12
-rw-r--r--scroller/qkineticscroller_p.h16
-rw-r--r--testapp/main.cpp15
-rw-r--r--testapp/settingswidget.cpp6
-rw-r--r--testapp/testapp.pro4
7 files changed, 136 insertions, 99 deletions
diff --git a/scroller/qflickgesture.cpp b/scroller/qflickgesture.cpp
index a1eef75..1feb050 100644
--- a/scroller/qflickgesture.cpp
+++ b/scroller/qflickgesture.cpp
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
+
class QFlickGesturePrivate
{
public:
@@ -57,21 +58,11 @@ public:
QKineticScroller *scroller()
{
- // qDebug() << "QKineticScroller::scroller"<<target<<"parent:"<<target->parent();
- QKineticScroller *res = 0;
-
- if (!target)
- return 0;
-
- res = target->property("kineticScroller").value<QKineticScroller *>();
- if (res)
- return res;
-
- if (!target->parent())
+ if (!target || !target->parent())
return 0;
- res = target->parent()->property("kineticScroller").value<QKineticScroller *>();
- return res;
+ QKineticScroller *s = target->parent()->property("kineticScroller").value<QKineticScroller *>();
+ return s;
}
QPointer<QWidget> target;
@@ -92,7 +83,6 @@ QFlickGestureRecognizer::QFlickGestureRecognizer()
QGesture *QFlickGestureRecognizer::create(QObject *target)
{
- qDebug() << "Recognizer::create for"<<target<<"widget?"<<(target?target->isWidgetType():false);
if (target && target->isWidgetType()) {
QWidget *widget = static_cast<QWidget *>(target);
#if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
@@ -115,7 +105,6 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
QFlickGesturePrivate *d = q->d;
QKineticScroller *scroller = d->scroller();
- // qDebug() << "QFlickGestureRecognizer::recognize for"<<scroller;
if (!scroller)
return QGestureRecognizer::Ignore;
@@ -200,8 +189,10 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
void QFlickGestureRecognizer::reset(QGesture *state)
{
QFlickGesture *flick = static_cast<QFlickGesture*>(state);
+ /*
flick->d->target = 0;
flick->d->timer.start();
+ */
QGestureRecognizer::reset(state);
}
diff --git a/scroller/qkineticscroller.cpp b/scroller/qkineticscroller.cpp
index 75556a4..b835efc 100644
--- a/scroller/qkineticscroller.cpp
+++ b/scroller/qkineticscroller.cpp
@@ -44,14 +44,11 @@
#include <QApplication>
#include <QDesktopWidget>
#include <QtCore/qmath.h>
-#include <QtGui/qevent.h>
#include <QtDebug>
QT_BEGIN_NAMESPACE
-bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
#define KINETIC_SCROLLER_DEBUG
#ifdef KINETIC_SCROLLER_DEBUG
@@ -144,24 +141,22 @@ inline int qSign(qreal r)
/*!
Constructs a new kinetic scroller.
*/
-QKineticScroller::QKineticScroller(QObject *receiver)
+QKineticScroller::QKineticScroller()
: d_ptr(new QKineticScrollerPrivate())
{
Q_D(QKineticScroller);
d->q_ptr = this;
d->init();
- d->receiver = receiver;
}
/*! \internal
*/
-QKineticScroller::QKineticScroller(QObject *receiver, QKineticScrollerPrivate &dd)
+QKineticScroller::QKineticScroller(QKineticScrollerPrivate &dd)
: d_ptr(&dd)
{
Q_D(QKineticScroller);
d->q_ptr = this;
d->init();
- d->receiver = receiver;
}
/*!
@@ -195,7 +190,7 @@ QKineticScrollerPrivate::QKineticScrollerPrivate()
, scrollToY(false)
, overshootX(false)
, overshootY(false)
- , firstScroll(false)
+ , cancelPress(false)
, debugHook(0)
, debugHookUser(0)
{ }
@@ -210,11 +205,6 @@ void QKineticScrollerPrivate::init()
q->resetScrollMetrics();
}
-void QKineticScrollerPrivate::sendEvent(QObject *o, QEvent *e)
-{
- qt_sendSpontaneousEvent(o, e);
-}
-
void QKineticScroller::registerDebugHook(void (*callback)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition), void *user)
{
Q_D(QKineticScroller);
@@ -599,6 +589,8 @@ QPointF QKineticScrollerPrivate::calculateVelocity(qreal time)
void QKineticScrollerPrivate::handleDrag(const QPointF &position, qint64 timestamp)
{
+ Q_Q(QKineticScroller);
+
QPointF deltaPixel = position - lastPosition;
qint64 deltaTime = timestamp - lastTimestamp;
@@ -622,7 +614,7 @@ void QKineticScrollerPrivate::handleDrag(const QPointF &position, qint64 timesta
updateVelocity(deltaPixel, deltaTime);
// restrict velocity, if content is not scrollable
- QPointF maxPos = maximumContentPosition;
+ QPointF maxPos = q->maximumContentPosition();
bool canScrollX = maxPos.x() || (hOvershootPolicy == QKineticScroller::OvershootAlwaysOn);
bool canScrollY = maxPos.y() || (vOvershootPolicy == QKineticScroller::OvershootAlwaysOn);
@@ -654,24 +646,15 @@ void QKineticScrollerPrivate::handleDrag(const QPointF &position, qint64 timesta
bool QKineticScrollerPrivate::pressWhileInactive(QKineticScroller::Input, const QPointF &position, qint64 timestamp)
{
- QScrollPrepareEvent spe(position);
- qDebug() << "Sending prepare event to "<<receiver;
- sendEvent(receiver, &spe);
-
- qDebug() << "Returned with "<<spe.isAccepted()<<"for"<<spe.target();
- if (spe.isAccepted() && spe.target()) {
- target = spe.target();
- viewportSize = spe.viewportSize();
- maximumContentPosition = spe.maxContentPos();
- contentPosition = spe.contentPos();
-
- if ((maximumContentPosition > qreal(0)) ||
- (hOvershootPolicy == QKineticScroller::OvershootAlwaysOn) ||
- (vOvershootPolicy == QKineticScroller::OvershootAlwaysOn)) {
+ Q_Q(QKineticScroller);
+ if ((q->maximumContentPosition() > qreal(0)) ||
+ (hOvershootPolicy == QKineticScroller::OvershootAlwaysOn) ||
+ (vOvershootPolicy == QKineticScroller::OvershootAlwaysOn)) {
+ if (q->canStartScrollingAt(position)) {
lastPosition = pressPosition = position;
lastTimestamp = pressTimestamp = timestamp;
- firstScroll = true;
+ cancelPress = true;
setState(QKineticScroller::StatePressed);
}
}
@@ -699,7 +682,7 @@ bool QKineticScrollerPrivate::moveWhilePressed(QKineticScroller::Input, const QP
qreal deltaXtoY = qAbs(pressPosition.x() - position.x()) - qAbs(pressPosition.y() - position.y());
deltaXtoY /= pixelPerMeter;
- QPointF maxPos = maximumContentPosition;
+ QPointF maxPos = q->maximumContentPosition();
bool canScrollX = (maxPos.x() > 0);
bool canScrollY = (maxPos.y() > 0);
@@ -718,6 +701,8 @@ bool QKineticScrollerPrivate::moveWhilePressed(QKineticScroller::Input, const QP
}
if (moveStarted) {
+ if (cancelPress)
+ q->cancelPress(pressPosition);
setState(QKineticScroller::StateDragging);
// subtract the dragStartDistance
@@ -750,10 +735,12 @@ void QKineticScrollerPrivate::timerEventWhileDragging()
bool QKineticScrollerPrivate::releaseWhileDragging(QKineticScroller::Input, const QPointF &, qint64 timestamp)
{
+ Q_Q(QKineticScroller);
+
// calculate the fastSwipe velocity
- QPointF maxPos = maximumContentPosition;
+ QPointF maxPos = q->maximumContentPosition();
QPointF fastSwipeVelocity = QPoint(0, 0);
- QSizeF size = viewportSize;
+ QSizeF size = q->viewportSize();
if (size.width())
fastSwipeVelocity.setX(qMin(maximumVelocity, maxPos.x() / size.width() * fastSwipeBaseVelocity));
if (size.height())
@@ -824,6 +811,7 @@ bool QKineticScrollerPrivate::pressWhileScrolling(QKineticScroller::Input, const
{
lastPosition = pressPosition = position;
lastTimestamp = pressTimestamp = timestamp;
+ cancelPress = false;
setState(QKineticScroller::StatePressed);
return true;
}
@@ -905,7 +893,7 @@ void QKineticScrollerPrivate::setState(QKineticScroller::State newstate)
be reached after a platform-defined time span (1 second for Maemo 5).
The final speed at the end position is not guaranteed to be zero.
- \sa ensureVisible()
+ \sa ensureVisible(), maximumContentPosition()
*/
void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime)
{
@@ -918,7 +906,7 @@ void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime)
qreal time = qreal(scrollTime) / 1000;
- if ((pos == d->contentPosition) ||
+ if ((pos == contentPosition()) ||
(d->state == QKineticScroller::StatePressed) ||
(d->state == QKineticScroller::StateDragging)) {
return;
@@ -945,10 +933,10 @@ void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime)
// vstart = ((lDF / 2) * time ^ 2 + (pos - contentPos())) / (eDB ^ time / ln(eDB) + C)
// (for C = -1/ln(eDB) )
- QPointF scrollDir(qSign(pos.x() - d->contentPosition.x()),
- qSign(pos.y() - d->contentPosition.y()));
+ QPointF scrollDir(qSign(pos.x() - contentPosition().x()),
+ qSign(pos.y() - contentPosition().y()));
- QPointF v = (scrollDir * (d->linearDecelerationFactor / qreal(2)) * qreal(time) * qreal(time) + (pos - d->contentPosition) / d->pixelPerMeter);
+ QPointF v = (scrollDir * (d->linearDecelerationFactor / qreal(2)) * qreal(time) * qreal(time) + (pos - contentPosition()) / d->pixelPerMeter);
if (d->exponentialDecelerationBase != qreal(1))
v /= (qPow(d->exponentialDecelerationBase, time) - 1) / qLn(d->exponentialDecelerationBase);
else
@@ -971,16 +959,16 @@ void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime)
nearest valid position. The default value for both margins is 50 pixels.
This function performs the actual scrolling by calling scrollTo().
+
+ \sa maximumContentPosition()
*/
void QKineticScroller::ensureVisible(const QPointF &pos, int xmargin, int ymargin, int scrollTime)
{
- Q_D(QKineticScroller);
-
- QSizeF visible = d->viewportSize;
- QPointF currentPos = d->contentPosition;
+ QSizeF visible = viewportSize();
+ QPointF currentPos = contentPosition();
qKSDebug() << "QKS::ensureVisible(" << pos << " [pix], " << xmargin << " [pix], " << ymargin << " [pix], " << scrollTime << "[ms])";
- qKSDebug() << " --> content position:" << d->contentPosition;
+ qKSDebug() << " --> content position:" << contentPosition();
QRectF posRect(pos.x() - xmargin, pos.y() - ymargin, 2 * xmargin, 2 * ymargin);
QRectF visibleRect(currentPos, visible);
@@ -1016,12 +1004,14 @@ void QKineticScroller::ensureVisible(const QPointF &pos, int xmargin, int ymargi
*/
void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos)
{
+ Q_Q(QKineticScroller);
+
if (state == QKineticScroller::StateDragging && overshootDragResistanceFactor)
overshootPosition /= overshootDragResistanceFactor;
- QPointF oldPos = contentPosition + overshootPosition;
+ QPointF oldPos = q->contentPosition() + overshootPosition;
QPointF newPos = oldPos + deltaPos;
- QPointF maxPos = maximumContentPosition;
+ QPointF maxPos = q->maximumContentPosition();
QPointF oldScrollToDist = scrollToPosition - oldPos;
QPointF newScrollToDist = scrollToPosition - newPos;
@@ -1140,12 +1130,7 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos)
overshootPosition.setX(newOvershootX);
overshootPosition.setY(newOvershootY);
- if( target ) {
- QScrollEvent se(newClampedPos, overshootPosition, firstScroll);
- sendEvent(target, &se);
- firstScroll = false;
- }
- contentPosition = newClampedPos;
+ q->setContentPosition(newClampedPos, overshootPosition);
if (debugHook)
debugHook(debugHookUser, calculateVelocity(qreal(scrollAbsoluteTimer.elapsed()) / 1000), newClampedPos, overshootPosition);
@@ -1167,6 +1152,38 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos)
\value OvershootAlwaysOn Overshooting is always enabled (even when the content is not scrollable).
*/
+
+/*!
+ If kinetic scrolling can be started at the given content's \a position,
+ this function needs to return true; otherwise it needs to return false.
+
+ The default value is true, regardless of \a position.
+*/
+bool QKineticScroller::canStartScrollingAt(const QPointF &position) const
+{
+ Q_UNUSED(position);
+ return true;
+}
+
+/*!
+ Since a mouse press is always delivered normally when the scroller is in
+ the StateInactive state, we may need to cancel it as soon as the user
+ has moved the mouse far enough to actually start a kinetic scroll
+ operation.
+
+ The \a pressPosition parameter can be used to find out which widget (or
+ graphics item) received the mouse press in the first place.
+
+ Subclasses may choose to simulate a fake mouse release event for that
+ widget (or graphics item), preferably \bold not within its boundaries.
+ The default implementation does nothing.
+*/
+void QKineticScroller::cancelPress(const QPointF &pressPosition)
+{
+ Q_UNUSED(pressPosition);
+}
+
+
/*!
This function get called whenever the state of the kinetic scroller changes.
The old state is supplied as \a oldState, while the new state is returned by
@@ -1181,4 +1198,48 @@ void QKineticScroller::stateChanged(State oldState)
Q_UNUSED(oldState);
}
+/*!
+ \fn QPointF QKineticScroller::maximumContentPosition() const
+
+ Returns the maximum valid content position. The minimum is always \c
+ (0,0).
+
+ \sa scrollTo()
+*/
+
+/*!
+ \fn QSizeF QKineticScroller::viewportSize() const
+
+ Returns the size of the currently visible content positions. In the
+ case where an QAbstractScrollArea is used, this is equivalent to the
+ viewport() size.
+
+ \sa scrollTo()
+*/
+
+/*!
+ \fn QPointF QKineticScroller::contentPosition() const
+
+ \brief Returns the current position of the content.
+
+ Note that overshooting is not considered to be "real" scrolling so the
+ position might be (0,0) even if the user is currently dragging the
+ widget outside the "normal" maximumContentPosition().
+
+ \sa maximumContentPosition()
+*/
+
+
+/*!
+ \fn void QKineticScroller::setContentPosition(const QPointF &position, const QPointF &overshoot)
+
+ Set the content's \a position. This parameter will always be in the
+ valid range QPointF(0, 0) and maximumContentPosition().
+
+ In the case where overshooting is required, the \a overshoot parameter
+ will give the direction and the absolute distance to overshoot.
+
+ \sa maximumContentPosition()
+*/
+
QT_END_NAMESPACE
diff --git a/scroller/qkineticscroller.h b/scroller/qkineticscroller.h
index 610eb2f..56bf733 100644
--- a/scroller/qkineticscroller.h
+++ b/scroller/qkineticscroller.h
@@ -59,7 +59,6 @@ class QKineticScrollerPrivate;
class QKineticScroller
{
public:
- explicit QKineticScroller(QObject *receiver);
virtual ~QKineticScroller();
bool isEnabled() const;
@@ -131,7 +130,16 @@ public:
void registerDebugHook(void (*callback)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition), void *user);
protected:
+ explicit QKineticScroller();
+
+ virtual QSizeF viewportSize() const = 0;
+ virtual QPointF maximumContentPosition() const = 0;
+ virtual QPointF contentPosition() const = 0;
+ virtual void setContentPosition(const QPointF &pos, const QPointF &overshootDelta) = 0;
+
virtual void stateChanged(State oldState);
+ virtual bool canStartScrollingAt(const QPointF &pos) const;
+ virtual void cancelPress(const QPointF &pressPos);
enum Input {
InputPress,
@@ -141,7 +149,7 @@ protected:
bool handleInput(Input input, const QPointF &position, qint64 timestamp);
- QKineticScroller(QObject *receiver, QKineticScrollerPrivate &dd);
+ QKineticScroller(QKineticScrollerPrivate &dd);
QScopedPointer<QKineticScrollerPrivate> d_ptr;
private:
diff --git a/scroller/qkineticscroller_p.h b/scroller/qkineticscroller_p.h
index 0f5e030..6036beb 100644
--- a/scroller/qkineticscroller_p.h
+++ b/scroller/qkineticscroller_p.h
@@ -54,6 +54,7 @@
#include <QPointer>
#include <QObject>
#include <qkineticscroller.h>
+#include <QEvent>
#if QT_VERSION < 0x040700
# include <QTime>
#else
@@ -62,9 +63,6 @@
QT_BEGIN_NAMESPACE
-class QEvent;
-class QTimerEvent;
-
class QKineticScrollerPrivate : public QObject
{
Q_OBJECT
@@ -75,8 +73,6 @@ public:
virtual ~QKineticScrollerPrivate();
void init();
- void sendEvent(QObject *o, QEvent *e);
-
void setState(QKineticScroller::State s);
bool pressWhileInactive(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
@@ -123,14 +119,6 @@ public:
qreal fastSwipeMaximumTime;
int framesPerSecond;
- // widget info
- QPointer<QObject> receiver; // the object this scroller was registered for
-
- QPointer<QObject> target;
- QSizeF viewportSize;
- QPointF maximumContentPosition;
- QPointF contentPosition;
-
// state
bool enabled;
@@ -169,7 +157,7 @@ public:
qreal overshootStartTimeY;
int timerId;
- bool firstScroll;
+ bool cancelPress;
void (*debugHook)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition);
void *debugHookUser;
diff --git a/testapp/main.cpp b/testapp/main.cpp
index 3dd4e1e..c08c745 100644
--- a/testapp/main.cpp
+++ b/testapp/main.cpp
@@ -16,7 +16,6 @@
#endif
#include "qscrollareakineticscroller.h"
-#include <qflickgesture.h>
#include "qwebviewkineticscroller.h"
#include "settingswidget.h"
@@ -121,12 +120,6 @@ private:
QKineticScroller *installKineticScroller(QWidget *w)
{
- static Qt::GestureType gestureType = (Qt::GestureType)0;
- // need to register the gesture type
- if( !gestureType ) {
- gestureType = QGestureRecognizer::registerRecognizer( new QFlickGestureRecognizer() );
- }
-
#if defined(Q_WS_MAEMO_5)
// remove the old kinetic scroller if any
QAbstractKineticScroller *oldScroller = w->property("kineticScroller").value<QAbstractKineticScroller *>();
@@ -134,13 +127,13 @@ private:
#endif
// set a new kinetic scroller
if (QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(w)) {
- area->viewport()->grabGesture(gestureType);
- QKineticScroller *newScroller = new QKineticScroller(area);
+ QScrollAreaKineticScroller *newScroller = new QScrollAreaKineticScroller();
+ newScroller->setWidget(area);
w->setProperty("kineticScroller", QVariant::fromValue(static_cast<QKineticScroller*>(newScroller)) );
return newScroller;
} else if (QWebView *web = qobject_cast<QWebView *>(w)) {
- web->grabGesture(gestureType);
- QKineticScroller *newScroller = new QKineticScroller(web);
+ QWebViewKineticScroller *newScroller = new QWebViewKineticScroller();
+ newScroller->setWidget(web);
w->setProperty("kineticScroller", QVariant::fromValue(static_cast<QKineticScroller*>(newScroller)) );
return newScroller;
} else {
diff --git a/testapp/settingswidget.cpp b/testapp/settingswidget.cpp
index 30f1d90..e0f5b95 100644
--- a/testapp/settingswidget.cpp
+++ b/testapp/settingswidget.cpp
@@ -265,10 +265,8 @@ void SettingsWidget::addToGrid(QGridLayout *grid, QWidget *label, int widgetCoun
class HackScroller : public QKineticScroller {
public:
- /*
using QKineticScroller::viewportSize;
using QKineticScroller::maximumContentPosition;
- */
};
class HackSpinBox : public QSpinBox {
@@ -386,12 +384,8 @@ void SettingsWidget::setKineticScroller(QKineticScroller *scroller)
m_vospolicy->setCurrentIndex(m_vospolicy->findData(m_scroller->verticalOvershootPolicy()));
- /*
QSizeF vp = static_cast<HackScroller *>(m_scroller)->viewportSize();
QPointF maxc = static_cast<HackScroller *>(m_scroller)->maximumContentPosition();
- */
- QSizeF vp(200, 200);
- QPointF maxc(100, 1000);
m_scrollx->setRange(int(-vp.width()), int(maxc.x() + vp.width()));
m_scrolly->setRange(int(-vp.height()), int(maxc.y() + vp.height()));
diff --git a/testapp/testapp.pro b/testapp/testapp.pro
index 585fd4c..8f9d20a 100644
--- a/testapp/testapp.pro
+++ b/testapp/testapp.pro
@@ -15,8 +15,10 @@ win32:PRE_TARGETDEPS += ../scroller/scroller.lib
QT += webkit network
# Input
-HEADERS += plotwidget.h settingswidget.h
+HEADERS += plotwidget.h qscrollareakineticscroller.h qwebviewkineticscroller.h settingswidget.h
SOURCES += main.cpp \
plotwidget.cpp \
+ qscrollareakineticscroller.cpp \
+ qwebviewkineticscroller.cpp \
settingswidget.cpp
macx:LIBS += -frameworks Cocoa