src/qt3support/widgets/q3spinwidget.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the Qt3Support module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "q3rangecontrol.h"
00025 
00026 #ifndef QT_NO_SPINWIDGET
00027 
00028 #include "qabstractspinbox.h"
00029 #include "qevent.h"
00030 #include "qpainter.h"
00031 #include "qrect.h"
00032 #include "qstyle.h"
00033 #include "qstyleoption.h"
00034 #include "qtimer.h"
00035 
00036 class Q3SpinWidgetPrivate
00037 {
00038 public:
00039     Q3SpinWidgetPrivate()
00040         : upEnabled(true),
00041           downEnabled(true),
00042           theButton(0),
00043           buttonDown(0),
00044           timerUp(0),
00045           bsyms(Q3SpinWidget::UpDownArrows),
00046           ed (0) {}
00047     uint upEnabled :1;
00048     uint downEnabled :1;
00049     uint theButton :2;
00050     uint buttonDown :2;
00051     uint timerUp : 1;
00052     QRect up;
00053     QRect down;
00054     QTimer auRepTimer;
00055     Q3SpinWidget::ButtonSymbols bsyms;
00056     QWidget *ed;
00057     void startTimer(int msec) { auRepTimer.start(msec, true); }
00058     void startTimer(bool up, int msec) { timerUp = up; startTimer(msec); }
00059     void stopTimer() { auRepTimer.stop(); }
00060 };
00061 
00073 Q3SpinWidget::Q3SpinWidget(QWidget* parent, const char* name)
00074     : QWidget(parent, name)
00075 {
00076     d = new Q3SpinWidgetPrivate();
00077     connect(&d->auRepTimer, SIGNAL(timeout()), this, SLOT(timerDone()));
00078     setFocusPolicy(Qt::StrongFocus);
00079 
00080     arrange();
00081     updateDisplay();
00082 }
00083 
00084 
00089 Q3SpinWidget::~Q3SpinWidget()
00090 {
00091     delete d;
00092 }
00093 
00095 QWidget * Q3SpinWidget::editWidget()
00096 {
00097     return d->ed;
00098 }
00099 
00103 void Q3SpinWidget::setEditWidget(QWidget * w)
00104 {
00105     if (w) {
00106         if (w->parentWidget() != this)
00107             w->setParent(this);
00108         setFocusProxy(w);
00109     }
00110     d->ed = w;
00111     arrange();
00112     updateDisplay();
00113 }
00114 
00119 void Q3SpinWidget::mousePressEvent(QMouseEvent *e)
00120 {
00121     if (e->button() != Qt::LeftButton) {
00122         d->stopTimer();
00123         d->buttonDown = 0;
00124         d->theButton = 0;
00125         repaint(d->down.united(d->up));
00126         return;
00127     }
00128 
00129     uint oldButtonDown = d->buttonDown;
00130 
00131     if (d->down.contains(e->pos()) && d->downEnabled)
00132         d->buttonDown = 1;
00133     else if (d->up.contains(e->pos()) && d->upEnabled)
00134         d->buttonDown = 2;
00135     else
00136         d->buttonDown = 0;
00137 
00138     d->theButton = d->buttonDown;
00139     if (oldButtonDown != d->buttonDown) {
00140         if (!d->buttonDown) {
00141             repaint(d->down.united(d->up));
00142         } else if (d->buttonDown & 1) {
00143             repaint(d->down);
00144             stepDown();
00145             d->startTimer(false, 300);
00146         } else if (d->buttonDown & 2) {
00147             repaint(d->up);
00148             stepUp();
00149             d->startTimer(true, 300);
00150         }
00151     }
00152 
00153     if (!oldButtonDown && !d->buttonDown)
00154         e->ignore();
00155 
00156 }
00157 
00158 static QStyleOptionSpinBox getStyleOption(const Q3SpinWidget *spin)
00159 {
00160     QStyleOptionSpinBox opt;
00161     opt.init(spin);
00162     opt.frame = true;
00163     opt.subControls = 0;
00164     opt.buttonSymbols = (QAbstractSpinBox::ButtonSymbols)spin->buttonSymbols();
00165     opt.stepEnabled = 0;
00166     if (spin->isUpEnabled())
00167         opt.stepEnabled |= QAbstractSpinBox::StepUpEnabled;
00168     if (spin->isDownEnabled())
00169         opt.stepEnabled |= QAbstractSpinBox::StepDownEnabled;
00170     opt.activeSubControls = 0;
00171     return opt;
00172 }
00173 
00178 void Q3SpinWidget::arrange()
00179 {
00180     QStyleOptionSpinBox opt = getStyleOption(this);
00181     d->up = style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp, this);
00182     d->down = style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown, this);
00183     if (d->ed) {
00184         QRect r = style()->subControlRect(QStyle::CC_SpinBox, &opt,
00185                                           QStyle::SC_SpinBoxEditField, this);
00186         d->ed->setGeometry(r);
00187     }
00188 }
00189 
00194 void Q3SpinWidget::stepUp()
00195 {
00196     emit stepUpPressed();
00197 }
00198 
00199 void Q3SpinWidget::resizeEvent(QResizeEvent*)
00200 {
00201     arrange();
00202 }
00203 
00208 void Q3SpinWidget::stepDown()
00209 {
00210     emit stepDownPressed();
00211 }
00212 
00213 
00214 void Q3SpinWidget::timerDone()
00215 {
00216     // we use a double timer to make it possible for users to do
00217     // something with 0-timer on valueChanged.
00218     QTimer::singleShot(1, this, SLOT(timerDoneEx()));
00219 }
00220 
00221 void Q3SpinWidget::timerDoneEx()
00222 {
00223     if (!d->buttonDown)
00224         return;
00225     if (d->timerUp)
00226         stepUp();
00227     else
00228         stepDown();
00229     d->startTimer(100);
00230 }
00231 
00232 
00237 void Q3SpinWidget::mouseReleaseEvent(QMouseEvent *e)
00238 {
00239     if (e->button() != Qt::LeftButton)
00240         return;
00241 
00242     uint oldButtonDown = d->theButton;
00243     d->theButton = 0;
00244     if (oldButtonDown != d->theButton) {
00245         if (oldButtonDown & 1)
00246             repaint(d->down);
00247         else if (oldButtonDown & 2)
00248             repaint(d->up);
00249     }
00250     d->stopTimer();
00251     d->buttonDown = 0;
00252 
00253     if (!oldButtonDown && !d->buttonDown)
00254         e->ignore();
00255 }
00256 
00257 
00262 void Q3SpinWidget::mouseMoveEvent(QMouseEvent *e)
00263 {
00264     if (!(e->state() & Qt::LeftButton))
00265         return;
00266 
00267     uint oldButtonDown = d->theButton;
00268     if (oldButtonDown & 1 && !d->down.contains(e->pos())) {
00269         d->stopTimer();
00270         d->theButton = 0;
00271         repaint(d->down);
00272     } else if (oldButtonDown & 2 && !d->up.contains(e->pos())) {
00273         d->stopTimer();
00274         d->theButton = 0;
00275         repaint(d->up);
00276     } else if (!oldButtonDown && d->up.contains(e->pos()) && d->buttonDown & 2) {
00277         d->startTimer(500);
00278         d->theButton = 2;
00279         repaint(d->up);
00280     } else if (!oldButtonDown && d->down.contains(e->pos()) && d->buttonDown & 1) {
00281         d->startTimer(500);
00282         d->theButton = 1;
00283         repaint(d->down);
00284     }
00285 
00286     if (!oldButtonDown && !d->buttonDown)
00287         e->ignore();
00288 }
00289 
00290 
00294 #ifndef QT_NO_WHEELEVENT
00295 void Q3SpinWidget::wheelEvent(QWheelEvent *e)
00296 {
00297     e->accept();
00298     static float offset = 0;
00299     static Q3SpinWidget* offset_owner = 0;
00300     if (offset_owner != this) {
00301         offset_owner = this;
00302         offset = 0;
00303     }
00304     offset += -e->delta()/120;
00305     if (QABS(offset) < 1)
00306         return;
00307     int ioff = int(offset);
00308     int i;
00309     for(i=0; i < QABS(ioff); i++)
00310         offset > 0 ? stepDown() : stepUp();
00311     offset -= ioff;
00312 }
00313 #endif
00314 
00318 void Q3SpinWidget::paintEvent(QPaintEvent *)
00319 {
00320     QPainter p(this);
00321     QStyleOptionSpinBox opt = getStyleOption(this);
00322 
00323     if (d->theButton & 1)
00324         opt.activeSubControls = QStyle::SC_SpinBoxDown;
00325     else if (d->theButton & 2)
00326         opt.activeSubControls = QStyle::SC_SpinBoxUp;
00327     else
00328         opt.activeSubControls = QStyle::SC_None;
00329     opt.rect = style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxFrame, this);
00330     opt.subControls = QStyle::SC_All;
00331     style()->drawComplexControl(QStyle::CC_SpinBox, &opt, &p, this);
00332 }
00333 
00334 
00335 // ### What does the QEvent passed in contain? It used to be the previous style.
00339 void Q3SpinWidget::changeEvent(QEvent *ev)
00340 {
00341     if(ev->type() == QEvent::StyleChange) {
00342         arrange();
00343     } else if(ev->type() == QEvent::ActivationChange) {
00344         if (!isActiveWindow() && d->buttonDown) {         //was active, but lost focus
00345             d->stopTimer();
00346             d->buttonDown = 0;
00347             d->theButton = 0;
00348         }
00349     } else if(ev->type() == QEvent::EnabledChange) {
00350         d->upEnabled = isEnabled();
00351         d->downEnabled = isEnabled();
00352         updateDisplay();
00353     }
00354     QWidget::changeEvent(ev);
00355 }
00356 
00360 QRect Q3SpinWidget::upRect() const
00361 {
00362     return d->up;
00363 }
00364 
00368 QRect Q3SpinWidget::downRect() const
00369 {
00370     return d->down;
00371 }
00372 
00376 void Q3SpinWidget::updateDisplay()
00377 {
00378     if (!isEnabled()) {
00379         d->upEnabled = false;
00380         d->downEnabled = false;
00381     }
00382     if (d->theButton & 1 && (d->downEnabled) == 0) {
00383         d->theButton &= ~1;
00384         d->buttonDown &= ~1;
00385     }
00386 
00387     if (d->theButton & 2 && (d->upEnabled) == 0) {
00388         d->theButton &= ~2;
00389         d->buttonDown &= ~2;
00390     }
00391     repaint();
00392 }
00393 
00398 void Q3SpinWidget::setUpEnabled(bool on)
00399 {
00400     if ((bool)d->upEnabled != on) {
00401         d->upEnabled = on;
00402         updateDisplay();
00403     }
00404 }
00405 
00409 bool Q3SpinWidget::isUpEnabled() const
00410 {
00411     return d->upEnabled;
00412 }
00413 
00418 void Q3SpinWidget::setDownEnabled(bool on)
00419 {
00420     if ((bool)d->downEnabled != on) {
00421         d->downEnabled = on;
00422         updateDisplay();
00423     }
00424 }
00425 
00429 bool Q3SpinWidget::isDownEnabled() const
00430 {
00431     return d->downEnabled;
00432 }
00433 
00438 void Q3SpinWidget::setButtonSymbols(ButtonSymbols bs)
00439 {
00440     d->bsyms = bs;
00441 }
00442 
00446 Q3SpinWidget::ButtonSymbols Q3SpinWidget::buttonSymbols() const
00447 {
00448     return d->bsyms;
00449 }
00450 
00451 #endif

Generated on Thu Mar 15 11:59:51 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1