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
*****************************************************************************/
11
#include "qwt_double_range.h"
14
static double MinRelStep = 1.0e-10;
15
static double DefaultRelStep = 1.0e-2;
16
static double MinEps = 1.0e-10;
19
The range is initialized to [0.0, 100.0], the
20
step size to 1.0, and the value to 0.0.
22
QwtDoubleRange::QwtDoubleRange():
30
d_exactPrevValue(0.0),
36
//! Destroys the QwtDoubleRange
37
QwtDoubleRange::~QwtDoubleRange()
41
//! Set the value to be valid/invalid
42
void QwtDoubleRange::setValid(bool isValid)
44
if ( isValid != d_isValid )
51
//! Indicates if the value is valid
52
bool QwtDoubleRange::isValid() const
65
void QwtDoubleRange::setNewValue(double x, bool align)
69
d_prevValue = d_value;
71
vmin = qwtMin(d_minValue, d_maxValue);
72
vmax = qwtMax(d_minValue, d_maxValue);
79
if ((d_periodic) && (vmin != vmax))
80
d_value = x + ::ceil( (vmin - x) / (vmax - vmin ) )
87
if ((d_periodic) && (vmin != vmax))
88
d_value = x - ::ceil( ( x - vmax) / (vmax - vmin ))
96
d_exactPrevValue = d_exactValue;
97
d_exactValue = d_value;
104
d_value = d_minValue +
105
qwtRound((d_value - d_minValue) / d_step) * d_step;
108
d_value = d_minValue;
110
// correct rounding error at the border
111
if (fabs(d_value - d_maxValue) < MinEps * qwtAbs(d_step))
112
d_value = d_maxValue;
114
// correct rounding error if value = 0
115
if (::fabs(d_value) < MinEps * qwtAbs(d_step))
119
if (!d_isValid || d_prevValue != d_value)
127
\brief Adjust the value to the closest point in the step raster.
129
\warning The value is clipped when it lies outside the range.
130
When the range is QwtDoubleRange::periodic, it will
131
be mapped to a point in the interval such that
132
\verbatim new value := x + n * (max. value - min. value)\endverbatim
133
with an integer number n.
135
void QwtDoubleRange::fitValue(double x)
137
setNewValue(x, true);
142
\brief Set a new value without adjusting to the step raster
144
\warning The value is clipped when it lies outside the range.
145
When the range is QwtDoubleRange::periodic, it will
146
be mapped to a point in the interval such that
147
\verbatim new value := x + n * (max. value - min. value)\endverbatim
148
with an integer number n.
150
void QwtDoubleRange::setValue(double x)
152
setNewValue(x, false);
156
\brief Specify range and step size
158
\param vmin lower boundary of the interval
159
\param vmax higher boundary of the interval
160
\param vstep step width
161
\param pageSize page size in steps
163
\li A change of the range changes the value if it lies outside the
164
new range. The current value
165
will *not* be adjusted to the new step raster.
166
\li vmax < vmin is allowed.
167
\li If the step size is left out or set to zero, it will be
168
set to 1/100 of the interval length.
169
\li If the step size has an absurd value, it will be corrected
172
void QwtDoubleRange::setRange(double vmin, double vmax, double vstep, int pageSize)
174
bool rchg = ((d_maxValue != vmax) || (d_minValue != vmin));
183
// look if the step width has an acceptable
184
// value or otherwise change it.
191
d_pageSize = qwtLim(pageSize,0,
192
int(qwtAbs((d_maxValue - d_minValue) / d_step)));
195
// If the value lies out of the range, it
196
// will be changed. Note that it will not be adjusted to
197
// the new step width.
198
setNewValue(d_value, false);
200
// call notifier after the step width has been
207
\brief Change the step raster
208
\param vstep new step width
209
\warning The value will \e not be adjusted to the new step raster.
211
void QwtDoubleRange::setStep(double vstep)
213
double intv = d_maxValue - d_minValue;
217
newStep = intv * DefaultRelStep;
220
if ((intv > 0) && (vstep < 0) || (intv < 0) && (vstep > 0))
225
if ( fabs(newStep) < fabs(MinRelStep * intv) )
226
newStep = MinRelStep * intv;
229
if (newStep != d_step)
238
\brief Make the range periodic
240
When the range is periodic, the value will be set to a point
241
inside the interval such that
243
\verbatim point = value + n * width \endverbatim
245
if the user tries to set a new value which is outside the range.
246
If the range is nonperiodic (the default), values outside the
247
range will be clipped.
249
\param tf true for a periodic range
251
void QwtDoubleRange::setPeriodic(bool tf)
257
\brief Increment the value by a specified number of steps
258
\param nSteps Number of steps to increment
259
\warning As a result of this operation, the new value will always be
260
adjusted to the step raster.
262
void QwtDoubleRange::incValue(int nSteps)
265
setNewValue(d_value + double(nSteps) * d_step, true);
269
\brief Increment the value by a specified number of pages
270
\param nPages Number of pages to increment.
271
A negative number decrements the value.
272
\warning The Page size is specified in the constructor.
274
void QwtDoubleRange::incPages(int nPages)
277
setNewValue(d_value + double(nPages) * double(d_pageSize) * d_step, true);
281
\brief Notify a change of value
283
This virtual function is called whenever the value changes.
284
The default implementation does nothing.
286
void QwtDoubleRange::valueChange()
292
\brief Notify a change of the range
294
This virtual function is called whenever the range changes.
295
The default implementation does nothing.
297
void QwtDoubleRange::rangeChange()
303
\brief Notify a change of the step size
305
This virtual function is called whenever the step size changes.
306
The default implementation does nothing.
308
void QwtDoubleRange::stepChange()
313
\return the step size
314
\sa setStep(), setRange()
316
double QwtDoubleRange::step() const
318
return qwtAbs(d_step);
322
\brief Returns the value of the second border of the range
324
maxValue returns the value which has been specified
325
as the second parameter in QwtDoubleRange::setRange.
329
double QwtDoubleRange::maxValue() const
335
\brief Returns the value at the first border of the range
337
minValue returns the value which has been specified
338
as the first parameter in setRange().
342
double QwtDoubleRange::minValue() const
348
\brief Returns true if the range is periodic
351
bool QwtDoubleRange::periodic() const
356
//! Returns the page size in steps.
357
int QwtDoubleRange::pageSize() const
362
//! Returns the current value.
363
double QwtDoubleRange::value() const
369
\brief Returns the exact value
371
The exact value is the value which QwtDoubleRange::value would return
372
if the value were not adjusted to the step raster. It differs from
373
the current value only if QwtDoubleRange::fitValue or
374
QwtDoubleRange::incValue have been used before. This function
375
is intended for internal use in derived classes.
377
double QwtDoubleRange::exactValue() const
382
//! Returns the exact previous value
383
double QwtDoubleRange::exactPrevValue() const
385
return d_exactPrevValue;
388
//! Returns the previous value
389
double QwtDoubleRange::prevValue() const