AxisWidget.cxx
Go to the documentation of this file.
1 
12 #include "AxisWidget.h"
13 
14 #if QT_VERSION < 0x040000
15 #include <qabstractlayout.h>
16 #else
17 //Added by the Qt porting tool:
18 #include <QtGui/QHBoxLayout>
19 #include <QtGui/QVBoxLayout>
20 #endif
21 
22 #include "axes/Range.h"
23 
24 #include <qpushbutton.h>
25 #include <qpainter.h>
26 #include <qevent.h>
27 #include <qlabel.h>
28 #include <qcheckbox.h>
29 #include <qnamespace.h>
30 #include <qscrollbar.h>
31 #include <qlineedit.h>
32 #include <qmessagebox.h>
33 #include <qsizepolicy.h>
34 
35 #include <cassert>
36 
37 using std::string;
38 
39 using namespace hippodraw;
40 
44 AxisWidget ( QWidget * parent, const char * name, Qt::WFlags wflags )
45  : QWidget ( parent, name, wflags )
46 {
47 
48  // Init.
49 
50  lowTextLabel = new QLabel ( "Low: ", this, "lowTextLabel" );
51  highTextLabel = new QLabel ( "High:", this, "highTextLabel" );
52 
53  lowSlider = new QScrollBar ( Qt::Horizontal, this ); // Qt 4 way
54  lowSlider -> setRange ( 0, 99 );
55  lowSlider -> setPageStep ( 20 );
56  lowSlider -> setValue ( 50 );
57  QSizePolicy policy;
58  policy.setHorData ( QSizePolicy::MinimumExpanding );
59  lowSlider -> setSizePolicy ( policy );
60 #if QT_VERSION < 0x040000
61  lowSlider -> setLineStep ( 1 );
62  lowSlider ->setFocusPolicy ( WheelFocus );
63 #else
64  lowSlider -> setSingleStep ( 1 );
65  lowSlider ->setFocusPolicy ( Qt::WheelFocus );
66 #endif
67 
68  highSlider = new QScrollBar ( Qt::Horizontal, this );
69  highSlider -> setRange ( 0, 99 );
70  highSlider -> setPageStep ( 20 );
71  highSlider -> setValue ( 50 );
72  highSlider -> setSizePolicy ( policy );
73 #if QT_VERSION < 0x040000
74  highSlider -> setLineStep ( 1 );
75  highSlider ->setFocusPolicy ( WheelFocus );
76 #else
77  highSlider -> setSingleStep ( 1);
78  highSlider ->setFocusPolicy ( Qt::WheelFocus );
79 #endif
80  lowTextBox = new QLineEdit ( this, "lowTextBox" );
81  lowTextBox -> setMaximumHeight ( 26 );
82  highTextBox = new QLineEdit ( this, "highTextBox" );
83  highTextBox -> setMaximumHeight ( 26 );
84 
85  zoomPanCheckBox = new QCheckBox ( "Zoom/Pan", this, "zoomPanCheckBox" );
86 
87  m_isCut = false;
88 
89  // Layout.
90 
91  QVBoxLayout * grandParentLayout = new QVBoxLayout ( this, 2 );
92  QHBoxLayout * parentLayout = new QHBoxLayout ( grandParentLayout, 5 );
93 
94  QVBoxLayout * labelLayout = new QVBoxLayout ( parentLayout, 5 );
95  QVBoxLayout * textSliderLayout = new QVBoxLayout ( parentLayout, 5 );
96 
97  QHBoxLayout * lowLayout = new QHBoxLayout ( textSliderLayout, 5 );
98  QHBoxLayout * highLayout = new QHBoxLayout ( textSliderLayout, 5 );
99 
100  labelLayout->addWidget ( lowTextLabel );
101  labelLayout->addWidget ( highTextLabel );
102 
103  lowLayout->addWidget ( lowTextBox );
104  lowLayout->addWidget ( lowSlider );
105 
106  highLayout->addWidget ( highTextBox );
107  highLayout->addWidget ( highSlider );
108 
109  QHBoxLayout * checkboxlayout = new QHBoxLayout ( grandParentLayout, 5 );
110  checkboxlayout->addWidget ( zoomPanCheckBox );
111  checkboxlayout->setAlignment ( Qt::AlignHCenter );
112 
113  // Connect.
114 
115  connect ( lowTextBox, SIGNAL ( returnPressed() ),
116  this, SIGNAL ( lowTextReturnPressed () ) );
117 
118  connect ( highTextBox, SIGNAL ( returnPressed () ),
119  this, SIGNAL ( highTextReturnPressed () ) );
120 
121  connect ( lowSlider, SIGNAL ( sliderReleased () ),
122  this, SIGNAL ( lowSliderReleased () ) );
123 
124  connect ( highSlider, SIGNAL ( sliderReleased () ),
125  this, SIGNAL ( highSliderReleased () ) );
126 
127  connect ( lowSlider, SIGNAL ( valueChanged ( int ) ),
128  this, SIGNAL ( lowSliderValueChanged ( int ) ) );
129 
130  connect ( highSlider, SIGNAL ( valueChanged ( int ) ),
131  this, SIGNAL ( highSliderValueChanged ( int ) ) );
132 
133  connect ( lowSlider, SIGNAL ( sliderPressed () ),
134  this, SIGNAL ( lowSliderPressed () ) );
135 
136  connect ( highSlider, SIGNAL ( sliderPressed () ),
137  this, SIGNAL ( highSliderPressed () ) );
138 
139  connect ( zoomPanCheckBox, SIGNAL ( clicked () ),
140  this, SIGNAL ( zoomPanCheckBoxClicked () ) );
141 
142 }
143 
145 {
146  delete lowTextLabel;
147  delete highTextLabel;
148  delete lowSlider;
149  delete highSlider;
150  delete lowTextBox;
151  delete highTextBox;
152  delete zoomPanCheckBox;
153 }
154 
155 void
158  const Range & fullRange )
159 {
160 
161  if ( !zoomPanCheckBox->isChecked() ){
162 
163  QString text1 = highTextBox->text();
164  double hi = text1.toDouble();
165  QString text = lowTextBox->text();
166  double lo = text.toDouble();
167 
168  if ( lo >= hi ) {
169  invalidRangeError ( "Low not less than high" );
170  highTextBox->setText ( QString("%1").arg(currentRange.high()) );
171  lowTextBox->setText ( QString("%1").arg(currentRange.low()) );
172  return;
173  }
174 
175  currentRange.setRange ( lo, hi, currentRange.pos() );
176 
177  if ( !m_isCut ) return;
178 
179  // If cut, set the sliders.
180 
181  setSlider ( lowSlider, currentRange.low(), fullRange );
182  setSlider ( highSlider, currentRange.high(), fullRange );
183 
184  }
185 
186  else {
187 
188  if ( m_isCut ) {
189 
190  double width = ( lowTextBox->text()).toDouble();
191  double oldWidth = getWidthFromSlider ( fullRange );
192  double position = ( highTextBox->text()).toDouble();
193  double oldPosition = getPositionFromSlider ( fullRange );
194 
195  if ( position - width / 2 < fullRange.low() ||
196  position + width / 2 > fullRange.high() ) {
197 
198  lowTextBox->setText ( QString("%1").arg( oldWidth ) );
199  highTextBox->setText ( QString("%1").arg( oldPosition ) );
200  return;
201 
202  }
203 
204  // Set New Range.
205 
206  currentRange.setRange ( position - width / 2,
207  position + width / 2,
208  currentRange.pos() );
209 
210  // Update Sliders.
211 
212  setSliderZero ( lowSlider, width, fullRange );
213  setSlider ( highSlider, position, fullRange );
214 
215  }
216 
217  else {
218 
219  double width = ( lowTextBox->text()).toDouble();
220  double position = ( highTextBox->text()).toDouble();
221 
222  // Set New Range.
223 
224  currentRange.setRange ( position - width / 2,
225  position + width / 2,
226  currentRange.pos() );
227 
228  }
229 
230  }
231 
232 }
233 
234 void AxisWidget::processLowSliderReleased ( const Range & fullRange )
235 {
236  if ( !zoomPanCheckBox->isChecked() ){
237  assert ( m_isCut );
238  double low = (lowTextBox->text()).toDouble();
239  setSlider ( lowSlider, low, fullRange );
240  }
241  else {
242  double width = (lowTextBox->text()).toDouble();
243  setSliderZero ( lowSlider, width, fullRange );
244  }
245 
246 }
247 
249 {
250  double positionOrHigh = ( highTextBox->text() ).toDouble();
251  setSlider ( highSlider, positionOrHigh, fullRange );
252 }
253 
256 void
259  Range & currentRange,
260  const Range & fullRange )
261 {
262 
263  if ( ! zoomPanCheckBox->isChecked() ) {
264 
265  assert ( m_isCut );
266 
267  double new_low = getLowFromSlider ( fullRange );
268 
269  if ( new_low < currentRange.high() ){
270  currentRange.setLow ( new_low );
271  }
272 
273  // Update other guys : low text.
274 
275  double low = currentRange.low();
276  lowTextBox->setText ( QString("%1").arg(low));
277 
278  }
279 
280  else {
281 
282  if ( m_isCut ) {
283 
284  double width = getWidthFromSlider ( fullRange );
285  double position = getPositionFromSlider ( fullRange );
286 
287  if ( position - width / 2 < fullRange.low() ||
288  position + width / 2 > fullRange.high() ) {
289  return;
290 
291  }
292 
293  // Set New Range.
294 
295  currentRange.setRange ( position - width / 2,
296  position + width / 2,
297  currentRange.pos() );
298 
299  // Update TextBox.
300 
301  lowTextBox->setText ( QString("%1").arg( width ) );
302 
303  }
304 
305  else {
306 
307  double oldWidth = fullRange.length();
308  double width = oldWidth * lowSlider->value() / 50 ;
309  double position = ( fullRange.high() + fullRange.low() ) / 2 ;
310 
311  // Set New Range.
312 
313  currentRange.setRange ( position - width / 2,
314  position + width / 2,
315  currentRange.pos() );
316 
317  // Update TextBox.
318 
319  lowTextBox->setText ( QString("%1").arg( width ) );
320 
321 
322  }
323 
324  }
325 
326 }
327 
330 void
333  Range & currentRange,
334  const Range & fullRange )
335 {
336  if ( ! zoomPanCheckBox->isChecked() ) {
337 
338  assert ( m_isCut );
339 
340  double new_high = getHighFromSlider ( fullRange );
341 
342  if ( new_high > currentRange.low() ) {
343  currentRange.setHigh ( new_high );
344  }
345 
346  // Update other guys : high text.
347 
348  double high = currentRange.high();
349  highTextBox->setText ( QString("%1").arg(high));
350  }
351  else { // is in zoom/pan mode
352 
353  if ( m_isCut ) { //is in zoom/pan mode and is cut
354 
355  double width = currentRange.length ();
356  double position = getPositionFromSlider ( fullRange );
357 
358  // Set New Range.
359 
360  currentRange.setRange ( position - 0.5 * width,
361  position + 0.5 * width,
362  currentRange.pos() );
363 
364  // Update TextBoxes..
365 
366  highTextBox->setText ( QString("%1").arg( position ) );
367 
368  }
369  else { // is in zoom/pan but not cut
370 
371  double width = fullRange.length();
372  double oldPosition = ( fullRange.high() + fullRange.low() ) / 2 ;
373  double position = ( width *
374  ( ( double ) ( highSlider->value() - 50 ) ) / 50
375  ) + oldPosition;
376 
377  // Set New Range.
378 
379  currentRange.setRange ( position - width / 2,
380  position + width / 2,
381  currentRange.pos() );
382 
383  // Update TextBox.
384 
385  highTextBox->setText ( QString("%1").arg( position ) );
386  }
387  }
388 }
389 
390 void
392 processZoomPanCheckBoxClicked ( const Range & currentRange,
393  const Range & fullRange )
394 {
395 
396  bool checked = zoomPanCheckBox->isChecked();
397 
398  if ( m_isCut )
399  if ( checked )
400  {
401 
402  // Turn on the zoom / pan mode. Change high low labels, change the
403  // texts, change the sliders.
404 
405  highTextLabel->setText ( "Position" );
406  lowTextLabel->setText ( "Width " );
407 
408  double currentWidth = currentRange.high() - currentRange.low();
409  double currentPosition
410  = 0.5 * ( currentRange.high() + currentRange.low() );
411 
412  highTextBox->setText ( QString("%1").arg(currentPosition) );
413  lowTextBox->setText ( QString("%1").arg(currentWidth) );
414 
415  setSlider ( highSlider, currentPosition, fullRange );
416  setSliderZero ( lowSlider, currentWidth, fullRange );
417 
418  }
419  else
420  {
421  highTextLabel->setText ( "High " );
422  lowTextLabel->setText ( "Low " );
423 
424  highTextBox->setText ( QString("%1").arg(currentRange.high()) );
425  lowTextBox->setText ( QString("%1").arg(currentRange.low()) );
426 
427  setSlider ( highSlider, currentRange.high(), fullRange );
428  setSlider ( lowSlider, currentRange.low(), fullRange );
429 
430  }
431  else // i.e. ! m_isCut
432  if ( checked )
433  {
434  highTextLabel->setText ( "Position" );
435  lowTextLabel->setText ( "Width " );
436 
437  double currentWidth = currentRange.high() - currentRange.low();
438  double currentPosition
439  = 0.5 * ( currentRange.high() + currentRange.low() );
440 
441  highTextBox->setText ( QString("%1").arg(currentPosition) );
442  lowTextBox->setText ( QString("%1").arg(currentWidth) );
443  }
444  else
445  {
446  highTextLabel->setText ( "High " );
447  lowTextLabel->setText ( "Low " );
448 
449  highTextBox->setText ( QString("%1").arg ( currentRange.high() ) );
450  lowTextBox->setText ( QString("%1").arg ( currentRange.low() ) );
451  }
452 }
453 
454 void AxisWidget::setCut ( bool flag )
455 {
456  m_isCut = flag;
457 }
458 
459 void
461 invalidRangeError ( const std::string & bad )
462 {
463 
464  const string message
465  = "Attempt to apply invalid range:\n\n"
466  + bad + "\n\n"
467  + "Low end of range must be less than high end.";
468 
469  QMessageBox::critical ( this, // parent
470  "Range error", // caption
471  message.c_str(),
472  QMessageBox::Ok,
473  Qt::NoButton,
474  Qt::NoButton );
475 
476 }
477 
478 void AxisWidget::setLowText ( const QString & s, bool readonly )
479 {
480  lowTextBox->setText ( s );
481  lowTextBox->setReadOnly ( readonly );
482 }
483 
484 void AxisWidget::setHighText ( const QString & s, bool readonly )
485 {
486  highTextBox->setText ( s );
487  highTextBox->setReadOnly ( readonly );
488 }
489 
490 QScrollBar *
493 {
494  return lowSlider;
495 }
496 
498 {
499  return lowSlider->value();
500 }
501 
503 {
504  lowSlider->setValue ( value );
505 }
506 
507 QScrollBar *
510 {
511  return highSlider;
512 }
513 
515 {
516  return highSlider->value();
517 }
518 
520 {
521  highSlider->setValue ( value );
522 }
523 
524 void AxisWidget::setAllDisabled ( bool flag )
525 {
526  lowTextBox->setDisabled ( flag );
527  highTextBox->setDisabled ( flag );
528  lowSlider->setDisabled ( flag );
529  highSlider->setDisabled ( flag );
530  zoomPanCheckBox->setDisabled ( flag );
531 }
532 
533 void
535 updateCutControlValues ( const Range & currentRange,
536  const Range & fullRange )
537 {
538 
539  assert ( m_isCut );
540 
541  zoomPanCheckBox->setChecked ( false );
542  highTextLabel->setText ( "High " );
543  lowTextLabel->setText ( "Low " );
544 
545  highTextBox->setText ( QString("%1").arg(currentRange.high()) );
546  lowTextBox->setText ( QString("%1").arg(currentRange.low()) );
547 
548  setSlider ( highSlider, currentRange.high(), fullRange );
549  setSlider ( lowSlider, currentRange.low(), fullRange );
550 
551 }
552 
554 {
555  return zoomPanCheckBox->isChecked();
556 }
557 
558 void AxisWidget::setZoomPan ( bool check, bool disabled )
559 {
560  zoomPanCheckBox->setChecked ( check );
561  zoomPanCheckBox->setDisabled ( disabled );
562 }
563 
564 double
566 getWidthFromSlider ( const Range & fullRange )
567 {
568 
569  double width = ( ( (double)( lowSlider->value() -
570  lowSlider->minValue() ) ) /
571  ( (double)( lowSlider->maxValue() -
572  lowSlider->minValue() ) ) *
573  fullRange.length()
574  );
575  return width;
576 }
577 
578 double
580 getPositionFromSlider ( const Range & fullRange )
581 {
582 
583  double position
584  = ( ( static_cast <double>( highSlider->value() -
585  highSlider->minValue() ) ) /
586  ( static_cast <double>( highSlider->maxValue() -
587  highSlider->minValue() ) ) *
588  fullRange.length()
589  ) + fullRange.low();
590  return position;
591 }
592 
593 double
595 getLowFromSlider ( const Range & fullRange )
596 {
597 
598  double low
599  = ( ( static_cast<double>( lowSlider->value() -
600  lowSlider->minValue() ) ) /
601  ( static_cast<double>( lowSlider->maxValue() -
602  lowSlider->minValue() ) ) *
603  fullRange.length()
604  ) + fullRange.low();
605 
606  return low;
607 }
608 
609 double
611 getHighFromSlider ( const Range & fullRange )
612 {
613 
614  double high = ( ( static_cast <double>( highSlider->value() -
615  highSlider->minValue() ) ) /
616  ( static_cast<double>( highSlider->maxValue() -
617  highSlider->minValue() ) ) *
618  fullRange.length()
619  ) + fullRange.low();
620  return high;
621 }
622 
623 void
625 setSlider ( QScrollBar * s, double value,
626  const Range & fullRange )
627 {
628  int val
629  = static_cast < int >(
630  ( value - fullRange.low() ) /
631  fullRange.length () *
632  static_cast<double> ( s->maxValue() - s->minValue() )
633  ) + s->minValue();
634 
635  s->setValue ( val );
636 }
637 
638 void
640 setSliderZero ( QScrollBar * s, double value,
641  const Range & fullRange )
642 {
643  int val
644  = static_cast<int>(
645  ( value ) / fullRange.length () *
646  static_cast<double>( s->maxValue() - s->minValue() )
647  ) + s->minValue();
648 
649  s->setValue ( val );
650 }

Generated for HippoDraw Class Library by doxygen