~l3on/ubuntu/oneiric/qwt/fix-921430

« back to all changes in this revision

Viewing changes to qwt-5.0.1/src/qwt_double_range.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2007-10-05 15:20:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071005152041-qmybqh4fj9jejyo2
Tags: 5.0.2-2
* Handle nostrip build option. (Closes: #437877)
* Build libqwt5-doc package in binary-indep target. (Closes: #443110)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2
 
 * Qwt Widget Library
3
 
 * Copyright (C) 1997   Josef Wilgen
4
 
 * Copyright (C) 2002   Uwe Rathmann
5
 
 * 
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
 
 *****************************************************************************/
9
 
 
10
 
#include "qwt_double_range.h"
11
 
#include "qwt_math.h"
12
 
 
13
 
static double MinRelStep = 1.0e-10;
14
 
static double DefaultRelStep = 1.0e-2;
15
 
static double MinEps = 1.0e-10;
16
 
 
17
 
/*!
18
 
  The range is initialized to [0.0, 100.0], the
19
 
  step size to 1.0, and the value to 0.0.
20
 
*/
21
 
QwtDoubleRange::QwtDoubleRange():
22
 
    d_minValue(0.0),
23
 
    d_maxValue(0.0),
24
 
    d_step(1.0),
25
 
    d_pageSize(1),
26
 
    d_isValid(false),
27
 
    d_value(0.0),
28
 
    d_exactValue(0.0),
29
 
    d_exactPrevValue(0.0),
30
 
    d_prevValue(0.0),
31
 
    d_periodic(false)
32
 
{
33
 
}
34
 
 
35
 
//! Destroys the QwtDoubleRange
36
 
QwtDoubleRange::~QwtDoubleRange()
37
 
{
38
 
}
39
 
 
40
 
//! Set the value to be valid/invalid
41
 
void QwtDoubleRange::setValid(bool isValid)
42
 
{
43
 
    if ( isValid != d_isValid )
44
 
    {
45
 
        d_isValid = isValid;
46
 
        valueChange();
47
 
    }
48
 
}
49
 
 
50
 
//! Indicates if the value is valid
51
 
bool QwtDoubleRange::isValid() const
52
 
{
53
 
    return d_isValid;
54
 
}
55
 
 
56
 
/*!
57
 
  \brief No docs
58
 
  
59
 
  Description
60
 
  \param x ???
61
 
  \param align
62
 
  \todo Documentation
63
 
*/
64
 
void QwtDoubleRange::setNewValue(double x, bool align)
65
 
{
66
 
    double vmin,vmax;
67
 
    
68
 
    d_prevValue = d_value;
69
 
 
70
 
    vmin = qwtMin(d_minValue, d_maxValue);
71
 
    vmax = qwtMax(d_minValue, d_maxValue);
72
 
 
73
 
    // 
74
 
    // Range check
75
 
    //
76
 
    if (x < vmin)
77
 
    {
78
 
        if ((d_periodic) && (vmin != vmax))
79
 
           d_value = x + ceil( (vmin - x) / (vmax - vmin ) ) 
80
 
              * (vmax - vmin);
81
 
        else
82
 
           d_value = vmin;
83
 
    }
84
 
    else if (x > vmax)
85
 
    {
86
 
        if ((d_periodic) && (vmin != vmax))
87
 
           d_value = x - ceil( ( x - vmax) / (vmax - vmin )) 
88
 
              * (vmax - vmin);
89
 
        else
90
 
           d_value = vmax;
91
 
    }
92
 
    else
93
 
       d_value = x;
94
 
 
95
 
    d_exactPrevValue = d_exactValue;
96
 
    d_exactValue = d_value;
97
 
    
98
 
    // align to grid
99
 
    if (align)
100
 
    {
101
 
        if (d_step != 0.0)
102
 
           d_value = d_minValue +
103
 
             qRound((d_value - d_minValue) / d_step) * d_step;
104
 
        else
105
 
           d_value = d_minValue;
106
 
        
107
 
        // correct rounding error at the border
108
 
        if (fabs(d_value - d_maxValue) < MinEps * qwtAbs(d_step))
109
 
           d_value = d_maxValue;
110
 
 
111
 
        // correct rounding error if value = 0
112
 
        if (fabs(d_value) < MinEps * qwtAbs(d_step))
113
 
           d_value = 0.0;
114
 
    }
115
 
 
116
 
    if (!d_isValid || d_prevValue != d_value)
117
 
    {
118
 
        d_isValid = true;
119
 
        valueChange();
120
 
    }
121
 
}
122
 
 
123
 
/*!
124
 
  \brief  Adjust the value to the closest point in the step raster.
125
 
  \param x value
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.
131
 
*/
132
 
void QwtDoubleRange::fitValue(double x)
133
 
{
134
 
    setNewValue(x, true);
135
 
}
136
 
 
137
 
 
138
 
/*!
139
 
  \brief Set a new value without adjusting to the step raster
140
 
  \param x new value
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.
146
 
*/
147
 
void QwtDoubleRange::setValue(double x)
148
 
{
149
 
    setNewValue(x, false);
150
 
}
151
 
 
152
 
/*!
153
 
  \brief Specify  range and step size
154
 
 
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
159
 
  \warning
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
167
 
      to a better one.
168
 
*/
169
 
void QwtDoubleRange::setRange(double vmin, double vmax, double vstep, int pageSize)
170
 
{
171
 
    bool rchg = ((d_maxValue != vmax) || (d_minValue != vmin));
172
 
    
173
 
    if (rchg) 
174
 
    {
175
 
        d_minValue = vmin;
176
 
        d_maxValue = vmax;
177
 
    }
178
 
    
179
 
    //
180
 
    // look if the step width has an acceptable 
181
 
    // value or otherwise change it.
182
 
    //
183
 
    setStep(vstep);
184
 
 
185
 
    //
186
 
    // limit page size
187
 
    //
188
 
    d_pageSize = qwtLim(pageSize,0, 
189
 
        int(qwtAbs((d_maxValue - d_minValue) / d_step))); 
190
 
    
191
 
    // 
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);
196
 
    
197
 
    // call notifier after the step width has been 
198
 
    // adjusted.
199
 
    if (rchg)
200
 
       rangeChange();
201
 
}
202
 
 
203
 
/*!
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.
207
 
*/
208
 
void QwtDoubleRange::setStep(double vstep)
209
 
{
210
 
    double intv = d_maxValue - d_minValue;
211
 
    
212
 
    double newStep;
213
 
    if (vstep == 0.0)
214
 
       newStep = intv * DefaultRelStep;
215
 
    else
216
 
    {
217
 
        if ((intv > 0) && (vstep < 0) || (intv < 0) && (vstep > 0))
218
 
           newStep = -vstep;
219
 
        else
220
 
           newStep = vstep;
221
 
        
222
 
        if ( fabs(newStep) < fabs(MinRelStep * intv) )
223
 
           newStep = MinRelStep * intv;
224
 
    }
225
 
    
226
 
    if (newStep != d_step)
227
 
    {
228
 
        d_step = newStep;
229
 
        stepChange();
230
 
    }
231
 
}
232
 
 
233
 
 
234
 
/*!
235
 
  \brief Make the range periodic
236
 
 
237
 
  When the range is periodic, the value will be set to a point
238
 
  inside the interval such that
239
 
 
240
 
  \verbatim point = value + n * width \endverbatim
241
 
 
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.
245
 
 
246
 
  \param tf true for a periodic range
247
 
*/
248
 
void QwtDoubleRange::setPeriodic(bool tf)
249
 
{
250
 
    d_periodic = tf;
251
 
}
252
 
 
253
 
/*!
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.
258
 
*/
259
 
void QwtDoubleRange::incValue(int nSteps)
260
 
{
261
 
    if ( isValid() )
262
 
        setNewValue(d_value + double(nSteps) * d_step, true);
263
 
}
264
 
 
265
 
/*!
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.
270
 
*/
271
 
void QwtDoubleRange::incPages(int nPages)
272
 
{
273
 
    if ( isValid() )
274
 
        setNewValue(d_value + double(nPages) * double(d_pageSize) * d_step, true);
275
 
}
276
 
 
277
 
/*!
278
 
  \brief Notify a change of value
279
 
 
280
 
  This virtual function is called whenever the value changes.
281
 
  The default implementation does nothing.
282
 
*/
283
 
void QwtDoubleRange::valueChange()
284
 
{
285
 
}
286
 
 
287
 
 
288
 
/*!
289
 
  \brief Notify a change of the range
290
 
 
291
 
  This virtual function is called whenever the range changes.
292
 
  The default implementation does nothing.
293
 
*/
294
 
void QwtDoubleRange::rangeChange()
295
 
{
296
 
}
297
 
 
298
 
 
299
 
/*!
300
 
  \brief Notify a change of the step size
301
 
 
302
 
  This virtual function is called whenever the step size changes.
303
 
  The default implementation does nothing.
304
 
*/
305
 
void QwtDoubleRange::stepChange()
306
 
{
307
 
}
308
 
 
309
 
/*!
310
 
  \return the step size
311
 
  \sa QwtDoubleRange::setStep, QwtDoubleRange::setRange
312
 
*/
313
 
double QwtDoubleRange::step() const
314
 
{
315
 
    return qwtAbs(d_step);
316
 
}
317
 
 
318
 
/*!
319
 
  \brief Returns the value of the second border of the range
320
 
 
321
 
  maxValue returns the value which has been specified
322
 
  as the second parameter in  QwtDoubleRange::setRange.
323
 
    
324
 
  \sa QwtDoubleRange::setRange()
325
 
*/  
326
 
double QwtDoubleRange::maxValue() const
327
 
{   
328
 
    return d_maxValue;
329
 
330
 
    
331
 
/*!
332
 
  \brief Returns the value at the first border of the range
333
 
    
334
 
  minValue returns the value which has been specified
335
 
  as the first parameter in  setRange().
336
 
    
337
 
  \sa QwtDoubleRange::setRange()
338
 
*/
339
 
double QwtDoubleRange::minValue() const 
340
 
{
341
 
    return d_minValue; 
342
 
}   
343
 
 
344
 
/*!
345
 
  \brief Returns true if the range is periodic
346
 
  \sa QwtDoubleRange::setPeriodic()
347
 
*/
348
 
bool QwtDoubleRange::periodic() const 
349
 
350
 
    return d_periodic; 
351
 
}
352
 
 
353
 
//! Returns the page size in steps.
354
 
int QwtDoubleRange::pageSize() const 
355
 
356
 
    return d_pageSize; 
357
 
}
358
 
 
359
 
//! Returns the current value.
360
 
double QwtDoubleRange::value() const 
361
 
362
 
    return d_value; 
363
 
}
364
 
 
365
 
/*!
366
 
  \brief Returns the exact value
367
 
 
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.
373
 
*/
374
 
double QwtDoubleRange::exactValue() const 
375
 
376
 
    return d_exactValue; 
377
 
}
378
 
 
379
 
//! Returns the exact previous value
380
 
double QwtDoubleRange::exactPrevValue() const 
381
 
382
 
    return d_exactPrevValue; 
383
 
}
384
 
 
385
 
//! Returns the previous value
386
 
double QwtDoubleRange::prevValue() const 
387
 
388
 
    return d_prevValue; 
389
 
}