Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AxisWidget.cxx

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

Generated for HippoDraw-1.14.8.5 by doxygen 1.4.3