summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Engels <ralf.engels@nokia.com>2010-07-02 18:40:54 +0200
committerRalf Engels <ralf.engels@nokia.com>2010-07-02 18:40:54 +0200
commit61d18dd5ff3310f3a3831814d86a5283d1c4910d (patch)
tree061516fc3557122f1c8372b88d7e6944680024a9
parente3c1d7d45146fe99ef766a043c9d9eca3b4e22ed (diff)
New architecturescrollevent
-rw-r--r--scroller/qflickgesture.cpp256
-rw-r--r--scroller/qflickgesture.h30
-rw-r--r--scroller/qkineticscroller.cpp1182
-rw-r--r--scroller/qkineticscroller.h160
-rw-r--r--scroller/qkineticscroller_mac.mm69
-rw-r--r--scroller/qkineticscroller_maemo5.cpp55
-rw-r--r--scroller/qkineticscroller_p.h180
-rw-r--r--scroller/scroller.pro8
-rw-r--r--testapp/main.cpp16
-rw-r--r--testapp/settingswidget.cpp28
-rw-r--r--testapp/settingswidget.h3
11 files changed, 206 insertions, 1781 deletions
diff --git a/scroller/qflickgesture.cpp b/scroller/qflickgesture.cpp
index 6fa9dde..375fb62 100644
--- a/scroller/qflickgesture.cpp
+++ b/scroller/qflickgesture.cpp
@@ -39,177 +39,199 @@
**
****************************************************************************/
+#include <QGesture>
+#include <QEvent>
+#include <QWidget>
+
#include "qflickgesture.h"
-#include "qgesture.h"
-#include "qevent.h"
-#include "qwidget.h"
-#include "qabstractscrollarea.h"
-#include "qdebug.h"
+#include "qscroller.h"
+#include "qscroller_p.h"
+
+#include "private/qgesturemanager_p.h"
+#include "private/qgesture_p.h"
+
+#include <QTime>
+#include <QElapsedTimer>
+#include <QApplication>
+// #include <QtCore/qmath.h>
+// #include <QtGui/qevent.h>
+
+#include <QtDebug>
+
QT_BEGIN_NAMESPACE
-class QFlickGesturePrivate
+bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
+
+#define KINETIC_SCROLLER_DEBUG
+
+#ifdef KINETIC_SCROLLER_DEBUG
+# define qKSDebug qDebug
+#else
+# define qKSDebug while (false) qDebug
+#endif
+
+
+class QFlickGesturePrivate : public QGesturePrivate
{
+ Q_DECLARE_PUBLIC(QFlickGesture)
+
public:
- QFlickGesturePrivate()
+
+ QScroller *scroller()
{
+ if (!receiverScroller)
+ receiverScroller = QScroller::scroller(receiver);
+ return receiverScroller;
}
- QKineticScroller *scroller()
- {
- // qDebug() << "QKineticScroller::scroller"<<target<<"parent:"<<target->parent();
- QKineticScroller *res = 0;
+ QPointer<QObject> receiver;
+ QPointer<QScroller> receiverScroller;
- if (!target)
- return 0;
+ QFlickGesture *q_ptr;
+};
- res = target->property("kineticScroller").value<QKineticScroller *>();
- if (res)
- return res;
- if (!target->parent())
- return 0;
- res = target->parent()->property("kineticScroller").value<QKineticScroller *>();
- return res;
- }
+inline bool operator<=(const QPointF &p, qreal f)
+{
+ return (qAbs(p.x()) <= f) && (qAbs(p.y()) <= f);
+}
+inline bool operator<(const QPointF &p, qreal f)
+{
+ return (qAbs(p.x()) < f) && (qAbs(p.y()) < f);
+}
- QPointer<QWidget> target;
+inline bool operator>=(const QPointF &p, qreal f)
+{
+ return (qAbs(p.x()) >= f) || (qAbs(p.y()) >= f);
+}
+inline bool operator>(const QPointF &p, qreal f)
+{
+ return (qAbs(p.x()) > f) || (qAbs(p.y()) > f);
+}
-#if QT_VERSION < 0x040700
- QTime timer;
-#else
- QElapsedTimer timer;
-#endif
+inline QPointF qAbs(const QPointF &p)
+{
+ return QPointF(qAbs(p.x()), qAbs(p.y()));
+}
- friend class QFlickGesture;
-};
+inline int qSign(qreal r)
+{
+ return (r < 0) ? -1 : ((r > 0) ? 1 : 0);
+}
+/*!
+ \class QFlickGestureRecognizer
+ \since 4.8
+ \brief The \c QFlickGestureRecognizer is used to detect \c QFlickGesture.
+ \ingroup gestures
+
+ \sa {Gestures Programming}, QFlickGesture
+*/
QFlickGestureRecognizer::QFlickGestureRecognizer()
{
}
+/*! \reimp
+ */
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)
- // for scroll areas on Windows we want to use native gestures instead
- if (!qobject_cast<QAbstractScrollArea *>(target->parent()))
- widget->setAttribute(Qt::WA_AcceptTouchEvents);
-#else
+ QWidget *widget = static_cast<QWidget *>(target);
widget->setAttribute(Qt::WA_AcceptTouchEvents);
-#endif
- return new QFlickGesture(widget);
+
+ } else if (target) {
+ QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
+ if (go) {
+ go->setAcceptTouchEvents(true);
+ }
}
- return new QFlickGesture(0);
+ return new QFlickGesture(target);
}
+/*! The recognize function detects a touch event suitable to start the attached QScroller.
+ The QFlickGesture will be triggered when the scroller is not longer in the state
+ QScroller::StateInactive or QScrollerStatePressed. It will be finished or canceled
+ at the QEvent::TouchEnd.
+ Note that the QScroller might continue scrolling at this point.
+ */
QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
QObject *,
QEvent *event)
{
QFlickGesture *q = static_cast<QFlickGesture *>(state);
- QFlickGesturePrivate *d = q->d;
+ QFlickGesturePrivate *d = q->d_ptr;
- QKineticScroller *scroller = d->scroller();
- // qDebug() << "QFlickGestureRecognizer::recognize for"<<scroller;
+ QScroller *scroller = d->scroller();
if (!scroller)
- return QGestureRecognizer::Ignore;
+ return QGestureRecognizer::Ignore; // nothing to do without a scroller?
+ QScrollerPrivate *scrollerD = scroller->d_ptr;
// eat mouse events if the scroller is active
- if ((scroller->state() == QKineticScroller::StateDragging ||
- scroller->state() == QKineticScroller::StateScrolling) &&
+ if ((scrollerD->state == QScroller::StateDragging ||
+ scrollerD->state == QScroller::StateScrolling) &&
(event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseMove ||
event->type() == QEvent::MouseButtonDblClick ||
event->type() == QEvent::MouseButtonRelease) )
return QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint;
- // qDebug()<<"recognize event: "<<event<<"target:"<<d->target<<"scroller:"<<d->scroller();
-
- QKineticScroller::State oldState = scroller->state();
-
- // ignore all other events except touch
- /*
- QGestureRecognizer::Result resultVector[4] = {
- QGestureRecognizer::Ignore,
- QGestureRecognizer::MayBeGesture,
- QGestureRecognizer::TriggerGesture,
- QGestureRecognizer::TriggerGesture };
- */
-
+ // ignore everything except touch events
if (event->type() != QEvent::TouchBegin &&
event->type() != QEvent::TouchEnd &&
event->type() != QEvent::TouchUpdate)
return QGestureRecognizer::Ignore;
- // return resultVector[(int)oldState];
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
QTouchEvent::TouchPoint tp = ev->touchPoints().first();
- qint64 timestamp = d->timer.elapsed();
-
-
- QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
+ // inform the scroller about the new event
+ qint64 timestamp = scrollerD->timer.elapsed(); // TODO: have your own timer
switch (event->type()) {
case QEvent::TouchBegin:
- scroller->handleInput(QKineticScroller::InputPress, tp.pos(), timestamp);
+ scrollerD->handleInput(QScrollerPrivate::InputPress, tp.pos(), timestamp);
break;
- // return QGestureRecognizer::MayBeGesture;
case QEvent::TouchEnd:
- scroller->handleInput(QKineticScroller::InputRelease, tp.pos(), timestamp);
+ scrollerD->handleInput(QScrollerPrivate::InputRelease, tp.pos(), timestamp);
break;
- /*
- if (oldState == QKineticScroller::StatePressed)
- return QGestureRecognizer::CancelGesture;
- else
- return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
- */
case QEvent::TouchUpdate:
- scroller->handleInput(QKineticScroller::InputMove, tp.pos(), timestamp);
+ scrollerD->handleInput(QScrollerPrivate::InputMove, tp.pos(), timestamp);
break;
- /*
- if (scroller->state() == QKineticScroller::StatePressed)
- return QGestureRecognizer::MayBeGesture;
+ default:
+ break;
+ }
+
+ // depending on the scroller state return the gesture state
+ QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
+ bool scrollerActive = (scrollerD->state == QScroller::StateDragging ||
+ scrollerD->state == QScroller::StateScrolling);
+
+ switch (event->type()) {
+ case QEvent::TouchEnd:
+ if (scrollerActive)
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
else
+ return QGestureRecognizer::CancelGesture;
+ break;
+
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ if (scrollerActive)
return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
- */
+ else
+ return QGestureRecognizer::MayBeGesture;
+
default:
break;
}
- QKineticScroller::State newState = scroller->state();
-
- // old state: inactive, pressed, dragging, scrolling
- QGestureRecognizer::Result resultMatrix[4][4] = {
- // new state inactive
- {QGestureRecognizer::Ignore,
- QGestureRecognizer::CancelGesture,
- QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint},
- // new state pressed
- {QGestureRecognizer::MayBeGesture,
- QGestureRecognizer::Ignore,
- QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint},
- // new state dragging
- {QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint},
- // new state scrolling
- {QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint,
- QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint}
- };
-
- return resultMatrix[(int)newState][(int)oldState];
+ return QGestureRecognizer::Ignore;
}
+/*! \reimp
+ */
void QFlickGestureRecognizer::reset(QGesture *state)
{
// carefull here: the gesture is reset if we cancel or finishe the gesture.
@@ -217,27 +239,35 @@ void QFlickGestureRecognizer::reset(QGesture *state)
QGestureRecognizer::reset(state);
}
-
-
/*!
\class QFlickGesture
- \since 4.7
+ \since 4.8
\brief The QFlickGesture class describes a flicking gesture made by the user.
\ingroup gestures
+ The QFlickGesture is a smarter QPanGesture that uses QScroller and QScrollerProperties
+ to decide if it is triggered.
- \sa {Gestures Programming}, QPinchGesture, QSwipeGesture
+ \sa {Gestures Programming}, QScroller, QScrollerProperties
*/
/*!
\internal
*/
-QFlickGesture::QFlickGesture(QWidget *target, QObject *parent)
+QFlickGesture::QFlickGesture(QObject *receiver, QObject *parent)
: QGesture(parent)
+ , d_ptr(new QFlickGesturePrivate())
+{
+ Q_D(QFlickGesture);
+ d->q_ptr = this;
+ d->gestureType = Qt::FlickGesture;
+ d->receiver = receiver;
+
+ qDebug() << "QFlickGesture::FlickGesture for: " << receiver;
+}
+
+QFlickGesture::~QFlickGesture()
{
- d = new QFlickGesturePrivate();
- d->target = target;
- d->timer.start();
- qDebug() << "QFlickGesture::FlickGesture for: " << target;
+ delete d_ptr;
}
QT_END_NAMESPACE
diff --git a/scroller/qflickgesture.h b/scroller/qflickgesture.h
index b6571d0..5262bf0 100644
--- a/scroller/qflickgesture.h
+++ b/scroller/qflickgesture.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QFLICKGESTURE_P_H
-#define QFLICKGESTURE_P_H
+#ifndef QFLICKGESTURE_H
+#define QFLICKGESTURE_H
//
// W A R N I N G
@@ -56,8 +56,6 @@
#include "qgesturerecognizer.h"
#include "private/qgesture_p.h"
-#include "qkineticscroller.h"
-
QT_BEGIN_NAMESPACE
class QFlickGestureRecognizer : public QGestureRecognizer
@@ -77,14 +75,30 @@ class Q_GUI_EXPORT QFlickGesture : public QGesture
Q_OBJECT
public:
- QFlickGesture(QWidget *widget, QObject *parent = 0);
+ enum State
+ {
+ StateInactive,
+ StatePressed,
+ StateDragging,
+ StateScrolling,
+ };
- friend class QFlickGestureRecognizer;
+public:
+ QFlickGesture(QObject *receiver, QObject *parent = 0);
+ virtual ~QFlickGesture();
+
+ // void reset();
+
+protected:
+ QFlickGesturePrivate* d_ptr;
private:
- QFlickGesturePrivate *d;
+ Q_DISABLE_COPY(QFlickGesture)
+ Q_DECLARE_PRIVATE(QFlickGesture)
+
+ friend class QFlickGestureRecognizer;
};
QT_END_NAMESPACE
-#endif // QFLICKGESTURES_P_H
+#endif // QFLICKGESTURES_H
diff --git a/scroller/qkineticscroller.cpp b/scroller/qkineticscroller.cpp
deleted file mode 100644
index e031ec1..0000000
--- a/scroller/qkineticscroller.cpp
+++ /dev/null
@@ -1,1182 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qkineticscroller.h>
-#include <qkineticscroller_p.h>
-#include <QMap>
-#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
-# define qKSDebug qDebug
-#else
-# define qKSDebug while (false) qDebug
-#endif
-
-
-inline bool operator<=(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) <= f) && (qAbs(p.y()) <= f);
-}
-inline bool operator<(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) < f) && (qAbs(p.y()) < f);
-}
-
-inline bool operator>=(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) >= f) || (qAbs(p.y()) >= f);
-}
-inline bool operator>(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) > f) || (qAbs(p.y()) > f);
-}
-
-inline QPointF qAbs(const QPointF &p)
-{
- return QPointF(qAbs(p.x()), qAbs(p.y()));
-}
-
-inline int qSign(qreal r)
-{
- return (r < 0) ? -1 : ((r > 0) ? 1 : 0);
-}
-
-
-/*!
- \class QKineticScroller
- \brief The QKineticScroller class enables kinetic scrolling for any scrolling widget or graphics item.
- \ingroup qtmaemo5
- \since 4.6
- \preliminary
-
- With kinetic scrolling, the user can push the widget in a given
- direction and it will continue to scroll in this direction until it is
- stopped either by the user or by friction. Aspects of inertia, friction
- and other physical concepts can be changed in order to fine-tune an
- intuitive user experience.
-
- To enable kinetic scrolling for a widget or graphics item, you need to
- derive from this class and implement at least all the pure-virtual
- functions.
-
- Qt for Maemo 5 already comes with two implementations for
- QScrollArea and QWebView, and those kinetic scrollers are
- automatically instantiated and attached to these widgets on creation.
- In the QScrollArea case, the kinetic scroller is initially
- disabled. However, for QItemView and QScrollArea derived classes
- it is enabled by default. You can obtain these automatically created
- objects via a dynamic property:
-
- \code
- // disable the kinetic scroller on scrollArea
- QKineticScroller *scroller = scrollArea->property("kineticScroller")
- .value<QKineticScroller *>();
- if (scroller)
- scroller->setEnabled(false);
- \endcode
-
- In addition there is also an example on how you would add kinetic
- scrolling to a QGraphicsView based application in \c maemobrowser
- examples in the \c maemo5 examples directory.
-
- The kinetic scroller installs an event filter on the widget to handle mouse
- presses and moves on the widget \mdash presses and moves on a device's touch screen
- are also handled by this mechanism. These events will be interpreted as scroll actions
- depending on the current state() of the scroller.
-
- Even though this kinetic scroller has a huge number of settings, we
- recommend that you leave them all at their default values. In case you
- really want to change them you can try out the \c kineticscroller
- example in the \c maemo5 examples directory.
-
- \sa QWidget
-*/
-
-
-/*!
- Constructs a new kinetic scroller.
-*/
-QKineticScroller::QKineticScroller(QObject *receiver)
- : d_ptr(new QKineticScrollerPrivate())
-{
- Q_D(QKineticScroller);
- d->q_ptr = this;
- d->init();
- d->receiver = receiver;
-}
-
-/*! \internal
-*/
-QKineticScroller::QKineticScroller(QObject *receiver, QKineticScrollerPrivate &dd)
- : d_ptr(&dd)
-{
- Q_D(QKineticScroller);
- d->q_ptr = this;
- d->init();
- d->receiver = receiver;
-}
-
-/*!
- Destroys the scroller.
-*/
-QKineticScroller::~QKineticScroller()
-{
-}
-
-/*!
- \enum QKineticScroller::State
-
- This enum describes the possible states the kinetic scroller can be in.
-
- \value Inactive The scroller is inactive. It may also have been disabled.
- \value Pressed The user has pressed the mouse button (or pressed the
- the touch screen).
- \value Dragging The user is dragging the mouse cursor (or other input
- point) over the scroll area.
- \value Scrolling Scrolling is occurring without direct user input.
-*/
-
-QKineticScrollerPrivate::QKineticScrollerPrivate()
- : enabled(true)
- , state(QKineticScroller::StateInactive)
- , hOvershootPolicy(QKineticScroller::OvershootWhenScrollable)
- , vOvershootPolicy(QKineticScroller::OvershootWhenScrollable)
- , pressTimestamp(0)
- , lastTimestamp(0)
- , scrollToX(false)
- , scrollToY(false)
- , overshootX(false)
- , overshootY(false)
- , firstScroll(false)
- , debugHook(0)
- , debugHookUser(0)
-{ }
-
-QKineticScrollerPrivate::~QKineticScrollerPrivate()
-{ }
-
-void QKineticScrollerPrivate::init()
-{
- Q_Q(QKineticScroller);
- q->setDpiFromWidget(0);
- 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);
- d->debugHook = callback;
- d->debugHookUser = user;
-}
-
-void QKineticScroller::resetScrollMetrics()
-{
- static QMap<ScrollMetric, QVariant> metrics;
-
-#ifdef Q_WS_MAEMO_5
- metrics.insert(DragVelocitySmoothingFactor, qreal(0.15));
- metrics.insert(ExponentialDecelerationBase, qreal(0.38)); // 0.85^20
- metrics.insert(LinearDecelerationFactor, qreal(0));
- metrics.insert(OvershootSpringConstant, qreal(80.56));
- metrics.insert(OvershootDragResistanceFactor, qreal(1));
- metrics.insert(OvershootMaximumDistance, QPointF(qreal(15.0 / 1000), qreal(15.0 / 1000)));
- metrics.insert(DragStartDistance, qreal(2.5 / 1000));
- metrics.insert(DragStartDirectionErrorMargin, qreal(1.0 / 1000));
- metrics.insert(MaximumVelocity, qreal(6.84));
- metrics.insert(MinimumVelocity, qreal(0.0195));
- metrics.insert(MaximumNonAcceleratedVelocity, qreal(5.6));
- metrics.insert(MaximumClickThroughVelocity, qreal(0.0684));
- metrics.insert(AxisLockThreshold, qreal(0));
- metrics.insert(FastSwipeBaseVelocity, qreal(5.6 * 27));
- metrics.insert(FastSwipeMinimumVelocity, qreal(0.078));
- metrics.insert(FastSwipeMaximumTime, qreal(0.125));
- metrics.insert(FramesPerSecond, qreal(20));
-#else
- metrics.insert(DragVelocitySmoothingFactor, qreal(0.02));
- metrics.insert(ExponentialDecelerationBase, qreal(1));
- metrics.insert(LinearDecelerationFactor, qreal(0.38));
- metrics.insert(OvershootSpringConstant, qreal(15.0));
- metrics.insert(OvershootDragResistanceFactor, qreal(0.5));
- metrics.insert(OvershootMaximumDistance, QPointF(0,0)); // QPointF(qreal(14.25 / 1000), qreal(14.25 / 1000)));
- metrics.insert(DragStartDistance, qreal(2.5 / 1000));
- metrics.insert(DragStartDirectionErrorMargin, qreal(1.0 / 1000));
- metrics.insert(MaximumVelocity, qreal(6650.0 / 1000));
- metrics.insert(MinimumVelocity, qreal(30.0 / 1000));
- metrics.insert(MaximumNonAcceleratedVelocity, qreal(532.0 / 1000));
- metrics.insert(MaximumClickThroughVelocity, qreal(66.5 / 1000));
- metrics.insert(AxisLockThreshold, qreal(0));
- metrics.insert(FastSwipeBaseVelocity, qreal(51.3 / 1000));
- metrics.insert(FastSwipeMinimumVelocity, qreal(76.0 / 1000));
- metrics.insert(FastSwipeMaximumTime, qreal(0.125));
- metrics.insert(FramesPerSecond, qreal(60));
-#endif
-
- if (!metrics.isEmpty()) {
- for (QMap<ScrollMetric, QVariant>::const_iterator it = metrics.constBegin(); it != metrics.constEnd(); ++it)
- setScrollMetric(it.key(), it.value());
- if (metrics.count() != ScrollMetricCount)
- qWarning("QKineticScroller::resetAllMetrics(): scroll metrics parameter set did not contain all metrics.");
- } else {
- qWarning("QKineticScroller::resetAllMetrics(): no platform default parameter set available.");
- }
-}
-
-
-const char *QKineticScrollerPrivate::stateName(QKineticScroller::State state)
-{
- switch (state) {
- case QKineticScroller::StateInactive: return "inactive";
- case QKineticScroller::StatePressed: return "pressed";
- case QKineticScroller::StateDragging: return "dragging";
- case QKineticScroller::StateScrolling: return "scrolling";
- default: return "(invalid)";
- }
-}
-
-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)";
- }
-}
-
-
-
-
-void QKineticScrollerPrivate::timerEvent(QTimerEvent *e)
-{
- if (e->timerId() != timerId) {
- QObject::timerEvent(e);
- return;
- }
-
- struct timerevent {
- QKineticScroller::State state;
- typedef void (QKineticScrollerPrivate::*timerhandler_t)();
- timerhandler_t handler;
- };
-
- timerevent timerevents[] = {
- { QKineticScroller::StateDragging, &QKineticScrollerPrivate::timerEventWhileDragging },
- { QKineticScroller::StateScrolling, &QKineticScrollerPrivate::timerEventWhileScrolling },
- };
-
- for (int i = 0; i < int(sizeof(timerevents) / sizeof(*timerevents)); ++i) {
- timerevent *te = timerevents + i;
-
- if (state == te->state) {
- (this->*te->handler)();
- return;
- }
- }
-
- if (timerId) {
- qWarning() << "Unhandled timer event, while in state " << stateName(state);
- killTimer(timerId);
- timerId = 0;
- }
- // otherwise this is a timer event that was already queued when the
- // timer was killed, so just ignore it
-}
-
-bool QKineticScroller::handleInput(Input input, const QPointF &position, qint64 timestamp)
-{
- Q_D(QKineticScroller);
-
- qKSDebug() << "QKS::handleInput(" << input << ", " << position << ", " << timestamp << ")";
- struct statechange {
- State state;
- Input input;
- 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 < int(sizeof(statechanges) / sizeof(*statechanges)); ++i) {
- statechange *sc = statechanges + i;
-
- if (d->state == sc->state && input == sc->input)
- return (d->*sc->handler)(input, position - d->overshootPosition, timestamp);
- }
-
- qWarning() << "Unhandled input: got input " << d->inputName(input) << " while in state " << d->stateName(d->state);
- return false;
-}
-
-bool QKineticScroller::isEnabled() const
-{
- Q_D(const QKineticScroller);
- return d->enabled;
-}
-
-void QKineticScroller::setEnabled(bool b)
-{
- Q_D(QKineticScroller);
- d->enabled = b;
-}
-
-QKineticScroller::State QKineticScroller::state() const
-{
- Q_D(const QKineticScroller);
- return d->state;
-}
-
-/*!
- Resets the internal state of the kinetic scroller. This function is not
- needed for normal use. This function only needs to be called if the
- kinetic scroller is being re-attached to a different widget.
-*/
-void QKineticScroller::reset()
-{
- Q_D(QKineticScroller);
-
- d->setState(StateInactive);
-}
-
-QKineticScroller::OvershootPolicy QKineticScroller::horizontalOvershootPolicy() const
-{
- Q_D(const QKineticScroller);
- return d->hOvershootPolicy;
-}
-
-void QKineticScroller::setHorizontalOvershootPolicy(QKineticScroller::OvershootPolicy policy)
-{
- Q_D(QKineticScroller);
- d->hOvershootPolicy = policy;
-}
-
-QKineticScroller::OvershootPolicy QKineticScroller::verticalOvershootPolicy() const
-{
- Q_D(const QKineticScroller);
- return d->vOvershootPolicy;
-}
-
-void QKineticScroller::setVerticalOvershootPolicy(QKineticScroller::OvershootPolicy policy)
-{
- Q_D(QKineticScroller);
- d->vOvershootPolicy = policy;
-}
-
-QVariant QKineticScroller::scrollMetric(ScrollMetric metric) const
-{
- Q_D(const QKineticScroller);
-
- switch (metric) {
- case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor;
- case LinearDecelerationFactor: return d->linearDecelerationFactor;
- case ExponentialDecelerationBase: return d->exponentialDecelerationBase;
- case OvershootSpringConstant: return d->overshootSpringConstantRoot * d->overshootSpringConstantRoot;
- case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor;
- case OvershootMaximumDistance: return d->overshootMaximumDistance;
- case DragStartDistance: return d->dragStartDistance;
- 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 FramesPerSecond: return d->framesPerSecond;
- case FastSwipeMaximumTime: return d->fastSwipeMaximumTime;
- case FastSwipeMinimumVelocity: return d->fastSwipeMinimumVelocity;
- case FastSwipeBaseVelocity: return d->fastSwipeBaseVelocity;
- case ScrollMetricCount: break;
- }
- return QVariant();
-}
-
-
-void QKineticScroller::setScrollMetric(ScrollMetric metric, const QVariant &value)
-{
- Q_D(QKineticScroller);
-
- switch (metric) {
- case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case LinearDecelerationFactor: d->linearDecelerationFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case ExponentialDecelerationBase: d->exponentialDecelerationBase = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case OvershootSpringConstant: d->overshootSpringConstantRoot = qSqrt(value.toReal()); break;
- case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break;
- case OvershootMaximumDistance: d->overshootMaximumDistance = value.toPointF(); break;
- case DragStartDistance: d->dragStartDistance = 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(qreal(0), value.toReal(), qreal(1)); break;
- case FramesPerSecond: d->framesPerSecond = qBound(1, value.toInt(), 100); break;
- case FastSwipeMaximumTime: d->fastSwipeMaximumTime = value.toReal(); break;
- case FastSwipeMinimumVelocity: d->fastSwipeMinimumVelocity = value.toReal(); break;
- case FastSwipeBaseVelocity: d->fastSwipeBaseVelocity = value.toReal(); break;
- case ScrollMetricCount: break;
- }
-}
-
-qreal QKineticScroller::dpi() const
-{
- Q_D(const QKineticScroller);
- return d->pixelPerMeter / qreal(39.3700787);
-}
-
-
-void QKineticScroller::setDpi(qreal dpi)
-{
- Q_D(QKineticScroller);
- d->pixelPerMeter = dpi * qreal(39.3700787);
-}
-
-void QKineticScroller::setDpiFromWidget(QWidget *widget)
-{
- Q_D(QKineticScroller);
-
- QDesktopWidget *dw = QApplication::desktop();
- QPointF dpi = d->realDpi(widget ? dw->screenNumber(widget) : dw->primaryScreen());
- setDpi((dpi.x() + dpi.y()) / qreal(2));
-}
-
-#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAC)
-
-QPointF QKineticScrollerPrivate::realDpi(int screen)
-{
- QWidget *w = QApplication::desktop()->screen(screen);
- return QPointF(w->physicalDpiX(), w->physicalDpiY());
-}
-
-#endif
-
-
-void QKineticScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime)
-{
- qKSDebug() << "QKS::updateVelocity(" << deltaPixelRaw << " [delta pix], " << deltaTime << " [delta ms])";
-
- QPointF deltaPixel = deltaPixelRaw;
-
- // faster than 2.5mm/ms seems bogus (that would be a screen height in ~20 ms)
- if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / pixelPerMeter * 1000) > qreal(2.5))
- deltaPixel = deltaPixelRaw * qreal(2.5) * pixelPerMeter / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength();
-
- qreal inversSmoothingFactor = ((qreal(1) - dragVelocitySmoothingFactor) * qreal(deltaTime) / qreal(1000));
- QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / pixelPerMeter;
- newv = newv * (qreal(1) - inversSmoothingFactor) + releaseVelocity * inversSmoothingFactor;
-
- // newv = newv * dragVelocitySmoothingFactor + velocity * (qreal(1) - dragVelocitySmoothingFactor);
-
- if (deltaPixel.x())
- releaseVelocity.setX(qBound(-maximumVelocity, newv.x(), maximumVelocity));
- if (deltaPixel.y())
- releaseVelocity.setY(qBound(-maximumVelocity, newv.y(), maximumVelocity));
-
- qKSDebug() << " --> new velocity:" << releaseVelocity;
-}
-
-qreal QKineticScrollerPrivate::decelerate(qreal v, qreal t)
-{
- qreal result = v * qPow(exponentialDecelerationBase, t);
- qreal linear = linearDecelerationFactor * t;
- if (qAbs(result) > linear)
- return result + (result < 0 ? linear : -linear);
- else
- return 0;
-}
-
-/*! Calculates the current velocity during scrolling
- */
-QPointF QKineticScrollerPrivate::calculateVelocity(qreal time)
-{
- QPointF velocity;
-
- // -- x coordinate
- if (overshootX) {
- if (overshootSpringConstantRoot * (time-overshootStartTimeX) < M_PI) // prevent swinging around
- velocity.setX(overshootVelocity.x() * qCos(overshootSpringConstantRoot * (time - overshootStartTimeX)));
- else
- velocity.setX(-overshootVelocity.x());
-
- } else {
- qreal newVelocity = decelerate(releaseVelocity.x(), time);
-
- if (scrollToX) {
- if (qAbs(newVelocity) < qreal(30.0 / 1000) /* 30mm/s */)
- newVelocity = qreal(30.0 / 1000) * qSign(releaseVelocity.x());
-
- } else {
- if (qAbs(newVelocity) < qreal(0.5) * qreal(framesPerSecond) / pixelPerMeter /* 0.5 [pix/frame] */)
- newVelocity = 0;
- }
-
- velocity.setX(newVelocity);
- }
-
- // -- y coordinate
- if (overshootY) {
- if (overshootSpringConstantRoot * (time-overshootStartTimeY) < M_PI) // prevent swinging around
- velocity.setY(overshootVelocity.y() * qCos(overshootSpringConstantRoot * (time - overshootStartTimeY)));
- else
- velocity.setY(-overshootVelocity.y());
-
- } else {
- qreal newVelocity = decelerate(releaseVelocity.y(), time);
-
- if (scrollToY) {
- if (qAbs(newVelocity) < qreal(30.0 / 1000) /* 30mm/s */)
- newVelocity = qreal(30.0 / 1000) * qSign(releaseVelocity.y());
-
- } else {
- if (qAbs(newVelocity) < qreal(0.5) * qreal(framesPerSecond) / pixelPerMeter /* 0.5 [pix/frame] */)
- newVelocity = 0;
- }
-
- velocity.setY(newVelocity);
- }
-
- return velocity;
-}
-
-
-void QKineticScrollerPrivate::handleDrag(const QPointF &position, qint64 timestamp)
-{
- QPointF deltaPixel = position - lastPosition;
- qint64 deltaTime = timestamp - lastTimestamp;
-
- if (axisLockThreshold) {
- int dx = qAbs(deltaPixel.x());
- int dy = qAbs(deltaPixel.y());
- if (dx || dy) {
- bool vertical = (dy > dx);
- qreal alpha = qreal(vertical ? dx : dy) / qreal(vertical ? dy : dx);
- //qKSDebug() << "QKS::handleDrag() -- axis lock:" << alpha << " / " << axisLockThreshold << "- isvertical:" << vertical << "- dx:" << dx << "- dy:" << dy;
- if (alpha <= axisLockThreshold) {
- if (vertical)
- deltaPixel.setX(0);
- else
- deltaPixel.setY(0);
- }
- }
- }
-
- // calculate velocity (if the user would release the mouse NOW)
- updateVelocity(deltaPixel, deltaTime);
-
- // restrict velocity, if content is not scrollable
- QPointF maxPos = maximumContentPosition;
- bool canScrollX = maxPos.x() || (hOvershootPolicy == QKineticScroller::OvershootAlwaysOn);
- bool canScrollY = maxPos.y() || (vOvershootPolicy == QKineticScroller::OvershootAlwaysOn);
-
- if (!canScrollX) {
- deltaPixel.setX(0);
- releaseVelocity.setX(0);
- }
- if (!canScrollY) {
- deltaPixel.setY(0);
- releaseVelocity.setY(0);
- }
-
-// if (firstDrag) {
-// // Do not delay the first drag
-// setContentPositionHelper(q->contentPosition() - overshootDistance - deltaPixel);
-// dragDistance = QPointF(0, 0);
-// } else {
- dragDistance += deltaPixel;
-// }
-
- if (canScrollX)
- lastPosition.setX(position.x());
- if (canScrollY)
- lastPosition.setY(position.y());
- lastTimestamp = timestamp;
-}
-
-
-
-bool QKineticScrollerPrivate::pressWhileInactive(QKineticScroller::Input, const QPointF &position, qint64 timestamp)
-{
- QScrollPrepareEvent spe(position);
- sendEvent(receiver, &spe);
-
- qKSDebug() << "QScrollPrepareEvent 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)) {
-
- lastPosition = pressPosition = position;
- lastTimestamp = pressTimestamp = timestamp;
- firstScroll = true;
- setState(QKineticScroller::StatePressed);
- }
- }
- return false;
-}
-
-bool QKineticScrollerPrivate::releaseWhilePressed(QKineticScroller::Input, const QPointF &, qint64)
-{
- if (overshootX || overshootY)
- setState(QKineticScroller::StateScrolling);
- else
- setState(QKineticScroller::StateInactive);
- return false;
-}
-
-bool QKineticScrollerPrivate::moveWhilePressed(QKineticScroller::Input, const QPointF &position, qint64 timestamp)
-{
- Q_Q(QKineticScroller);
-
- QPointF deltaPixel = position - pressPosition;
-
- bool moveStarted = ((deltaPixel.manhattanLength() / pixelPerMeter) > dragStartDistance);
-
- if (moveStarted) {
- qreal deltaXtoY = qAbs(pressPosition.x() - position.x()) - qAbs(pressPosition.y() - position.y());
- deltaXtoY /= pixelPerMeter;
-
- QPointF maxPos = maximumContentPosition;
- bool canScrollX = (maxPos.x() > 0);
- bool canScrollY = (maxPos.y() > 0);
-
- if (hOvershootPolicy == QKineticScroller::OvershootAlwaysOn)
- canScrollX = true;
- if (vOvershootPolicy == QKineticScroller::OvershootAlwaysOn)
- canScrollY = true;
-
- if (deltaXtoY < 0) {
- if (!canScrollY && (!canScrollX || (-deltaXtoY >= dragStartDirectionErrorMargin)))
- moveStarted = false;
- } else {
- if (!canScrollX && (!canScrollY || (deltaXtoY >= dragStartDirectionErrorMargin)))
- moveStarted = false;
- }
- }
-
- if (moveStarted) {
- setState(QKineticScroller::StateDragging);
-
- // subtract the dragStartDistance
- deltaPixel = deltaPixel - deltaPixel * (dragStartDistance / deltaPixel.manhattanLength());
-
- if (!deltaPixel.isNull()) {
- // handleDrag updates lastPosition, lastTimestamp and velocity
- handleDrag(pressPosition + deltaPixel, timestamp);
- }
- }
- return moveStarted;
-}
-
-bool QKineticScrollerPrivate::moveWhileDragging(QKineticScroller::Input, const QPointF &position, qint64 timestamp)
-{
- // handleDrag updates lastPosition, lastTimestamp and velocity
- handleDrag(position, timestamp);
- return true;
-}
-
-void QKineticScrollerPrivate::timerEventWhileDragging()
-{
- if (!dragDistance.isNull()) {
- qKSDebug() << "QKS::timerEventWhileDragging() -- dragDistance:" << dragDistance;
-
- setContentPositionHelper(-dragDistance);
- dragDistance = QPointF(0, 0);
- }
-}
-
-bool QKineticScrollerPrivate::releaseWhileDragging(QKineticScroller::Input, const QPointF &, qint64 timestamp)
-{
- // calculate the fastSwipe velocity
- QPointF maxPos = maximumContentPosition;
- QPointF fastSwipeVelocity = QPoint(0, 0);
- QSizeF size = viewportSize;
- if (size.width())
- fastSwipeVelocity.setX(qMin(maximumVelocity, maxPos.x() / size.width() * fastSwipeBaseVelocity));
- if (size.height())
- fastSwipeVelocity.setY(qMin(maximumVelocity, maxPos.y() / size.height() * fastSwipeBaseVelocity));
-
- if (fastSwipeMaximumTime &&
- ((timestamp - pressTimestamp) < qint64(fastSwipeMaximumTime * 1000)) &&
- (oldVelocity > fastSwipeMinimumVelocity)) {
-
- // more than one fast swipe in a row: add fastSwipeVelocity
- int signX = 0, signY = 0;
- if (releaseVelocity.x())
- signX = (releaseVelocity.x() > 0) == (oldVelocity.x() > 0) ? 1 : -1;
- if (releaseVelocity.y())
- signY = (releaseVelocity.y() > 0) == (oldVelocity.y() > 0) ? 1 : -1;
-
- releaseVelocity.setX(signX * (oldVelocity.x() + (oldVelocity.x() > 0 ? fastSwipeVelocity.x() : -fastSwipeVelocity.x())));
- releaseVelocity.setY(signY * (oldVelocity.y() + (oldVelocity.y() > 0 ? fastSwipeVelocity.y() : -fastSwipeVelocity.y())));
-
- } else if (releaseVelocity >= minimumVelocity) {
-
- // if we have a fast swipe, accelerate it to the fastSwipe velocity
- if ((qAbs(releaseVelocity.x()) > maximumNonAcceleratedVelocity) &&
- (fastSwipeVelocity.x() > maximumNonAcceleratedVelocity)) {
- releaseVelocity.setX(releaseVelocity.x() > 0 ? fastSwipeVelocity.x() : -fastSwipeVelocity.x());
- }
- if ((qAbs(releaseVelocity.y()) > maximumNonAcceleratedVelocity) &&
- (fastSwipeVelocity.y() > maximumNonAcceleratedVelocity)) {
- releaseVelocity.setY(releaseVelocity.y() > 0 ? fastSwipeVelocity.y() : -fastSwipeVelocity.y());
- }
-
- }
-
- qKSDebug() << "QKS::releaseWhileDragging() -- velocity:" << releaseVelocity << "-- minimum velocity:" << minimumVelocity;
- if (overshootX || overshootY)
- setState(QKineticScroller::StateScrolling);
- else if (releaseVelocity >= minimumVelocity)
- setState(QKineticScroller::StateScrolling);
- else
- setState(QKineticScroller::StateInactive);
-
- return true;
-}
-
-void QKineticScrollerPrivate::timerEventWhileScrolling()
-{
- qreal deltaTime = qreal(scrollRelativeTimer.restart()) / 1000;
- qreal time = qreal(scrollAbsoluteTimer.elapsed()) / 1000;
-
- // calculate the velocity for the passed interval deltatime.
- // using the midpoint of the interval gives a better precision than using just time.
- QPointF newVelocity = calculateVelocity(time - deltaTime / 2);
- QPointF deltaPos = newVelocity * deltaTime * pixelPerMeter;
-
- // -- move (convert from [m/s] to [pix/frame]
- if (!deltaPos.isNull())
- setContentPositionHelper(deltaPos);
-
- qKSDebug() << "QKS::timerEventWhileScrolling() -- DeltaPos:" << deltaPos << "- NewVel:" << newVelocity << "- Time:" << time;
-
- if (newVelocity.isNull() ||
- (releaseVelocity.isNull() && !scrollToX && !scrollToY && !overshootX && !overshootY))
- // if (newVelocity.isNull())
- setState(QKineticScroller::StateInactive);
-}
-
-bool QKineticScrollerPrivate::pressWhileScrolling(QKineticScroller::Input, const QPointF &position, qint64 timestamp)
-{
- lastPosition = pressPosition = position;
- lastTimestamp = pressTimestamp = timestamp;
- setState(QKineticScroller::StatePressed);
- return true;
-}
-
-void QKineticScrollerPrivate::setState(QKineticScroller::State newstate)
-{
- Q_Q(QKineticScroller);
-
- if (state == newstate)
- return;
-
- qKSDebug() << "QKS::setState(" << stateName(newstate) << ")";
-
- switch (newstate) {
- case QKineticScroller::StateInactive:
- if (state == QKineticScroller::StateScrolling) {
- if (timerId) {
- killTimer(timerId);
- timerId = 0;
- } else {
- qKSDebug() << " --> state change from " << stateName(state) << " to " << stateName(newstate) << ", but timer is not active.";
- }
- }
- releaseVelocity = QPointF(0, 0);
- break;
-
- case QKineticScroller::StatePressed:
- if (timerId) {
- killTimer(timerId);
- timerId = 0;
- }
- scrollToX = false;
- scrollToY = false;
- oldVelocity = releaseVelocity;
- // releaseVelocity = QPointF(0, 0);
- break;
-
- case QKineticScroller::StateDragging:
-
- dragDistance = QPointF(0, 0);
- if (state == QKineticScroller::StatePressed) {
- if (!timerId) {
- timerId = startTimer(1000 / framesPerSecond);
- } else {
- qKSDebug() << " --> state change from " << stateName(state) << " to " << stateName(newstate) << ", but timer is already active.";
- }
- }
-
- break;
-
- case QKineticScroller::StateScrolling:
- if (!timerId) {
- timerId = startTimer(1000 / framesPerSecond);
- }
- scrollRelativeTimer.start();
- scrollAbsoluteTimer.start();
-
- if (state == QKineticScroller::StateDragging) {
- // TODO: better calculate StartTime using the current releaseVelocity
- overshootStartTimeX = overshootStartTimeY = qreal(scrollAbsoluteTimer.elapsed()) / 1000 - M_PI / (overshootSpringConstantRoot * 2);
- overshootVelocity = overshootPosition / pixelPerMeter * overshootSpringConstantRoot;
- }
-
- break;
- }
-
- qSwap(state, newstate);
- q->stateChanged(newstate);
-}
-
-/*!
- Starts scrolling the widget so that the point \a pos is visible inside
- the viewport.
-
- If the specified point cannot be reached, the contents are scrolled to the
- nearest valid position (in this case the scroller might or might not overshoot).
-
- The scrolling speed will be calculated so that the given position will
- 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()
-*/
-void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime)
-{
- Q_D(QKineticScroller);
-
- if (scrollTime <= 0)
- scrollTime = 1;
-
- qKSDebug() << "QKS::scrollTo(" << pos << " [pix], " << scrollTime << " [ms])";
-
- qreal time = qreal(scrollTime) / 1000;
-
- if ((pos == d->contentPosition) ||
- (d->state == QKineticScroller::StatePressed) ||
- (d->state == QKineticScroller::StateDragging)) {
- return;
- }
-
- // estimate the minimal start velocity
- // if the start velocity is below that then the scrolling would stop before scrollTime.
- //qreal vMin = d->linearDecelerationFactor * time / qPow(d->exponentialDecelerationBase, time);
-
- /*
- // estimate of the distance passed within the vMin time during scrollTime
- qreal distMin = qreal(scrollTime) * vMin / 2.0;
-
- QPointF v = QPointF((pos.x()-contentPosition().x()) / distMin * vMin,
- (pos.y()-contentPosition().y()) / distMin * vMin);
-
- */
-
- // v(t) = vstart * exponentialDecelerationBase ^ t - linearDecelerationFactor * t
- // pos(t) = integrate(v(t) * dt)
- // pos(t) = vstart * (eDB ^ t / ln(eDB) + C) - lDF / 2 * t ^ 2
- //
- // pos(time) = pos - contentsPos()
- // 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 v = (scrollDir * (d->linearDecelerationFactor / qreal(2)) * qreal(time) * qreal(time) + (pos - d->contentPosition) / d->pixelPerMeter);
- if (d->exponentialDecelerationBase != qreal(1))
- v /= (qPow(d->exponentialDecelerationBase, time) - 1) / qLn(d->exponentialDecelerationBase);
- else
- v /= time;
-
- d->scrollToPosition = pos;
- d->scrollToX = true;
- d->scrollToY = true;
- d->releaseVelocity = v;
- d->scrollRelativeTimer.restart();
- d->scrollAbsoluteTimer.restart();
- d->setState(QKineticScroller::StateScrolling);
-}
-
-/*!
- Starts scrolling the widget so that the point \a pos is visible inside the
- viewport with margins specified in pixels by \a xmargin and \a ymargin.
-
- If the specified point cannot be reached, the contents are scrolled to the
- nearest valid position. The default value for both margins is 50 pixels.
-
- This function performs the actual scrolling by calling scrollTo().
-*/
-void QKineticScroller::ensureVisible(const QPointF &pos, int xmargin, int ymargin, int scrollTime)
-{
- Q_D(QKineticScroller);
-
- QSizeF visible = d->viewportSize;
- QPointF currentPos = d->contentPosition;
-
- qKSDebug() << "QKS::ensureVisible(" << pos << " [pix], " << xmargin << " [pix], " << ymargin << " [pix], " << scrollTime << "[ms])";
- qKSDebug() << " --> content position:" << d->contentPosition;
-
- QRectF posRect(pos.x() - xmargin, pos.y() - ymargin, 2 * xmargin, 2 * ymargin);
- QRectF visibleRect(currentPos, visible);
-
- if (visibleRect.contains(posRect))
- return;
-
- QPointF newPos = currentPos;
- if (posRect.top() < visibleRect.top())
- newPos.setY(posRect.top());
- else if (posRect.bottom() > visibleRect.bottom())
- newPos.setY(posRect.bottom() - visible.height());
- if (posRect.left() < visibleRect.left())
- newPos.setX(posRect.left());
- else if (posRect.right() > visibleRect.right())
- newPos.setY(posRect.right() - visible.width());
-
- scrollTo(newPos, scrollTime);
-}
-
-
-/*! \internal
- Helps when setting the content position.
- It will try to move the content by the requested delta but stop in case
- when we are coming back from an overshoot or a scrollTo.
- It will also indicate a new overshooting condition by the overshootX and oversthootY flags.
-
- In this cases it will reset the velocity variables and other flags.
-
- Also keeps track of the current over-shooting value in overshootPosition.
-
- \deltaPos is the amout of pixels the current content position should be moved
-*/
-void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos)
-{
- if (state == QKineticScroller::StateDragging && overshootDragResistanceFactor)
- overshootPosition /= overshootDragResistanceFactor;
-
- QPointF oldPos = contentPosition + overshootPosition;
- QPointF newPos = oldPos + deltaPos;
- QPointF maxPos = maximumContentPosition;
-
- QPointF oldScrollToDist = scrollToPosition - oldPos;
- QPointF newScrollToDist = scrollToPosition - newPos;
-
- qKSDebug() << "QKS::setContentPositionHelper(" << deltaPos << " [pix])";
- qKSDebug() << " --> overshoot:" << overshootPosition << "- old pos:" << oldPos << "- new pos:" << newPos;
-
- QPointF oldClampedPos;
- oldClampedPos.setX(qBound(qreal(0), oldPos.x(), maxPos.x()));
- oldClampedPos.setY(qBound(qreal(0), oldPos.y(), maxPos.y()));
-
- QPointF newClampedPos;
- newClampedPos.setX(qBound(qreal(0), newPos.x(), maxPos.x()));
- newClampedPos.setY(qBound(qreal(0), newPos.y(), maxPos.y()));
-
- // --- handle overshooting and stop if the coordinate is going back inside the normal area
- bool alwaysOvershootX = (hOvershootPolicy == QKineticScroller::OvershootAlwaysOn);
- bool alwaysOvershootY = (vOvershootPolicy == QKineticScroller::OvershootAlwaysOn);
- bool noOvershootX = (hOvershootPolicy == QKineticScroller::OvershootAlwaysOff) ||
- ((state == QKineticScroller::StateDragging) && !overshootDragResistanceFactor);
- bool noOvershootY = (vOvershootPolicy == QKineticScroller::OvershootAlwaysOff) ||
- ((state == QKineticScroller::StateDragging) && !overshootDragResistanceFactor);
- bool canOvershootX = !noOvershootX && (alwaysOvershootX || maxPos.x());
- bool canOvershootY = !noOvershootY && (alwaysOvershootY || maxPos.y());
-
- qreal oldOvershootX = (canOvershootX) ? oldPos.x() - oldClampedPos.x() : 0;
- qreal oldOvershootY = (canOvershootY) ? oldPos.y() - oldClampedPos.y() : 0;
-
- qreal newOvershootX = (canOvershootX) ? newPos.x() - newClampedPos.x() : 0;
- qreal newOvershootY = (canOvershootY) ? newPos.y() - newClampedPos.y() : 0;
-
- if (state == QKineticScroller::StateDragging && overshootDragResistanceFactor) {
- oldOvershootX *= overshootDragResistanceFactor;
- oldOvershootY *= overshootDragResistanceFactor;
- newOvershootX *= overshootDragResistanceFactor;
- newOvershootY *= overshootDragResistanceFactor;
- }
-
- // -- stop at the maximum overshoot distance (if set)
- if (!overshootMaximumDistance.isNull()) {
- newOvershootX = qBound(-overshootMaximumDistance.x() * pixelPerMeter, newOvershootX, overshootMaximumDistance.x() * pixelPerMeter);
-
- newOvershootY = qBound(-overshootMaximumDistance.y() * pixelPerMeter, newOvershootY, overshootMaximumDistance.y() * pixelPerMeter);
- }
-
- // --- sanity check for scrollTo in case we can't even scroll that direction
- if (!(maxPos.x() || alwaysOvershootX))
- scrollToX = false;
- if (!(maxPos.y() || alwaysOvershootY))
- scrollToY = false;
-
- // --- handle crossing over borders (scrollTo and overshoot)
- qKSDebug() << " --> old overshoot Y:" << oldOvershootY << "- new overshoot Y:" << newOvershootY;
- // -- x axis
- if (scrollToX && qSign(oldScrollToDist.x()) != qSign(newScrollToDist.x())) {
- newClampedPos.setX(scrollToPosition.x());
- newOvershootX = 0;
- releaseVelocity.setX(0);
- scrollToX = false;
-
- } else if (oldOvershootX && (qSign(oldOvershootX) != qSign(newOvershootX))) {
- newClampedPos.setX((oldOvershootX < 0) ? 0 : maxPos.x());
- newOvershootX = 0;
- releaseVelocity.setX(0);
- overshootVelocity.setX(0);
- overshootX = false;
-
- } else if (!oldOvershootX && newOvershootX) {
- overshootStartTimeX = qreal(scrollAbsoluteTimer.elapsed()) / 1000;
- overshootVelocity.setX(calculateVelocity(overshootStartTimeX).x());
-
- // restrict the overshoot to overshootMaximumDistance
- qreal maxOvershootVelocity = overshootMaximumDistance.x() * overshootSpringConstantRoot;
- if (overshootMaximumDistance.x() && qAbs(overshootVelocity.x()) > maxOvershootVelocity)
- overshootVelocity.setX(maxOvershootVelocity * qSign(newOvershootX));
-
- // -- prevent going into overshoot too far
- if (state != QKineticScroller::StateDragging)
- newOvershootX = qSign(newOvershootX) * qreal(0.0001);
-
- scrollToX = false;
- overshootX = true;
- }
-
- // -- y axis
- if (scrollToY && qSign(oldScrollToDist.y()) != qSign(newScrollToDist.y())) {
- newClampedPos.setY(scrollToPosition.y());
- newOvershootY = 0;
- releaseVelocity.setY(0);
- scrollToY = false;
-
- } else if (oldOvershootY && (qSign(oldOvershootY) != qSign(newOvershootY))) {
- newClampedPos.setY((oldOvershootY < 0) ? 0 : maxPos.y());
- newOvershootY = 0;
- releaseVelocity.setY(0);
- overshootVelocity.setY(0);
- overshootY = false;
-
- } else if (!oldOvershootY && newOvershootY) {
- overshootStartTimeY = qreal(scrollAbsoluteTimer.elapsed()) / 1000;
- overshootVelocity.setY(calculateVelocity(overshootStartTimeY).y());
-
- // -- restrict the overshoot to overshootMaximumDistance
- qreal maxOvershootVelocity = overshootMaximumDistance.y() * overshootSpringConstantRoot;
- if (overshootMaximumDistance.y() && (qAbs(overshootVelocity.y()) > maxOvershootVelocity))
- overshootVelocity.setY(maxOvershootVelocity * qSign(newOvershootY));
-
- // -- prevent going into overshoot too far
- if (state != QKineticScroller::StateDragging)
- newOvershootY = qSign(newOvershootY) * qreal(0.0001);
-
- scrollToY = false;
- overshootY = true;
- }
-
- overshootPosition.setX(newOvershootX);
- overshootPosition.setY(newOvershootY);
-
- if( target ) {
- QScrollEvent se(newClampedPos, overshootPosition, firstScroll);
- sendEvent(target, &se);
- firstScroll = false;
- }
- contentPosition = newClampedPos;
-
- if (debugHook)
- debugHook(debugHookUser, calculateVelocity(qreal(scrollAbsoluteTimer.elapsed()) / 1000), newClampedPos, overshootPosition);
-
- qKSDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition <<
- "- overshoot x/y?:" << overshootX << "/" << overshootY << "- scrollto x/y?:" << scrollToX << "/" << scrollToY;
-}
-
-
-/*!
- \enum QKineticScroller::OvershootPolicy
-
- This enum describes the various modes of overshooting.
-
- \value OvershootWhenScrollable Overshooting is when the content is scrollable. This is the default.
-
- \value OvershootAlwaysOff Overshooting is never enabled (even when the content is scrollable).
-
- \value OvershootAlwaysOn Overshooting is always enabled (even when the content is not scrollable).
-*/
-
-/*!
- 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
- calling state().
-
- The default implementation does nothing.
-
- \sa state()
-*/
-void QKineticScroller::stateChanged(State oldState)
-{
- Q_UNUSED(oldState);
-}
-
-QT_END_NAMESPACE
diff --git a/scroller/qkineticscroller.h b/scroller/qkineticscroller.h
deleted file mode 100644
index 610eb2f..0000000
--- a/scroller/qkineticscroller.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKINETICSCROLLER_H
-#define QKINETICSCROLLER_H
-
-#include <QtCore/qmetatype.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFlickGestureRecognizer;
-class QKineticScrollerPrivate;
-
-class QKineticScroller
-{
-public:
- explicit QKineticScroller(QObject *receiver);
- virtual ~QKineticScroller();
-
- bool isEnabled() const;
- void setEnabled(bool b);
-
- enum State
- {
- StateInactive,
- StatePressed,
- StateDragging,
- StateScrolling,
- };
-
- State state() const;
- void reset();
-
- enum OvershootPolicy
- {
- OvershootWhenScrollable,
- OvershootAlwaysOff,
- OvershootAlwaysOn,
- };
-
- OvershootPolicy horizontalOvershootPolicy() const;
- void setHorizontalOvershootPolicy(OvershootPolicy policy);
- OvershootPolicy verticalOvershootPolicy() const;
- void setVerticalOvershootPolicy(OvershootPolicy policy);
-
- enum ScrollMetric
- {
- DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
-
- LinearDecelerationFactor, // qreal [m/s^2]
- ExponentialDecelerationBase, // qreal
- OvershootSpringConstant, // qreal [kg/s^2]
- OvershootDragResistanceFactor, // qreal [0..1]
- OvershootMaximumDistance, // QPointF([m], [m])
-
- DragStartDistance, // qreal [m]
- DragStartDirectionErrorMargin, // qreal [m]
-
- MinimumVelocity, // qreal [m/s]
- MaximumVelocity, // qreal [m/s]
- MaximumNonAcceleratedVelocity, // qreal [m/s]
-
- MaximumClickThroughVelocity, // qreal [m/s]
- AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|)
-
- FramesPerSecond, // int [frames/s]
-
- FastSwipeMaximumTime, // qreal [s]
- FastSwipeMinimumVelocity, // qreal [m/s]
- FastSwipeBaseVelocity, // qreal [m/s]
-
- ScrollMetricCount
- };
-
- QVariant scrollMetric(ScrollMetric metric) const;
- void setScrollMetric(ScrollMetric metric, const QVariant &value);
- void resetScrollMetrics();
-
- void scrollTo(const QPointF &pos, int scrollTime = 1000);
- void ensureVisible(const QPointF &pos, int xmargin, int ymargin, int scrollTime = 1000);
-
- qreal dpi() const;
- void setDpi(qreal dpi);
- void setDpiFromWidget(QWidget *widget);
-
- void registerDebugHook(void (*callback)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition), void *user);
-
-protected:
- virtual void stateChanged(State oldState);
-
- enum Input {
- InputPress,
- InputMove,
- InputRelease
- };
-
- bool handleInput(Input input, const QPointF &position, qint64 timestamp);
-
- QKineticScroller(QObject *receiver, QKineticScrollerPrivate &dd);
- QScopedPointer<QKineticScrollerPrivate> d_ptr;
-
-private:
- Q_DISABLE_COPY(QKineticScroller)
- Q_DECLARE_PRIVATE(QKineticScroller)
-
- friend class QFlickGestureRecognizer;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QKineticScroller *)
-
-QT_END_HEADER
-
-#endif // QKINETICSCROLLER_H
diff --git a/scroller/qkineticscroller_mac.mm b/scroller/qkineticscroller_mac.mm
deleted file mode 100644
index b358063..0000000
--- a/scroller/qkineticscroller_mac.mm
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <Cocoa/Cocoa.h>
-
-#include "qkineticscroller_p.h"
-
-#ifdef Q_WS_MAC
-
-QPointF QKineticScrollerPrivate::realDpi(int screen)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSArray *nsscreens = [NSScreen screens];
-
- if (screen < 0 || screen >= int([nsscreens count]))
- screen = 0;
-
- NSScreen *nsscreen = [nsscreens objectAtIndex:screen];
- CGDirectDisplayID display = [[[nsscreen deviceDescription] objectForKey:@"NSScreenNumber"] intValue];
-
- CGSize mmsize = CGDisplayScreenSize(display);
- if (mmsize.width > 0 && mmsize.height > 0) {
- return QPointF(CGDisplayPixelsWide(display) / mmsize.width,
- CGDisplayPixelsHigh(display) / mmsize.height) * qreal(25.4);
- } else {
- return QPointF();
- }
- [pool release];
-}
-
-#endif
diff --git a/scroller/qkineticscroller_maemo5.cpp b/scroller/qkineticscroller_maemo5.cpp
deleted file mode 100644
index 4c6c9cc..0000000
--- a/scroller/qkineticscroller_maemo5.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkineticscroller_p.h"
-
-#ifdef Q_WS_MAEMO_5
-
-QPointF QKineticScrollerPrivate::realDpi(int screen)
-{
- // The DPI value is hardcoded to 96 on Maemo5:
- // https://projects.maemo.org/bugzilla/show_bug.cgi?id=152525
- // This value (260) is only correct for the N900 though, but
- // there's no way to get the real DPI at run time.
- return QPointF(260, 260);
-}
-
-#endif
diff --git a/scroller/qkineticscroller_p.h b/scroller/qkineticscroller_p.h
deleted file mode 100644
index 0f5e030..0000000
--- a/scroller/qkineticscroller_p.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QTime>
-#include <QPointer>
-#include <QObject>
-#include <qkineticscroller.h>
-#if QT_VERSION < 0x040700
-# include <QTime>
-#else
-# include <QElapsedTimer>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QEvent;
-class QTimerEvent;
-
-class QKineticScrollerPrivate : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PUBLIC(QKineticScroller)
-
-public:
- QKineticScrollerPrivate();
- 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);
- bool moveWhilePressed(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
- bool releaseWhilePressed(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
- bool moveWhileDragging(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
- bool releaseWhileDragging(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
- bool pressWhileScrolling(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
-
- void timerEvent(QTimerEvent *);
- void timerEventWhileDragging();
- void timerEventWhileScrolling();
-
- void handleDrag(const QPointF &position, qint64 timestamp);
- void updateVelocity(const QPointF &deltaPixel, qint64 deltaTime);
-
- qreal decelerate(qreal v, qreal t);
- QPointF calculateVelocity(qreal time);
- void setContentPositionHelper(const QPointF &deltaPos);
-
- QPointF realDpi(int screen);
-
-
- static const char *stateName(QKineticScroller::State state);
- static const char *inputName(QKineticScroller::Input input);
-
- // metrics
-
- qreal dragVelocitySmoothingFactor;
- qreal linearDecelerationFactor;
- qreal exponentialDecelerationBase;
- qreal overshootSpringConstantRoot;
- QPointF overshootMaximumDistance;
- qreal overshootDragResistanceFactor;
- qreal dragStartDistance;
- qreal dragStartDirectionErrorMargin;
- qreal maximumVelocity;
- qreal minimumVelocity;
- qreal maximumNonAcceleratedVelocity;
- qreal maximumClickThroughVelocity;
- qreal axisLockThreshold;
- qreal fastSwipeBaseVelocity;
- qreal fastSwipeMinimumVelocity;
- 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;
- QKineticScroller::State state;
- QKineticScroller::OvershootPolicy hOvershootPolicy;
- QKineticScroller::OvershootPolicy vOvershootPolicy;
- QPointF oldVelocity;
-
- QPointF pressPosition;
- QPointF lastPosition;
- qint64 pressTimestamp;
- qint64 lastTimestamp;
-
- QPointF dragDistance; // the distance we should move during the next drag timer event
-
- QPointF scrollToPosition;
- bool scrollToX;
- bool scrollToY;
-
- QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor)
- bool overshootX;
- bool overshootY;
-
- qreal pixelPerMeter;
-
-#if QT_VERSION < 0x040700
- QTime scrollRelativeTimer;
- QTime scrollAbsoluteTimer;
-#else
- QElapsedTimer scrollRelativeTimer;
- QElapsedTimer scrollAbsoluteTimer;
-#endif
- QPointF releaseVelocity; // the starting velocity of the scrolling state
- QPointF overshootVelocity; // the starting velocity when going into overshoot
- qreal overshootStartTimeX;
- qreal overshootStartTimeY;
- int timerId;
-
- bool firstScroll;
-
- void (*debugHook)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition);
- void *debugHookUser;
-
- QKineticScroller *q_ptr;
-};
-
-QT_END_NAMESPACE
diff --git a/scroller/scroller.pro b/scroller/scroller.pro
index 28b794b..cc11f24 100644
--- a/scroller/scroller.pro
+++ b/scroller/scroller.pro
@@ -9,10 +9,10 @@ DEPENDPATH += .
INCLUDEPATH += .
# Input
-HEADERS += qkineticscroller.h qkineticscroller_p.h qflickgesture.h
-SOURCES += qkineticscroller.cpp qflickgesture.cpp
+HEADERS += qscroller.h qscroller_p.h qscrollerproperties.h qscrollerproperties_p.h qflickgesture.h
+SOURCES += qscroller.cpp qscrollerproperties.cpp qflickgesture.cpp
-macx:SOURCES += qkineticscroller_mac.mm
-maemo5:SOURCES += qkineticscroller_maemo5.cpp
+#macx:SOURCES += qkineticscroller_mac.mm
+#maemo5:SOURCES += qkineticscroller_maemo5.cpp
macx:LIBS += -framework Cocoa
diff --git a/testapp/main.cpp b/testapp/main.cpp
index 3dd4e1e..9ec8a70 100644
--- a/testapp/main.cpp
+++ b/testapp/main.cpp
@@ -15,7 +15,7 @@
# include <QAbstractKineticScroller>
#endif
-#include "qscrollareakineticscroller.h"
+// #include "qscrollareakineticscroller.h"
#include <qflickgesture.h>
#include "qwebviewkineticscroller.h"
@@ -88,11 +88,11 @@ private slots:
return;
switch (page) {
case 0:
- m_settings->setKineticScroller(m_list_scroller);
+ m_settings->setKineticScroller(m_list->viewport(), m_list_scroller);
m_plot->setKineticScroller(m_list_scroller);
break;
case 1:
- m_settings->setKineticScroller(m_web_scroller);
+ m_settings->setKineticScroller(m_web, m_web_scroller);
m_plot->setKineticScroller(m_web_scroller);
break;
default:
@@ -140,6 +140,16 @@ private:
return newScroller;
} else if (QWebView *web = qobject_cast<QWebView *>(w)) {
web->grabGesture(gestureType);
+
+ QKineticScroller prop;
+ prop.
+ QFlickGestureRecognizer::setProperties(web, prop);
+
+ prop = QFlickGestureRecognizer::properties(web);
+
+ QFlicker f(web);
+ f.ensureVisible(10, 10);
+
QKineticScroller *newScroller = new QKineticScroller(web);
w->setProperty("kineticScroller", QVariant::fromValue(static_cast<QKineticScroller*>(newScroller)) );
return newScroller;
diff --git a/testapp/settingswidget.cpp b/testapp/settingswidget.cpp
index 30f1d90..f61f297 100644
--- a/testapp/settingswidget.cpp
+++ b/testapp/settingswidget.cpp
@@ -51,8 +51,11 @@
#include <QCheckBox>
#include <QScrollArea>
+#include <QDebug>
+
#include "settingswidget.h"
#include "qkineticscroller.h"
+#include "qflickgesture.h"
struct MetricItem
{
@@ -69,7 +72,8 @@ class MetricItemUpdater : public QObject
Q_OBJECT
public:
MetricItemUpdater(MetricItem *item)
- : m_item(item), m_scroller(0)
+ : m_item(item)
+ , m_scroller(0)
{
if (m_item->min.type() == QVariant::PointF) {
m_slider = new QSlider(Qt::Horizontal);
@@ -277,7 +281,10 @@ public:
};
SettingsWidget::SettingsWidget(bool smallscreen)
- : QScrollArea(), m_scroller(0), m_smallscreen(smallscreen)
+ : QScrollArea()
+ , m_widget(0)
+ , m_scroller(0)
+ , m_smallscreen(smallscreen)
{
setWindowTitle(QLatin1String("Settings"));
QWidget *view = new QWidget();
@@ -368,8 +375,9 @@ SettingsWidget::SettingsWidget(bool smallscreen)
setWidgetResizable(true);
}
-void SettingsWidget::setKineticScroller(QKineticScroller *scroller)
+void SettingsWidget::setKineticScroller(QWidget *widget, QKineticScroller *scroller)
{
+ m_widget = widget;
m_scroller = scroller;
//setEnabled(m_scroller);
@@ -380,8 +388,8 @@ void SettingsWidget::setKineticScroller(QKineticScroller *scroller)
if (!m_scroller)
return;
- m_onoff->setChecked(m_scroller->isEnabled());
- m_dpi->setValue(m_scroller->dpi());
+ //TODO m_onoff->setChecked(m_scroller->isEnabled());
+ //TODO m_dpi->setValue(m_scroller->dpi());
m_hospolicy->setCurrentIndex(m_hospolicy->findData(m_scroller->horizontalOvershootPolicy()));
m_vospolicy->setCurrentIndex(m_vospolicy->findData(m_scroller->verticalOvershootPolicy()));
@@ -399,14 +407,18 @@ void SettingsWidget::setKineticScroller(QKineticScroller *scroller)
void SettingsWidget::enabledChanged(bool on)
{
+ /* TODO
if (m_scroller)
m_scroller->setEnabled(on);
+ */
}
void SettingsWidget::dpiChanged(int dpi)
{
+ /* TODO
if (m_scroller)
m_scroller->setDpi(dpi);
+ */
}
void SettingsWidget::overshootPolicyChanged(int index)
@@ -427,7 +439,11 @@ void SettingsWidget::scrollTo()
return;
if (!m_scroller)
return;
- m_scroller->scrollTo(QPointF(m_scrollx->value(), m_scrolly->value()), m_scrolltime->value());
+
+qDebug() << "SettingsWidget::scrollTo" << m_scrollx->value();
+
+ QFlickGesture *flick = QFlickGestureRecognizer::getFlickGesture(m_widget);
+ flick->scrollTo(QPointF(m_scrollx->value(), m_scrolly->value()), m_scrolltime->value());
}
#include "settingswidget.moc"
diff --git a/testapp/settingswidget.h b/testapp/settingswidget.h
index ec7a180..c0605e4 100644
--- a/testapp/settingswidget.h
+++ b/testapp/settingswidget.h
@@ -59,7 +59,7 @@ class SettingsWidget : public QScrollArea
public:
SettingsWidget(bool smallscreen = false);
- void setKineticScroller(QKineticScroller *scroller);
+ void setKineticScroller(QWidget *widget, QKineticScroller *scroller);
private slots:
void enabledChanged(bool on);
@@ -70,6 +70,7 @@ private slots:
private:
void addToGrid(QGridLayout *grid, QWidget *label, int widgetCount, ...);
+ QWidget *m_widget;
QKineticScroller *m_scroller;
QCheckBox *m_onoff;
QSpinBox *m_dpi, *m_scrollx, *m_scrolly, *m_scrolltime;