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 d_data = new PrivateData;
00054
00055 #if QT_VERSION >= 0x040000
00056 using namespace Qt;
00057 #endif
00058
00059 QHBoxLayout *layout = new QHBoxLayout(this);
00060 layout->setSpacing(0);
00061 layout->setMargin(0);
00062
00063 int i;
00064 for(i = ButtonCnt - 1; i >= 0; i--)
00065 {
00066 QwtArrowButton *btn =
00067 new QwtArrowButton(i+1, Qt::DownArrow,this);
00068 btn->setFocusPolicy(NoFocus);
00069 btn->installEventFilter(this);
00070 layout->addWidget(btn);
00071
00072 connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00073 connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00074
00075 d_data->buttonDown[i] = btn;
00076 }
00077
00078 d_data->valueEdit = new QLineEdit(this);
00079 d_data->valueEdit->setReadOnly(false);
00080 d_data->valueEdit->setValidator(new QDoubleValidator(d_data->valueEdit));
00081 layout->addWidget(d_data->valueEdit);
00082
00083 #if QT_VERSION >= 0x040000
00084 connect( d_data->valueEdit, SIGNAL(editingFinished()),
00085 SLOT(textChanged()) );
00086 #else
00087 connect( d_data->valueEdit, SIGNAL(returnPressed()), SLOT(textChanged()) );
00088 connect( d_data->valueEdit, SIGNAL(lostFocus()), SLOT(textChanged()) );
00089 #endif
00090
00091 layout->setStretchFactor(d_data->valueEdit, 10);
00092
00093 for(i = 0; i < ButtonCnt; i++)
00094 {
00095 #if QT_VERSION >= 0x040000
00096 using namespace Qt;
00097 #endif
00098 QwtArrowButton *btn =
00099 new QwtArrowButton(i+1, Qt::UpArrow, this);
00100 btn->setFocusPolicy(NoFocus);
00101 btn->installEventFilter(this);
00102 layout->addWidget(btn);
00103
00104 connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00105 connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00106
00107 d_data->buttonUp[i] = btn;
00108 }
00109
00110 setNumButtons(2);
00111 setRange(0.0,1.0,0.001);
00112 setValue(0.0);
00113
00114 setSizePolicy(
00115 QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
00116
00117 setFocusProxy(d_data->valueEdit);
00118 setFocusPolicy(StrongFocus);
00119 }
00120
00121 QwtCounter::~QwtCounter()
00122 {
00123 delete d_data;
00124 }
00125
00129 void QwtCounter::polish()
00130 {
00131 const int w = d_data->valueEdit->fontMetrics().width("W") + 8;
00132
00133 for ( int i = 0; i < ButtonCnt; i++ )
00134 {
00135 d_data->buttonDown[i]->setMinimumWidth(w);
00136 d_data->buttonUp[i]->setMinimumWidth(w);
00137 }
00138
00139 #if QT_VERSION < 0x040000
00140 QWidget::polish();
00141 #endif
00142 }
00143
00145 void QwtCounter::textChanged()
00146 {
00147 if ( !d_data->editable )
00148 return;
00149
00150 bool converted = false;
00151
00152 const double value = d_data->valueEdit->text().toDouble(&converted);
00153 if ( converted )
00154 setValue( value );
00155 }
00156
00163 void QwtCounter::setEditable(bool editable)
00164 {
00165 #if QT_VERSION >= 0x040000
00166 using namespace Qt;
00167 #endif
00168 if ( editable == d_data->editable )
00169 return;
00170
00171 d_data->editable = editable;
00172 d_data->valueEdit->setReadOnly(!editable);
00173 }
00174
00176 bool QwtCounter::editable() const
00177 {
00178 return d_data->editable;
00179 }
00180
00184 bool QwtCounter::event ( QEvent * e )
00185 {
00186 #if QT_VERSION >= 0x040000
00187 if ( e->type() == QEvent::PolishRequest )
00188 polish();
00189 #endif
00190 return QWidget::event(e);
00191 }
00192
00214 void QwtCounter::keyPressEvent (QKeyEvent *e)
00215 {
00216 bool accepted = true;
00217
00218 switch ( e->key() )
00219 {
00220 case Qt::Key_Home:
00221 #if QT_VERSION >= 0x040000
00222 if ( e->modifiers() & Qt::ControlModifier )
00223 #else
00224 if ( e->state() & Qt::ControlButton )
00225 #endif
00226 setValue(minValue());
00227 else
00228 accepted = false;
00229 break;
00230 case Qt::Key_End:
00231 #if QT_VERSION >= 0x040000
00232 if ( e->modifiers() & Qt::ControlModifier )
00233 #else
00234 if ( e->state() & Qt::ControlButton )
00235 #endif
00236 setValue(maxValue());
00237 else
00238 accepted = false;
00239 break;
00240 case Qt::Key_Up:
00241 incValue(d_data->increment[0]);
00242 break;
00243 case Qt::Key_Down:
00244 incValue(-d_data->increment[0]);
00245 break;
00246 case Qt::Key_PageUp:
00247 case Qt::Key_PageDown:
00248 {
00249 int increment = d_data->increment[0];
00250 if ( d_data->nButtons >= 2 )
00251 increment = d_data->increment[1];
00252 if ( d_data->nButtons >= 3 )
00253 {
00254 #if QT_VERSION >= 0x040000
00255 if ( e->modifiers() & Qt::ShiftModifier )
00256 #else
00257 if ( e->state() & Qt::ShiftButton )
00258 #endif
00259 increment = d_data->increment[2];
00260 }
00261 if ( e->key() == Qt::Key_PageDown )
00262 increment = -increment;
00263 incValue(increment);
00264 break;
00265 }
00266 default:
00267 accepted = false;
00268 }
00269
00270 if ( accepted )
00271 {
00272 e->accept();
00273 return;
00274 }
00275
00276 QWidget::keyPressEvent (e);
00277 }
00278
00279 void QwtCounter::wheelEvent(QWheelEvent *e)
00280 {
00281 e->accept();
00282
00283 if ( d_data->nButtons <= 0 )
00284 return;
00285
00286 int increment = d_data->increment[0];
00287 if ( d_data->nButtons >= 2 )
00288 {
00289 #if QT_VERSION >= 0x040000
00290 if ( e->modifiers() & Qt::ControlModifier )
00291 #else
00292 if ( e->state() & Qt::ControlButton )
00293 #endif
00294 increment = d_data->increment[1];
00295 }
00296 if ( d_data->nButtons >= 3 )
00297 {
00298 #if QT_VERSION >= 0x040000
00299 if ( e->modifiers() & Qt::ShiftModifier )
00300 #else
00301 if ( e->state() & Qt::ShiftButton )
00302 #endif
00303 increment = d_data->increment[2];
00304 }
00305
00306 for ( int i = 0; i < d_data->nButtons; i++ )
00307 {
00308 if ( d_data->buttonDown[i]->geometry().contains(e->pos()) ||
00309 d_data->buttonUp[i]->geometry().contains(e->pos()) )
00310 {
00311 increment = d_data->increment[i];
00312 }
00313 }
00314
00315 const int wheel_delta = 120;
00316
00317 int delta = e->delta();
00318 if ( delta >= 2 * wheel_delta )
00319 delta /= 2;
00320
00321 incValue(delta / wheel_delta * increment);
00322 }
00323
00333 void QwtCounter::setIncSteps(QwtCounter::Button btn, int nSteps)
00334 {
00335 if (( btn >= 0) && (btn < ButtonCnt))
00336 d_data->increment[btn] = nSteps;
00337 }
00338
00345 int QwtCounter::incSteps(QwtCounter::Button btn) const
00346 {
00347 if (( btn >= 0) && (btn < ButtonCnt))
00348 return d_data->increment[btn];
00349
00350 return 0;
00351 }
00352
00360 void QwtCounter::setValue(double v)
00361 {
00362 QwtDoubleRange::setValue(v);
00363
00364 showNum(value());
00365 updateButtons();
00366 }
00367
00371 void QwtCounter::valueChange()
00372 {
00373 if ( isValid() )
00374 showNum(value());
00375 else
00376 d_data->valueEdit->setText(QString::null);
00377
00378 updateButtons();
00379
00380 if ( isValid() )
00381 emit valueChanged(value());
00382 }
00383
00392 void QwtCounter::updateButtons()
00393 {
00394 if ( isValid() )
00395 {
00396
00397
00398
00399 for ( int i = 0; i < ButtonCnt; i++ )
00400 {
00401 d_data->buttonDown[i]->setEnabled(value() > minValue());
00402 d_data->buttonUp[i]->setEnabled(value() < maxValue());
00403 }
00404 }
00405 else
00406 {
00407 for ( int i = 0; i < ButtonCnt; i++ )
00408 {
00409 d_data->buttonDown[i]->setEnabled(false);
00410 d_data->buttonUp[i]->setEnabled(false);
00411 }
00412 }
00413 }
00414
00419 void QwtCounter::setNumButtons(int n)
00420 {
00421 if ( n<0 || n>ButtonCnt )
00422 return;
00423
00424 for ( int i = 0; i < ButtonCnt; i++ )
00425 {
00426 if ( i < n )
00427 {
00428 d_data->buttonDown[i]->show();
00429 d_data->buttonUp[i]->show();
00430 }
00431 else
00432 {
00433 d_data->buttonDown[i]->hide();
00434 d_data->buttonUp[i]->hide();
00435 }
00436 }
00437
00438 d_data->nButtons = n;
00439 }
00440
00444 int QwtCounter::numButtons() const
00445 {
00446 return d_data->nButtons;
00447 }
00448
00450 void QwtCounter::showNum(double d)
00451 {
00452 QString v;
00453 v.setNum(d);
00454
00455 const int cursorPos = d_data->valueEdit->cursorPosition();
00456 d_data->valueEdit->setText(v);
00457 d_data->valueEdit->setCursorPosition(cursorPos);
00458 }
00459
00461 void QwtCounter::btnClicked()
00462 {
00463 for ( int i = 0; i < ButtonCnt; i++ )
00464 {
00465 if ( d_data->buttonUp[i] == sender() )
00466 incValue(d_data->increment[i]);
00467
00468 if ( d_data->buttonDown[i] == sender() )
00469 incValue(-d_data->increment[i]);
00470 }
00471 }
00472
00474 void QwtCounter::btnReleased()
00475 {
00476 emit buttonReleased(value());
00477 }
00478
00485 void QwtCounter::rangeChange()
00486 {
00487 updateButtons();
00488 }
00489
00491 QSize QwtCounter::sizeHint() const
00492 {
00493 QString tmp;
00494
00495 int w = tmp.setNum(minValue()).length();
00496 int w1 = tmp.setNum(maxValue()).length();
00497 if ( w1 > w )
00498 w = w1;
00499 w1 = tmp.setNum(minValue() + step()).length();
00500 if ( w1 > w )
00501 w = w1;
00502 w1 = tmp.setNum(maxValue() - step()).length();
00503 if ( w1 > w )
00504 w = w1;
00505
00506 tmp.fill('9', w);
00507
00508 QFontMetrics fm(d_data->valueEdit->font());
00509 w = fm.width(tmp) + 2;
00510 #if QT_VERSION >= 0x040000
00511 if ( d_data->valueEdit->hasFrame() )
00512 w += 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00513 #else
00514 w += 2 * d_data->valueEdit->frameWidth();
00515 #endif
00516
00517
00518
00519
00520 w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();
00521
00522 const int h = qwtMin(QWidget::sizeHint().height(),
00523 d_data->valueEdit->minimumSizeHint().height());
00524 return QSize(w, h);
00525 }
00526
00528 double QwtCounter::step() const
00529 {
00530 return QwtDoubleRange::step();
00531 }
00532
00534 void QwtCounter::setStep(double s)
00535 {
00536 QwtDoubleRange::setStep(s);
00537 }
00538
00540 double QwtCounter::minVal() const
00541 {
00542 return minValue();
00543 }
00544
00546 void QwtCounter::setMinValue(double m)
00547 {
00548 setRange(m, maxValue(), step());
00549 }
00550
00552 double QwtCounter::maxVal() const
00553 {
00554 return QwtDoubleRange::maxValue();
00555 }
00556
00558 void QwtCounter::setMaxValue(double m)
00559 {
00560 setRange(minValue(), m, step());
00561 }
00562
00564 void QwtCounter::setStepButton1(int nSteps)
00565 {
00566 setIncSteps(Button1, nSteps);
00567 }
00568
00570 int QwtCounter::stepButton1() const
00571 {
00572 return incSteps(Button1);
00573 }
00574
00576 void QwtCounter::setStepButton2(int nSteps)
00577 {
00578 setIncSteps(Button2, nSteps);
00579 }
00580
00582 int QwtCounter::stepButton2() const
00583 {
00584 return incSteps(Button2);
00585 }
00586
00588 void QwtCounter::setStepButton3(int nSteps)
00589 {
00590 setIncSteps(Button3, nSteps);
00591 }
00592
00594 int QwtCounter::stepButton3() const
00595 {
00596 return incSteps(Button3);
00597 }
00598
00599 double QwtCounter::value() const
00600 {
00601 return QwtDoubleRange::value();
00602 }
00603