diff options
author | Robert Griebl <rgriebl@trolltech.com> | 2010-04-14 02:44:41 +0200 |
---|---|---|
committer | Robert Griebl <rgriebl@trolltech.com> | 2010-04-14 02:44:41 +0200 |
commit | 3d0e9c5aa5b560e85ee761a55ca40f4c31acf232 (patch) | |
tree | d8f603696de3f0cefd00105dd32d75943207290d | |
parent | 4010a59ca9e71f85b683f7b389dd60915f99fad1 (diff) |
added a have-fun-with-scroll=metrics widget to the example app
-rw-r--r-- | kineticscroller.pro | 4 | ||||
-rw-r--r-- | main.cpp | 19 | ||||
-rw-r--r-- | metrics.cpp | 202 | ||||
-rw-r--r-- | metrics.h | 2 | ||||
-rw-r--r-- | qkineticscroller.cpp | 3 | ||||
-rw-r--r-- | qkineticscroller.h | 7 |
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 @@ -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] |