diff options
author | Robert Griebl <rgriebl@trolltech.com> | 2010-03-30 13:24:24 +0200 |
---|---|---|
committer | Robert Griebl <rgriebl@trolltech.com> | 2010-03-30 13:24:24 +0200 |
commit | d71d6f2c96c0b591241e18b480b1a12290e6c3e6 (patch) | |
tree | a9e62d54bf23e682f3d744c54b9fa20bd7a131c6 | |
parent | d6b663fcd6230492728d7c4b4a304b209533232c (diff) |
compile fixes
-rw-r--r-- | qkineticscroller.cpp | 193 | ||||
-rw-r--r-- | qkineticscroller.h | 37 | ||||
-rw-r--r-- | qkineticscroller_p.h | 32 |
3 files changed, 142 insertions, 120 deletions
diff --git a/qkineticscroller.cpp b/qkineticscroller.cpp index cdc5e9c..f60f51e 100644 --- a/qkineticscroller.cpp +++ b/qkineticscroller.cpp @@ -142,7 +142,7 @@ void QKineticScroller::reset() { Q_D(QKineticScroller); - d->setState(Inactive); + d->setState(StateInactive); } /*! @@ -158,8 +158,7 @@ void QKineticScroller::reset() \value AutoScrolling Scrolling is occurring without direct user input. */ - -static const char *stateName(QKineticScroller::State state) +const char *QKineticScrollerPrivate::stateName(QKineticScroller::State state) { switch (state) { case QKineticScroller::StateInactive: return "inactive"; @@ -167,16 +166,18 @@ static const char *stateName(QKineticScroller::State state) case QKineticScroller::StateDragging: return "dragging"; case QKineticScroller::StateScrolling: return "scrolling"; case QKineticScroller::StateBackshooting: return "backshooting"; - default: return "(invalid)"; + default: return "(invalid)"; + } } -static const char *inputName(QKineticScroller::Input input) +const char *QKineticScrollerPrivate::inputName(QKineticScroller::Input input) { switch (input) { case QKineticScroller::InputPress: return "press"; case QKineticScroller::InputMove: return "move"; case QKineticScroller::InputRelease: return "release"; - default: return "(invalid)"; + default: return "(invalid)"; + } } @@ -184,36 +185,37 @@ static const char *inputName(QKineticScroller::Input input) void QKineticScrollerPrivate::timerEvent(QTimerEvent *e) { - Q_Q(QKineticScroller); - if (e->timerId() != timerId) { QObject::timerEvent(e); return; } struct timerevent { - State state; - bool (QKineticScrollerPrivate::*handler)(qint64 elapsed); + QKineticScroller::State state; + QElapsedTimer *elapsedTimer; + typedef void (QKineticScrollerPrivate::*timerhandler_t)(qint64 elapsed); + timerhandler_t handler; }; - + timerevent timerevents[] = { - { StateDragging, QKineticScrollerPrivate::timerEventWhileDragging } - { StateScrolling, QKineticScrollerPrivate::timerEventWhileScrolling } - { StateBackshooting, QKineticScrollerPrivate::timerEventWhileBackshooting } - } - - for (int i = 0; i < sizeof(timerevents) / sizeof(*timerevents); ++i) { + { QKineticScroller::StateDragging, &dragTimer, &QKineticScrollerPrivate::timerEventWhileDragging }, + { QKineticScroller::StateScrolling, &scrollTimer, &QKineticScrollerPrivate::timerEventWhileScrolling }, + { QKineticScroller::StateBackshooting, &backshootTimer, &QKineticScrollerPrivate::timerEventWhileBackshooting } + }; + + for (int i = 0; i < int(sizeof(timerevents) / sizeof(*timerevents)); ++i) { timerevent *te = timerevents + i; - + if (state == te->state) { - te->handler(elapsed.restart()); + qint64 elapsed = te->elapsedTimer ? te->elapsedTimer->restart() : 0; + (this->*te->handler)(elapsed); return; } } qWarning() << "Unhandled timer event, while in state " << stateName(state); killTimer(timerId); - timerId = 0; + timerId = 0; } bool QKineticScroller::handleInput(Input input, const QPointF &position, qint64 timestamp) @@ -223,72 +225,73 @@ bool QKineticScroller::handleInput(Input input, const QPointF &position, qint64 struct statechange { State state; Input input; - bool (QKineticScrollerPrivate::*handler)(Input input, const QPointF &position, qint64 timestamp); + typedef bool (QKineticScrollerPrivate::*inputhandler_t)(Input input, const QPointF &position, qint64 timestamp); + inputhandler_t handler; }; - + statechange statechanges[] = { - { StateInactive, InputPress, QKineticScrollerPrivate::pressWhileInactive }, - { StatePressed, InputMove, QKineticScrollerPrivate::moveWhilePressed }, - { StatePressed, InputRelease, QKineticScrollerPrivate::releaseWhilePressed }, - { StateDragging, InputMove, QKineticScrollerPrivate::moveWhileDragging }, - { StateDragging, InputRelease, QKineticScrollerPrivate::releaseWhileDragging }, - { StateScrolling, InputPress, QKineticScrollerPrivate::pressWhileScrolling } - } - - for (int i = 0; i < sizeof(statechanges) / sizeof(*statechanges); ++i) { - statchange *sc = statechanges + i; - + { StateInactive, InputPress, &QKineticScrollerPrivate::pressWhileInactive }, + { StatePressed, InputMove, &QKineticScrollerPrivate::moveWhilePressed }, + { StatePressed, InputRelease, &QKineticScrollerPrivate::releaseWhilePressed }, + { StateDragging, InputMove, &QKineticScrollerPrivate::moveWhileDragging }, + { StateDragging, InputRelease, &QKineticScrollerPrivate::releaseWhileDragging }, + { StateScrolling, InputPress, &QKineticScrollerPrivate::pressWhileScrolling } + }; + + for (int i = 0; i < int(sizeof(statechanges) / sizeof(*statechanges)); ++i) { + statechange *sc = statechanges + i; + if (d->state == sc->state && input == sc->input) - return sc->handler(input, position, timestamp); + return (d->*sc->handler)(input, position, timestamp); } - + qWarning() << "Unhandled input: got input " << d->inputName(input) << " while in state " << d->stateName(d->state); - return false; + return false; } - -QVariant QKineticScroller::scrollMetrics(ScrollMetrics metric) const + +QVariant QKineticScroller::scrollMetric(ScrollMetric metric) const { - Q_D(QKineticScroller); - + Q_D(const QKineticScroller); + switch (metric) { case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor; case FrictionCoefficent: return d->frictionCoefficent; case OvershootFrictionCoefficent: return d->overshootFricitionCoefficient; case OvershootSpringConstant: return d->overshootSpringConstant; - case OvershootMaximumDistance: return d->overshootMaximumDistance; + case OvershootMaximumDistance: return d->overshootMaximumDistance; case DragStartDistance: return d->dragStartDistance; - case DragStartDirectionErrorMargin: return d->dragStartDirectionErrorMargin; + case DragStartDirectionErrorMargin: return d->dragStartDirectionErrorMargin; case MinimumVelocity: return d->minimumVelocity; case MaximumVelocity: return d->maximumVelocity; case MaximumNonAcceleratedVelocity: return d->maximumNonAcceleratedVelocity; case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity; case AxisLockThreshold: return d->axisLockThreshold; - case FramesPerMillisecond: return d->framesPerMillisecond; + case FramesPerSecond: return d->framesPerSecond; } return QVariant(); } - -void QKineticScroller::setScrollMetrics(ScrollMetrics metric, const QVariant &value) + +void QKineticScroller::setScrollMetric(ScrollMetric metric, const QVariant &value) { Q_D(QKineticScroller); - + switch (metric) { - case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(0, value.toReal(), 1); break; - case FrictionCoefficent: d->frictionCoefficent = qBound(0, value.toReal(), 1); break; - case OvershootFrictionCoefficent: d->overshootFricitionCoefficient = qBound(0, value.toReal(), 1); break; + case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; + case FrictionCoefficent: d->frictionCoefficent = qBound(qreal(0), value.toReal(), qreal(1)); break; + case OvershootFrictionCoefficent: d->overshootFricitionCoefficient = qBound(qreal(0), value.toReal(), qreal(1)); break; case OvershootSpringConstant: d->overshootSpringConstant = value.toReal(); break; - case OvershootMaximumDistance: d->overshootMaximumDistance = value.toPointF(); break; + case OvershootMaximumDistance: d->overshootMaximumDistance = value.toPointF(); break; case DragStartDistance: d->dragStartDistance = value.toReal(); break; - case DragStartDirectionErrorMargin: d->dragStartDirectionErrorMargin = value.toReal(); break; + case DragStartDirectionErrorMargin: d->dragStartDirectionErrorMargin = value.toReal(); break; case MinimumVelocity: d->minimumVelocity = value.toReal(); break; case MaximumVelocity: d->maximumVelocity = value.toReal(); break; case MaximumNonAcceleratedVelocity: d->maximumNonAcceleratedVelocity = value.toReal(); break; case MaximumClickThroughVelocity: d->maximumClickThroughVelocity = value.toReal(); break; - case AxisLockThreshold: d->axisLockThreshold = qBound(0, value.toReal(), 1); break; - case FramesPerMillisecond: d->framesPerMillisecond = qBound(1, value.toInt(), 100); break; + case AxisLockThreshold: d->axisLockThreshold = qBound(qreal(0), value.toReal(), qreal(1)); break; + case FramesPerSecond: d->framesPerSecond = qBound(1, value.toInt(), 100); break; } } @@ -296,7 +299,7 @@ void QKineticScrollerPrivate::handleDrag(const QPointF &position, qint64 timesta { Q_Q(QKineticScroller); - QPointF deltaPixel = position - lastPostion; + QPointF deltaPixel = position - lastPosition; qint64 deltaTime = timestamp - lastTimestamp; if (axisLockThreshold) { @@ -317,13 +320,13 @@ void QKineticScrollerPrivate::handleDrag(const QPointF &position, qint64 timesta // calculate velocity (if the user would release the mouse NOW) QPointF newVelocity = calculateVelocity(deltaPixel, deltaTime); - + // restrict velocity, if content is not scrollable - QPoint maxPos = q->maximumContentPosition(); + QPointF maxPos = q->maximumContentPosition(); bool canScrollX = maxPos.x() || (overshootPolicy == QKineticScroller::OvershootAlwaysOn); bool canScrollY = maxPos.y() || (overshootPolicy == QKineticScroller::OvershootAlwaysOn); - if (!canScrolX)) { + if (!canScrollX) { deltaPixel.setX(0); newVelocity.setX(0); } @@ -374,29 +377,30 @@ QPointF qAbs(const QPointF &p) -bool QKineticScrollerPrivate::pressWhileInactive(Input, const QPointF &position, qint64 timestamp) +bool QKineticScrollerPrivate::pressWhileInactive(QKineticScroller::Input, const QPointF &position, qint64 timestamp) { Q_Q(QKineticScroller); - - if ((q->maximumContentPosition() > qreal(0)) || (overshootPolicy == QKineticScroller::OvershootAlwaysOn)) + + if ((q->maximumContentPosition() > qreal(0)) || (overshootPolicy == QKineticScroller::OvershootAlwaysOn)) { if (q->canStartScrollingAt(position)) { - lastPosition = pressPosition = position; + lastPosition = pressPosition = position; lastTimestamp = pressTimestamp = timestamp; setState(QKineticScroller::StatePressed); } } + return false; } -bool QKineticScrollerPrivate::releaseWhilePressed(Input, const QPointF &position, qint64 timestamp) +bool QKineticScrollerPrivate::releaseWhilePressed(QKineticScroller::Input, const QPointF &position, qint64 timestamp) { setState(QKineticScroller::StateInactive); return false; } -bool QKineticScrollerPrivate::moveWhilePressed(Input, const QPointF &position, qint64 timestamp) +bool QKineticScrollerPrivate::moveWhilePressed(QKineticScroller::Input, const QPointF &position, qint64 timestamp) { Q_Q(QKineticScroller); - + QPointF deltaPixel = position - pressPosition; bool moveStarted = (deltaPixel.manhattanLength() > dragStartDistance); @@ -422,8 +426,8 @@ bool QKineticScrollerPrivate::moveWhilePressed(Input, const QPointF &position, q if (moveStarted) { q->cancelPress(pressPosition); - setState(QKineticScroller::Dragging); - + setState(QKineticScroller::StateDragging); + // ignore the dragStartDistance deltaPixel = deltaPixel - deltaPixel * (dragStartDistance / deltaPixel.manhattanLength()); @@ -435,7 +439,7 @@ bool QKineticScrollerPrivate::moveWhilePressed(Input, const QPointF &position, q return moveStarted; } -bool QKineticScrollerPrivate::moveWhileDragging(Input, const QPointF &position, qint64 timestamp) +bool QKineticScrollerPrivate::moveWhileDragging(QKineticScroller::Input, const QPointF &position, qint64 timestamp) { // handleDrag updates lastPosition, lastTimestamp and velocity handleDrag(position, timestamp); @@ -444,17 +448,19 @@ bool QKineticScrollerPrivate::moveWhileDragging(Input, const QPointF &position, void QKineticScrollerPrivate::timerEventWhileDragging(qint64 timestamp) { + Q_Q(QKineticScroller); + if (!dragDistance.isNull()) setScrollPositionHelper(q->contentPosition() - overshootDistance - dragDistance); } -bool QKineticScrollerPrivate::releaseWhileDragging(Input, const QPointF &position, qint64 timestamp) +bool QKineticScrollerPrivate::releaseWhileDragging(QKineticScroller::Input, const QPointF &position, qint64 timestamp) { Q_Q(QKineticScroller); // ... - - setState(QKineticScroller::AutoScrolling); + + setState(QKineticScroller::StateScrolling); return true; } @@ -463,12 +469,12 @@ void QKineticScrollerPrivate::timerEventWhileScrolling(qint64 timestamp) Q_Q(QKineticScroller); } -bool QKineticScrollerPrivate::pressWhileScrolling(Input, const QPointF &position, qint64 timestamp) +bool QKineticScrollerPrivate::pressWhileScrolling(QKineticScroller::Input, const QPointF &position, qint64 timestamp) { oldVelocity = velocity; velocity = QPointF(0, 0); - setState(QKineticScroller::Pressed); + setState(QKineticScroller::StatePressed); return true; } @@ -480,45 +486,46 @@ void QKineticScrollerPrivate::timerEventWhileBackshooting(qint64 timestamp) void QKineticScrollerPrivate::setState(QKineticScroller::State newstate) { + Q_Q(QKineticScroller); + if (state == newstate) return; - bool startTimer = false, stopTimer = false; - switch (state) { case QKineticScroller::StatePressed: - if (newstate == QKineticScroller::Dragging) { + if (newstate == QKineticScroller::StateDragging) { if (!timerId) { timerId = startTimer(1000 / framesPerSecond); } else { qWarning() << "State change from " << stateName(state) << " to " << stateName(newstate) << ", but timer is already activate."; - } + } + } break; - case QKineticScroller::Scrolling: - case QKineticScroller::Backshooting: - if (newstate == QKineticScroller::Inactive) { + case QKineticScroller::StateScrolling: + case QKineticScroller::StateBackshooting: + if (newstate == QKineticScroller::StateInactive) { if (timerId) { killTimer(timerId); timerId = 0; } else { qWarning() << "State change from " << stateName(state) << " to " << stateName(newstate) << ", but timer is not activate."; - } + } } break; } - + switch (newstate) { - case QKineticScroller::Inactive: - case QKineticScroller::Pressed: + case QKineticScroller::StateInactive: + case QKineticScroller::StatePressed: velocity = QPointF(0, 0); break; - case QKineticScroller::Dragging: + case QKineticScroller::StateDragging: dragDistance = QPointF(0, 0); break; } qSwap(state, newstate); - emit stateChanged(newstate); + q->stateChanged(newstate); } @@ -526,29 +533,29 @@ void QKineticScrollerPrivate::setState(QKineticScroller::State newstate) Decomposes the position into a scroll and an overshoot part. Also keeps track of the current over-shooting value in overshootDist. */ -void QKineticScrollerPrivate::setScrollPositionHelper(const QPoint &pos) +void QKineticScrollerPrivate::setScrollPositionHelper(const QPointF &pos) { Q_Q(QKineticScroller); - QPointF maxPos = q->maximumScrollPosition(); + QPointF maxPos = q->maximumContentPosition(); QPointF clampedPos; - clampedPos.setX(qBound(0, pos.x(), maxPos.x())); - clampedPos.setY(qBound(0, pos.y(), maxPos.y())); + clampedPos.setX(qBound(qreal(0), pos.x(), maxPos.x())); + clampedPos.setY(qBound(qreal(0), pos.y(), maxPos.y())); bool alwaysOvershoot = (overshootPolicy == QKineticScroller::OvershootAlwaysOn); qreal overshootX = (maxPos.x() || alwaysOvershoot) ? clampedPos.x() - pos.x() : 0; qreal overshootY = (maxPos.y() || alwaysOvershoot) ? clampedPos.y() - pos.y() : 0; - if (overshootMaximumDistance) { + if (!overshootMaximumDistance.isNull()) { overshootDistance.setX(qBound(-overshootMaximumDistance.x(), overshootX, overshootMaximumDistance.x())); overshootDistance.setY(qBound(-overshootMaximumDistance.y(), overshootY, overshootMaximumDistance.y())); } else { overshootDistance = QPointF(overshootX, overshootY); } - qKSDebug() << "setPosition raw: " << pos << ", clamped: " << clampedPos << ", overshoot: " << overshootDist; - q->setScrollPosition(clampedPos, overshootPolicy == QKineticScroller::OvershootAlwaysOff ? QPoint() : overshootDistance); + qKSDebug() << "setPosition raw: " << pos << ", clamped: " << clampedPos << ", overshoot: " << overshootDistance; + q->setContentPosition(clampedPos, overshootPolicy == QKineticScroller::OvershootAlwaysOff ? QPoint() : overshootDistance); } @@ -587,7 +594,7 @@ bool QKineticScroller::canStartScrollingAt(const QPointF &position) const 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. + widget (or graphics item), preferably \bold not within its boundaries. The default implementation does nothing. */ void QKineticScroller::cancelPress(const QPointF &pressPosition) diff --git a/qkineticscroller.h b/qkineticscroller.h index 3210e11..85d4d1d 100644 --- a/qkineticscroller.h +++ b/qkineticscroller.h @@ -45,6 +45,7 @@ #include <QtCore/qmetatype.h> #include <QtCore/qpoint.h> #include <QtCore/qrect.h> +#include <QtCore/qvariant.h> QT_BEGIN_HEADER @@ -70,9 +71,10 @@ public: StateScrolling, StateBackshooting }; - + State state() const; - + void reset(); + enum OvershootPolicy { OvershootWhenScrollable, @@ -82,41 +84,43 @@ public: OvershootPolicy overshootPolicy() const; void setOvershootPolicy(OvershootPolicy policy); - + enum ScrollMetric { DragVelocitySmoothingFactor, // [0..1] v = v_new* DASF + v_old * (1-DASF) - + /* A factor between \c 0 and \c 1 */ - + FrictionCoefficent, // [0..1] - OvershootFrictionCoefficent, // [0..1] + OvershootFrictionCoefficent, // [0..1] OvershootSpringConstant, // [0...[ OvershootMaximumDistance, // ([m], [m]) - + DragStartDistance, // [m] DragStartDirectionErrorMargin, // [] dx/dy - + MinimumVelocity, // [m/s] MaximumVelocity, // [m/s] MaximumNonAcceleratedVelocity, // [m/s] MaximumClickThroughVelocity, // [m/s] //fastVelocityFactor???? - + AxisLockThreshold, // [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) - - FramesPerMilliSecond, // [frames/s] - + + FramesPerSecond, // [frames/s] + FastSwipeMaximumTimeBetweenReleases, // [s] FastSwipeMinimumVelocity, // [m/s] - FastSwipeAccelerationFactor, // [m/s^2] + FastSwipeAccelerationFactor, // [m/s^2] }; - + QVariant scrollMetric(ScrollMetric metric) const; void setScrollMetric(ScrollMetric metric, const QVariant &value); - + protected: + explicit QKineticScroller(); + virtual QSizeF viewportSize() const = 0; virtual QPointF maximumContentPosition() const = 0; virtual QPointF contentPosition() const = 0; @@ -132,7 +136,7 @@ protected: InputRelease }; - bool handleInput(Input input, const QPointF &position, qint64 timestamp) + bool handleInput(Input input, const QPointF &position, qint64 timestamp); QKineticScroller(QKineticScrollerPrivate &dd); QScopedPointer<QKineticScrollerPrivate> d_ptr; @@ -140,7 +144,6 @@ protected: private: Q_DISABLE_COPY(QKineticScroller) Q_DECLARE_PRIVATE(QKineticScroller) - }; QT_END_NAMESPACE diff --git a/qkineticscroller_p.h b/qkineticscroller_p.h index 8b4b99b..8dd6e99 100644 --- a/qkineticscroller_p.h +++ b/qkineticscroller_p.h @@ -53,8 +53,9 @@ #include <QTime> #include <QPointer> #include <QObject> -#include <QKineticScroller> +#include <qkineticscroller.h> #include <QEvent> +#include <QElapsedTimer> QT_BEGIN_NAMESPACE @@ -83,10 +84,15 @@ public: void timerEventWhileBackshooting(qint64 timestamp); void handleDrag(const QPointF &position, qint64 timestamp); - void setScrollPositionHelper(const QPoint &position); - + void setScrollPositionHelper(const QPointF &position); + + static const char *stateName(QKineticScroller::State state); + static const char *inputName(QKineticScroller::Input input); + + QKineticScroller *q_ptr; + // metrics - + qreal dragVelocitySmoothingFactor; qreal frictionCoefficent; qreal overshootFricitionCoefficient; @@ -97,24 +103,30 @@ public: qreal maximumVelocity; qreal minimumVelocity; qreal maximumNonAcceleratedVelocity; - qreal maximumClickThroughVelocity; + qreal maximumClickThroughVelocity; qreal axisLockThreshold; - int framesPerMillisecond; + int framesPerSecond; + + QKineticScroller::OvershootPolicy overshootPolicy; // state - + bool enabled; QKineticScroller::State state; QPointF velocity; QPointF oldVelocity; - + QPointF pressPosition; QPointF lastPosition; + qint64 pressTimestamp; qint64 lastTimestamp; - + QPointF dragDistance; QPointF overshootDistance; - + + QElapsedTimer dragTimer; + QElapsedTimer scrollTimer; + QElapsedTimer backshootTimer; int timerId; }; |