00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00217
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
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) {
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