diff options
Diffstat (limited to 'metrics.cpp')
-rw-r--r-- | metrics.cpp | 202 |
1 files changed, 202 insertions, 0 deletions
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" |