source: vendor/trolltech/current/src/widgets/qspinwidget.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 9.6 KB
Line 
1/****************************************************************************
2**
3** Implementation of QSpinWidget class
4**
5** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
6**
7** This file is part of the widgets module of the Qt GUI Toolkit.
8**
9** This file may be distributed under the terms of the Q Public License
10** as defined by Trolltech AS of Norway and appearing in the file
11** LICENSE.QPL included in the packaging of this file.
12**
13** This file may be distributed and/or modified under the terms of the
14** GNU General Public License version 2 as published by the Free Software
15** Foundation and appearing in the file LICENSE.GPL included in the
16** packaging of this file.
17**
18** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
19** licenses may use this file in accordance with the Qt Commercial License
20** Agreement provided with the Software.
21**
22** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
23** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24**
25** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
26** information about Qt Commercial License Agreements.
27** See http://www.trolltech.com/qpl/ for QPL licensing information.
28** See http://www.trolltech.com/gpl/ for GPL licensing information.
29**
30** Contact info@trolltech.com if any conditions of this licensing are
31** not clear to you.
32**
33**********************************************************************/
34
35#include "qrangecontrol.h"
36
37#ifndef QT_NO_SPINWIDGET
38
39#include "qrect.h"
40#include "qtimer.h"
41#include "qstyle.h"
42#include "qpainter.h"
43
44class QSpinWidgetPrivate
45{
46public:
47 QSpinWidgetPrivate()
48 : upEnabled( TRUE ),
49 downEnabled( TRUE ),
50 theButton( 0 ),
51 buttonDown( 0 ),
52 timerUp( 0 ),
53 bsyms( QSpinWidget::UpDownArrows ),
54 ed ( 0 ) {}
55 uint upEnabled :1;
56 uint downEnabled :1;
57 uint theButton :2;
58 uint buttonDown :2;
59 uint timerUp : 1;
60 QRect up;
61 QRect down;
62 QTimer auRepTimer;
63 QSpinWidget::ButtonSymbols bsyms;
64 QWidget *ed;
65 void startTimer( int msec ) { auRepTimer.start( msec, TRUE ); }
66 void startTimer( bool up, int msec ) { timerUp = up; startTimer( msec ); }
67 void stopTimer() { auRepTimer.stop(); }
68};
69
70/*!
71
72 \class QSpinWidget qspinwidget.h
73 \brief The QSpinWidget class is an internal range control related class.
74
75 \internal
76
77 Constructs an empty range control widget with parent \a parent
78 called \a name.
79
80*/
81
82QSpinWidget::QSpinWidget( QWidget* parent, const char* name )
83 : QWidget( parent, name )
84{
85 d = new QSpinWidgetPrivate();
86 connect( &d->auRepTimer, SIGNAL( timeout() ), this, SLOT( timerDone() ) );
87 setFocusPolicy( StrongFocus );
88
89 arrange();
90 updateDisplay();
91}
92
93
94/*! Destroys the object and frees any allocated resources.
95
96*/
97
98QSpinWidget::~QSpinWidget()
99{
100 delete d;
101}
102
103/*! */
104QWidget * QSpinWidget::editWidget()
105{
106 return d->ed;
107}
108
109/*!
110 Sets the editing widget to \a w.
111*/
112void QSpinWidget::setEditWidget( QWidget * w )
113{
114 if ( w ) {
115 w->reparent( this, QPoint( 0, 0 ) );
116 setFocusProxy( w );
117 }
118 d->ed = w;
119 arrange();
120 updateDisplay();
121}
122
123/*! \reimp
124
125*/
126
127void QSpinWidget::mousePressEvent( QMouseEvent *e )
128{
129 if ( e->button() != LeftButton ) {
130 d->stopTimer();
131 d->buttonDown = 0;
132 d->theButton = 0;
133 repaint( d->down.unite( d->up ), FALSE );
134 return;
135 }
136
137 uint oldButtonDown = d->buttonDown;
138
139 if ( d->down.contains( e->pos() ) && d->downEnabled )
140 d->buttonDown = 1;
141 else if ( d->up.contains( e->pos() ) && d->upEnabled )
142 d->buttonDown = 2;
143 else
144 d->buttonDown = 0;
145
146 d->theButton = d->buttonDown;
147 if ( oldButtonDown != d->buttonDown ) {
148 if ( !d->buttonDown ) {
149 repaint( d->down.unite( d->up ), FALSE );
150 } else if ( d->buttonDown & 1 ) {
151 repaint( d->down, FALSE );
152 stepDown();
153 d->startTimer( FALSE, 300 );
154 } else if ( d->buttonDown & 2 ) {
155 repaint( d->up, FALSE );
156 stepUp();
157 d->startTimer( TRUE, 300 );
158 }
159 }
160}
161
162/*!
163
164*/
165
166void QSpinWidget::arrange()
167{
168 d->up = QStyle::visualRect( style().querySubControlMetrics( QStyle::CC_SpinWidget, this,
169 QStyle::SC_SpinWidgetUp ), this );
170 d->down = QStyle::visualRect( style().querySubControlMetrics( QStyle::CC_SpinWidget, this,
171 QStyle::SC_SpinWidgetDown ), this );
172 if ( d->ed ) {
173 QRect r = QStyle::visualRect( style().querySubControlMetrics( QStyle::CC_SpinWidget, this,
174 QStyle::SC_SpinWidgetEditField ), this );
175 d->ed->setGeometry( r );
176 }
177}
178
179/*!
180
181*/
182
183void QSpinWidget::stepUp()
184{
185 emit stepUpPressed();
186}
187
188void QSpinWidget::resizeEvent( QResizeEvent* )
189{
190 arrange();
191}
192
193/*!
194
195*/
196
197void QSpinWidget::stepDown()
198{
199 emit stepDownPressed();
200}
201
202
203void QSpinWidget::timerDone()
204{
205 // we use a double timer to make it possible for users to do
206 // something with 0-timer on valueChanged.
207 QTimer::singleShot( 1, this, SLOT( timerDoneEx() ) );
208}
209
210void QSpinWidget::timerDoneEx()
211{
212 if ( !d->buttonDown )
213 return;
214 if ( d->timerUp )
215 stepUp();
216 else
217 stepDown();
218 d->startTimer( 100 );
219}
220
221
222void QSpinWidget::windowActivationChange( bool oldActive )
223{
224 //was active, but lost focus
225 if ( oldActive && d->buttonDown ) {
226 d->stopTimer();
227 d->buttonDown = 0;
228 d->theButton = 0;
229 }
230 QWidget::windowActivationChange( oldActive );
231}
232
233
234
235/*!
236 The event is passed in \a e.
237*/
238
239void QSpinWidget::mouseReleaseEvent( QMouseEvent *e )
240{
241 if ( e->button() != LeftButton )
242 return;
243
244 uint oldButtonDown = d->theButton;
245 d->theButton = 0;
246 if ( oldButtonDown != d->theButton ) {
247 if ( oldButtonDown & 1 )
248 repaint( d->down, FALSE );
249 else if ( oldButtonDown & 2 )
250 repaint( d->up, FALSE );
251 }
252 d->stopTimer();
253 d->buttonDown = 0;
254}
255
256
257/*!
258 The event is passed in \a e.
259*/
260
261void QSpinWidget::mouseMoveEvent( QMouseEvent *e )
262{
263 if ( !(e->state() & LeftButton ) )
264 return;
265
266 uint oldButtonDown = d->theButton;
267 if ( oldButtonDown & 1 && !d->down.contains( e->pos() ) ) {
268 d->stopTimer();
269 d->theButton = 0;
270 repaint( d->down, FALSE );
271 } else if ( oldButtonDown & 2 && !d->up.contains( e->pos() ) ) {
272 d->stopTimer();
273 d->theButton = 0;
274 repaint( d->up, FALSE );
275 } else if ( !oldButtonDown && d->up.contains( e->pos() ) && d->buttonDown & 2 ) {
276 d->startTimer( 500 );
277 d->theButton = 2;
278 repaint( d->up, FALSE );
279 } else if ( !oldButtonDown && d->down.contains( e->pos() ) && d->buttonDown & 1 ) {
280 d->startTimer( 500 );
281 d->theButton = 1;
282 repaint( d->down, FALSE );
283 }
284}
285
286
287/*!
288 The event is passed in \a e.
289*/
290#ifndef QT_NO_WHEELEVENT
291void QSpinWidget::wheelEvent( QWheelEvent *e )
292{
293 e->accept();
294 static float offset = 0;
295 static QSpinWidget* offset_owner = 0;
296 if ( offset_owner != this ) {
297 offset_owner = this;
298 offset = 0;
299 }
300 offset += -e->delta()/120;
301 if ( QABS( offset ) < 1 )
302 return;
303 int ioff = int(offset);
304 int i;
305 for( i=0; i < QABS( ioff ); i++ )
306 offset > 0 ? stepDown() : stepUp();
307 offset -= ioff;
308}
309#endif
310
311/*!
312
313*/
314void QSpinWidget::paintEvent( QPaintEvent * )
315{
316 QPainter p( this );
317
318 QStyle::SFlags flags = QStyle::Style_Default;
319 if (isEnabled())
320 flags |= QStyle::Style_Enabled;
321 if (hasFocus() || focusProxy() && focusProxy()->hasFocus())
322 flags |= QStyle::Style_HasFocus;
323
324 QStyle::SCFlags active;
325 if ( d->theButton & 1 )
326 active = QStyle::SC_SpinWidgetDown;
327 else if ( d->theButton & 2 )
328 active = QStyle::SC_SpinWidgetUp;
329 else
330 active = QStyle::SC_None;
331
332 QRect fr = QStyle::visualRect(
333 style().querySubControlMetrics( QStyle::CC_SpinWidget, this,
334 QStyle::SC_SpinWidgetFrame ), this );
335 style().drawComplexControl( QStyle::CC_SpinWidget, &p, this,
336 fr, colorGroup(),
337 flags,
338 (uint)QStyle::SC_All,
339 active );
340}
341
342
343/*!
344 The previous style is passed in \a old.
345*/
346
347void QSpinWidget::styleChange( QStyle& old )
348{
349 arrange();
350 QWidget::styleChange( old );
351}
352
353/*!
354*/
355
356QRect QSpinWidget::upRect() const
357{
358 return d->up;
359}
360
361/*!
362*/
363
364QRect QSpinWidget::downRect() const
365{
366 return d->down;
367}
368
369/*!
370*/
371
372void QSpinWidget::updateDisplay()
373{
374 if ( !isEnabled() ) {
375 d->upEnabled = FALSE;
376 d->downEnabled = FALSE;
377 }
378 if ( d->theButton & 1 && ( d->downEnabled ) == 0 ) {
379 d->theButton &= ~1;
380 d->buttonDown &= ~1;
381 }
382
383 if ( d->theButton & 2 && ( d->upEnabled ) == 0 ) {
384 d->theButton &= ~2;
385 d->buttonDown &= ~2;
386 }
387 repaint( FALSE );
388}
389
390
391/*!
392 The previous enabled state is passed in \a old.
393*/
394
395void QSpinWidget::enableChanged( bool )
396{
397 d->upEnabled = isEnabled();
398 d->downEnabled = isEnabled();
399 updateDisplay();
400}
401
402
403/*!
404 Sets up-enabled to \a on.
405*/
406
407void QSpinWidget::setUpEnabled( bool on )
408{
409 if ( (bool)d->upEnabled != on ) {
410 d->upEnabled = on;
411 updateDisplay();
412 }
413}
414
415/*!
416*/
417
418bool QSpinWidget::isUpEnabled() const
419{
420 return d->upEnabled;
421}
422
423/*!
424 Sets down-enabled to \a on.
425*/
426
427void QSpinWidget::setDownEnabled( bool on )
428{
429 if ( (bool)d->downEnabled != on ) {
430 d->downEnabled = on;
431 updateDisplay();
432 }
433}
434
435/*!
436*/
437
438bool QSpinWidget::isDownEnabled() const
439{
440 return d->downEnabled;
441}
442
443/*!
444 Sets the button symbol to \a bs.
445*/
446
447void QSpinWidget::setButtonSymbols( ButtonSymbols bs )
448{
449 d->bsyms = bs;
450}
451
452/*!
453*/
454
455QSpinWidget::ButtonSymbols QSpinWidget::buttonSymbols() const
456{
457 return d->bsyms;
458}
459
460#endif
Note: See TracBrowser for help on using the repository browser.