qwt_double_range.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_double_range.h"
00011 #include "qwt_math.h"
00012 
00013 static double MinRelStep = 1.0e-10;
00014 static double DefaultRelStep = 1.0e-2;
00015 static double MinEps = 1.0e-10;
00016 
00021 QwtDoubleRange::QwtDoubleRange():
00022     d_minValue(0.0),
00023     d_maxValue(0.0),
00024     d_step(1.0),
00025     d_pageSize(1),
00026     d_isValid(false),
00027     d_value(0.0),
00028     d_exactValue(0.0),
00029     d_exactPrevValue(0.0),
00030     d_prevValue(0.0),
00031     d_periodic(false)
00032 {
00033 }
00034 
00036 QwtDoubleRange::~QwtDoubleRange()
00037 {
00038 }
00039 
00041 void QwtDoubleRange::setValid(bool isValid)
00042 {
00043     if ( isValid != d_isValid )
00044     {
00045         d_isValid = isValid;
00046         valueChange();
00047     }
00048 }
00049 
00051 bool QwtDoubleRange::isValid() const
00052 {
00053     return d_isValid;
00054 }
00055 
00064 void QwtDoubleRange::setNewValue(double x, bool align)
00065 {
00066     double vmin,vmax;
00067     
00068     d_prevValue = d_value;
00069 
00070     vmin = qwtMin(d_minValue, d_maxValue);
00071     vmax = qwtMax(d_minValue, d_maxValue);
00072 
00073     // 
00074     // Range check
00075     //
00076     if (x < vmin)
00077     {
00078         if ((d_periodic) && (vmin != vmax))
00079            d_value = x + ceil( (vmin - x) / (vmax - vmin ) ) 
00080               * (vmax - vmin);
00081         else
00082            d_value = vmin;
00083     }
00084     else if (x > vmax)
00085     {
00086         if ((d_periodic) && (vmin != vmax))
00087            d_value = x - ceil( ( x - vmax) / (vmax - vmin )) 
00088               * (vmax - vmin);
00089         else
00090            d_value = vmax;
00091     }
00092     else
00093        d_value = x;
00094 
00095     d_exactPrevValue = d_exactValue;
00096     d_exactValue = d_value;
00097     
00098     // align to grid
00099     if (align)
00100     {
00101         if (d_step != 0.0)
00102            d_value = d_minValue +
00103              qRound((d_value - d_minValue) / d_step) * d_step;
00104         else
00105            d_value = d_minValue;
00106         
00107         // correct rounding error at the border
00108         if (fabs(d_value - d_maxValue) < MinEps * qwtAbs(d_step))
00109            d_value = d_maxValue;
00110 
00111         // correct rounding error if value = 0
00112         if (fabs(d_value) < MinEps * qwtAbs(d_step))
00113            d_value = 0.0;
00114     }
00115 
00116     if (!d_isValid || d_prevValue != d_value)
00117     {
00118         d_isValid = true;
00119         valueChange();
00120     }
00121 }
00122 
00132 void QwtDoubleRange::fitValue(double x)
00133 {
00134     setNewValue(x, true);
00135 }
00136 
00137 
00147 void QwtDoubleRange::setValue(double x)
00148 {
00149     setNewValue(x, false);
00150 }
00151 
00169 void QwtDoubleRange::setRange(double vmin, double vmax, double vstep, int pageSize)
00170 {
00171     bool rchg = ((d_maxValue != vmax) || (d_minValue != vmin));
00172     
00173     if (rchg) 
00174     {
00175         d_minValue = vmin;
00176         d_maxValue = vmax;
00177     }
00178     
00179     //
00180     // look if the step width has an acceptable 
00181     // value or otherwise change it.
00182     //
00183     setStep(vstep);
00184 
00185     //
00186     // limit page size
00187     //
00188     d_pageSize = qwtLim(pageSize,0, 
00189         int(qwtAbs((d_maxValue - d_minValue) / d_step))); 
00190     
00191     // 
00192     // If the value lies out of the range, it 
00193     // will be changed. Note that it will not be adjusted to 
00194     // the new step width.
00195     setNewValue(d_value, false);
00196     
00197     // call notifier after the step width has been 
00198     // adjusted.
00199     if (rchg)
00200        rangeChange();
00201 }
00202 
00208 void QwtDoubleRange::setStep(double vstep)
00209 {
00210     double intv = d_maxValue - d_minValue;
00211     
00212     double newStep;
00213     if (vstep == 0.0)
00214        newStep = intv * DefaultRelStep;
00215     else
00216     {
00217         if ((intv > 0) && (vstep < 0) || (intv < 0) && (vstep > 0))
00218            newStep = -vstep;
00219         else
00220            newStep = vstep;
00221         
00222         if ( fabs(newStep) < fabs(MinRelStep * intv) )
00223            newStep = MinRelStep * intv;
00224     }
00225     
00226     if (newStep != d_step)
00227     {
00228         d_step = newStep;
00229         stepChange();
00230     }
00231 }
00232 
00233 
00248 void QwtDoubleRange::setPeriodic(bool tf)
00249 {
00250     d_periodic = tf;
00251 }
00252 
00259 void QwtDoubleRange::incValue(int nSteps)
00260 {
00261     if ( isValid() )
00262         setNewValue(d_value + double(nSteps) * d_step, true);
00263 }
00264 
00271 void QwtDoubleRange::incPages(int nPages)
00272 {
00273     if ( isValid() )
00274         setNewValue(d_value + double(nPages) * double(d_pageSize) * d_step, true);
00275 }
00276 
00283 void QwtDoubleRange::valueChange()
00284 {
00285 }
00286 
00287 
00294 void QwtDoubleRange::rangeChange()
00295 {
00296 }
00297 
00298 
00305 void QwtDoubleRange::stepChange()
00306 {
00307 }
00308 
00313 double QwtDoubleRange::step() const
00314 {
00315     return qwtAbs(d_step);
00316 }
00317 
00326 double QwtDoubleRange::maxValue() const
00327 {   
00328     return d_maxValue;
00329 } 
00330     
00339 double QwtDoubleRange::minValue() const 
00340 {
00341     return d_minValue; 
00342 }   
00343 
00348 bool QwtDoubleRange::periodic() const 
00349 { 
00350     return d_periodic; 
00351 }
00352 
00354 int QwtDoubleRange::pageSize() const 
00355 { 
00356     return d_pageSize; 
00357 }
00358 
00360 double QwtDoubleRange::value() const 
00361 { 
00362     return d_value; 
00363 }
00364 
00374 double QwtDoubleRange::exactValue() const 
00375 { 
00376     return d_exactValue; 
00377 }
00378 
00380 double QwtDoubleRange::exactPrevValue() const 
00381 { 
00382     return d_exactPrevValue; 
00383 }
00384 
00386 double QwtDoubleRange::prevValue() const 
00387 { 
00388     return d_prevValue; 
00389 }

Generated on Mon Feb 26 21:22:36 2007 for Qwt User's Guide by  doxygen 1.4.6