1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the Qwt License, Version 1.0
8
*****************************************************************************/
11
#include <qdatetime.h>
12
#include "qwt_abstract_slider.h"
16
#define WHEEL_DELTA 120
19
class QwtAbstractSlider::PrivateData
44
Qt::Orientation orientation;
51
\param orientation Orientation
52
\param parent Parent widget
54
QwtAbstractSlider::QwtAbstractSlider(
55
Qt::Orientation orientation, QWidget *parent):
58
d_data = new QwtAbstractSlider::PrivateData;
59
d_data->orientation = orientation;
61
#if QT_VERSION >= 0x040000
64
setFocusPolicy(TabFocus);
68
QwtAbstractSlider::~QwtAbstractSlider()
71
killTimer(d_data->tmrID);
77
En/Disable read only mode
79
In read only mode the slider can't be controlled by mouse
82
\param readOnly Enables in case of true
85
void QwtAbstractSlider::setReadOnly(bool readOnly)
87
d_data->readOnly = readOnly;
92
In read only mode the slider can't be controlled by mouse
95
\return true if read only
98
bool QwtAbstractSlider::isReadOnly() const
100
return d_data->readOnly;
104
\brief Set the orientation.
105
\param o Orientation. Allowed values are
106
Qt::Horizontal and Qt::Vertical.
108
void QwtAbstractSlider::setOrientation(Qt::Orientation o)
110
d_data->orientation = o;
117
Qt::Orientation QwtAbstractSlider::orientation() const
119
return d_data->orientation;
122
//! Stop updating if automatic scrolling is active
124
void QwtAbstractSlider::stopMoving()
128
killTimer(d_data->tmrID);
134
\brief Specify the update interval for automatic scrolling
135
\param t update interval in milliseconds
138
void QwtAbstractSlider::setUpdateTime(int t)
146
//! Mouse press event handler
147
void QwtAbstractSlider::mousePressEvent(QMouseEvent *e)
157
const QPoint &p = e->pos();
159
d_data->timerTick = 0;
161
getScrollMode(p, d_data->scrollMode, d_data->direction);
164
switch(d_data->scrollMode)
168
d_data->mouseOffset = 0;
169
d_data->tmrID = startTimer(qwtMax(250, 2 * d_data->updTime));
173
d_data->time.start();
175
d_data->mouseOffset = getValue(p) - value();
176
emit sliderPressed();
180
d_data->mouseOffset = 0;
181
d_data->direction = 0;
187
//! Emits a valueChanged() signal if necessary
188
void QwtAbstractSlider::buttonReleased()
190
if ((!d_data->tracking) || (value() != prevValue()))
191
emit valueChanged(value());
195
//! Mouse Release Event handler
196
void QwtAbstractSlider::mouseReleaseEvent(QMouseEvent *e)
206
const double inc = step();
208
switch(d_data->scrollMode)
212
setPosition(e->pos());
213
d_data->direction = 0;
214
d_data->mouseOffset = 0;
215
if (d_data->mass > 0.0)
217
const int ms = d_data->time.elapsed();
218
if ((fabs(d_data->speed) > 0.0) && (ms < 50))
219
d_data->tmrID = startTimer(d_data->updTime);
223
d_data->scrollMode = ScrNone;
226
emit sliderReleased();
233
setPosition(e->pos());
234
d_data->direction = 0;
235
d_data->mouseOffset = 0;
236
d_data->scrollMode = ScrNone;
244
if (!d_data->timerTick)
245
QwtDoubleRange::incPages(d_data->direction);
246
d_data->timerTick = 0;
248
d_data->scrollMode = ScrNone;
255
if (!d_data->timerTick)
256
QwtDoubleRange::fitValue(value() + double(d_data->direction) * inc);
257
d_data->timerTick = 0;
259
d_data->scrollMode = ScrNone;
265
d_data->scrollMode = ScrNone;
273
Move the slider to a specified point, adjust the value
274
and emit signals if necessary.
276
void QwtAbstractSlider::setPosition(const QPoint &p)
278
QwtDoubleRange::fitValue(getValue(p) - d_data->mouseOffset);
283
\brief Enables or disables tracking.
285
If tracking is enabled, the slider emits a
286
valueChanged() signal whenever its value
287
changes (the default behaviour). If tracking
288
is disabled, the value changed() signal will only
290
<li>the user releases the mouse
291
button and the value has changed or
292
<li>at the end of automatic scrolling.</ul>
293
Tracking is enabled by default.
294
\param enable \c true (enable) or \c false (disable) tracking.
296
void QwtAbstractSlider::setTracking(bool enable)
298
d_data->tracking = enable;
302
Mouse Move Event handler
305
void QwtAbstractSlider::mouseMoveEvent(QMouseEvent *e)
316
if (d_data->scrollMode == ScrMouse )
318
setPosition(e->pos());
319
if (d_data->mass > 0.0)
321
double ms = double(d_data->time.elapsed());
324
d_data->speed = (exactValue() - exactPrevValue()) / ms;
325
d_data->time.start();
327
if (value() != prevValue())
328
emit sliderMoved(value());
336
void QwtAbstractSlider::wheelEvent(QWheelEvent *e)
347
int mode = ScrNone, direction = 0;
349
// Give derived classes a chance to say ScrNone
350
getScrollMode(e->pos(), mode, direction);
351
if ( mode != ScrNone )
353
const int inc = e->delta() / WHEEL_DELTA;
354
QwtDoubleRange::incPages(inc);
355
if (value() != prevValue())
356
emit sliderMoved(value());
363
- Key_Down, KeyLeft\n
365
- Key_Up, Key_Right\n
371
void QwtAbstractSlider::keyPressEvent(QKeyEvent *e)
386
if ( orientation() == Qt::Vertical )
390
if ( orientation() == Qt::Vertical )
394
if ( orientation() == Qt::Horizontal )
398
if ( orientation() == Qt::Horizontal )
405
if ( increment != 0 )
407
QwtDoubleRange::incValue(increment);
408
if (value() != prevValue())
409
emit sliderMoved(value());
417
void QwtAbstractSlider::timerEvent(QTimerEvent *)
419
const double inc = step();
421
switch (d_data->scrollMode)
425
if (d_data->mass > 0.0)
427
d_data->speed *= exp( - double(d_data->updTime) * 0.001 / d_data->mass );
428
const double newval =
429
exactValue() + d_data->speed * double(d_data->updTime);
430
QwtDoubleRange::fitValue(newval);
431
// stop if d_data->speed < one step per second
432
if (fabs(d_data->speed) < 0.001 * fabs(step()))
447
QwtDoubleRange::incPages(d_data->direction);
448
if (!d_data->timerTick)
450
killTimer(d_data->tmrID);
451
d_data->tmrID = startTimer(d_data->updTime);
457
QwtDoubleRange::fitValue(value() + double(d_data->direction) * inc);
458
if (!d_data->timerTick)
460
killTimer(d_data->tmrID);
461
d_data->tmrID = startTimer(d_data->updTime);
472
d_data->timerTick = 1;
477
Notify change of value
479
This function can be reimplemented by derived classes
480
in order to keep track of changes, i.e. repaint the widget.
481
The default implementation emits a valueChanged() signal
482
if tracking is enabled.
484
void QwtAbstractSlider::valueChange()
486
if (d_data->tracking)
487
emit valueChanged(value());
491
\brief Set the slider's mass for flywheel effect.
493
If the slider's mass is greater then 0, it will continue
494
to move after the mouse button has been released. Its speed
495
decreases with time at a rate depending on the slider's mass.
496
A large mass means that it will continue to move for a
499
Derived widgets may overload this function to make it public.
501
\param val New mass in kg
503
\bug If the mass is smaller than 1g, it is set to zero.
504
The maximal mass is limited to 100kg.
507
void QwtAbstractSlider::setMass(double val)
511
else if (val > 100.0)
512
d_data->mass = 100.0;
521
double QwtAbstractSlider::mass() const
528
\brief Move the slider to a specified value
530
This function can be used to move the slider to a value
531
which is not an integer multiple of the step size.
535
void QwtAbstractSlider::setValue(double val)
537
if (d_data->scrollMode == ScrMouse)
539
QwtDoubleRange::setValue(val);
544
\brief Set the slider's value to the nearest integer multiple
548
\sa setValue(), incValue()
550
void QwtAbstractSlider::fitValue(double value)
552
if (d_data->scrollMode == ScrMouse)
554
QwtDoubleRange::fitValue(value);
558
\brief Increment the value by a specified number of steps
559
\param steps number of steps
562
void QwtAbstractSlider::incValue(int steps)
564
if (d_data->scrollMode == ScrMouse)
566
QwtDoubleRange::incValue(steps);
569
void QwtAbstractSlider::setMouseOffset(double offset)
571
d_data->mouseOffset = offset;
574
double QwtAbstractSlider::mouseOffset() const
576
return d_data->mouseOffset;
579
int QwtAbstractSlider::scrollMode() const
581
return d_data->scrollMode;