source: trunk/doc/src/snippets/qabstractsliderisnippet.cpp@ 973

Last change on this file since 973 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 13.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41QAbstractSliderPrivate::QAbstractSliderPrivate()
42 : minimum(0), maximum(99), singleStep(1), pageStep(10),
43 value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false),
44 invertedAppearance(false), invertedControls(false),
45 orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
46{
47}
48
49QAbstractSliderPrivate::~QAbstractSliderPrivate()
50{
51}
52
53oid QAbstractSlider::setRange(int min, int max)
54{
55 Q_D(QAbstractSlider);
56 int oldMin = d->minimum;
57 int oldMax = d->maximum;
58 d->minimum = min;
59 d->maximum = qMax(min, max);
60 if (oldMin != d->minimum || oldMax != d->maximum) {
61 sliderChange(SliderRangeChange);
62 emit rangeChanged(d->minimum, d->maximum);
63 setValue(d->value); // re-bound
64 }
65}
66
67
68void QAbstractSliderPrivate::setSteps(int single, int page)
69{
70 Q_Q(QAbstractSlider);
71 singleStep = qAbs(single);
72 pageStep = qAbs(page);
73 q->sliderChange(QAbstractSlider::SliderStepsChange);
74}
75
76AbstractSlider::QAbstractSlider(QWidget *parent)
77 :QWidget(*new QAbstractSliderPrivate, parent, 0)
78{
79}
80
81QAbstractSlider::QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent)
82 :QWidget(dd, parent, 0)
83{
84}
85
86QAbstractSlider::~QAbstractSlider()
87{
88}
89
90void QAbstractSlider::setOrientation(Qt::Orientation orientation)
91{
92 Q_D(QAbstractSlider);
93 if (d->orientation == orientation)
94 return;
95
96 d->orientation = orientation;
97 if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
98 QSizePolicy sp = sizePolicy();
99 sp.transpose();
100 setSizePolicy(sp);
101 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
102 }
103 update();
104 updateGeometry();
105}
106
107Qt::Orientation QAbstractSlider::orientation() const
108{
109 Q_D(const QAbstractSlider);
110 return d->orientation;
111}
112
113
114void QAbstractSlider::setMinimum(int min)
115{
116 Q_D(QAbstractSlider);
117 setRange(min, qMax(d->maximum, min));
118}
119
120int QAbstractSlider::minimum() const
121{
122 Q_D(const QAbstractSlider);
123 return d->minimum;
124}
125
126
127void QAbstractSlider::setMaximum(int max)
128{
129 Q_D(QAbstractSlider);
130 setRange(qMin(d->minimum, max), max);
131}
132
133int QAbstractSlider::maximum() const
134{
135 Q_D(const QAbstractSlider);
136 return d->maximum;
137}
138
139
140
141void QAbstractSlider::setSingleStep(int step)
142{
143 Q_D(QAbstractSlider);
144 d->setSteps(step, d->pageStep);
145}
146
147int QAbstractSlider::singleStep() const
148{
149 Q_D(const QAbstractSlider);
150 return d->singleStep;
151}
152
153
154void QAbstractSlider::setPageStep(int step)
155{
156 Q_D(QAbstractSlider);
157 d->setSteps(d->singleStep, step);
158}
159
160int QAbstractSlider::pageStep() const
161{
162 Q_D(const QAbstractSlider);
163 return d->pageStep;
164}
165
166oid QAbstractSlider::setTracking(bool enable)
167{
168 Q_D(QAbstractSlider);
169 d->tracking = enable;
170}
171
172bool QAbstractSlider::hasTracking() const
173{
174 Q_D(const QAbstractSlider);
175 return d->tracking;
176}
177
178
179
180void QAbstractSlider::setSliderDown(bool down)
181{
182 Q_D(QAbstractSlider);
183 bool doEmit = d->pressed != down;
184
185 d->pressed = down;
186
187 if (doEmit) {
188 if (down)
189 emit sliderPressed();
190 else
191 emit sliderReleased();
192 }
193
194 if (!down && d->position != d->value)
195 triggerAction(SliderMove);
196}
197
198bool QAbstractSlider::isSliderDown() const
199{
200 Q_D(const QAbstractSlider);
201 return d->pressed;
202}
203
204
205void QAbstractSlider::setSliderPosition(int position)
206{
207 Q_D(QAbstractSlider);
208 position = d->bound(position);
209 if (position == d->position)
210 return;
211 d->position = position;
212 if (!d->tracking)
213 update();
214 if (d->pressed)
215 emit sliderMoved(position);
216 if (d->tracking && !d->blocktracking)
217 triggerAction(SliderMove);
218}
219
220int QAbstractSlider::sliderPosition() const
221{
222 Q_D(const QAbstractSlider);
223 return d->position;
224}
225
226
227
228int QAbstractSlider::value() const
229{
230 Q_D(const QAbstractSlider);
231 return d->value;
232}
233
234//! [0]
235void QAbstractSlider::setValue(int value)
236//! [0]
237{
238 Q_D(QAbstractSlider);
239 value = d->bound(value);
240 if (d->value == value && d->position == value)
241 return;
242 d->value = value;
243 if (d->position != value) {
244 d->position = value;
245 if (d->pressed)
246 emit sliderMoved((d->position = value));
247 }
248#ifndef QT_NO_ACCESSIBILITY
249//! [1]
250 QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
251//! [1]
252#endif
253 sliderChange(SliderValueChange);
254 emit valueChanged(value);
255//! [2]
256}
257//! [2]
258
259bool QAbstractSlider::invertedAppearance() const
260{
261 Q_D(const QAbstractSlider);
262 return d->invertedAppearance;
263}
264
265void QAbstractSlider::setInvertedAppearance(bool invert)
266{
267 Q_D(QAbstractSlider);
268 d->invertedAppearance = invert;
269 update();
270}
271
272
273
274bool QAbstractSlider::invertedControls() const
275{
276 Q_D(const QAbstractSlider);
277 return d->invertedControls;
278}
279
280void QAbstractSlider::setInvertedControls(bool invert)
281{
282 Q_D(QAbstractSlider);
283 d->invertedControls = invert;
284}
285
286void QAbstractSlider::triggerAction(SliderAction action)
287{
288 Q_D(QAbstractSlider);
289 d->blocktracking = true;
290 switch (action) {
291 case SliderSingleStepAdd:
292 setSliderPosition(d->value + d->singleStep);
293 break;
294 case SliderSingleStepSub:
295 setSliderPosition(d->value - d->singleStep);
296 break;
297 case SliderPageStepAdd:
298 setSliderPosition(d->value + d->pageStep);
299 break;
300 case SliderPageStepSub:
301 setSliderPosition(d->value - d->pageStep);
302 break;
303 case SliderToMinimum:
304 setSliderPosition(d->minimum);
305 break;
306 case SliderToMaximum:
307 setSliderPosition(d->maximum);
308 break;
309 case SliderMove:
310 case SliderNoAction:
311 break;
312 };
313 emit actionTriggered(action);
314 d->blocktracking = false;
315 setValue(d->position);
316}
317
318void QAbstractSlider::setRepeatAction(SliderAction action, int thresholdTime, int repeatTime)
319{
320 Q_D(QAbstractSlider);
321 if ((d->repeatAction = action) == SliderNoAction) {
322 d->repeatActionTimer.stop();
323 } else {
324 d->repeatActionTime = repeatTime;
325 d->repeatActionTimer.start(thresholdTime, this);
326 }
327}
328
329QAbstractSlider::SliderAction QAbstractSlider::repeatAction() const
330{
331 Q_D(const QAbstractSlider);
332 return d->repeatAction;
333}
334
335void QAbstractSlider::timerEvent(QTimerEvent *e)
336{
337 Q_D(QAbstractSlider);
338 if (e->timerId() == d->repeatActionTimer.timerId()) {
339 if (d->repeatActionTime) { // was threshold time, use repeat time next time
340 d->repeatActionTimer.start(d->repeatActionTime, this);
341 d->repeatActionTime = 0;
342 }
343 if (d->repeatAction == SliderPageStepAdd)
344 d->setAdjustedSliderPosition(d->value + d->pageStep);
345 else if (d->repeatAction == SliderPageStepSub)
346 d->setAdjustedSliderPosition(d->value - d->pageStep);
347 else
348 triggerAction(d->repeatAction);
349 }
350}
351
352oid QAbstractSlider::sliderChange(SliderChange)
353{
354 update();
355}
356
357
358#ifndef QT_NO_WHEELEVENT
359void QAbstractSlider::wheelEvent(QWheelEvent * e)
360{
361 Q_D(QAbstractSlider);
362 e->ignore();
363 if (e->orientation() != d->orientation && !rect().contains(e->pos()))
364 return;
365
366 static qreal offset = 0;
367 static QAbstractSlider *offset_owner = 0;
368 if (offset_owner != this){
369 offset_owner = this;
370 offset = 0;
371 }
372
373 int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep);
374 if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
375 step = d->pageStep;
376 offset += e->delta() * step / 120;
377 if (d->invertedControls)
378 offset = -offset;
379
380 if (qAbs(offset) < 1)
381 return;
382
383 int prevValue = d->value;
384 d->position = d->value + int(offset); // value will be updated by triggerAction()
385 triggerAction(SliderMove);
386 if (prevValue == d->value) {
387 offset = 0;
388 } else {
389 offset -= int(offset);
390 e->accept();
391 }
392}
393#endif
394void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
395{
396 Q_D(QAbstractSlider);
397 SliderAction action = SliderNoAction;
398 switch (ev->key()) {
399#ifdef QT_KEYPAD_NAVIGATION
400 case Qt::Key_Select:
401 if (QApplication::keypadNavigationEnabled())
402 setEditFocus(!hasEditFocus());
403 else
404 ev->ignore();
405 break;
406 case Qt::Key_Back:
407 if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
408 setValue(d->origValue);
409 setEditFocus(false);
410 } else
411 ev->ignore();
412 break;
413#endif
414
415 // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird.
416 case Qt::Key_Left:
417#ifdef QT_KEYPAD_NAVIGATION
418 if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
419 ev->ignore();
420 return;
421 }
422 if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
423 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
424 else
425#endif
426 action = !d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd;
427 break;
428 case Qt::Key_Right:
429#ifdef QT_KEYPAD_NAVIGATION
430 if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
431 ev->ignore();
432 return;
433 }
434 if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
435 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
436 else
437#endif
438 action = !d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub;
439 break;
440 case Qt::Key_Up:
441#ifdef QT_KEYPAD_NAVIGATION
442 if (QApplication::keypadNavigationEnabled()) {
443 ev->ignore();
444 break;
445 }
446#endif
447 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
448 break;
449 case Qt::Key_Down:
450#ifdef QT_KEYPAD_NAVIGATION
451 if (QApplication::keypadNavigationEnabled()) {
452 ev->ignore();
453 break;
454 }
455#endif
456 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
457 break;
458 case Qt::Key_PageUp:
459 action = d->invertedControls ? SliderPageStepSub : SliderPageStepAdd;
460 break;
461 case Qt::Key_PageDown:
462 action = d->invertedControls ? SliderPageStepAdd : SliderPageStepSub;
463 break;
464 case Qt::Key_Home:
465 action = SliderToMinimum;
466 break;
467 case Qt::Key_End:
468 action = SliderToMaximum;
469 break;
470 default:
471 ev->ignore();
472 break;
473 }
474 if (action)
475 triggerAction(action);
476}
477
478void QAbstractSlider::changeEvent(QEvent *ev)
479{
480 Q_D(QAbstractSlider);
481 switch (ev->type()) {
482 case QEvent::EnabledChange:
483 if (!isEnabled()) {
484 d->repeatActionTimer.stop();
485 setSliderDown(false);
486 }
487 // fall through...
488 default:
489 QWidget::changeEvent(ev);
490 }
491}
492
493bool QAbstractSlider::event(QEvent *e)
494{
495#ifdef QT_KEYPAD_NAVIGATION
496 Q_D(QAbstractSlider);
497 switch (e->type()) {
498 case QEvent::FocusIn:
499 d->origValue = d->value;
500 break;
501 default:
502 break;
503 }
504#endif
505
506 return QWidget::event(e);
507}
508
509
Note: See TracBrowser for help on using the repository browser.