00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qlayout.h>
00013 #include <qlineedit.h>
00014 #include <qvalidator.h>
00015 #include <qevent.h>
00016 #include <qstyle.h>
00017 #include "qwt_math.h"
00018 #include "qwt_counter.h"
00019 #include "qwt_arrow_button.h"
00020
00021 class QwtCounter::PrivateData
00022 {
00023 public:
00024 PrivateData():
00025 editable(true)
00026 {
00027 increment[Button1] = 1;
00028 increment[Button2] = 10;
00029 increment[Button3] = 100;
00030 }
00031
00032 QwtArrowButton *buttonDown[ButtonCnt];
00033 QwtArrowButton *buttonUp[ButtonCnt];
00034 QLineEdit *valueEdit;
00035
00036 int increment[ButtonCnt];
00037 int nButtons;
00038
00039 bool editable;
00040 };
00041
00050 QwtCounter::QwtCounter(QWidget *parent):
00051 QWidget(parent)
00052 {
00053 initCounter();
00054 }
00055
00056 #if QT_VERSION < 0x040000
00057
00065 QwtCounter::QwtCounter(QWidget *parent, const char *name):
00066 QWidget(parent, name)
00067 {
00068 initCounter();
00069 }
00070 #endif
00071
00072 void QwtCounter::initCounter()
00073 {
00074 d_data = new PrivateData;
00075
00076 #if QT_VERSION >= 0x040000
00077 using namespace Qt;
00078 #endif
00079
00080 QHBoxLayout *layout = new QHBoxLayout(this);
00081 layout->setSpacing(0);
00082 layout->setMargin(0);
00083
00084 int i;
00085 for(i = ButtonCnt - 1; i >= 0; i--)
00086 {
00087 QwtArrowButton *btn =
00088 new QwtArrowButton(i+1, Qt::DownArrow,this);
00089 btn->setFocusPolicy(NoFocus);
00090 btn->installEventFilter(this);
00091 layout->addWidget(btn);
00092
00093 connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00094 connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00095
00096 d_data->buttonDown[i] = btn;
00097 }
00098
00099 d_data->valueEdit = new QLineEdit(this);
00100 d_data->valueEdit->setReadOnly(false);
00101 d_data->valueEdit->setValidator(new QDoubleValidator(d_data->valueEdit));
00102 layout->addWidget(d_data->valueEdit);
00103
00104 #if QT_VERSION >= 0x040000
00105 connect( d_data->valueEdit, SIGNAL(editingFinished()),
00106 SLOT(textChanged()) );
00107 #else
00108 connect( d_data->valueEdit, SIGNAL(returnPressed()), SLOT(textChanged()) );
00109 connect( d_data->valueEdit, SIGNAL(lostFocus()), SLOT(textChanged()) );
00110 #endif
00111
00112 layout->setStretchFactor(d_data->valueEdit, 10);
00113
00114 for(i = 0; i < ButtonCnt; i++)
00115 {
00116 #if QT_VERSION >= 0x040000
00117 using namespace Qt;
00118 #endif
00119 QwtArrowButton *btn =
00120 new QwtArrowButton(i+1, Qt::UpArrow, this);
00121 btn->setFocusPolicy(NoFocus);
00122 btn->installEventFilter(this);
00123 layout->addWidget(btn);
00124
00125 connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00126 connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00127
00128 d_data->buttonUp[i] = btn;
00129 }
00130
00131 setNumButtons(2);
00132 setRange(0.0,1.0,0.001);
00133 setValue(0.0);
00134
00135 setSizePolicy(
00136 QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
00137
00138 setFocusProxy(d_data->valueEdit);
00139 setFocusPolicy(StrongFocus);
00140 }
00141
00143 QwtCounter::~QwtCounter()
00144 {
00145 delete d_data;
00146 }
00147
00151 void QwtCounter::polish()
00152 {
00153 const int w = d_data->valueEdit->fontMetrics().width("W") + 8;
00154
00155 for ( int i = 0; i < ButtonCnt; i++ )
00156 {
00157 d_data->buttonDown[i]->setMinimumWidth(w);
00158 d_data->buttonUp[i]->setMinimumWidth(w);
00159 }
00160
00161 #if QT_VERSION < 0x040000
00162 QWidget::polish();
00163 #endif
00164 }
00165
00167 void QwtCounter::textChanged()
00168 {
00169 if ( !d_data->editable )
00170 return;
00171
00172 bool converted = false;
00173
00174 const double value = d_data->valueEdit->text().toDouble(&converted);
00175 if ( converted )
00176 setValue( value );
00177 }
00178
00185 void QwtCounter::setEditable(bool editable)
00186 {
00187 #if QT_VERSION >= 0x040000
00188 using namespace Qt;
00189 #endif
00190 if ( editable == d_data->editable )
00191 return;
00192
00193 d_data->editable = editable;
00194 d_data->valueEdit->setReadOnly(!editable);
00195 }
00196
00198 bool QwtCounter::editable() const
00199 {
00200 return d_data->editable;
00201 }
00202
00206 bool QwtCounter::event ( QEvent * e )
00207 {
00208 #if QT_VERSION >= 0x040000
00209 if ( e->type() == QEvent::PolishRequest )
00210 polish();
00211 #endif
00212 return QWidget::event(e);
00213 }
00214
00236 void QwtCounter::keyPressEvent (QKeyEvent *e)
00237 {
00238 bool accepted = true;
00239
00240 switch ( e->key() )
00241 {
00242 case Qt::Key_Home:
00243 #if QT_VERSION >= 0x040000
00244 if ( e->modifiers() & Qt::ControlModifier )
00245 #else
00246 if ( e->state() & Qt::ControlButton )
00247 #endif
00248 setValue(minValue());
00249 else
00250 accepted = false;
00251 break;
00252 case Qt::Key_End:
00253 #if QT_VERSION >= 0x040000
00254 if ( e->modifiers() & Qt::ControlModifier )
00255 #else
00256 if ( e->state() & Qt::ControlButton )
00257 #endif
00258 setValue(maxValue());
00259 else
00260 accepted = false;
00261 break;
00262 case Qt::Key_Up:
00263 incValue(d_data->increment[0]);
00264 break;
00265 case Qt::Key_Down:
00266 incValue(-d_data->increment[0]);
00267 break;
00268 case Qt::Key_PageUp:
00269 case Qt::Key_PageDown:
00270 {
00271 int increment = d_data->increment[0];
00272 if ( d_data->nButtons >= 2 )
00273 increment = d_data->increment[1];
00274 if ( d_data->nButtons >= 3 )
00275 {
00276 #if QT_VERSION >= 0x040000
00277 if ( e->modifiers() & Qt::ShiftModifier )
00278 #else
00279 if ( e->state() & Qt::ShiftButton )
00280 #endif
00281 increment = d_data->increment[2];
00282 }
00283 if ( e->key() == Qt::Key_PageDown )
00284 increment = -increment;
00285 incValue(increment);
00286 break;
00287 }
00288 default:
00289 accepted = false;
00290 }
00291
00292 if ( accepted )
00293 {
00294 e->accept();
00295 return;
00296 }
00297
00298 QWidget::keyPressEvent (e);
00299 }
00300
00301 void QwtCounter::wheelEvent(QWheelEvent *e)
00302 {
00303 e->accept();
00304
00305 if ( d_data->nButtons <= 0 )
00306 return;
00307
00308 int increment = d_data->increment[0];
00309 if ( d_data->nButtons >= 2 )
00310 {
00311 #if QT_VERSION >= 0x040000
00312 if ( e->modifiers() & Qt::ControlModifier )
00313 #else
00314 if ( e->state() & Qt::ControlButton )
00315 #endif
00316 increment = d_data->increment[1];
00317 }
00318 if ( d_data->nButtons >= 3 )
00319 {
00320 #if QT_VERSION >= 0x040000
00321 if ( e->modifiers() & Qt::ShiftModifier )
00322 #else
00323 if ( e->state() & Qt::ShiftButton )
00324 #endif
00325 increment = d_data->increment[2];
00326 }
00327
00328 for ( int i = 0; i < d_data->nButtons; i++ )
00329 {
00330 if ( d_data->buttonDown[i]->geometry().contains(e->pos()) ||
00331 d_data->buttonUp[i]->geometry().contains(e->pos()) )
00332 {
00333 increment = d_data->increment[i];
00334 }
00335 }
00336
00337 const int wheel_delta = 120;
00338
00339 int delta = e->delta();
00340 if ( delta >= 2 * wheel_delta )
00341 delta /= 2;
00342
00343 incValue(delta / wheel_delta * increment);
00344 }
00345
00355 void QwtCounter::setIncSteps(QwtCounter::Button btn, int nSteps)
00356 {
00357 if (( btn >= 0) && (btn < ButtonCnt))
00358 d_data->increment[btn] = nSteps;
00359 }
00360
00367 int QwtCounter::incSteps(QwtCounter::Button btn) const
00368 {
00369 if (( btn >= 0) && (btn < ButtonCnt))
00370 return d_data->increment[btn];
00371
00372 return 0;
00373 }
00374
00382 void QwtCounter::setValue(double v)
00383 {
00384 QwtDoubleRange::setValue(v);
00385
00386 showNum(value());
00387 updateButtons();
00388 }
00389
00393 void QwtCounter::valueChange()
00394 {
00395 if ( isValid() )
00396 showNum(value());
00397 else
00398 d_data->valueEdit->setText(QString::null);
00399
00400 updateButtons();
00401
00402 if ( isValid() )
00403 emit valueChanged(value());
00404 }
00405
00414 void QwtCounter::updateButtons()
00415 {
00416 if ( isValid() )
00417 {
00418
00419
00420
00421 for ( int i = 0; i < ButtonCnt; i++ )
00422 {
00423 d_data->buttonDown[i]->setEnabled(value() > minValue());
00424 d_data->buttonUp[i]->setEnabled(value() < maxValue());
00425 }
00426 }
00427 else
00428 {
00429 for ( int i = 0; i < ButtonCnt; i++ )
00430 {
00431 d_data->buttonDown[i]->setEnabled(false);
00432 d_data->buttonUp[i]->setEnabled(false);
00433 }
00434 }
00435 }
00436
00441 void QwtCounter::setNumButtons(int n)
00442 {
00443 if ( n<0 || n>ButtonCnt )
00444 return;
00445
00446 for ( int i = 0; i < ButtonCnt; i++ )
00447 {
00448 if ( i < n )
00449 {
00450 d_data->buttonDown[i]->show();
00451 d_data->buttonUp[i]->show();
00452 }
00453 else
00454 {
00455 d_data->buttonDown[i]->hide();
00456 d_data->buttonUp[i]->hide();
00457 }
00458 }
00459
00460 d_data->nButtons = n;
00461 }
00462
00466 int QwtCounter::numButtons() const
00467 {
00468 return d_data->nButtons;
00469 }
00470
00472 void QwtCounter::showNum(double d)
00473 {
00474 QString v;
00475 v.setNum(d);
00476
00477 const int cursorPos = d_data->valueEdit->cursorPosition();
00478 d_data->valueEdit->setText(v);
00479 d_data->valueEdit->setCursorPosition(cursorPos);
00480 }
00481
00483 void QwtCounter::btnClicked()
00484 {
00485 for ( int i = 0; i < ButtonCnt; i++ )
00486 {
00487 if ( d_data->buttonUp[i] == sender() )
00488 incValue(d_data->increment[i]);
00489
00490 if ( d_data->buttonDown[i] == sender() )
00491 incValue(-d_data->increment[i]);
00492 }
00493 }
00494
00496 void QwtCounter::btnReleased()
00497 {
00498 emit buttonReleased(value());
00499 }
00500
00507 void QwtCounter::rangeChange()
00508 {
00509 updateButtons();
00510 }
00511
00513 QSize QwtCounter::sizeHint() const
00514 {
00515 QString tmp;
00516
00517 int w = tmp.setNum(minValue()).length();
00518 int w1 = tmp.setNum(maxValue()).length();
00519 if ( w1 > w )
00520 w = w1;
00521 w1 = tmp.setNum(minValue() + step()).length();
00522 if ( w1 > w )
00523 w = w1;
00524 w1 = tmp.setNum(maxValue() - step()).length();
00525 if ( w1 > w )
00526 w = w1;
00527
00528 tmp.fill('9', w);
00529
00530 QFontMetrics fm(d_data->valueEdit->font());
00531 w = fm.width(tmp) + 2;
00532 #if QT_VERSION >= 0x040000
00533 if ( d_data->valueEdit->hasFrame() )
00534 w += 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00535 #else
00536 w += 2 * d_data->valueEdit->frameWidth();
00537 #endif
00538
00539
00540
00541
00542 w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();
00543
00544 const int h = qwtMin(QWidget::sizeHint().height(),
00545 d_data->valueEdit->minimumSizeHint().height());
00546 return QSize(w, h);
00547 }
00548
00550 double QwtCounter::step() const
00551 {
00552 return QwtDoubleRange::step();
00553 }
00554
00556 void QwtCounter::setStep(double s)
00557 {
00558 QwtDoubleRange::setStep(s);
00559 }
00560
00562 double QwtCounter::minVal() const
00563 {
00564 return minValue();
00565 }
00566
00568 void QwtCounter::setMinValue(double m)
00569 {
00570 setRange(m, maxValue(), step());
00571 }
00572
00574 double QwtCounter::maxVal() const
00575 {
00576 return QwtDoubleRange::maxValue();
00577 }
00578
00580 void QwtCounter::setMaxValue(double m)
00581 {
00582 setRange(minValue(), m, step());
00583 }
00584
00586 void QwtCounter::setStepButton1(int nSteps)
00587 {
00588 setIncSteps(Button1, nSteps);
00589 }
00590
00592 int QwtCounter::stepButton1() const
00593 {
00594 return incSteps(Button1);
00595 }
00596
00598 void QwtCounter::setStepButton2(int nSteps)
00599 {
00600 setIncSteps(Button2, nSteps);
00601 }
00602
00604 int QwtCounter::stepButton2() const
00605 {
00606 return incSteps(Button2);
00607 }
00608
00610 void QwtCounter::setStepButton3(int nSteps)
00611 {
00612 setIncSteps(Button3, nSteps);
00613 }
00614
00616 int QwtCounter::stepButton3() const
00617 {
00618 return incSteps(Button3);
00619 }
00620
00621 double QwtCounter::value() const
00622 {
00623 return QwtDoubleRange::value();
00624 }
00625