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 <cfloat>
00011 #include "qwt_double_range.h"
00012 #include "qwt_math.h"
00013 
00014 static double MinRelStep = 1.0e-10;
00015 static double DefaultRelStep = 1.0e-2;
00016 static double MinEps = 1.0e-10;
00017 
00022 QwtDoubleRange::QwtDoubleRange():
00023     d_minValue(0.0),
00024     d_maxValue(0.0),
00025     d_step(1.0),
00026     d_pageSize(1),
00027     d_isValid(false),
00028     d_value(0.0),
00029     d_exactValue(0.0),
00030     d_exactPrevValue(0.0),
00031     d_prevValue(0.0),
00032     d_periodic(false)
00033 {
00034 }
00035 
00037 QwtDoubleRange::~QwtDoubleRange()
00038 {
00039 }
00040 
00042 void QwtDoubleRange::setValid(bool isValid)
00043 {
00044     if ( isValid != d_isValid )
00045     {
00046         d_isValid = isValid;
00047         valueChange();
00048     }
00049 }
00050 
00052 bool QwtDoubleRange::isValid() const
00053 {
00054     return d_isValid;
00055 }
00056 
00065 void QwtDoubleRange::setNewValue(double x, bool align)
00066 {
00067     double vmin,vmax;
00068     
00069     d_prevValue = d_value;
00070 
00071     vmin = qwtMin(d_minValue, d_maxValue);
00072     vmax = qwtMax(d_minValue, d_maxValue);
00073 
00074     // 
00075     // Range check
00076     //
00077     if (x < vmin)
00078     {
00079         if ((d_periodic) && (vmin != vmax))
00080            d_value = x + ::ceil( (vmin - x) / (vmax - vmin ) ) 
00081               * (vmax - vmin);
00082         else
00083            d_value = vmin;
00084     }
00085     else if (x > vmax)
00086     {
00087         if ((d_periodic) && (vmin != vmax))
00088            d_value = x - ::ceil( ( x - vmax) / (vmax - vmin )) 
00089               * (vmax - vmin);
00090         else
00091            d_value = vmax;
00092     }
00093     else
00094        d_value = x;
00095 
00096     d_exactPrevValue = d_exactValue;
00097     d_exactValue = d_value;
00098     
00099     // align to grid
00100     if (align)
00101     {
00102         if (d_step != 0.0)
00103         {
00104            d_value = d_minValue +
00105              qwtRound((d_value - d_minValue) / d_step) * d_step;
00106         }
00107         else
00108             d_value = d_minValue;
00109         
00110         // correct rounding error at the border
00111         if (fabs(d_value - d_maxValue) < MinEps * qwtAbs(d_step))
00112             d_value = d_maxValue;
00113 
00114         // correct rounding error if value = 0
00115         if (::fabs(d_value) < MinEps * qwtAbs(d_step))
00116             d_value = 0.0;
00117     }
00118 
00119     if (!d_isValid || d_prevValue != d_value)
00120     {
00121         d_isValid = true;
00122         valueChange();
00123     }
00124 }
00125 
00135 void QwtDoubleRange::fitValue(double x)
00136 {
00137     setNewValue(x, true);
00138 }
00139 
00140 
00150 void QwtDoubleRange::setValue(double x)
00151 {
00152     setNewValue(x, false);
00153 }
00154 
00172 void QwtDoubleRange::setRange(double vmin, double vmax, double vstep, int pageSize)
00173 {
00174     bool rchg = ((d_maxValue != vmax) || (d_minValue != vmin));
00175     
00176     if (rchg) 
00177     {
00178         d_minValue = vmin;
00179         d_maxValue = vmax;
00180     }
00181     
00182     //
00183     // look if the step width has an acceptable 
00184     // value or otherwise change it.
00185     //
00186     setStep(vstep);
00187 
00188     //
00189     // limit page size
00190     //
00191     d_pageSize = qwtLim(pageSize,0, 
00192         int(qwtAbs((d_maxValue - d_minValue) / d_step))); 
00193     
00194     // 
00195     // If the value lies out of the range, it 
00196     // will be changed. Note that it will not be adjusted to 
00197     // the new step width.
00198     setNewValue(d_value, false);
00199     
00200     // call notifier after the step width has been 
00201     // adjusted.
00202     if (rchg)
00203        rangeChange();
00204 }
00205 
00211 void QwtDoubleRange::setStep(double vstep)
00212 {
00213     double intv = d_maxValue - d_minValue;
00214     
00215     double newStep;
00216     if (vstep == 0.0)
00217        newStep = intv * DefaultRelStep;
00218     else
00219     {
00220         if ((intv > 0) && (vstep < 0) || (intv < 0) && (vstep > 0))
00221            newStep = -vstep;
00222         else
00223            newStep = vstep;
00224         
00225         if ( fabs(newStep) < fabs(MinRelStep * intv) )
00226            newStep = MinRelStep * intv;
00227     }
00228     
00229     if (newStep != d_step)
00230     {
00231         d_step = newStep;
00232         stepChange();
00233     }
00234 }
00235 
00236 
00251 void QwtDoubleRange::setPeriodic(bool tf)
00252 {
00253     d_periodic = tf;
00254 }
00255 
00262 void QwtDoubleRange::incValue(int nSteps)
00263 {
00264     if ( isValid() )
00265         setNewValue(d_value + double(nSteps) * d_step, true);
00266 }
00267 
00274 void QwtDoubleRange::incPages(int nPages)
00275 {
00276     if ( isValid() )
00277         setNewValue(d_value + double(nPages) * double(d_pageSize) * d_step, true);
00278 }
00279 
00286 void QwtDoubleRange::valueChange()
00287 {
00288 }
00289 
00290 
00297 void QwtDoubleRange::rangeChange()
00298 {
00299 }
00300 
00301 
00308 void QwtDoubleRange::stepChange()
00309 {
00310 }
00311 
00316 double QwtDoubleRange::step() const
00317 {
00318     return qwtAbs(d_step);
00319 }
00320 
00329 double QwtDoubleRange::maxValue() const
00330 {   
00331     return d_maxValue;
00332 } 
00333     
00342 double QwtDoubleRange::minValue() const 
00343 {
00344     return d_minValue; 
00345 }   
00346 
00351 bool QwtDoubleRange::periodic() const 
00352 { 
00353     return d_periodic; 
00354 }
00355 
00357 int QwtDoubleRange::pageSize() const 
00358 { 
00359     return d_pageSize; 
00360 }
00361 
00363 double QwtDoubleRange::value() const 
00364 { 
00365     return d_value; 
00366 }
00367 
00377 double QwtDoubleRange::exactValue() const 
00378 { 
00379     return d_exactValue; 
00380 }
00381 
00383 double QwtDoubleRange::exactPrevValue() const 
00384 { 
00385     return d_exactPrevValue; 
00386 }
00387 
00389 double QwtDoubleRange::prevValue() const 
00390 { 
00391     return d_prevValue; 
00392 }

Generated on Sat May 24 18:47:39 2008 for Qwt User's Guide by  doxygen 1.5.0