Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

qwt_counter.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 // vim: expandtab
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         blockKeys(false),
00026         keyPressed(false),
00027         editable(true)
00028     {
00029         increment[Button1] = 1;
00030         increment[Button2] = 10;
00031         increment[Button3] = 100;
00032     }
00033 
00034     QwtArrowButton *buttonDown[ButtonCnt];
00035     QwtArrowButton *buttonUp[ButtonCnt];
00036     QLineEdit *valueEdit;
00037 
00038     int increment[ButtonCnt];
00039     int nButtons;
00040 
00041     bool blockKeys;
00042     bool keyPressed;
00043     bool editable;
00044 };
00045 
00054 QwtCounter::QwtCounter(QWidget *parent):
00055     QWidget(parent) 
00056 {
00057     d_data = new PrivateData;
00058 
00059 #if QT_VERSION >= 0x040000
00060     using namespace Qt;
00061 #endif
00062 
00063     QHBoxLayout *layout = new QHBoxLayout(this);
00064     layout->setSpacing(0);
00065     layout->setMargin(0);
00066 
00067     int i;
00068     for(i = ButtonCnt - 1; i >= 0; i--)
00069     {
00070         QwtArrowButton *btn =
00071             new QwtArrowButton(i+1, Qt::DownArrow,this);
00072         btn->setFocusPolicy(StrongFocus);
00073         btn->installEventFilter(this);
00074         layout->addWidget(btn);
00075 
00076         connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00077         connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00078 
00079         d_data->buttonDown[i] = btn;
00080     }
00081 
00082     d_data->valueEdit = new QLineEdit(this);
00083     d_data->valueEdit->setReadOnly(false);
00084     d_data->valueEdit->setFocusPolicy(StrongFocus);
00085     d_data->valueEdit->setValidator(new QDoubleValidator(d_data->valueEdit));
00086     layout->addWidget(d_data->valueEdit);
00087 
00088 #if QT_VERSION >= 0x040000
00089     connect( d_data->valueEdit, SIGNAL(editingFinished()), 
00090         SLOT(textChanged()) );
00091 #else
00092     connect( d_data->valueEdit, SIGNAL(returnPressed()), SLOT(textChanged()) );
00093     connect( d_data->valueEdit, SIGNAL(lostFocus()), SLOT(textChanged()) );
00094 #endif
00095 
00096     layout->setStretchFactor(d_data->valueEdit, 10);
00097 
00098     for(i = 0; i < ButtonCnt; i++)
00099     {
00100 #if QT_VERSION >= 0x040000
00101         using namespace Qt;
00102 #endif
00103         QwtArrowButton *btn =
00104             new QwtArrowButton(i+1, Qt::UpArrow, this);
00105         btn->setFocusPolicy(StrongFocus);
00106         btn->installEventFilter(this);
00107         layout->addWidget(btn);
00108 
00109         connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00110         connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00111     
00112         d_data->buttonUp[i] = btn;
00113     }
00114 
00115     setNumButtons(2);
00116     setRange(0.0,1.0,0.001);
00117     setValue(0.0);
00118 
00119     setSizePolicy(
00120         QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
00121 }
00122 
00123 QwtCounter::~QwtCounter()
00124 {
00125     delete d_data;
00126 }
00127 
00131 void QwtCounter::polish()
00132 {
00133     const int w = d_data->valueEdit->fontMetrics().width("W") + 8;
00134 
00135     for ( int i = 0; i < ButtonCnt; i++ )
00136     {
00137         d_data->buttonDown[i]->setMinimumWidth(w);
00138         d_data->buttonUp[i]->setMinimumWidth(w);
00139     }
00140 
00141 #if QT_VERSION < 0x040000
00142     QWidget::polish();
00143 #endif
00144 }
00145 
00147 void QwtCounter::textChanged() 
00148 {
00149     if ( !d_data->editable ) 
00150         return;
00151 
00152     bool converted = false;
00153 
00154     const double value = d_data->valueEdit->text().toDouble(&converted);
00155     if ( converted ) 
00156        setValue( value );
00157 }
00158 
00165 void QwtCounter::setEditable(bool editable)
00166 {
00167 #if QT_VERSION >= 0x040000
00168     using namespace Qt;
00169 #endif
00170     if ( editable == d_data->editable ) 
00171         return;
00172 
00173     d_data->editable = editable;
00174     if ( d_data->editable )   
00175     {
00176         d_data->valueEdit->setReadOnly(false);
00177         d_data->valueEdit->setFocusPolicy(StrongFocus);
00178     } 
00179     else 
00180     {
00181         d_data->valueEdit->setReadOnly(true);
00182         d_data->valueEdit->setFocusPolicy(NoFocus);
00183     }
00184 }
00185 
00187 bool QwtCounter::editable() const 
00188 {   
00189     return d_data->editable;
00190 }
00191 
00195 bool QwtCounter::event ( QEvent * e ) 
00196 {
00197 #if QT_VERSION >= 0x040000
00198     if ( e->type() == QEvent::PolishRequest )
00199         polish();
00200 #endif
00201     return QWidget::event(e);
00202 }
00203 
00205 bool QwtCounter::eventFilter(QObject *object, QEvent *e)
00206 {
00207     if ( object->inherits("QPushButton") )
00208     {
00209         if ( e->type() == QEvent::KeyPress )
00210         {
00211             if ( !((QKeyEvent *)e)->isAutoRepeat() )
00212                 d_data->keyPressed = true;
00213         }
00214 
00215         if ( e->type() == QEvent::KeyRelease )
00216         {
00217             if ( !((QKeyEvent *)e)->isAutoRepeat() )
00218             {
00219                 d_data->keyPressed = false;
00220 
00221                 // Unblock key events. They might be blocked
00222                 // to interrupt auto repeat, when we changed
00223                 // the focus to a different button.
00224 
00225                 d_data->blockKeys = false;
00226             }
00227         }
00228     }
00229 
00230     return QWidget::eventFilter(object, e);
00231 }
00232 
00242 void QwtCounter::setIncSteps(QwtCounter::Button btn, int nSteps)
00243 {
00244     if (( btn >= 0) && (btn < ButtonCnt))
00245        d_data->increment[btn] = nSteps;
00246 }
00247 
00254 int QwtCounter::incSteps(QwtCounter::Button btn) const
00255 {
00256     if (( btn >= 0) && (btn < ButtonCnt))
00257        return d_data->increment[btn];
00258 
00259     return 0;
00260 }
00261 
00269 void QwtCounter::setValue(double v)
00270 {
00271     QwtDoubleRange::setValue(v);
00272 
00273     showNum(value());
00274     updateButtons();
00275 }
00276 
00280 void QwtCounter::valueChange()
00281 {
00282     if ( isValid() )
00283         showNum(value());
00284     else
00285         d_data->valueEdit->setText(QString::null);
00286 
00287     updateButtons();
00288 
00289     if ( isValid() )
00290         emit valueChanged(value());
00291 }
00292 
00301 void QwtCounter::updateButtons()
00302 {
00303     if ( isValid() )
00304     {
00305         // 1. save enabled state of the smallest down- and up-button
00306         // 2. change enabled state on under- or over-flow
00307         // 3. switch focus if the enabled state has changed
00308 
00309         int oldEnabledDown = d_data->buttonDown[0]->isEnabled();
00310         int oldEnabledUp = d_data->buttonUp[0]->isEnabled();
00311 
00312         for ( int i = 0; i < ButtonCnt; i++ )
00313         {
00314             d_data->buttonDown[i]->setEnabled(value() > minValue());
00315             d_data->buttonUp[i]->setEnabled(value() < maxValue());
00316         }
00317 
00318         QPushButton *focusButton = NULL;
00319         if (oldEnabledDown && !d_data->buttonDown[0]->isEnabled())
00320             focusButton = d_data->buttonUp[0];
00321 
00322         if (oldEnabledUp && !d_data->buttonUp[0]->isEnabled())
00323             focusButton = d_data->buttonDown[0];
00324 
00325         if ( focusButton )
00326         {
00327             focusButton->setFocus();
00328             if ( d_data->keyPressed )
00329             {
00330                 // Stop auto repeat until the key has been released 
00331                 d_data->blockKeys = true;
00332             }
00333         }
00334     }
00335     else
00336     {
00337         for ( int i = 0; i < ButtonCnt; i++ )
00338         {
00339             d_data->buttonDown[i]->setEnabled(false);
00340             d_data->buttonUp[i]->setEnabled(false);
00341         }
00342     }
00343 }
00344 
00349 void QwtCounter::setNumButtons(int n)
00350 {
00351     if ( n<0 || n>ButtonCnt )
00352         return;
00353 
00354     for ( int i = 0; i < ButtonCnt; i++ )
00355     {
00356         if ( i < n )
00357         {
00358             d_data->buttonDown[i]->show();
00359             d_data->buttonUp[i]->show();
00360         }
00361         else
00362         {
00363             d_data->buttonDown[i]->hide();
00364             d_data->buttonUp[i]->hide();
00365         }
00366     }
00367 
00368     d_data->nButtons = n;
00369 }
00370 
00374 int QwtCounter::numButtons() const 
00375 { 
00376     return d_data->nButtons; 
00377 }
00378 
00380 void QwtCounter::showNum(double d)
00381 {
00382     QString v;
00383     v.setNum(d);
00384 
00385     d_data->valueEdit->setText(v);
00386     d_data->valueEdit->setCursorPosition(0);
00387 }
00388 
00390 void QwtCounter::btnClicked()
00391 {
00392     if (d_data->blockKeys)
00393     {
00394         // When we set the focus to a different button,
00395         // auto repeat has been stopped until the key will
00396         // be released
00397 
00398         return;
00399     }
00400 
00401     for ( int i = 0; i < ButtonCnt; i++ )
00402     {
00403         if ( d_data->buttonUp[i] == sender() )
00404             incValue(d_data->increment[i]);
00405 
00406         if ( d_data->buttonDown[i] == sender() )
00407             incValue(-d_data->increment[i]);
00408     }
00409 }
00410 
00412 void QwtCounter::btnReleased()
00413 {
00414     emit buttonReleased(value());
00415 }
00416 
00423 void QwtCounter::rangeChange()
00424 {
00425     updateButtons();
00426 }
00427 
00429 QSize QwtCounter::sizeHint() const
00430 {
00431     QString tmp;
00432 
00433     int w = tmp.setNum(minValue()).length();
00434     int w1 = tmp.setNum(maxValue()).length();
00435     if ( w1 > w )
00436         w = w1;
00437     w1 = tmp.setNum(minValue() + step()).length();
00438     if ( w1 > w )
00439         w = w1;
00440     w1 = tmp.setNum(maxValue() - step()).length();
00441     if ( w1 > w )
00442         w = w1;
00443 
00444     tmp.fill('9', w);
00445 
00446     QFontMetrics fm(d_data->valueEdit->font());
00447     w = fm.width(tmp) + 2;
00448 #if QT_VERSION >= 0x040000
00449     if ( d_data->valueEdit->hasFrame() )
00450         w += 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00451 #else
00452     w += 2 * d_data->valueEdit->frameWidth(); 
00453 #endif
00454 
00455     // Now we replace default sizeHint contribution of d_data->valueEdit by
00456     // what we really need.
00457 
00458     w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();
00459 
00460     const int h = qwtMin(QWidget::sizeHint().height(), 
00461         d_data->valueEdit->minimumSizeHint().height());
00462     return QSize(w, h);
00463 }
00464 
00466 double QwtCounter::step() const
00467 {
00468     return QwtDoubleRange::step();
00469 }
00470     
00472 void QwtCounter::setStep(double s)
00473 {
00474     QwtDoubleRange::setStep(s);
00475 }
00476 
00478 double QwtCounter::minVal() const
00479 {
00480     return minValue();
00481 }
00482 
00484 void QwtCounter::setMinValue(double m)
00485 {
00486     setRange(m, maxValue(), step());
00487 }
00488 
00490 double QwtCounter::maxVal() const
00491 {
00492     return QwtDoubleRange::maxValue();
00493 }
00494 
00496 void QwtCounter::setMaxValue(double m)
00497 {
00498     setRange(minValue(), m, step());
00499 }
00500 
00502 void QwtCounter::setStepButton1(int nSteps)
00503 {
00504     setIncSteps(Button1, nSteps);
00505 }
00506 
00508 int QwtCounter::stepButton1() const
00509 {
00510     return incSteps(Button1);
00511 }
00512 
00514 void QwtCounter::setStepButton2(int nSteps)
00515 {
00516     setIncSteps(Button2, nSteps);
00517 }
00518 
00520 int QwtCounter::stepButton2() const
00521 {
00522     return incSteps(Button2);
00523 }
00524 
00526 void QwtCounter::setStepButton3(int nSteps)
00527 {
00528     setIncSteps(Button3, nSteps);
00529 }
00530 
00532 int QwtCounter::stepButton3() const
00533 {
00534     return incSteps(Button3);
00535 }
00536 
00537 double QwtCounter::value() const
00538 {
00539     return QwtDoubleRange::value();
00540 }
00541 

Generated on Wed Aug 31 23:02:29 2005 for Qwt User's Guide by  doxygen 1.4.1