qwt_counter.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_arrow_button.h"
11 #include "qwt_counter.h"
12 #include "qwt_painter.h"
13 #include "qwt_math.h"
14 
15 #include <qlayout.h>
16 #include <qlineedit.h>
17 #include <qvalidator.h>
18 #include <qevent.h>
19 #include <qstyle.h>
20 
22 {
23  public:
24  PrivateData()
25  : minimum( 0.0 )
26  , maximum( 0.0 )
27  , singleStep( 1.0 )
28  , isValid( false )
29  , value( 0.0 )
30  , wrapping( false )
31  {
32  increment[Button1] = 1;
33  increment[Button2] = 10;
34  increment[Button3] = 100;
35  }
36 
39  QLineEdit* valueEdit;
40 
41  int increment[ButtonCnt];
42  int numButtons;
43 
44  double minimum;
45  double maximum;
46  double singleStep;
47 
48  bool isValid;
49  double value;
50 
51  bool wrapping;
52 };
53 
65 QwtCounter::QwtCounter( QWidget* parent )
66  : QWidget( parent )
67 {
68  initCounter();
69 }
70 
72 {
73  m_data = new PrivateData;
74 
75  QHBoxLayout* layout = new QHBoxLayout( this );
76  layout->setSpacing( 0 );
77  layout->setContentsMargins( QMargins() );
78 
79  for ( int i = ButtonCnt - 1; i >= 0; i-- )
80  {
81  QwtArrowButton* btn =
82  new QwtArrowButton( i + 1, Qt::DownArrow, this );
83  btn->setFocusPolicy( Qt::NoFocus );
84  layout->addWidget( btn );
85 
86  connect( btn, SIGNAL(released()), SLOT(btnReleased()) );
87  connect( btn, SIGNAL(clicked()), SLOT(btnClicked()) );
88 
89  m_data->buttonDown[i] = btn;
90  }
91 
92  m_data->valueEdit = new QLineEdit( this );
93  m_data->valueEdit->setReadOnly( false );
94  m_data->valueEdit->setValidator( new QDoubleValidator( m_data->valueEdit ) );
95  layout->addWidget( m_data->valueEdit );
96 
97  connect( m_data->valueEdit, SIGNAL(editingFinished()), SLOT(textChanged()) );
98 
99  layout->setStretchFactor( m_data->valueEdit, 10 );
100 
101  for ( int i = 0; i < ButtonCnt; i++ )
102  {
103  QwtArrowButton* btn =
104  new QwtArrowButton( i + 1, Qt::UpArrow, this );
105  btn->setFocusPolicy( Qt::NoFocus );
106  layout->addWidget( btn );
107 
108  connect( btn, SIGNAL(released()), SLOT(btnReleased()) );
109  connect( btn, SIGNAL(clicked()), SLOT(btnClicked()) );
110 
111  m_data->buttonUp[i] = btn;
112  }
113 
114  setNumButtons( 2 );
115  setRange( 0.0, 1.0 );
116  setSingleStep( 0.001 );
117  setValue( 0.0 );
118 
119  setSizePolicy(
120  QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
121 
122  setFocusProxy( m_data->valueEdit );
123  setFocusPolicy( Qt::StrongFocus );
124 }
125 
128 {
129  delete m_data;
130 }
131 
142 void QwtCounter::setValid( bool on )
143 {
144  if ( on != m_data->isValid )
145  {
146  m_data->isValid = on;
147 
148  updateButtons();
149 
150  if ( m_data->isValid )
151  {
152  showNumber( value() );
153  Q_EMIT valueChanged( value() );
154  }
155  else
156  {
157  m_data->valueEdit->setText( QString() );
158  }
159  }
160 }
161 
167 {
168  return m_data->isValid;
169 }
170 
177 void QwtCounter::setReadOnly( bool on )
178 {
179  m_data->valueEdit->setReadOnly( on );
180 }
181 
187 {
188  return m_data->valueEdit->isReadOnly();
189 }
190 
202 void QwtCounter::setValue( double value )
203 {
204  const double vmin = qwtMinF( m_data->minimum, m_data->maximum );
205  const double vmax = qwtMaxF( m_data->minimum, m_data->maximum );
206 
207  value = qBound( vmin, value, vmax );
208 
209  if ( !m_data->isValid || value != m_data->value )
210  {
211  m_data->isValid = true;
212  m_data->value = value;
213 
214  showNumber( value );
215  updateButtons();
216 
217  Q_EMIT valueChanged( value );
218  }
219 }
220 
225 double QwtCounter::value() const
226 {
227  return m_data->value;
228 }
229 
241 void QwtCounter::setRange( double min, double max )
242 {
243  max = qwtMaxF( min, max );
244 
245  if ( m_data->maximum == max && m_data->minimum == min )
246  return;
247 
248  m_data->minimum = min;
249  m_data->maximum = max;
250 
252 
253  const double value = qBound( min, m_data->value, max );
254 
255  if ( value != m_data->value )
256  {
257  m_data->value = value;
258 
259  if ( m_data->isValid )
260  {
261  showNumber( value );
262  Q_EMIT valueChanged( value );
263  }
264  }
265 
266  updateButtons();
267 }
268 
277 void QwtCounter::setMinimum( double value )
278 {
279  setRange( value, maximum() );
280 }
281 
286 double QwtCounter::minimum() const
287 {
288  return m_data->minimum;
289 }
290 
297 void QwtCounter::setMaximum( double value )
298 {
299  setRange( minimum(), value );
300 }
301 
306 double QwtCounter::maximum() const
307 {
308  return m_data->maximum;
309 }
310 
319 void QwtCounter::setSingleStep( double stepSize )
320 {
321  m_data->singleStep = qwtMaxF( stepSize, 0.0 );
322 }
323 
328 double QwtCounter::singleStep() const
329 {
330  return m_data->singleStep;
331 }
332 
342 void QwtCounter::setWrapping( bool on )
343 {
344  m_data->wrapping = on;
345 }
346 
351 bool QwtCounter::wrapping() const
352 {
353  return m_data->wrapping;
354 }
355 
362 void QwtCounter::setNumButtons( int numButtons )
363 {
364  if ( numButtons < 0 || numButtons > QwtCounter::ButtonCnt )
365  return;
366 
367  for ( int i = 0; i < QwtCounter::ButtonCnt; i++ )
368  {
369  if ( i < numButtons )
370  {
371  m_data->buttonDown[i]->show();
372  m_data->buttonUp[i]->show();
373  }
374  else
375  {
376  m_data->buttonDown[i]->hide();
377  m_data->buttonUp[i]->hide();
378  }
379  }
380 
382 }
383 
388 int QwtCounter::numButtons() const
389 {
390  return m_data->numButtons;
391 }
392 
403 void QwtCounter::setIncSteps( QwtCounter::Button button, int numSteps )
404 {
405  if ( button >= 0 && button < QwtCounter::ButtonCnt )
406  m_data->increment[ button ] = numSteps;
407 }
408 
417 {
418  if ( button >= 0 && button < QwtCounter::ButtonCnt )
419  return m_data->increment[ button ];
420 
421  return 0;
422 }
423 
424 
429 void QwtCounter::setStepButton1( int nSteps )
430 {
431  setIncSteps( QwtCounter::Button1, nSteps );
432 }
433 
435 int QwtCounter::stepButton1() const
436 {
437  return incSteps( QwtCounter::Button1 );
438 }
439 
444 void QwtCounter::setStepButton2( int nSteps )
445 {
446  setIncSteps( QwtCounter::Button2, nSteps );
447 }
448 
450 int QwtCounter::stepButton2() const
451 {
452  return incSteps( QwtCounter::Button2 );
453 }
454 
459 void QwtCounter::setStepButton3( int nSteps )
460 {
461  setIncSteps( QwtCounter::Button3, nSteps );
462 }
463 
465 int QwtCounter::stepButton3() const
466 {
467  return incSteps( QwtCounter::Button3 );
468 }
469 
472 {
473  bool converted = false;
474 
475  const double value = m_data->valueEdit->text().toDouble( &converted );
476  if ( converted )
477  setValue( value );
478 }
479 
485 bool QwtCounter::event( QEvent* event )
486 {
487  if ( event->type() == QEvent::PolishRequest )
488  {
489  const QFontMetrics fm = m_data->valueEdit->fontMetrics();
490 
491  const int w = QwtPainter::horizontalAdvance( fm, "W" ) + 8;
492  for ( int i = 0; i < ButtonCnt; i++ )
493  {
494  m_data->buttonDown[i]->setMinimumWidth( w );
495  m_data->buttonUp[i]->setMinimumWidth( w );
496  }
497  }
498 
499  return QWidget::event( event );
500 }
501 
524 void QwtCounter::keyPressEvent ( QKeyEvent* event )
525 {
526  bool accepted = true;
527 
528  switch ( event->key() )
529  {
530  case Qt::Key_Home:
531  {
532  if ( event->modifiers() & Qt::ControlModifier )
533  setValue( minimum() );
534  else
535  accepted = false;
536  break;
537  }
538  case Qt::Key_End:
539  {
540  if ( event->modifiers() & Qt::ControlModifier )
541  setValue( maximum() );
542  else
543  accepted = false;
544  break;
545  }
546  case Qt::Key_Up:
547  {
549  break;
550  }
551  case Qt::Key_Down:
552  {
554  break;
555  }
556  case Qt::Key_PageUp:
557  case Qt::Key_PageDown:
558  {
559  int increment = m_data->increment[0];
560  if ( m_data->numButtons >= 2 )
561  increment = m_data->increment[1];
562  if ( m_data->numButtons >= 3 )
563  {
564  if ( event->modifiers() & Qt::ShiftModifier )
565  increment = m_data->increment[2];
566  }
567  if ( event->key() == Qt::Key_PageDown )
568  increment = -increment;
569  incrementValue( increment );
570  break;
571  }
572  default:
573  {
574  accepted = false;
575  }
576  }
577 
578  if ( accepted )
579  {
580  event->accept();
581  return;
582  }
583 
584  QWidget::keyPressEvent ( event );
585 }
586 
591 void QwtCounter::wheelEvent( QWheelEvent* event )
592 {
593  event->accept();
594 
595  if ( m_data->numButtons <= 0 )
596  return;
597 
598  int increment = m_data->increment[0];
599  if ( m_data->numButtons >= 2 )
600  {
601  if ( event->modifiers() & Qt::ControlModifier )
602  increment = m_data->increment[1];
603  }
604  if ( m_data->numButtons >= 3 )
605  {
606  if ( event->modifiers() & Qt::ShiftModifier )
607  increment = m_data->increment[2];
608  }
609 
610 #if QT_VERSION < 0x050e00
611  const QPoint wheelPos = event->pos();
612  const int wheelDelta = event->delta();
613 #else
614  const QPoint wheelPos = event->position().toPoint();
615 
616  const QPoint delta = event->angleDelta();
617  const int wheelDelta = ( qAbs( delta.x() ) > qAbs( delta.y() ) )
618  ? delta.x() : delta.y();
619 #endif
620 
621  for ( int i = 0; i < m_data->numButtons; i++ )
622  {
623  if ( m_data->buttonDown[i]->geometry().contains( wheelPos ) ||
624  m_data->buttonUp[i]->geometry().contains( wheelPos ) )
625  {
626  increment = m_data->increment[i];
627  }
628  }
629 
630  incrementValue( wheelDelta / 120 * increment );
631 }
632 
633 void QwtCounter::incrementValue( int numSteps )
634 {
635  const double min = m_data->minimum;
636  const double max = m_data->maximum;
637  double stepSize = m_data->singleStep;
638 
639  if ( !m_data->isValid || min >= max || stepSize <= 0.0 )
640  return;
641 
642 
643 #if 1
644  stepSize = qwtMaxF( stepSize, 1.0e-10 * ( max - min ) );
645 #endif
646 
647  double value = m_data->value + numSteps * stepSize;
648 
649  if ( m_data->wrapping )
650  {
651  const double range = max - min;
652 
653  if ( value < min )
654  {
655  value += std::ceil( ( min - value ) / range ) * range;
656  }
657  else if ( value > max )
658  {
659  value -= std::ceil( ( value - max ) / range ) * range;
660  }
661  }
662  else
663  {
664  value = qBound( min, value, max );
665  }
666 
667  value = min + qRound( ( value - min ) / stepSize ) * stepSize;
668 
669  if ( stepSize > 1e-12 )
670  {
671  if ( qFuzzyCompare( value + 1.0, 1.0 ) )
672  {
673  // correct rounding error if value = 0
674  value = 0.0;
675  }
676  else if ( qFuzzyCompare( value, max ) )
677  {
678  // correct rounding error at the border
679  value = max;
680  }
681  }
682 
683  if ( value != m_data->value )
684  {
685  m_data->value = value;
686  showNumber( m_data->value );
687  updateButtons();
688 
689  Q_EMIT valueChanged( m_data->value );
690  }
691 }
692 
693 
703 {
704  if ( m_data->isValid )
705  {
706  // 1. save enabled state of the smallest down- and up-button
707  // 2. change enabled state on under- or over-flow
708 
709  for ( int i = 0; i < QwtCounter::ButtonCnt; i++ )
710  {
711  m_data->buttonDown[i]->setEnabled( value() > minimum() );
712  m_data->buttonUp[i]->setEnabled( value() < maximum() );
713  }
714  }
715  else
716  {
717  for ( int i = 0; i < QwtCounter::ButtonCnt; i++ )
718  {
719  m_data->buttonDown[i]->setEnabled( false );
720  m_data->buttonUp[i]->setEnabled( false );
721  }
722  }
723 }
729 void QwtCounter::showNumber( double number )
730 {
731  QString text;
732  text.setNum( number );
733 
734  const int cursorPos = m_data->valueEdit->cursorPosition();
735  m_data->valueEdit->setText( text );
736  m_data->valueEdit->setCursorPosition( cursorPos );
737 }
738 
741 {
742  for ( int i = 0; i < ButtonCnt; i++ )
743  {
744  if ( m_data->buttonUp[i] == sender() )
746 
747  if ( m_data->buttonDown[i] == sender() )
749  }
750 }
751 
754 {
755  Q_EMIT buttonReleased( value() );
756 }
757 
759 QSize QwtCounter::sizeHint() const
760 {
761  QString tmp;
762 
763  int w = tmp.setNum( minimum() ).length();
764  int w1 = tmp.setNum( maximum() ).length();
765  if ( w1 > w )
766  w = w1;
767  w1 = tmp.setNum( minimum() + singleStep() ).length();
768  if ( w1 > w )
769  w = w1;
770  w1 = tmp.setNum( maximum() - singleStep() ).length();
771  if ( w1 > w )
772  w = w1;
773 
774  tmp.fill( '9', w );
775 
776  w = QwtPainter::horizontalAdvance( m_data->valueEdit->fontMetrics(), tmp ) + 2;
777 
778  if ( m_data->valueEdit->hasFrame() )
779  w += 2 * style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
780 
781  // Now we replace default sizeHint contribution of m_data->valueEdit by
782  // what we really need.
783 
784  w += QWidget::sizeHint().width() - m_data->valueEdit->sizeHint().width();
785 
786  const int h = qMin( QWidget::sizeHint().height(),
787  m_data->valueEdit->minimumSizeHint().height() );
788 
789  return QSize( w, h );
790 }
791 
792 #if QWT_MOC_INCLUDE
793 #include "moc_qwt_counter.cpp"
794 #endif
QwtCounter::Button1
@ Button1
Button intended for minor steps.
Definition: qwt_counter.h:77
QwtCounter::PrivateData::numButtons
int numButtons
Definition: qwt_counter.cpp:49
QwtCounter::ButtonCnt
@ ButtonCnt
Number of buttons.
Definition: qwt_counter.h:86
QwtCounter::wheelEvent
virtual void wheelEvent(QWheelEvent *) QWT_OVERRIDE
Definition: qwt_counter.cpp:591
QwtCounter::singleStep
double singleStep
Definition: qwt_counter.h:62
QwtCounter::event
virtual bool event(QEvent *) QWT_OVERRIDE
Definition: qwt_counter.cpp:485
QwtCounter::m_data
PrivateData * m_data
Definition: qwt_counter.h:164
QwtCounter::setValue
void setValue(double)
Set a new value without adjusting to the step raster.
Definition: qwt_counter.cpp:202
QwtCounter::initCounter
void initCounter()
Definition: qwt_counter.cpp:71
QwtPainter::horizontalAdvance
static int horizontalAdvance(const QFontMetrics &, const QString &)
Definition: qwt_painter.cpp:1379
QwtCounter::PrivateData::buttonDown
QwtArrowButton * buttonDown[ButtonCnt]
Definition: qwt_counter.cpp:44
QwtCounter::setNumButtons
void setNumButtons(int)
Definition: qwt_counter.cpp:362
QwtCounter::showNumber
void showNumber(double)
Definition: qwt_counter.cpp:729
QwtCounter::setSingleStep
void setSingleStep(double stepSize)
Set the step size of the counter.
Definition: qwt_counter.cpp:319
QwtCounter::setReadOnly
void setReadOnly(bool)
Allow/disallow the user to manually edit the value.
Definition: qwt_counter.cpp:177
QwtCounter::setMaximum
void setMaximum(double)
Definition: qwt_counter.cpp:297
qwt_math.h
QwtCounter::PrivateData::buttonUp
QwtArrowButton * buttonUp[ButtonCnt]
Definition: qwt_counter.cpp:45
qwt_arrow_button.h
QwtCounter::btnReleased
void btnReleased()
Button released.
Definition: qwt_counter.cpp:753
qwtMinF
QWT_CONSTEXPR float qwtMinF(float a, float b)
Definition: qwt_math.h:103
QwtCounter::QwtCounter
QwtCounter(QWidget *parent=NULL)
Definition: qwt_counter.cpp:65
QwtCounter::PrivateData::PrivateData
PrivateData()
Definition: qwt_counter.cpp:31
QwtCounter::Button2
@ Button2
Button intended for medium steps.
Definition: qwt_counter.h:80
QwtCounter::maximum
double maximum
Definition: qwt_counter.h:61
QwtCounter::Button3
@ Button3
Button intended for large steps.
Definition: qwt_counter.h:83
QwtCounter::PrivateData
Definition: qwt_counter.cpp:21
QwtCounter::PrivateData::isValid
bool isValid
Definition: qwt_counter.cpp:55
QwtCounter::PrivateData::increment
int increment[ButtonCnt]
Definition: qwt_counter.cpp:48
QwtCounter::isValid
bool isValid() const
Definition: qwt_counter.cpp:166
QwtCounter::isReadOnly
bool isReadOnly() const
Definition: qwt_counter.cpp:186
qwtMaxF
QWT_CONSTEXPR float qwtMaxF(float a, float b)
Definition: qwt_math.h:127
QwtCounter::~QwtCounter
virtual ~QwtCounter()
Destructor.
Definition: qwt_counter.cpp:127
QwtCounter::keyPressEvent
virtual void keyPressEvent(QKeyEvent *) QWT_OVERRIDE
Definition: qwt_counter.cpp:524
QwtCounter::setStepButton3
void setStepButton3(int nSteps)
Definition: qwt_counter.cpp:459
QwtCounter::setValid
void setValid(bool)
Definition: qwt_counter.cpp:142
QwtCounter::setStepButton1
void setStepButton1(int nSteps)
Definition: qwt_counter.cpp:429
QwtCounter::setMinimum
void setMinimum(double)
Definition: qwt_counter.cpp:277
QwtCounter::setWrapping
void setWrapping(bool)
En/Disable wrapping.
Definition: qwt_counter.cpp:342
QwtCounter::valueChanged
void valueChanged(double value)
qwt_counter.h
QwtCounter::PrivateData::singleStep
double singleStep
Definition: qwt_counter.cpp:53
QwtCounter::incrementValue
void incrementValue(int numSteps)
Definition: qwt_counter.cpp:633
QwtCounter::stepButton2
int stepButton2
returns the number of increment steps for button 2
Definition: qwt_counter.h:66
QwtCounter::textChanged
void textChanged()
Set from lineedit.
Definition: qwt_counter.cpp:471
QwtCounter::btnClicked
void btnClicked()
Button clicked.
Definition: qwt_counter.cpp:740
QwtCounter::PrivateData::maximum
double maximum
Definition: qwt_counter.cpp:52
qwt_painter.h
QwtCounter::stepButton1
int stepButton1
returns the number of increment steps for button 1
Definition: qwt_counter.h:65
QwtCounter::minimum
double minimum
Definition: qwt_counter.h:60
QwtCounter::PrivateData::value
double value
Definition: qwt_counter.cpp:56
QwtCounter::setStepButton2
void setStepButton2(int nSteps)
Definition: qwt_counter.cpp:444
QwtCounter::buttonReleased
void buttonReleased(double value)
QwtCounter::wrapping
bool wrapping
Definition: qwt_counter.h:70
QwtCounter::incSteps
int incSteps(QwtCounter::Button) const
Definition: qwt_counter.cpp:416
QwtCounter::PrivateData::valueEdit
QLineEdit * valueEdit
Definition: qwt_counter.cpp:46
QwtCounter::stepButton3
int stepButton3
returns the number of increment steps for button 3
Definition: qwt_counter.h:67
QwtCounter::setRange
void setRange(double min, double max)
Set the minimum and maximum values.
Definition: qwt_counter.cpp:241
QwtArrowButton
Arrow Button.
Definition: qwt_arrow_button.h:23
QwtCounter::PrivateData::minimum
double minimum
Definition: qwt_counter.cpp:51
QwtCounter::sizeHint
virtual QSize sizeHint() const QWT_OVERRIDE
A size hint.
Definition: qwt_counter.cpp:759
QwtCounter::value
double value
Definition: qwt_counter.h:59
QwtCounter::updateButtons
void updateButtons()
Update buttons according to the current value.
Definition: qwt_counter.cpp:702
QwtCounter::numButtons
int numButtons
Definition: qwt_counter.h:64
QwtCounter::Button
Button
Button index.
Definition: qwt_counter.h:74
QwtCounter::setIncSteps
void setIncSteps(QwtCounter::Button, int numSteps)
Definition: qwt_counter.cpp:403
QwtCounter::PrivateData::wrapping
bool wrapping
Definition: qwt_counter.cpp:58


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