qwt_abstract_slider.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
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  *****************************************************************************/
9 
10 #include "qwt_abstract_slider.h"
11 #include "qwt_scale_map.h"
12 #include "qwt_scale_div.h"
13 #include "qwt_math.h"
14 
15 #include <qevent.h>
16 
17 static double qwtAlignToScaleDiv(
18  const QwtAbstractSlider* slider, double value )
19 {
20  const QwtScaleDiv& sd = slider->scaleDiv();
21 
22  const int tValue = slider->transform( value );
23 
24  if ( tValue == slider->transform( sd.lowerBound() ) )
25  return sd.lowerBound();
26 
27  if ( tValue == slider->transform( sd.upperBound() ) )
28  return sd.upperBound();
29 
30  for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
31  {
32  const QList< double > ticks = sd.ticks( i );
33  for ( int j = 0; j < ticks.size(); j++ )
34  {
35  if ( slider->transform( ticks[ j ] ) == tValue )
36  return ticks[ j ];
37  }
38  }
39 
40  return value;
41 }
42 
44 {
45  public:
47  : isScrolling( false )
48  , isTracking( true )
49  , pendingValueChanged( false )
50  , readOnly( false )
51  , totalSteps( 100 )
52  , singleSteps( 1 )
53  , pageSteps( 10 )
54  , stepAlignment( true )
55  , isValid( false )
56  , value( 0.0 )
57  , wrapping( false )
58  , invertedControls( false )
59  {
60  }
61 
63  bool isTracking;
65 
66  bool readOnly;
67 
68  uint totalSteps;
70  uint pageSteps;
72 
73  bool isValid;
74  double value;
75 
76  bool wrapping;
78 };
79 
92  : QwtAbstractScale( parent )
93 {
95 
96  setScale( 0.0, 100.0 );
97  setFocusPolicy( Qt::StrongFocus );
98 }
99 
102 {
103  delete m_data;
104 }
105 
114 {
115  if ( on != m_data->isValid )
116  {
117  m_data->isValid = on;
118  sliderChange();
119 
120  Q_EMIT valueChanged( m_data->value );
121  }
122 }
123 
126 {
127  return m_data->isValid;
128 }
129 
142 {
143  if ( m_data->readOnly != on )
144  {
145  m_data->readOnly = on;
146  setFocusPolicy( on ? Qt::StrongFocus : Qt::NoFocus );
147 
148  update();
149  }
150 }
151 
160 {
161  return m_data->readOnly;
162 }
163 
178 {
179  m_data->isTracking = on;
180 }
181 
187 {
188  return m_data->isTracking;
189 }
190 
195 void QwtAbstractSlider::mousePressEvent( QMouseEvent* event )
196 {
197  if ( isReadOnly() )
198  {
199  event->ignore();
200  return;
201  }
202 
203  if ( !m_data->isValid || lowerBound() == upperBound() )
204  return;
205 
206  m_data->isScrolling = isScrollPosition( event->pos() );
207 
208  if ( m_data->isScrolling )
209  {
210  m_data->pendingValueChanged = false;
211 
212  Q_EMIT sliderPressed();
213  }
214 }
215 
220 void QwtAbstractSlider::mouseMoveEvent( QMouseEvent* event )
221 {
222  if ( isReadOnly() )
223  {
224  event->ignore();
225  return;
226  }
227 
228  if ( m_data->isValid && m_data->isScrolling )
229  {
230  double value = scrolledTo( event->pos() );
231  if ( value != m_data->value )
232  {
233  value = boundedValue( value );
234 
235  if ( m_data->stepAlignment )
236  {
237  value = alignedValue( value );
238  }
239  else
240  {
241  value = qwtAlignToScaleDiv( this, value );
242  }
243 
244  if ( value != m_data->value )
245  {
246  m_data->value = value;
247 
248  sliderChange();
249 
250  Q_EMIT sliderMoved( m_data->value );
251 
252  if ( m_data->isTracking )
253  Q_EMIT valueChanged( m_data->value );
254  else
255  m_data->pendingValueChanged = true;
256  }
257  }
258  }
259 }
260 
265 void QwtAbstractSlider::mouseReleaseEvent( QMouseEvent* event )
266 {
267  if ( isReadOnly() )
268  {
269  event->ignore();
270  return;
271  }
272 
273  if ( m_data->isScrolling && m_data->isValid )
274  {
275  m_data->isScrolling = false;
276 
278  Q_EMIT valueChanged( m_data->value );
279 
280  Q_EMIT sliderReleased();
281  }
282 }
283 
296 void QwtAbstractSlider::wheelEvent( QWheelEvent* event )
297 {
298  if ( isReadOnly() )
299  {
300  event->ignore();
301  return;
302  }
303 
304  if ( !m_data->isValid || m_data->isScrolling )
305  return;
306 
307 #if QT_VERSION < 0x050000
308  const int wheelDelta = event->delta();
309 #else
310  const QPoint delta = event->angleDelta();
311  const int wheelDelta = ( qAbs( delta.x() ) > qAbs( delta.y() ) )
312  ? delta.x() : delta.y();
313 #endif
314 
315  int numSteps = 0;
316 
317  if ( ( event->modifiers() & Qt::ControlModifier ) ||
318  ( event->modifiers() & Qt::ShiftModifier ) )
319  {
320  // one page regardless of delta
321  numSteps = m_data->pageSteps;
322  if ( wheelDelta < 0 )
323  numSteps = -numSteps;
324  }
325  else
326  {
327  const int numTurns = ( wheelDelta / 120 );
328  numSteps = numTurns * m_data->singleSteps;
329  }
330 
331  if ( m_data->invertedControls )
332  numSteps = -numSteps;
333 
334  const double value = incrementedValue( m_data->value, numSteps );
335  if ( value != m_data->value )
336  {
337  m_data->value = value;
338  sliderChange();
339 
340  Q_EMIT sliderMoved( m_data->value );
341  Q_EMIT valueChanged( m_data->value );
342  }
343 }
344 
370 void QwtAbstractSlider::keyPressEvent( QKeyEvent* event )
371 {
372  if ( isReadOnly() )
373  {
374  event->ignore();
375  return;
376  }
377 
378  if ( !m_data->isValid || m_data->isScrolling )
379  return;
380 
381  int numSteps = 0;
382  double value = m_data->value;
383 
384  switch ( event->key() )
385  {
386  case Qt::Key_Left:
387  {
388  numSteps = -static_cast< int >( m_data->singleSteps );
389  if ( isInverted() )
390  numSteps = -numSteps;
391 
392  break;
393  }
394  case Qt::Key_Right:
395  {
396  numSteps = m_data->singleSteps;
397  if ( isInverted() )
398  numSteps = -numSteps;
399 
400  break;
401  }
402  case Qt::Key_Down:
403  {
404  numSteps = -static_cast< int >( m_data->singleSteps );
405  if ( m_data->invertedControls )
406  numSteps = -numSteps;
407  break;
408  }
409  case Qt::Key_Up:
410  {
411  numSteps = m_data->singleSteps;
412  if ( m_data->invertedControls )
413  numSteps = -numSteps;
414 
415  break;
416  }
417  case Qt::Key_PageUp:
418  {
419  numSteps = m_data->pageSteps;
420  if ( m_data->invertedControls )
421  numSteps = -numSteps;
422  break;
423  }
424  case Qt::Key_PageDown:
425  {
426  numSteps = -static_cast< int >( m_data->pageSteps );
427  if ( m_data->invertedControls )
428  numSteps = -numSteps;
429  break;
430  }
431  case Qt::Key_Home:
432  {
433  value = minimum();
434  break;
435  }
436  case Qt::Key_End:
437  {
438  value = maximum();
439  break;
440  }
441  default:
442  {
443  event->ignore();
444  }
445  }
446 
447  if ( numSteps != 0 )
448  {
449  value = incrementedValue( m_data->value, numSteps );
450  }
451 
452  if ( value != m_data->value )
453  {
454  m_data->value = value;
455  sliderChange();
456 
457  Q_EMIT sliderMoved( m_data->value );
458  Q_EMIT valueChanged( m_data->value );
459  }
460 }
461 
474 void QwtAbstractSlider::setTotalSteps( uint stepCount )
475 {
476  m_data->totalSteps = stepCount;
477 }
478 
484 {
485  return m_data->totalSteps;
486 }
487 
499 void QwtAbstractSlider::setSingleSteps( uint stepCount )
500 {
501  m_data->singleSteps = stepCount;
502 }
503 
509 {
510  return m_data->singleSteps;
511 }
512 
524 void QwtAbstractSlider::setPageSteps( uint stepCount )
525 {
526  m_data->pageSteps = stepCount;
527 }
528 
533 uint QwtAbstractSlider::pageSteps() const
534 {
535  return m_data->pageSteps;
536 }
537 
548 {
549  if ( on != m_data->stepAlignment )
550  {
551  m_data->stepAlignment = on;
552  }
553 }
554 
560 {
561  return m_data->stepAlignment;
562 }
563 
570 void QwtAbstractSlider::setValue( double value )
571 {
572  value = qBound( minimum(), value, maximum() );
573 
574  const bool changed = ( m_data->value != value ) || !m_data->isValid;
575 
576  m_data->value = value;
577  m_data->isValid = true;
578 
579  if ( changed )
580  {
581  sliderChange();
582  Q_EMIT valueChanged( m_data->value );
583  }
584 }
585 
587 double QwtAbstractSlider::value() const
588 {
589  return m_data->value;
590 }
591 
600 {
601  m_data->wrapping = on;
602 }
603 
608 bool QwtAbstractSlider::wrapping() const
609 {
610  return m_data->wrapping;
611 }
612 
629 {
630  m_data->invertedControls = on;
631 }
632 
638 {
639  return m_data->invertedControls;
640 }
641 
651 {
652  const double value = incrementedValue(
653  m_data->value, stepCount );
654 
655  if ( value != m_data->value )
656  {
657  m_data->value = value;
658  sliderChange();
659  }
660 }
661 
671  double value, int stepCount ) const
672 {
673  if ( m_data->totalSteps == 0 )
674  return value;
675 
676  const QwtTransform* transformation =
678 
679  if ( transformation == NULL )
680  {
681  const double range = maximum() - minimum();
682  value += stepCount * range / m_data->totalSteps;
683  }
684  else
685  {
687  map.setPaintInterval( 0, m_data->totalSteps );
688 
689  // we need equidistant steps according to
690  // paint device coordinates
691  const double range = transformation->transform( maximum() )
692  - transformation->transform( minimum() );
693 
694  const double stepSize = range / m_data->totalSteps;
695 
696  double v = transformation->transform( value );
697 
698  v = qRound( v / stepSize ) * stepSize;
699  v += stepCount * range / m_data->totalSteps;
700 
701  value = transformation->invTransform( v );
702  }
703 
704  value = boundedValue( value );
705 
706  if ( m_data->stepAlignment )
707  value = alignedValue( value );
708 
709  return value;
710 }
711 
712 double QwtAbstractSlider::boundedValue( double value ) const
713 {
714  const double vmin = minimum();
715  const double vmax = maximum();
716 
717  if ( m_data->wrapping && vmin != vmax )
718  {
719  if ( qFuzzyCompare( scaleMap().pDist(), 360.0 ) )
720  {
721  // full circle scales: min and max are the same
722 
723  if ( qFuzzyCompare( value, vmax ) )
724  {
725  value = vmin;
726  }
727  else
728  {
729  const double range = vmax - vmin;
730 
731  if ( value < vmin )
732  {
733  value += std::ceil( ( vmin - value ) / range ) * range;
734  }
735  else if ( value > vmax )
736  {
737  value -= std::ceil( ( value - vmax ) / range ) * range;
738  }
739  }
740  }
741  else
742  {
743  if ( value < vmin )
744  value = vmax;
745  else if ( value > vmax )
746  value = vmin;
747  }
748  }
749  else
750  {
751  value = qBound( vmin, value, vmax );
752  }
753 
754  return value;
755 }
756 
757 double QwtAbstractSlider::alignedValue( double value ) const
758 {
759  if ( m_data->totalSteps == 0 )
760  return value;
761 
762  double stepSize;
763 
764  if ( scaleMap().transformation() == NULL )
765  {
766  stepSize = ( maximum() - minimum() ) / m_data->totalSteps;
767  if ( stepSize > 0.0 )
768  {
769  value = lowerBound() +
770  qRound( ( value - lowerBound() ) / stepSize ) * stepSize;
771  }
772  }
773  else
774  {
775  stepSize = ( scaleMap().p2() - scaleMap().p1() ) / m_data->totalSteps;
776 
777  if ( stepSize > 0.0 )
778  {
779  double v = scaleMap().transform( value );
780 
781  v = scaleMap().p1() +
782  qRound( ( v - scaleMap().p1() ) / stepSize ) * stepSize;
783 
784  value = scaleMap().invTransform( v );
785  }
786  }
787 
788  if ( qAbs( stepSize ) > 1e-12 )
789  {
790  if ( qFuzzyCompare( value + 1.0, 1.0 ) )
791  {
792  // correct rounding error if value = 0
793  value = 0.0;
794  }
795  else
796  {
797  // correct rounding error at the border
798  if ( qFuzzyCompare( value, upperBound() ) )
799  value = upperBound();
800  else if ( qFuzzyCompare( value, lowerBound() ) )
801  value = lowerBound();
802  }
803  }
804 
805  return value;
806 }
807 
812 {
813  const double value = qBound( minimum(), m_data->value, maximum() );
814 
815  const bool changed = ( value != m_data->value );
816  if ( changed )
817  {
818  m_data->value = value;
819  }
820 
821  if ( m_data->isValid || changed )
822  Q_EMIT valueChanged( m_data->value );
823 
824  updateGeometry();
825  update();
826 }
827 
830 {
831  update();
832 }
833 
834 #if QWT_MOC_INCLUDE
835 #include "moc_qwt_abstract_slider.cpp"
836 #endif
QwtAbstractSlider::~QwtAbstractSlider
virtual ~QwtAbstractSlider()
Destructor.
Definition: qwt_abstract_slider.cpp:101
QwtAbstractSlider::setWrapping
void setWrapping(bool)
Definition: qwt_abstract_slider.cpp:599
QwtAbstractSlider::PrivateData::totalSteps
uint totalSteps
Definition: qwt_abstract_slider.cpp:68
QwtAbstractSlider::invertedControls
bool invertedControls
Definition: qwt_abstract_slider.h:54
QwtScaleMap::invTransform
double invTransform(double p) const
Definition: qwt_scale_map.h:154
qwt_abstract_slider.h
QwtAbstractScale::scaleMap
const QwtScaleMap & scaleMap() const
Definition: qwt_abstract_scale.cpp:357
QwtTransform::transform
virtual double transform(double value) const =0
qwt_scale_div.h
QwtAbstractSlider::valueChanged
void valueChanged(double value)
Notify a change of value.
QwtAbstractSlider::PrivateData::singleSteps
uint singleSteps
Definition: qwt_abstract_slider.cpp:69
QwtAbstractSlider::PrivateData::pageSteps
uint pageSteps
Definition: qwt_abstract_slider.cpp:70
QwtAbstractSlider::PrivateData::stepAlignment
bool stepAlignment
Definition: qwt_abstract_slider.cpp:71
QwtAbstractSlider::alignedValue
double alignedValue(double) const
Definition: qwt_abstract_slider.cpp:757
QwtAbstractSlider::wheelEvent
virtual void wheelEvent(QWheelEvent *) QWT_OVERRIDE
Definition: qwt_abstract_slider.cpp:296
QwtAbstractSlider::setReadOnly
void setReadOnly(bool)
Definition: qwt_abstract_slider.cpp:141
QwtAbstractSlider::sliderChange
virtual void sliderChange()
Calling update()
Definition: qwt_abstract_slider.cpp:829
QwtAbstractSlider::keyPressEvent
virtual void keyPressEvent(QKeyEvent *) QWT_OVERRIDE
Definition: qwt_abstract_slider.cpp:370
QwtTransform
A transformation between coordinate systems.
Definition: qwt_transform.h:35
QwtAbstractSlider::setValid
void setValid(bool)
Definition: qwt_abstract_slider.cpp:113
QwtAbstractSlider::setValue
void setValue(double value)
Definition: qwt_abstract_slider.cpp:570
qwtAlignToScaleDiv
static double qwtAlignToScaleDiv(const QwtAbstractSlider *slider, double value)
Definition: qwt_abstract_slider.cpp:17
QwtAbstractSlider::setInvertedControls
void setInvertedControls(bool)
Definition: qwt_abstract_slider.cpp:628
QwtAbstractScale::maximum
double maximum() const
Definition: qwt_abstract_scale.cpp:409
QwtAbstractSlider::scaleChange
virtual void scaleChange() QWT_OVERRIDE
Definition: qwt_abstract_slider.cpp:811
QwtTransform::invTransform
virtual double invTransform(double value) const =0
QwtScaleDiv::lowerBound
double lowerBound() const
Definition: qwt_scale_div.cpp:131
QwtAbstractSlider::pageSteps
uint pageSteps
Definition: qwt_abstract_slider.h:47
QwtAbstractScale
An abstract base class for widgets having a scale.
Definition: qwt_abstract_scale.h:36
QwtAbstractSlider::wrapping
bool wrapping
Definition: qwt_abstract_slider.h:52
QwtAbstractSlider::sliderMoved
void sliderMoved(double value)
QList< double >
QwtAbstractSlider::setPageSteps
void setPageSteps(uint)
Set the number of steps for a page increment.
Definition: qwt_abstract_slider.cpp:524
QwtAbstractSlider::PrivateData::wrapping
bool wrapping
Definition: qwt_abstract_slider.cpp:76
qwt_math.h
QwtAbstractScale::lowerBound
double lowerBound
Definition: qwt_abstract_scale.h:40
QwtAbstractSlider::singleSteps
uint singleSteps
Definition: qwt_abstract_slider.h:46
QwtAbstractSlider::PrivateData::isTracking
bool isTracking
Definition: qwt_abstract_slider.cpp:63
QwtAbstractScale::upperBound
double upperBound
Definition: qwt_abstract_scale.h:41
QwtAbstractSlider::PrivateData::isValid
bool isValid
Definition: qwt_abstract_slider.cpp:73
QwtAbstractSlider::setTracking
void setTracking(bool)
Enables or disables tracking.
Definition: qwt_abstract_slider.cpp:177
QwtAbstractSlider::mousePressEvent
virtual void mousePressEvent(QMouseEvent *) QWT_OVERRIDE
Definition: qwt_abstract_slider.cpp:195
QwtAbstractSlider::PrivateData::readOnly
bool readOnly
Definition: qwt_abstract_slider.cpp:66
QwtAbstractSlider::totalSteps
uint totalSteps
Definition: qwt_abstract_slider.h:45
QwtScaleDiv::ticks
QList< double > ticks(int tickType) const
Definition: qwt_scale_div.cpp:309
QwtScaleMap::p1
double p1() const
Definition: qwt_scale_map.h:99
QwtAbstractSlider::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *) QWT_OVERRIDE
Definition: qwt_abstract_slider.cpp:265
QwtAbstractSlider::incrementValue
void incrementValue(int stepCount)
Definition: qwt_abstract_slider.cpp:650
QwtScaleDiv::NTickTypes
@ NTickTypes
Number of valid tick types.
Definition: qwt_scale_div.h:52
QwtAbstractSlider::sliderReleased
void sliderReleased()
QwtAbstractSlider::isTracking
bool isTracking() const
Definition: qwt_abstract_slider.cpp:186
update
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
qwt_scale_map.h
QwtAbstractSlider::PrivateData::pendingValueChanged
bool pendingValueChanged
Definition: qwt_abstract_slider.cpp:64
range_format::map
@ map
QwtAbstractScale::transform
int transform(double) const
Definition: qwt_abstract_scale.cpp:369
QwtAbstractSlider::sliderPressed
void sliderPressed()
QwtAbstractScale::scaleDiv
const QwtScaleDiv & scaleDiv() const
Definition: qwt_abstract_scale.cpp:349
QwtScaleDiv::upperBound
double upperBound() const
Definition: qwt_scale_div.cpp:151
QwtAbstractScale::minimum
double minimum() const
Definition: qwt_abstract_scale.cpp:399
QwtAbstractSlider::setTotalSteps
void setTotalSteps(uint)
Set the number of steps.
Definition: qwt_abstract_slider.cpp:474
QwtAbstractSlider::scrolledTo
virtual double scrolledTo(const QPoint &pos) const =0
Determine the value for a new position of the movable part of the slider.
QwtAbstractSlider::setStepAlignment
void setStepAlignment(bool)
Enable step alignment.
Definition: qwt_abstract_slider.cpp:547
QwtAbstractSlider::PrivateData
Definition: qwt_abstract_slider.cpp:43
QwtAbstractSlider::isValid
bool isValid() const
Definition: qwt_abstract_slider.cpp:125
QwtAbstractSlider::stepAlignment
bool stepAlignment
Definition: qwt_abstract_slider.h:48
QwtAbstractSlider::value
double value
Returns the current value.
Definition: qwt_abstract_slider.h:43
QwtAbstractSlider::isScrollPosition
virtual bool isScrollPosition(const QPoint &pos) const =0
Determine what to do when the user presses a mouse button.
QwtAbstractSlider::PrivateData::isScrolling
bool isScrolling
Definition: qwt_abstract_slider.cpp:62
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtAbstractSlider::isReadOnly
bool isReadOnly() const
Definition: qwt_abstract_slider.cpp:159
QwtAbstractSlider::incrementedValue
double incrementedValue(double value, int stepCount) const
Definition: qwt_abstract_slider.cpp:670
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:26
QwtScaleMap::p2
double p2() const
Definition: qwt_scale_map.h:107
QwtAbstractSlider::m_data
PrivateData * m_data
Definition: qwt_abstract_slider.h:170
QwtAbstractScale::setScale
void setScale(double lowerBound, double upperBound)
Specify a scale.
Definition: qwt_abstract_scale.cpp:130
QwtAbstractSlider::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *) QWT_OVERRIDE
Definition: qwt_abstract_slider.cpp:220
QwtAbstractSlider::setSingleSteps
void setSingleSteps(uint)
Set the number of steps for a single increment.
Definition: qwt_abstract_slider.cpp:499
QwtScaleDiv
A class representing a scale division.
Definition: qwt_scale_div.h:33
QwtAbstractSlider::QwtAbstractSlider
QwtAbstractSlider(QWidget *parent=NULL)
Constructor.
Definition: qwt_abstract_slider.cpp:91
QwtAbstractScale::isInverted
bool isInverted() const
Definition: qwt_abstract_scale.cpp:390
QwtScaleMap::transformation
const QwtTransform * transformation() const
Get the transformation.
Definition: qwt_scale_map.cpp:88
QwtAbstractSlider
An abstract base class for slider widgets with a scale.
Definition: qwt_abstract_slider.h:32
QwtAbstractSlider::PrivateData::value
double value
Definition: qwt_abstract_slider.cpp:74
QwtAbstractSlider::boundedValue
double boundedValue(double) const
Definition: qwt_abstract_slider.cpp:712
QwtAbstractSlider::PrivateData::PrivateData
PrivateData()
Definition: qwt_abstract_slider.cpp:46
QwtAbstractSlider::PrivateData::invertedControls
bool invertedControls
Definition: qwt_abstract_slider.cpp:77


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:45