1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "q3rangecontrol.h"
30
#ifndef QT_NO_RANGECONTROL
35
\class Q3RangeControl qrangecontrol.h
36
\brief The Q3RangeControl class provides an integer value within a range.
40
Although originally designed for the QScrollBar widget, the
41
Q3RangeControl can also be used in conjunction with other widgets
42
such as QSlider and QSpinBox. Here are the five main concepts in
47
\i \e{Current value} The bounded integer that
48
Q3RangeControl maintains. value() returns it, and several
49
functions, including setValue(), set it.
51
\i \e{Minimum} The lowest value that value() can ever
52
return. Returned by minValue() and set by setRange() or one of the
55
\i \e{Maximum} The highest value that value() can ever
56
return. Returned by maxValue() and set by setRange() or one of the
59
\i \e{Line step} The smaller of two natural steps that
60
Q3RangeControl provides and typically corresponds to the user
61
pressing an arrow key. The line step is returned by lineStep()
62
and set using setSteps(). The functions addLine() and
63
subtractLine() respectively increment and decrement the current
66
\i \e{Page step} The larger of two natural steps that
67
Q3RangeControl provides and typically corresponds to the user
68
pressing PageUp or PageDown. The page step is returned by
69
pageStep() and set using setSteps(). The functions addPage() and
70
substractPage() respectively increment and decrement the current
75
Unity (1) may be viewed as a third step size. setValue() lets you
76
set the current value to any integer in the allowed range, not
77
just minValue() + \e n * lineStep() for integer values of \e n.
78
Some widgets may allow the user to set any value at all; others
79
may just provide multiples of lineStep() or pageStep().
81
Q3RangeControl provides three virtual functions that are well
82
suited for updating the on-screen representation of range controls
83
and emitting signals: valueChange(), rangeChange() and
86
Q3RangeControl also provides a function called bound() which lets
87
you force arbitrary integers to be within the allowed range of the
90
We recommend that all widgets that inherit Q3RangeControl provide
91
at least a signal called valueChanged(); many widgets will want to
92
provide addStep(), addPage(), substractStep() and substractPage()
95
Note that you must use multiple inheritance if you plan to
96
implement a widget using Q3RangeControl because Q3RangeControl is
97
not derived from QWidget.
102
Constructs a range control with a minimum value of 0, maximum
103
value of 99, line step of 1, page step of 10 and initial value 0.
106
Q3RangeControl::Q3RangeControl()
118
Constructs a range control whose value can never be smaller than
119
\a minValue or greater than \a maxValue, whose line step size is
120
\a lineStep and page step size is \a pageStep and whose value is
121
initially \a value (which is guaranteed to be in range using
125
Q3RangeControl::Q3RangeControl(int minValue, int maxValue,
126
int lineStep, int pageStep,
131
line = QABS(lineStep);
132
page = QABS(pageStep);
133
prevVal = minVal - 1;
139
Destroys the range control
142
Q3RangeControl::~Q3RangeControl()
148
\fn int Q3RangeControl::value() const
150
Returns the current range control value. This is guaranteed to be
151
within the range [minValue(), maxValue()].
153
\sa setValue() prevValue()
157
\fn int Q3RangeControl::prevValue() const
159
Returns the previous value of the range control. "Previous value"
160
means the value before the last change occurred. Setting a new
161
range may affect the value, too, because the value is forced to be
162
inside the specified range. When the range control is initially
163
created, this is the same as value().
165
prevValue() can be outside the current legal range if a call to
166
setRange() causes the current value to change. For example, if the
167
range was [0, 1000] and the current value is 500, setRange(0, 400)
168
makes value() return 400 and prevValue() return 500.
170
\sa value() setRange()
174
Sets the range control's value to \a value and forces it to be
175
within the legal range.
177
Calls the virtual valueChange() function if the new value is
178
different from the previous value. The old value can still be
179
retrieved using prevValue().
184
void Q3RangeControl::setValue(int value)
186
directSetValue(value);
192
Sets the range control \a value directly without calling
195
Forces the new \a value to be within the legal range.
197
You will rarely have to call this function. However, if you want
198
to change the range control's value inside the overloaded method
199
valueChange(), setValue() would call the function valueChange()
200
again. To avoid this recursion you must use directSetValue()
206
void Q3RangeControl::directSetValue(int value)
213
Equivalent to \c{setValue(value() + pageStep())}.
215
If the value is changed, then valueChange() is called.
217
\sa subtractPage() addLine() setValue()
220
void Q3RangeControl::addPage()
222
setValue(value() + pageStep());
226
Equivalent to \c{setValue(value() - pageStep())}.
228
If the value is changed, then valueChange() is called.
230
\sa addPage() subtractLine() setValue()
233
void Q3RangeControl::subtractPage()
235
setValue(value() - pageStep());
239
Equivalent to \c{setValue(value() + lineStep())}.
241
If the value is changed, then valueChange() is called.
243
\sa subtractLine() addPage() setValue()
246
void Q3RangeControl::addLine()
248
setValue(value() + lineStep());
252
Equivalent to \c{setValue(value() - lineStep())}.
254
If the value is changed, then valueChange() is called.
256
\sa addLine() subtractPage() setValue()
259
void Q3RangeControl::subtractLine()
261
setValue(value() - lineStep());
266
\fn int Q3RangeControl::minValue() const
268
Returns the minimum value of the range.
270
\sa setMinValue() setRange() maxValue()
274
\fn int Q3RangeControl::maxValue() const
276
Returns the maximum value of the range.
278
\sa setMaxValue() setRange() minValue()
282
Sets the minimum value of the range to \a minVal.
284
If necessary, the maxValue() is adjusted so that the range remains
287
\sa minValue() setMaxValue()
289
void Q3RangeControl::setMinValue(int minVal)
291
int maxVal = maxValue();
294
setRange(minVal, maxVal);
298
Sets the minimum value of the range to \a maxVal.
300
If necessary, the minValue() is adjusted so that the range remains
303
\sa maxValue() setMinValue()
305
void Q3RangeControl::setMaxValue(int maxVal)
307
int minVal = minValue();
310
setRange(minVal, maxVal);
314
Sets the range control's minimum value to \a minValue and its
315
maximum value to \a maxValue.
317
Calls the virtual rangeChange() function if one or both of the new
318
minimum and maximum values are different from the previous
319
setting. Calls the virtual valueChange() function if the current
320
value is adjusted because it was outside the new range.
322
If \a maxValue is smaller than \a minValue, \a minValue becomes
323
the only legal value.
325
\sa minValue() maxValue()
328
void Q3RangeControl::setRange(int minValue, int maxValue)
330
if (minValue > maxValue) {
331
qWarning("Q3RangeControl::setRange: minValue %d > maxValue %d",
335
if (minValue == minVal && maxValue == maxVal)
339
int tmp = bound(val);
350
\fn int Q3RangeControl::lineStep() const
352
Returns the line step.
354
\sa setSteps() pageStep()
358
\fn int Q3RangeControl::pageStep() const
360
Returns the page step.
362
\sa setSteps() lineStep()
366
Sets the range's line step to \a lineStep and page step to \a
369
Calls the virtual stepChange() function if the new line step
370
or page step are different from the previous settings.
372
\sa lineStep() pageStep() setRange()
375
void Q3RangeControl::setSteps(int lineStep, int pageStep)
377
if (lineStep != line || pageStep != page) {
378
line = QABS(lineStep);
379
page = QABS(pageStep);
386
This virtual function is called whenever the range control value
387
changes. You can reimplement it if you want to be notified when
388
the value changes. The default implementation does nothing.
390
Note that this method is called after the value has changed. The
391
previous value can be retrieved using prevValue().
393
\sa setValue(), addPage(), subtractPage(), addLine(),
394
subtractLine() rangeChange(), stepChange()
397
void Q3RangeControl::valueChange()
403
This virtual function is called whenever the range control's range
404
changes. You can reimplement it if you want to be notified when
405
the range changes. The default implementation does nothing.
407
Note that this method is called after the range has changed.
409
\sa setRange(), valueChange(), stepChange()
412
void Q3RangeControl::rangeChange()
418
This virtual function is called whenever the range control's
419
line or page step settings change. You can reimplement it if you
420
want to be notified when the step changes. The default
421
implementation does nothing.
423
Note that this method is called after a step setting has changed.
425
\sa setSteps(), rangeChange(), valueChange()
428
void Q3RangeControl::stepChange()
434
Forces the value \a v to be within the range from minValue() to
435
maxValue() inclusive, and returns the result.
437
This function is provided so that you can easily force other
438
numbers than value() into the allowed range. You do not need to
439
call it in order to use Q3RangeControl itself.
441
\sa setValue() value() minValue() maxValue()
444
int Q3RangeControl::bound(int v) const
455
Converts \a logical_val to a pixel position. minValue() maps to 0,
456
maxValue() maps to \a span and other values are distributed evenly
459
This function can handle the entire integer range without
460
overflow, providing \a span is \<= 4096.
462
Calling this method is useful when actually drawing a range
463
control such as a QScrollBar on-screen.
465
\sa valueFromPosition()
468
int Q3RangeControl::positionFromValue(int logical_val, int span) const
470
if (span <= 0 || logical_val < minValue() || maxValue() <= minValue())
472
if (logical_val > maxValue())
475
uint range = maxValue() - minValue();
476
uint p = logical_val - minValue();
478
if (range > (uint)INT_MAX/4096) {
479
const int scale = 4096*2;
480
return ((p/scale) * span) / (range/scale);
481
// ### the above line is probably not 100% correct
482
// ### but fixing it isn't worth the extreme pain...
483
} else if (range > (uint)span) {
484
return (2*p*span + range) / (2*range);
486
uint div = span / range;
487
uint mod = span % range;
488
return p*div + (2*p*mod + range) / (2*range);
490
//equiv. to (p*span)/range + 0.5
491
// no overflow because of this implicit assumption:
497
Converts the pixel position \a pos to a value. 0 maps to
498
minValue(), \a span maps to maxValue() and other values are
499
distributed evenly in-between.
501
This function can handle the entire integer range without
504
Calling this method is useful if you actually implemented a range
505
control widget such as QScrollBar and want to handle mouse press
506
events. This function then maps screen coordinates to the logical
509
\sa positionFromValue()
512
int Q3RangeControl::valueFromPosition(int pos, int span) const
514
if (span <= 0 || pos <= 0)
519
uint range = maxValue() - minValue();
521
if ((uint)span > range)
522
return minValue() + (2*pos*range + span) / (2*span);
524
uint div = range / span;
525
uint mod = range % span;
526
return minValue() + pos*div + (2*pos*mod + span) / (2*span);
528
// equiv. to minValue() + (pos*range)/span + 0.5
529
// no overflow because of this implicit assumption:
530
// pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX)