summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <rgriebl@trolltech.com>2010-04-14 02:44:41 +0200
committerRobert Griebl <rgriebl@trolltech.com>2010-04-14 02:44:41 +0200
commit3d0e9c5aa5b560e85ee761a55ca40f4c31acf232 (patch)
treed8f603696de3f0cefd00105dd32d75943207290d
parent4010a59ca9e71f85b683f7b389dd60915f99fad1 (diff)
added a have-fun-with-scroll=metrics widget to the example app
-rw-r--r--kineticscroller.pro4
-rw-r--r--main.cpp19
-rw-r--r--metrics.cpp202
-rw-r--r--metrics.h2
-rw-r--r--qkineticscroller.cpp3
-rw-r--r--qkineticscroller.h7
6 files changed, 224 insertions, 13 deletions
diff --git a/kineticscroller.pro b/kineticscroller.pro
index 3e34413..3d51d54 100644
--- a/kineticscroller.pro
+++ b/kineticscroller.pro
@@ -8,5 +8,5 @@ DEPENDPATH += .
INCLUDEPATH += .
# Input
-HEADERS += qkineticscroller.h qkineticscroller_p.h qscrollareakineticscroller.h
-SOURCES += main.cpp qkineticscroller.cpp qscrollareakineticscroller.cpp
+HEADERS += qkineticscroller.h qkineticscroller_p.h qscrollareakineticscroller.h metrics.h
+SOURCES += main.cpp qkineticscroller.cpp qscrollareakineticscroller.cpp metrics.cpp
diff --git a/main.cpp b/main.cpp
index 4b243fc..2c44120 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,18 +1,29 @@
#include <QtGui>
#include "qscrollareakineticscroller.h"
+#include "metrics.h"
+
int main(int argc, char **argv)
{
QApplication a(argc, argv);
-
+
+ QWidget *w = new QWidget();
QListWidget *lw = new QListWidget();
-
+
for (int i = 0; i < 1000; ++i)
new QListWidgetItem(QString("Oa dsjfhdk jhdsjk hfdskj k %1").arg(i), lw);
-
+
QScrollAreaKineticScroller *s = new QScrollAreaKineticScroller();
s->setWidget(lw);
- lw->show();
+
+ QWidget *metrics = metricsWidget(s);
+
+ QHBoxLayout *lay = new QHBoxLayout(w);
+ lay->addWidget(lw);
+ lay->addWidget(metrics);
+
+ w->show();
+ w->raise();
s->scrollTo(QPointF(80,3000));
diff --git a/metrics.cpp b/metrics.cpp
new file mode 100644
index 0000000..0fda845
--- /dev/null
+++ b/metrics.cpp
@@ -0,0 +1,202 @@
+#include <QtGui>
+#include "qkineticscroller.h"
+
+struct MetricItem
+{
+ QKineticScroller::ScrollMetric metric;
+ const char *name;
+ int scaling;
+ const char *unit;
+ QVariant min, max;
+ QVariant step;
+};
+
+class ItemUpdater : public QObject
+{
+ Q_OBJECT
+public:
+ ItemUpdater(MetricItem *item, QKineticScroller *scroller)
+ : m_item(item), m_scroller(scroller)
+ {
+ if (m_item->min.type() == QVariant::PointF) {
+ m_slider = new QSlider(Qt::Horizontal);
+ m_slider->setSingleStep(1);
+ m_slider->setMinimum(-1);
+ m_slider->setMaximum(int((m_item->max.toPointF().x() - m_item->min.toPointF().x()) / m_item->step.toReal()));
+ m_slider->setValue(-1);
+ m_slider2 = new QSlider(Qt::Horizontal);
+ m_slider2->setSingleStep(1);
+ m_slider2->setMinimum(-1);
+ m_slider2->setMaximum(int((m_item->max.toPointF().y() - m_item->min.toPointF().y()) / m_item->step.toReal()));
+ m_slider2->setValue(-1);
+ m_control = new QWidget();
+ QHBoxLayout *lay = new QHBoxLayout(m_control);
+ lay->setContentsMargins(0, 0, 0, 0);
+ lay->addWidget(m_slider);
+ lay->addWidget(m_slider2);
+ } else {
+ m_slider = new QSlider(Qt::Horizontal);
+ m_slider->setSingleStep(1);
+ m_slider->setMinimum(-1);
+ m_slider->setMaximum(int((m_item->max.toReal() - m_item->min.toReal()) / m_item->step.toReal()));
+ m_slider->setValue(-1);
+ m_slider2 = 0;
+ m_control = m_slider;
+ }
+ m_unitLabel = new QLabel(QLatin1String(m_item->unit));
+ m_valueLabel = new QLabel();
+ m_nameLabel = new QLabel(QLatin1String(m_item->name));
+ m_resetButton = new QToolButton();
+ m_resetButton->setText(QLatin1String("Reset"));
+ m_resetButton->setEnabled(false);
+
+ connect(m_resetButton, SIGNAL(clicked()), this, SLOT(reset()));
+ connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int)));
+ if (m_slider2)
+ connect(m_slider2, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int)));
+
+ m_default_value = m_scroller->scrollMetric(m_item->metric);
+ valueChanged(m_default_value);
+
+ m_slider->setMinimum(0);
+ if (m_slider2)
+ m_slider2->setMinimum(0);
+ }
+
+ QWidget *nameLabel() { return m_nameLabel; }
+ QWidget *unitLabel() { return m_unitLabel; }
+ QWidget *valueLabel() { return m_valueLabel; }
+ QWidget *valueControl() { return m_control; }
+ QWidget *resetButton() { return m_resetButton; }
+
+private slots:
+ void valueChanged(const QVariant v)
+ {
+ m_value = v;
+ switch (m_item->min.type()) {
+ case QVariant::Double: {
+ m_slider->setValue(int((m_value.toReal() * m_item->scaling - m_item->min.toReal()) / m_item->step.toReal()));
+ break;
+ }
+ case QVariant::Int: {
+ m_slider->setValue(int((m_value.toInt() * m_item->scaling - m_item->min.toInt()) / m_item->step.toInt()));
+ break;
+ }
+ case QVariant::PointF: {
+ m_slider->setValue(int((m_value.toPointF().x() * m_item->scaling - m_item->min.toPointF().x()) / m_item->step.toReal()));
+ m_slider2->setValue(int((m_value.toPointF().y() * m_item->scaling - m_item->min.toPointF().y()) / m_item->step.toReal()));
+ break;
+ }
+ default: break;
+ }
+ }
+
+ void sliderChanged(int value)
+ {
+ bool second = (m_slider2 && (sender() == m_slider2));
+ QString text;
+
+ switch (m_item->min.type()) {
+ case QVariant::Double: {
+ qreal d = m_item->min.toReal() + qreal(value) * m_item->step.toReal();
+ text = QString::number(d);
+ m_value = d / qreal(m_item->scaling);
+ break;
+ }
+ case QVariant::Int: {
+ int i = m_item->min.toInt() + int(qreal(value) * m_item->step.toReal());
+ text = QString::number(i);
+ m_value = i / m_item->scaling;
+ break;
+ }
+ case QVariant::PointF: {
+ qreal p = (second ? m_item->min.toPointF().y() : m_item->min.toPointF().x()) + qreal(value) * m_item->step.toReal();
+ text = QString("%1, %2").arg(second ? m_value.toPointF().x() * m_item->scaling : p).arg(second ? p : m_value.toPointF().y() * m_item->scaling);
+ m_value = QPointF(second ? m_value.toPointF().x() : p / m_item->scaling, second ? p / m_item->scaling : m_value.toPointF().y());
+ break;
+ }
+ default: break;
+ }
+ m_valueLabel->setText(text);
+ m_scroller->setScrollMetric(m_item->metric, m_value);
+
+ m_resetButton->setEnabled(m_value != m_default_value);
+ }
+
+ void reset()
+ {
+ m_scroller->setScrollMetric(m_item->metric, m_value);
+ valueChanged(m_default_value);
+ }
+
+private:
+ MetricItem *m_item;
+ QKineticScroller *m_scroller;
+
+ QSlider *m_slider, *m_slider2;
+ QLabel *m_unitLabel, *m_nameLabel, *m_valueLabel;
+ QToolButton *m_resetButton;
+ QWidget *m_control;
+
+ QVariant m_value, m_default_value;
+};
+
+#define METRIC(x) QKineticScroller::x, #x
+
+MetricItem items[QKineticScroller::ScrollMetricCount] = {
+ { METRIC(DragVelocitySmoothingFactor), 1, "", qreal(0), qreal(1), qreal(0.01) },
+
+ { METRIC(LinearDecelerationFactor), 1, "m/s^2", qreal(0), qreal(3), qreal(0.01) },
+ { METRIC(ExponentialDecelerationBase), 1, "", qreal(0), qreal(1), qreal(0.01) },
+ { METRIC(OvershootSpringConstant), 1, "kg/s^2", qreal(1), qreal(500), qreal(1) },
+ { METRIC(OvershootDragResistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) },
+ { METRIC(OvershootMaximumDistance), 1000, "(mm, mm)", QPointF(0, 0), QPointF(500, 500), qreal(1) },
+
+ { METRIC(DragStartDistance), 1000, "mm", qreal(1), qreal(20), qreal(0.1) },
+ { METRIC(DragStartDirectionErrorMargin), 1000, "mm", qreal(1), qreal(20), qreal(0.1) },
+
+ { METRIC(MinimumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) },
+ { METRIC(MaximumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) },
+ { METRIC(MaximumNonAcceleratedVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) },
+
+ { METRIC(MaximumClickThroughVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) },
+ { METRIC(AxisLockThreshold), 1, "", qreal(0), qreal(1), qreal(0.01) },
+
+ { METRIC(FramesPerSecond), 1, "frames/s", int(10), int(100), int(1) },
+
+ { METRIC(FastSwipeMaximumTime), 1000, "ms", qreal(10), qreal(1000), qreal(1) },
+ { METRIC(FastSwipeMinimumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) },
+ { METRIC(FastSwipeBaseVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }
+};
+
+#undef METRIC
+
+QGridLayout *createControlGrid(QWidget *parent, QKineticScroller *scroller)
+{
+ QGridLayout *grid = new QGridLayout();
+ int row = 0;
+
+ for (int i = 0; i < QKineticScroller::ScrollMetricCount; i++) {
+ ItemUpdater *u = new ItemUpdater(items + i, scroller);
+ u->setParent(parent);
+
+ grid->addWidget(u->nameLabel(), row, 0);
+ grid->addWidget(u->valueControl(), row, 1);
+ grid->addWidget(u->valueLabel(), row, 2);
+ grid->addWidget(u->unitLabel(), row, 3);
+ grid->addWidget(u->resetButton(), row, 4);
+
+ row++;
+ }
+ return grid;
+}
+
+QWidget *metricsWidget(QKineticScroller *scroller)
+{
+ QWidget *w = new QWidget();
+ w->setWindowTitle(QLatin1String("Kinetic Scroller Metrics"));
+ w->setLayout(createControlGrid(w, scroller));
+ return w;
+}
+
+#include "metrics.moc"
diff --git a/metrics.h b/metrics.h
new file mode 100644
index 0000000..14d8624
--- /dev/null
+++ b/metrics.h
@@ -0,0 +1,2 @@
+
+extern QWidget *metricsWidget(QKineticScroller *scroller);
diff --git a/qkineticscroller.cpp b/qkineticscroller.cpp
index 704205e..bdf4cfa 100644
--- a/qkineticscroller.cpp
+++ b/qkineticscroller.cpp
@@ -231,7 +231,6 @@ void QKineticScroller::resetScrollMetrics()
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(OvershootMaximumVelocity, qreal(247.0 / 1000));
metrics.insert(DragStartDistance, qreal(2.5 / 1000));
metrics.insert(DragStartDirectionErrorMargin, qreal(1.0 / 1000));
metrics.insert(MaximumVelocity, qreal(6650.0 / 1000));
@@ -411,7 +410,6 @@ QVariant QKineticScroller::scrollMetric(ScrollMetric metric) const
case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity;
case AxisLockThreshold: return d->axisLockThreshold;
case FramesPerSecond: return d->framesPerSecond;
- case OvershootMaximumVelocity: return d->overshootMaximumVelocity;
case FastSwipeMaximumTime: return d->fastSwipeMaximumTime;
case FastSwipeMinimumVelocity: return d->fastSwipeMinimumVelocity;
case FastSwipeBaseVelocity: return d->fastSwipeBaseVelocity;
@@ -440,7 +438,6 @@ void QKineticScroller::setScrollMetric(ScrollMetric metric, const QVariant &valu
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 OvershootMaximumVelocity: d->overshootMaximumVelocity = value.toReal(); break;
case FastSwipeMaximumTime: d->fastSwipeMaximumTime = value.toReal(); break;
case FastSwipeMinimumVelocity: d->fastSwipeMinimumVelocity = value.toReal(); break;
case FastSwipeBaseVelocity: d->fastSwipeBaseVelocity = value.toReal(); break;
diff --git a/qkineticscroller.h b/qkineticscroller.h
index a574891..145f5cb 100644
--- a/qkineticscroller.h
+++ b/qkineticscroller.h
@@ -58,7 +58,7 @@ class QKineticScrollerPrivate;
class Q_GUI_EXPORT QKineticScroller
{
public:
- ~QKineticScroller();
+ virtual ~QKineticScroller();
bool isEnabled() const;
void setEnabled(bool b);
@@ -89,11 +89,10 @@ public:
DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
LinearDecelerationFactor, // qreal [m/s^2]
- ExponentialDecelerationBase, // qreal [0..1]
- OvershootSpringConstant, // qreal [0..1]
+ ExponentialDecelerationBase, // qreal
+ OvershootSpringConstant, // qreal [kg/s^2]
OvershootDragResistanceFactor, // qreal [0..1]
OvershootMaximumDistance, // QPointF([m], [m])
- OvershootMaximumVelocity, // qreal [m/s]
DragStartDistance, // qreal [m]
DragStartDirectionErrorMargin, // qreal [m]