1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the Qwt License, Version 1.0
8
*****************************************************************************/
10
#include "qwt_double_range.h"
13
static double MinRelStep = 1.0e-10;
14
static double DefaultRelStep = 1.0e-2;
15
static double MinEps = 1.0e-10;
18
The range is initialized to [0.0, 100.0], the
19
step size to 1.0, and the value to 0.0.
21
QwtDoubleRange::QwtDoubleRange():
29
d_exactPrevValue(0.0),
35
//! Destroys the QwtDoubleRange
36
QwtDoubleRange::~QwtDoubleRange()
40
//! Set the value to be valid/invalid
41
void QwtDoubleRange::setValid(bool isValid)
43
if ( isValid != d_isValid )
50
//! Indicates if the value is valid
51
bool QwtDoubleRange::isValid() const
64
void QwtDoubleRange::setNewValue(double x, bool align)
68
d_prevValue = d_value;
70
vmin = qwtMin(d_minValue, d_maxValue);
71
vmax = qwtMax(d_minValue, d_maxValue);
78
if ((d_periodic) && (vmin != vmax))
79
d_value = x + ceil( (vmin - x) / (vmax - vmin ) )
86
if ((d_periodic) && (vmin != vmax))
87
d_value = x - ceil( ( x - vmax) / (vmax - vmin ))
95
d_exactPrevValue = d_exactValue;
96
d_exactValue = d_value;
102
d_value = d_minValue +
103
qRound((d_value - d_minValue) / d_step) * d_step;
105
d_value = d_minValue;
107
// correct rounding error at the border
108
if (fabs(d_value - d_maxValue) < MinEps * qwtAbs(d_step))
109
d_value = d_maxValue;
111
// correct rounding error if value = 0
112
if (fabs(d_value) < MinEps * qwtAbs(d_step))
116
if (!d_isValid || d_prevValue != d_value)
124
\brief Adjust the value to the closest point in the step raster.
126
\warning The value is clipped when it lies outside the range.
127
When the range is QwtDoubleRange::periodic, it will
128
be mapped to a point in the interval such that
129
\verbatim new value := x + n * (max. value - min. value)\endverbatim
130
with an integer number n.
132
void QwtDoubleRange::fitValue(double x)
134
setNewValue(x, true);
139
\brief Set a new value without adjusting to the step raster
141
\warning The value is clipped when it lies outside the range.
142
When the range is QwtDoubleRange::periodic, it will
143
be mapped to a point in the interval such that
144
\verbatim new value := x + n * (max. value - min. value)\endverbatim
145
with an integer number n.
147
void QwtDoubleRange::setValue(double x)
149
setNewValue(x, false);
153
\brief Specify range and step size
155
\param vmin lower boundary of the interval
156
\param vmax higher boundary of the interval
157
\param vstep step width
158
\param pageSize page size in steps
160
\li A change of the range changes the value if it lies outside the
161
new range. The current value
162
will *not* be adjusted to the new step raster.
163
\li vmax < vmin is allowed.
164
\li If the step size is left out or set to zero, it will be
165
set to 1/100 of the interval length.
166
\li If the step size has an absurd value, it will be corrected
169
void QwtDoubleRange::setRange(double vmin, double vmax, double vstep, int pageSize)
171
bool rchg = ((d_maxValue != vmax) || (d_minValue != vmin));
180
// look if the step width has an acceptable
181
// value or otherwise change it.
188
d_pageSize = qwtLim(pageSize,0,
189
int(qwtAbs((d_maxValue - d_minValue) / d_step)));
192
// If the value lies out of the range, it
193
// will be changed. Note that it will not be adjusted to
194
// the new step width.
195
setNewValue(d_value, false);
197
// call notifier after the step width has been
204
\brief Change the step raster
205
\param vstep new step width
206
\warning The value will \e not be adjusted to the new step raster.
208
void QwtDoubleRange::setStep(double vstep)
210
double intv = d_maxValue - d_minValue;
214
newStep = intv * DefaultRelStep;
217
if ((intv > 0) && (vstep < 0) || (intv < 0) && (vstep > 0))
222
if ( fabs(newStep) < fabs(MinRelStep * intv) )
223
newStep = MinRelStep * intv;
226
if (newStep != d_step)
235
\brief Make the range periodic
237
When the range is periodic, the value will be set to a point
238
inside the interval such that
240
\verbatim point = value + n * width \endverbatim
242
if the user tries to set a new value which is outside the range.
243
If the range is nonperiodic (the default), values outside the
244
range will be clipped.
246
\param tf true for a periodic range
248
void QwtDoubleRange::setPeriodic(bool tf)
254
\brief Increment the value by a specified number of steps
255
\param nSteps Number of steps to increment
256
\warning As a result of this operation, the new value will always be
257
adjusted to the step raster.
259
void QwtDoubleRange::incValue(int nSteps)
262
setNewValue(d_value + double(nSteps) * d_step, true);
266
\brief Increment the value by a specified number of pages
267
\param nPages Number of pages to increment.
268
A negative number decrements the value.
269
\warning The Page size is specified in the constructor.
271
void QwtDoubleRange::incPages(int nPages)
274
setNewValue(d_value + double(nPages) * double(d_pageSize) * d_step, true);
278
\brief Notify a change of value
280
This virtual function is called whenever the value changes.
281
The default implementation does nothing.
283
void QwtDoubleRange::valueChange()
289
\brief Notify a change of the range
291
This virtual function is called whenever the range changes.
292
The default implementation does nothing.
294
void QwtDoubleRange::rangeChange()
300
\brief Notify a change of the step size
302
This virtual function is called whenever the step size changes.
303
The default implementation does nothing.
305
void QwtDoubleRange::stepChange()
310
\return the step size
311
\sa QwtDoubleRange::setStep, QwtDoubleRange::setRange
313
double QwtDoubleRange::step() const
315
return qwtAbs(d_step);
319
\brief Returns the value of the second border of the range
321
maxValue returns the value which has been specified
322
as the second parameter in QwtDoubleRange::setRange.
324
\sa QwtDoubleRange::setRange()
326
double QwtDoubleRange::maxValue() const
332
\brief Returns the value at the first border of the range
334
minValue returns the value which has been specified
335
as the first parameter in setRange().
337
\sa QwtDoubleRange::setRange()
339
double QwtDoubleRange::minValue() const
345
\brief Returns true if the range is periodic
346
\sa QwtDoubleRange::setPeriodic()
348
bool QwtDoubleRange::periodic() const
353
//! Returns the page size in steps.
354
int QwtDoubleRange::pageSize() const
359
//! Returns the current value.
360
double QwtDoubleRange::value() const
366
\brief Returns the exact value
368
The exact value is the value which QwtDoubleRange::value would return
369
if the value were not adjusted to the step raster. It differs from
370
the current value only if QwtDoubleRange::fitValue or
371
QwtDoubleRange::incValue have been used before. This function
372
is intended for internal use in derived classes.
374
double QwtDoubleRange::exactValue() const
379
//! Returns the exact previous value
380
double QwtDoubleRange::exactPrevValue() const
382
return d_exactPrevValue;
385
//! Returns the previous value
386
double QwtDoubleRange::prevValue() const