From 7f241982bf395fa703d8c0c91fa4e7e25085cca3 Mon Sep 17 00:00:00 2001 From: Ralf Engels Date: Fri, 28 May 2010 19:34:05 +0200 Subject: Revert "Using scrollevents" This reverts commit 536b3fb03ace6d49697d0cda19368133672de778. --- scroller/qflickgesture.cpp | 21 ++---- scroller/qkineticscroller.cpp | 161 +++++++++++++++++++++++++++++------------- scroller/qkineticscroller.h | 12 +++- scroller/qkineticscroller_p.h | 16 +---- testapp/main.cpp | 15 ++-- testapp/settingswidget.cpp | 6 -- testapp/testapp.pro | 4 +- 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"<parent(); - QKineticScroller *res = 0; - - if (!target) - return 0; - - res = target->property("kineticScroller").value(); - if (res) - return res; - - if (!target->parent()) + if (!target || !target->parent()) return 0; - res = target->parent()->property("kineticScroller").value(); - return res; + QKineticScroller *s = target->parent()->property("kineticScroller").value(); + return s; } QPointer target; @@ -92,7 +83,6 @@ QFlickGestureRecognizer::QFlickGestureRecognizer() QGesture *QFlickGestureRecognizer::create(QObject *target) { - qDebug() << "Recognizer::create for"<isWidgetType():false); if (target && target->isWidgetType()) { QWidget *widget = static_cast(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"<(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 #include #include -#include #include 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 "< 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 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 #include #include +#include #if QT_VERSION < 0x040700 # include #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 receiver; // the object this scroller was registered for - - QPointer 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 #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(); @@ -134,13 +127,13 @@ private: #endif // set a new kinetic scroller if (QAbstractScrollArea *area = qobject_cast(w)) { - area->viewport()->grabGesture(gestureType); - QKineticScroller *newScroller = new QKineticScroller(area); + QScrollAreaKineticScroller *newScroller = new QScrollAreaKineticScroller(); + newScroller->setWidget(area); w->setProperty("kineticScroller", QVariant::fromValue(static_cast(newScroller)) ); return newScroller; } else if (QWebView *web = qobject_cast(w)) { - web->grabGesture(gestureType); - QKineticScroller *newScroller = new QKineticScroller(web); + QWebViewKineticScroller *newScroller = new QWebViewKineticScroller(); + newScroller->setWidget(web); w->setProperty("kineticScroller", QVariant::fromValue(static_cast(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(m_scroller)->viewportSize(); QPointF maxc = static_cast(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 -- cgit v1.2.3