AxisWidget.cxx

Go to the documentation of this file.
00001 
00012 #include "AxisWidget.h"
00013 
00014 #if QT_VERSION < 0x040000
00015 #include <qabstractlayout.h>
00016 #else
00017 //Added by the Qt porting tool:
00018 #include <QtGui/QHBoxLayout>
00019 #include <QtGui/QVBoxLayout>
00020 #endif
00021 
00022 #include "axes/Range.h"
00023 
00024 #include <qpushbutton.h>
00025 #include <qpainter.h>
00026 #include <qevent.h>
00027 #include <qlabel.h>
00028 #include <qcheckbox.h>
00029 #include <qnamespace.h>
00030 #include <qscrollbar.h>
00031 #include <qlineedit.h>
00032 #include <qmessagebox.h>
00033 #include <qsizepolicy.h>
00034 
00035 #include <cassert>
00036 
00037 using std::string;
00038 
00039 using namespace hippodraw;
00040 
00043 AxisWidget::
00044 AxisWidget ( QWidget * parent, const char * name,  Qt::WFlags wflags )
00045   : QWidget ( parent, name, wflags )
00046 {
00047 
00048   // Init.
00049   
00050   lowTextLabel = new QLabel  ( "Low: ", this, "lowTextLabel" );
00051   highTextLabel = new QLabel ( "High:", this, "highTextLabel" );
00052   
00053   lowSlider = new QScrollBar ( Qt::Horizontal, this ); // Qt 4 way
00054   lowSlider -> setRange ( 0, 99 );
00055   lowSlider -> setPageStep ( 20 );
00056   lowSlider -> setValue ( 50 );
00057   QSizePolicy policy;
00058   policy.setHorData ( QSizePolicy::MinimumExpanding );
00059   lowSlider -> setSizePolicy ( policy );
00060 #if QT_VERSION < 0x040000
00061   lowSlider -> setLineStep ( 1 );
00062   lowSlider ->setFocusPolicy ( WheelFocus );
00063 #else
00064   lowSlider -> setSingleStep ( 1 );
00065   lowSlider ->setFocusPolicy ( Qt::WheelFocus );
00066 #endif
00067 
00068   highSlider = new QScrollBar ( Qt::Horizontal, this );
00069   highSlider -> setRange ( 0, 99 );
00070   highSlider -> setPageStep ( 20 );
00071   highSlider -> setValue ( 50 );
00072   highSlider -> setSizePolicy ( policy );
00073 #if QT_VERSION < 0x040000
00074   highSlider -> setLineStep ( 1 );
00075   highSlider ->setFocusPolicy ( WheelFocus );
00076 #else
00077   highSlider -> setSingleStep ( 1);
00078   highSlider ->setFocusPolicy ( Qt::WheelFocus );
00079 #endif
00080   lowTextBox = new QLineEdit ( this, "lowTextBox" );
00081   lowTextBox -> setMaximumHeight ( 26 );
00082   highTextBox = new QLineEdit ( this, "highTextBox" );
00083   highTextBox -> setMaximumHeight ( 26 );
00084   
00085   zoomPanCheckBox = new QCheckBox ( "Zoom/Pan", this, "zoomPanCheckBox" );
00086   
00087   m_isCut = false;
00088 
00089   // Layout.
00090 
00091   QVBoxLayout * grandParentLayout = new QVBoxLayout ( this, 2 );
00092   QHBoxLayout * parentLayout = new QHBoxLayout ( grandParentLayout, 5 );
00093 
00094   QVBoxLayout * labelLayout = new QVBoxLayout ( parentLayout, 5 );
00095   QVBoxLayout * textSliderLayout = new QVBoxLayout ( parentLayout, 5 );
00096 
00097   QHBoxLayout * lowLayout = new QHBoxLayout ( textSliderLayout, 5 );
00098   QHBoxLayout * highLayout = new QHBoxLayout ( textSliderLayout, 5 );
00099 
00100   labelLayout->addWidget ( lowTextLabel );
00101   labelLayout->addWidget ( highTextLabel );
00102 
00103   lowLayout->addWidget ( lowTextBox );
00104   lowLayout->addWidget ( lowSlider );
00105 
00106   highLayout->addWidget ( highTextBox );
00107   highLayout->addWidget ( highSlider );
00108   
00109   QHBoxLayout * checkboxlayout = new QHBoxLayout ( grandParentLayout, 5 );
00110   checkboxlayout->addWidget ( zoomPanCheckBox );
00111   checkboxlayout->setAlignment ( Qt::AlignHCenter );
00112 
00113   // Connect.
00114   
00115   connect ( lowTextBox, SIGNAL ( returnPressed() ),
00116             this, SIGNAL ( lowTextReturnPressed () ) );
00117   
00118   connect ( highTextBox, SIGNAL ( returnPressed () ),
00119             this, SIGNAL ( highTextReturnPressed () ) );
00120   
00121   connect ( lowSlider, SIGNAL ( sliderReleased () ),
00122             this, SIGNAL ( lowSliderReleased () ) );
00123   
00124   connect ( highSlider, SIGNAL ( sliderReleased () ),
00125             this, SIGNAL ( highSliderReleased () ) );
00126   
00127   connect ( lowSlider, SIGNAL ( valueChanged ( int ) ),
00128             this, SIGNAL ( lowSliderValueChanged ( int ) ) );
00129   
00130   connect ( highSlider, SIGNAL ( valueChanged ( int ) ),
00131             this, SIGNAL ( highSliderValueChanged ( int ) ) );
00132 
00133   connect ( lowSlider, SIGNAL ( sliderPressed () ),
00134             this, SIGNAL ( lowSliderPressed () ) );
00135   
00136   connect ( highSlider, SIGNAL ( sliderPressed () ),
00137             this, SIGNAL ( highSliderPressed () ) );
00138   
00139   connect ( zoomPanCheckBox, SIGNAL ( clicked () ),
00140             this, SIGNAL ( zoomPanCheckBoxClicked () ) );
00141 
00142 }
00143 
00144 AxisWidget::~AxisWidget ()
00145 {
00146   delete lowTextLabel;
00147   delete highTextLabel;
00148   delete lowSlider;
00149   delete highSlider;
00150   delete lowTextBox;
00151   delete highTextBox;
00152   delete zoomPanCheckBox;
00153 }
00154 
00155 void
00156 AxisWidget::
00157 processTextBoxReturnPressed ( Range & currentRange, 
00158                               const Range & fullRange )
00159 {
00160 
00161   if ( !zoomPanCheckBox->isChecked() ){
00162 
00163     QString text1 = highTextBox->text();
00164     double hi = text1.toDouble();
00165     QString text = lowTextBox->text();
00166     double lo = text.toDouble();
00167     
00168     if ( lo >= hi ) {
00169       invalidRangeError ( "Low not less than high" );
00170       highTextBox->setText ( QString("%1").arg(currentRange.high()) );
00171       lowTextBox->setText ( QString("%1").arg(currentRange.low()) );
00172       return;
00173     }
00174     
00175     currentRange.setRange ( lo, hi, currentRange.pos() );
00176     
00177     if ( !m_isCut ) return;
00178     
00179     // If cut, set the sliders.
00180     
00181     setSlider ( lowSlider,  currentRange.low(),  fullRange );
00182     setSlider ( highSlider, currentRange.high(), fullRange );
00183 
00184   }
00185   
00186   else {
00187 
00188     if ( m_isCut ) {
00189       
00190       double width = ( lowTextBox->text()).toDouble();    
00191       double oldWidth = getWidthFromSlider ( fullRange );
00192       double position = ( highTextBox->text()).toDouble();
00193       double oldPosition = getPositionFromSlider ( fullRange );
00194       
00195       if ( position - width / 2 < fullRange.low() || 
00196            position + width / 2 > fullRange.high() ) {
00197         
00198         lowTextBox->setText ( QString("%1").arg( oldWidth ) );
00199         highTextBox->setText ( QString("%1").arg( oldPosition ) );
00200         return;
00201         
00202       }
00203       
00204       // Set New Range.
00205       
00206       currentRange.setRange ( position - width / 2, 
00207                                position + width / 2, 
00208                                currentRange.pos() );
00209       
00210       // Update Sliders.
00211       
00212       setSliderZero ( lowSlider, width, fullRange );
00213       setSlider ( highSlider, position, fullRange );
00214 
00215     }
00216 
00217     else {
00218 
00219       double width = ( lowTextBox->text()).toDouble();    
00220       double position = ( highTextBox->text()).toDouble();
00221       
00222       // Set New Range.
00223       
00224       currentRange.setRange ( position - width / 2, 
00225                               position + width / 2, 
00226                               currentRange.pos() );
00227 
00228     }
00229 
00230   }
00231 
00232 }
00233 
00234 void AxisWidget::processLowSliderReleased ( const Range & fullRange )
00235 {
00236   if ( !zoomPanCheckBox->isChecked() ){
00237     assert ( m_isCut );    
00238     double low = (lowTextBox->text()).toDouble();    
00239     setSlider ( lowSlider, low, fullRange );
00240   }
00241   else {
00242     double width =  (lowTextBox->text()).toDouble();    
00243     setSliderZero ( lowSlider, width, fullRange );
00244   }
00245   
00246 }
00247 
00248 void AxisWidget::processHighSliderReleased ( const Range & fullRange )
00249 {
00250   double positionOrHigh = ( highTextBox->text() ).toDouble();
00251   setSlider ( highSlider, positionOrHigh, fullRange );
00252 }
00253 
00256 void
00257 AxisWidget::
00258 processLowSliderMoved ( int,
00259                         Range & currentRange,
00260                         const Range & fullRange )
00261 {
00262 
00263   if ( ! zoomPanCheckBox->isChecked() ) {
00264     
00265     assert ( m_isCut );
00266 
00267     double new_low = getLowFromSlider ( fullRange );
00268     
00269     if ( new_low < currentRange.high() ){
00270       currentRange.setLow ( new_low );
00271     }
00272     
00273     // Update other guys : low text.
00274     
00275     double low = currentRange.low();
00276     lowTextBox->setText ( QString("%1").arg(low));
00277     
00278   }
00279   
00280   else {
00281 
00282     if ( m_isCut ) {
00283       
00284       double width = getWidthFromSlider ( fullRange );
00285       double position = getPositionFromSlider ( fullRange );
00286       
00287       if ( position - width / 2 < fullRange.low() || 
00288            position + width / 2 > fullRange.high() ) {
00289         return;
00290         
00291       }
00292       
00293       // Set New Range.
00294       
00295       currentRange.setRange ( position - width / 2, 
00296                               position + width / 2, 
00297                               currentRange.pos() );  
00298       
00299       // Update TextBox.
00300       
00301       lowTextBox->setText ( QString("%1").arg( width ) );
00302       
00303     }
00304 
00305     else {
00306 
00307       double oldWidth = fullRange.length();
00308       double width =  oldWidth * lowSlider->value() / 50 ;
00309       double position = ( fullRange.high() + fullRange.low() ) / 2 ;
00310 
00311       // Set New Range.
00312       
00313       currentRange.setRange ( position - width / 2, 
00314                               position + width / 2, 
00315                               currentRange.pos() );  
00316       
00317       // Update TextBox.
00318       
00319       lowTextBox->setText ( QString("%1").arg( width ) );
00320       
00321 
00322     }
00323 
00324   }
00325 
00326 }
00327 
00330 void
00331 AxisWidget::
00332 processHighSliderMoved ( int,
00333                          Range & currentRange,
00334                          const Range & fullRange )
00335 {
00336   if ( ! zoomPanCheckBox->isChecked() ) {
00337  
00338     assert ( m_isCut );
00339 
00340     double new_high = getHighFromSlider ( fullRange );
00341       
00342     if ( new_high > currentRange.low() ) {
00343       currentRange.setHigh ( new_high );
00344     }
00345 
00346     // Update other guys : high text.
00347       
00348     double high = currentRange.high();
00349     highTextBox->setText ( QString("%1").arg(high));  
00350   } 
00351   else { // is in zoom/pan mode
00352 
00353     if ( m_isCut ) { //is in zoom/pan mode and is cut
00354 
00355       double width = currentRange.length ();
00356       double position = getPositionFromSlider ( fullRange );
00357       
00358       // Set New Range.
00359       
00360       currentRange.setRange ( position - 0.5 * width,
00361                               position + 0.5 * width,
00362                               currentRange.pos() );  
00363       
00364       // Update TextBoxes..
00365       
00366       highTextBox->setText ( QString("%1").arg( position ) );
00367       
00368     }
00369     else { // is in zoom/pan but not cut
00370 
00371       double width = fullRange.length();
00372       double oldPosition = ( fullRange.high() + fullRange.low() ) / 2 ;
00373       double position = ( width * 
00374                           ( ( double ) ( highSlider->value() - 50 ) ) / 50
00375                           ) + oldPosition;
00376 
00377       // Set New Range.
00378       
00379       currentRange.setRange ( position - width / 2, 
00380                               position + width / 2, 
00381                               currentRange.pos() );  
00382       
00383       // Update TextBox.
00384       
00385       highTextBox->setText ( QString("%1").arg( position ) );
00386     }
00387   }
00388 }
00389 
00390 void
00391 AxisWidget::
00392 processZoomPanCheckBoxClicked ( const Range & currentRange,
00393                                 const Range & fullRange )
00394 {
00395 
00396   bool checked = zoomPanCheckBox->isChecked();
00397   
00398   if ( m_isCut )
00399     if ( checked )
00400       {
00401         
00402         // Turn on the zoom / pan mode. Change high low labels, change the
00403         // texts, change the sliders.
00404         
00405         highTextLabel->setText ( "Position" );
00406         lowTextLabel->setText  ( "Width   " );
00407         
00408         double currentWidth = currentRange.high() - currentRange.low();
00409         double currentPosition 
00410           = 0.5 * ( currentRange.high() + currentRange.low() );
00411         
00412         highTextBox->setText ( QString("%1").arg(currentPosition) );
00413         lowTextBox->setText ( QString("%1").arg(currentWidth) );
00414         
00415         setSlider ( highSlider, currentPosition, fullRange );
00416         setSliderZero ( lowSlider, currentWidth, fullRange );
00417         
00418       }
00419     else
00420       {
00421         highTextLabel->setText ( "High    " );
00422         lowTextLabel->setText  ( "Low     " );
00423         
00424         highTextBox->setText ( QString("%1").arg(currentRange.high()) );
00425         lowTextBox->setText ( QString("%1").arg(currentRange.low()) );
00426         
00427         setSlider ( highSlider, currentRange.high(), fullRange );
00428         setSlider ( lowSlider, currentRange.low(), fullRange );
00429         
00430       }
00431   else // i.e. ! m_isCut
00432     if ( checked )
00433       {
00434         highTextLabel->setText ( "Position" );
00435         lowTextLabel->setText  ( "Width   " );
00436         
00437         double currentWidth = currentRange.high() - currentRange.low();
00438         double currentPosition 
00439           = 0.5 * ( currentRange.high() + currentRange.low() );
00440         
00441         highTextBox->setText ( QString("%1").arg(currentPosition) );
00442         lowTextBox->setText ( QString("%1").arg(currentWidth) );
00443       }
00444     else
00445       {
00446         highTextLabel->setText ( "High    " );
00447         lowTextLabel->setText  ( "Low     " );
00448       
00449         highTextBox->setText ( QString("%1").arg ( currentRange.high() ) );
00450         lowTextBox->setText ( QString("%1").arg ( currentRange.low() ) );
00451       }
00452 }
00453 
00454 void AxisWidget::setCut ( bool flag )
00455 {
00456   m_isCut = flag;
00457 }
00458 
00459 void 
00460 AxisWidget::
00461 invalidRangeError ( const std::string & bad )
00462 {
00463 
00464   const string message 
00465     = "Attempt to apply invalid range:\n\n"
00466     + bad + "\n\n"
00467     + "Low end of range must be less than high end.";
00468 
00469   QMessageBox::critical ( this, // parent
00470                           "Range error", // caption
00471                           message.c_str(),
00472                           QMessageBox::Ok,
00473                           Qt::NoButton,
00474                           Qt::NoButton );
00475 
00476 }
00477 
00478 void AxisWidget::setLowText ( const  QString & s, bool readonly )
00479 {
00480   lowTextBox->setText ( s );
00481   lowTextBox->setReadOnly ( readonly );
00482 }
00483 
00484 void AxisWidget::setHighText ( const QString & s, bool readonly )
00485 {
00486   highTextBox->setText ( s );
00487   highTextBox->setReadOnly ( readonly );
00488 }
00489 
00490 QScrollBar *
00491 AxisWidget::
00492 getLowSlider ()
00493 {
00494   return lowSlider;
00495 }
00496 
00497 int AxisWidget::getLowSliderValue ()
00498 {
00499   return lowSlider->value();
00500 }
00501   
00502 void AxisWidget::setLowSliderValue ( int value )
00503 {
00504   lowSlider->setValue ( value );
00505 }
00506 
00507 QScrollBar *
00508 AxisWidget::
00509 getHighSlider ()
00510 {
00511   return highSlider;
00512 }
00513 
00514 int AxisWidget::getHighSliderValue ()
00515 {
00516   return highSlider->value();
00517 }
00518   
00519 void AxisWidget::setHighSliderValue ( int value )
00520 {
00521   highSlider->setValue ( value );
00522 }
00523 
00524 void AxisWidget::setAllDisabled ( bool flag )
00525 {
00526   lowTextBox->setDisabled ( flag );
00527   highTextBox->setDisabled ( flag );
00528   lowSlider->setDisabled ( flag );
00529   highSlider->setDisabled ( flag );
00530   zoomPanCheckBox->setDisabled ( flag );
00531 }
00532 
00533 void
00534 AxisWidget::
00535 updateCutControlValues ( const Range & currentRange,
00536                          const Range & fullRange )
00537 {
00538 
00539   assert ( m_isCut );
00540 
00541   zoomPanCheckBox->setChecked ( false );
00542   highTextLabel->setText ( "High    " );
00543   lowTextLabel->setText  ( "Low     " );
00544 
00545   highTextBox->setText ( QString("%1").arg(currentRange.high()) );
00546   lowTextBox->setText ( QString("%1").arg(currentRange.low()) );
00547 
00548   setSlider ( highSlider, currentRange.high(), fullRange );
00549   setSlider ( lowSlider, currentRange.low(), fullRange );
00550 
00551 }
00552 
00553 bool AxisWidget::isZoomPanChecked ()
00554 {
00555   return zoomPanCheckBox->isChecked();
00556 }
00557 
00558 void AxisWidget::setZoomPan ( bool check, bool disabled )
00559 {
00560   zoomPanCheckBox->setChecked ( check );
00561   zoomPanCheckBox->setDisabled ( disabled );
00562 }
00563 
00564 double
00565 AxisWidget::
00566 getWidthFromSlider ( const Range & fullRange )
00567 {
00568 
00569   double width = ( ( (double)( lowSlider->value() -
00570                                lowSlider->minValue() ) ) / 
00571                    ( (double)( lowSlider->maxValue() - 
00572                                lowSlider->minValue() ) ) *
00573                    fullRange.length()
00574                    );
00575   return width;
00576 }
00577 
00578 double
00579 AxisWidget::
00580 getPositionFromSlider ( const Range & fullRange )
00581 {
00582 
00583   double position 
00584     = ( ( static_cast <double>( highSlider->value() -
00585                                 highSlider->minValue() ) ) / 
00586         ( static_cast <double>( highSlider->maxValue() - 
00587                                 highSlider->minValue() ) ) *
00588         fullRange.length()
00589         ) + fullRange.low();
00590   return position;
00591 }
00592 
00593 double
00594 AxisWidget::
00595 getLowFromSlider ( const Range & fullRange )
00596 {
00597 
00598   double low 
00599     = ( ( static_cast<double>( lowSlider->value() -
00600                                lowSlider->minValue() ) ) / 
00601         ( static_cast<double>( lowSlider->maxValue() - 
00602                                lowSlider->minValue() ) ) *
00603                  fullRange.length()
00604                  ) + fullRange.low();
00605 
00606   return low;
00607 }
00608 
00609 double
00610 AxisWidget::
00611 getHighFromSlider ( const Range & fullRange )
00612 {
00613 
00614   double high = ( ( static_cast <double>( highSlider->value() -
00615                                           highSlider->minValue() ) ) / 
00616                   ( static_cast<double>( highSlider->maxValue() - 
00617                                          highSlider->minValue() ) ) *
00618                   fullRange.length()
00619                   ) + fullRange.low();
00620   return high;
00621 }
00622 
00623 void
00624 AxisWidget::
00625 setSlider ( QScrollBar * s, double value, 
00626             const Range & fullRange )
00627 {
00628   int val 
00629     = static_cast < int >(
00630                           ( value - fullRange.low() ) / 
00631                           fullRange.length () *
00632                           static_cast<double> ( s->maxValue() - s->minValue() )
00633                           ) + s->minValue();
00634   
00635   s->setValue ( val );
00636 }  
00637 
00638 void
00639 AxisWidget::
00640 setSliderZero ( QScrollBar * s, double value, 
00641                 const Range & fullRange )
00642 {
00643   int val 
00644     = static_cast<int>(
00645                        ( value ) / fullRange.length () *
00646                        static_cast<double>( s->maxValue() - s->minValue() )
00647                        ) + s->minValue();
00648   
00649   s->setValue ( val );    
00650 }

Generated for HippoDraw Class Library by doxygen