You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
604 lines
14 KiB
604 lines
14 KiB
15 years ago
|
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
||
|
* Qwt Widget Library
|
||
|
* Copyright (C) 1997 Josef Wilgen
|
||
|
* Copyright (C) 2002 Uwe Rathmann
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the Qwt License, Version 1.0
|
||
|
*****************************************************************************/
|
||
|
|
||
|
// vim: expandtab
|
||
|
|
||
|
#include <qlayout.h>
|
||
|
#include <qlineedit.h>
|
||
|
#include <qvalidator.h>
|
||
|
#include <qevent.h>
|
||
|
#include <qstyle.h>
|
||
|
#include "qwt_math.h"
|
||
|
#include "qwt_counter.h"
|
||
|
#include "qwt_arrow_button.h"
|
||
|
|
||
|
class QwtCounter::PrivateData
|
||
|
{
|
||
|
public:
|
||
|
PrivateData():
|
||
14 years ago
|
editable(true) {
|
||
15 years ago
|
increment[Button1] = 1;
|
||
|
increment[Button2] = 10;
|
||
|
increment[Button3] = 100;
|
||
|
}
|
||
|
|
||
|
QwtArrowButton *buttonDown[ButtonCnt];
|
||
|
QwtArrowButton *buttonUp[ButtonCnt];
|
||
|
QLineEdit *valueEdit;
|
||
|
|
||
|
int increment[ButtonCnt];
|
||
|
int nButtons;
|
||
|
|
||
|
bool editable;
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
The default number of buttons is set to 2. The default increments are:
|
||
|
\li Button 1: 1 step
|
||
|
\li Button 2: 10 steps
|
||
|
\li Button 3: 100 steps
|
||
|
|
||
|
\param parent
|
||
|
*/
|
||
|
QwtCounter::QwtCounter(QWidget *parent):
|
||
14 years ago
|
QWidget(parent)
|
||
15 years ago
|
{
|
||
|
initCounter();
|
||
|
}
|
||
|
|
||
|
#if QT_VERSION < 0x040000
|
||
|
/*!
|
||
|
The default number of buttons is set to 2. The default increments are:
|
||
|
\li Button 1: 1 step
|
||
|
\li Button 2: 10 steps
|
||
|
\li Button 3: 100 steps
|
||
|
|
||
|
\param parent
|
||
|
*/
|
||
|
QwtCounter::QwtCounter(QWidget *parent, const char *name):
|
||
14 years ago
|
QWidget(parent, name)
|
||
15 years ago
|
{
|
||
|
initCounter();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void QwtCounter::initCounter()
|
||
|
{
|
||
|
d_data = new PrivateData;
|
||
|
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
using namespace Qt;
|
||
|
#endif
|
||
|
|
||
|
QHBoxLayout *layout = new QHBoxLayout(this);
|
||
|
layout->setSpacing(0);
|
||
|
layout->setMargin(0);
|
||
|
|
||
|
int i;
|
||
14 years ago
|
for(i = ButtonCnt - 1; i >= 0; i--) {
|
||
15 years ago
|
QwtArrowButton *btn =
|
||
|
new QwtArrowButton(i+1, Qt::DownArrow,this);
|
||
|
btn->setFocusPolicy(NoFocus);
|
||
|
btn->installEventFilter(this);
|
||
|
layout->addWidget(btn);
|
||
|
|
||
|
connect(btn, SIGNAL(released()), SLOT(btnReleased()));
|
||
|
connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
|
||
|
|
||
|
d_data->buttonDown[i] = btn;
|
||
|
}
|
||
|
|
||
|
d_data->valueEdit = new QLineEdit(this);
|
||
|
d_data->valueEdit->setReadOnly(false);
|
||
|
d_data->valueEdit->setValidator(new QDoubleValidator(d_data->valueEdit));
|
||
|
layout->addWidget(d_data->valueEdit);
|
||
|
|
||
|
#if QT_VERSION >= 0x040000
|
||
14 years ago
|
connect( d_data->valueEdit, SIGNAL(editingFinished()),
|
||
|
SLOT(textChanged()) );
|
||
15 years ago
|
#else
|
||
|
connect( d_data->valueEdit, SIGNAL(returnPressed()), SLOT(textChanged()) );
|
||
|
connect( d_data->valueEdit, SIGNAL(lostFocus()), SLOT(textChanged()) );
|
||
|
#endif
|
||
|
|
||
|
layout->setStretchFactor(d_data->valueEdit, 10);
|
||
|
|
||
14 years ago
|
for(i = 0; i < ButtonCnt; i++) {
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
|
using namespace Qt;
|
||
|
#endif
|
||
|
QwtArrowButton *btn =
|
||
|
new QwtArrowButton(i+1, Qt::UpArrow, this);
|
||
|
btn->setFocusPolicy(NoFocus);
|
||
|
btn->installEventFilter(this);
|
||
|
layout->addWidget(btn);
|
||
|
|
||
|
connect(btn, SIGNAL(released()), SLOT(btnReleased()));
|
||
|
connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
|
||
14 years ago
|
|
||
15 years ago
|
d_data->buttonUp[i] = btn;
|
||
|
}
|
||
|
|
||
|
setNumButtons(2);
|
||
|
setRange(0.0,1.0,0.001);
|
||
|
setValue(0.0);
|
||
|
|
||
|
setSizePolicy(
|
||
|
QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
|
||
|
|
||
|
setFocusProxy(d_data->valueEdit);
|
||
|
setFocusPolicy(StrongFocus);
|
||
|
}
|
||
|
|
||
|
//! Destructor
|
||
|
QwtCounter::~QwtCounter()
|
||
|
{
|
||
|
delete d_data;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Sets the minimum width for the buttons
|
||
|
*/
|
||
|
void QwtCounter::polish()
|
||
|
{
|
||
|
const int w = d_data->valueEdit->fontMetrics().width("W") + 8;
|
||
|
|
||
14 years ago
|
for ( int i = 0; i < ButtonCnt; i++ ) {
|
||
15 years ago
|
d_data->buttonDown[i]->setMinimumWidth(w);
|
||
|
d_data->buttonUp[i]->setMinimumWidth(w);
|
||
|
}
|
||
|
|
||
|
#if QT_VERSION < 0x040000
|
||
|
QWidget::polish();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//! Set from lineedit
|
||
14 years ago
|
void QwtCounter::textChanged()
|
||
15 years ago
|
{
|
||
14 years ago
|
if ( !d_data->editable )
|
||
15 years ago
|
return;
|
||
|
|
||
|
bool converted = false;
|
||
|
|
||
|
const double value = d_data->valueEdit->text().toDouble(&converted);
|
||
14 years ago
|
if ( converted )
|
||
|
setValue( value );
|
||
15 years ago
|
}
|
||
|
|
||
|
/**
|
||
|
\brief Allow/disallow the user to manually edit the value
|
||
|
|
||
|
\param editable true enables editing
|
||
|
\sa editable()
|
||
|
*/
|
||
|
void QwtCounter::setEditable(bool editable)
|
||
|
{
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
using namespace Qt;
|
||
|
#endif
|
||
14 years ago
|
if ( editable == d_data->editable )
|
||
15 years ago
|
return;
|
||
|
|
||
|
d_data->editable = editable;
|
||
|
d_data->valueEdit->setReadOnly(!editable);
|
||
|
}
|
||
|
|
||
|
//! returns whether the line edit is edatble. (default is yes)
|
||
14 years ago
|
bool QwtCounter::editable() const
|
||
|
{
|
||
15 years ago
|
return d_data->editable;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
14 years ago
|
Handle PolishRequest events
|
||
15 years ago
|
*/
|
||
14 years ago
|
bool QwtCounter::event ( QEvent * e )
|
||
15 years ago
|
{
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
if ( e->type() == QEvent::PolishRequest )
|
||
|
polish();
|
||
|
#endif
|
||
|
return QWidget::event(e);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Handles key events
|
||
|
|
||
|
- Ctrl + Qt::Key_Home
|
||
|
Step to minValue()
|
||
|
- Ctrl + Qt::Key_End
|
||
|
Step to maxValue()
|
||
|
- Qt::Key_Up
|
||
|
Increment by incSteps(QwtCounter::Button1)
|
||
|
- Qt::Key_Down
|
||
|
Decrement by incSteps(QwtCounter::Button1)
|
||
|
- Qt::Key_PageUp
|
||
|
Increment by incSteps(QwtCounter::Button2)
|
||
|
- Qt::Key_PageDown
|
||
|
Decrement by incSteps(QwtCounter::Button2)
|
||
|
- Shift + Qt::Key_PageUp
|
||
|
Increment by incSteps(QwtCounter::Button3)
|
||
|
- Shift + Qt::Key_PageDown
|
||
|
Decrement by incSteps(QwtCounter::Button3)
|
||
|
*/
|
||
|
|
||
|
void QwtCounter::keyPressEvent (QKeyEvent *e)
|
||
|
{
|
||
|
bool accepted = true;
|
||
|
|
||
14 years ago
|
switch ( e->key() ) {
|
||
|
case Qt::Key_Home:
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
14 years ago
|
if ( e->modifiers() & Qt::ControlModifier )
|
||
15 years ago
|
#else
|
||
14 years ago
|
if ( e->state() & Qt::ControlButton )
|
||
15 years ago
|
#endif
|
||
14 years ago
|
setValue(minValue());
|
||
|
else
|
||
|
accepted = false;
|
||
|
break;
|
||
|
case Qt::Key_End:
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
14 years ago
|
if ( e->modifiers() & Qt::ControlModifier )
|
||
15 years ago
|
#else
|
||
14 years ago
|
if ( e->state() & Qt::ControlButton )
|
||
15 years ago
|
#endif
|
||
14 years ago
|
setValue(maxValue());
|
||
|
else
|
||
|
accepted = false;
|
||
|
break;
|
||
|
case Qt::Key_Up:
|
||
|
incValue(d_data->increment[0]);
|
||
|
break;
|
||
|
case Qt::Key_Down:
|
||
|
incValue(-d_data->increment[0]);
|
||
|
break;
|
||
|
case Qt::Key_PageUp:
|
||
|
case Qt::Key_PageDown: {
|
||
|
int increment = d_data->increment[0];
|
||
|
if ( d_data->nButtons >= 2 )
|
||
|
increment = d_data->increment[1];
|
||
|
if ( d_data->nButtons >= 3 ) {
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
14 years ago
|
if ( e->modifiers() & Qt::ShiftModifier )
|
||
15 years ago
|
#else
|
||
14 years ago
|
if ( e->state() & Qt::ShiftButton )
|
||
15 years ago
|
#endif
|
||
14 years ago
|
increment = d_data->increment[2];
|
||
15 years ago
|
}
|
||
14 years ago
|
if ( e->key() == Qt::Key_PageDown )
|
||
|
increment = -increment;
|
||
|
incValue(increment);
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
accepted = false;
|
||
15 years ago
|
}
|
||
|
|
||
14 years ago
|
if ( accepted ) {
|
||
15 years ago
|
e->accept();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
QWidget::keyPressEvent (e);
|
||
|
}
|
||
|
|
||
|
void QwtCounter::wheelEvent(QWheelEvent *e)
|
||
|
{
|
||
|
e->accept();
|
||
|
|
||
|
if ( d_data->nButtons <= 0 )
|
||
|
return;
|
||
|
|
||
|
int increment = d_data->increment[0];
|
||
14 years ago
|
if ( d_data->nButtons >= 2 ) {
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
|
if ( e->modifiers() & Qt::ControlModifier )
|
||
|
#else
|
||
|
if ( e->state() & Qt::ControlButton )
|
||
|
#endif
|
||
|
increment = d_data->increment[1];
|
||
|
}
|
||
14 years ago
|
if ( d_data->nButtons >= 3 ) {
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
|
if ( e->modifiers() & Qt::ShiftModifier )
|
||
|
#else
|
||
|
if ( e->state() & Qt::ShiftButton )
|
||
|
#endif
|
||
|
increment = d_data->increment[2];
|
||
|
}
|
||
14 years ago
|
|
||
|
for ( int i = 0; i < d_data->nButtons; i++ ) {
|
||
15 years ago
|
if ( d_data->buttonDown[i]->geometry().contains(e->pos()) ||
|
||
14 years ago
|
d_data->buttonUp[i]->geometry().contains(e->pos()) ) {
|
||
15 years ago
|
increment = d_data->increment[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const int wheel_delta = 120;
|
||
|
|
||
|
int delta = e->delta();
|
||
|
if ( delta >= 2 * wheel_delta )
|
||
|
delta /= 2; // Never saw an abs(delta) < 240
|
||
|
|
||
|
incValue(delta / wheel_delta * increment);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Specify the number of steps by which the value
|
||
|
is incremented or decremented when a specified button
|
||
|
is pushed.
|
||
|
|
||
|
\param btn One of \c QwtCounter::Button1, \c QwtCounter::Button2,
|
||
|
\c QwtCounter::Button3
|
||
|
\param nSteps Number of steps
|
||
|
*/
|
||
|
void QwtCounter::setIncSteps(QwtCounter::Button btn, int nSteps)
|
||
|
{
|
||
|
if (( btn >= 0) && (btn < ButtonCnt))
|
||
14 years ago
|
d_data->increment[btn] = nSteps;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
\return the number of steps by which a specified button increments the value
|
||
|
or 0 if the button is invalid.
|
||
|
\param btn One of \c QwtCounter::Button1, \c QwtCounter::Button2,
|
||
|
\c QwtCounter::Button3
|
||
|
*/
|
||
|
int QwtCounter::incSteps(QwtCounter::Button btn) const
|
||
|
{
|
||
|
if (( btn >= 0) && (btn < ButtonCnt))
|
||
14 years ago
|
return d_data->increment[btn];
|
||
15 years ago
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Set a new value
|
||
|
\param v new value
|
||
|
Calls QwtDoubleRange::setValue and does all visual updates.
|
||
|
\sa QwtDoubleRange::setValue
|
||
|
*/
|
||
|
|
||
|
void QwtCounter::setValue(double v)
|
||
|
{
|
||
|
QwtDoubleRange::setValue(v);
|
||
|
|
||
|
showNum(value());
|
||
|
updateButtons();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Notify a change of value
|
||
|
*/
|
||
|
void QwtCounter::valueChange()
|
||
|
{
|
||
|
if ( isValid() )
|
||
|
showNum(value());
|
||
|
else
|
||
|
d_data->valueEdit->setText(QString::null);
|
||
|
|
||
|
updateButtons();
|
||
|
|
||
|
if ( isValid() )
|
||
|
emit valueChanged(value());
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Update buttons according to the current value
|
||
|
|
||
|
When the QwtCounter under- or over-flows, the focus is set to the smallest
|
||
|
up- or down-button and counting is disabled.
|
||
|
|
||
|
Counting is re-enabled on a button release event (mouse or space bar).
|
||
|
*/
|
||
|
void QwtCounter::updateButtons()
|
||
|
{
|
||
14 years ago
|
if ( isValid() ) {
|
||
15 years ago
|
// 1. save enabled state of the smallest down- and up-button
|
||
|
// 2. change enabled state on under- or over-flow
|
||
|
|
||
14 years ago
|
for ( int i = 0; i < ButtonCnt; i++ ) {
|
||
15 years ago
|
d_data->buttonDown[i]->setEnabled(value() > minValue());
|
||
|
d_data->buttonUp[i]->setEnabled(value() < maxValue());
|
||
|
}
|
||
14 years ago
|
} else {
|
||
|
for ( int i = 0; i < ButtonCnt; i++ ) {
|
||
15 years ago
|
d_data->buttonDown[i]->setEnabled(false);
|
||
|
d_data->buttonUp[i]->setEnabled(false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Specify the number of buttons on each side of the label
|
||
|
\param n Number of buttons
|
||
|
*/
|
||
|
void QwtCounter::setNumButtons(int n)
|
||
|
{
|
||
|
if ( n<0 || n>ButtonCnt )
|
||
|
return;
|
||
|
|
||
14 years ago
|
for ( int i = 0; i < ButtonCnt; i++ ) {
|
||
|
if ( i < n ) {
|
||
15 years ago
|
d_data->buttonDown[i]->show();
|
||
|
d_data->buttonUp[i]->show();
|
||
14 years ago
|
} else {
|
||
15 years ago
|
d_data->buttonDown[i]->hide();
|
||
|
d_data->buttonUp[i]->hide();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
d_data->nButtons = n;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return The number of buttons on each side of the widget.
|
||
|
*/
|
||
14 years ago
|
int QwtCounter::numButtons() const
|
||
|
{
|
||
|
return d_data->nButtons;
|
||
15 years ago
|
}
|
||
|
|
||
|
//! Display number string
|
||
|
void QwtCounter::showNum(double d)
|
||
|
{
|
||
|
QString v;
|
||
|
v.setNum(d);
|
||
|
|
||
|
const int cursorPos = d_data->valueEdit->cursorPosition();
|
||
|
d_data->valueEdit->setText(v);
|
||
|
d_data->valueEdit->setCursorPosition(cursorPos);
|
||
|
}
|
||
|
|
||
|
//! Button clicked
|
||
|
void QwtCounter::btnClicked()
|
||
|
{
|
||
14 years ago
|
for ( int i = 0; i < ButtonCnt; i++ ) {
|
||
15 years ago
|
if ( d_data->buttonUp[i] == sender() )
|
||
|
incValue(d_data->increment[i]);
|
||
|
|
||
|
if ( d_data->buttonDown[i] == sender() )
|
||
|
incValue(-d_data->increment[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//! Button released
|
||
|
void QwtCounter::btnReleased()
|
||
|
{
|
||
|
emit buttonReleased(value());
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Notify change of range
|
||
|
|
||
|
This function updates the enabled property of
|
||
|
all buttons contained in QwtCounter.
|
||
|
*/
|
||
|
void QwtCounter::rangeChange()
|
||
|
{
|
||
|
updateButtons();
|
||
|
}
|
||
|
|
||
|
//! A size hint
|
||
|
QSize QwtCounter::sizeHint() const
|
||
|
{
|
||
|
QString tmp;
|
||
|
|
||
|
int w = tmp.setNum(minValue()).length();
|
||
|
int w1 = tmp.setNum(maxValue()).length();
|
||
|
if ( w1 > w )
|
||
|
w = w1;
|
||
|
w1 = tmp.setNum(minValue() + step()).length();
|
||
|
if ( w1 > w )
|
||
|
w = w1;
|
||
|
w1 = tmp.setNum(maxValue() - step()).length();
|
||
|
if ( w1 > w )
|
||
|
w = w1;
|
||
|
|
||
|
tmp.fill('9', w);
|
||
|
|
||
|
QFontMetrics fm(d_data->valueEdit->font());
|
||
|
w = fm.width(tmp) + 2;
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
if ( d_data->valueEdit->hasFrame() )
|
||
|
w += 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||
|
#else
|
||
14 years ago
|
w += 2 * d_data->valueEdit->frameWidth();
|
||
15 years ago
|
#endif
|
||
|
|
||
|
// Now we replace default sizeHint contribution of d_data->valueEdit by
|
||
|
// what we really need.
|
||
|
|
||
|
w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();
|
||
|
|
||
14 years ago
|
const int h = qwtMin(QWidget::sizeHint().height(),
|
||
|
d_data->valueEdit->minimumSizeHint().height());
|
||
15 years ago
|
return QSize(w, h);
|
||
|
}
|
||
|
|
||
|
//! returns the step size
|
||
|
double QwtCounter::step() const
|
||
|
{
|
||
|
return QwtDoubleRange::step();
|
||
|
}
|
||
14 years ago
|
|
||
15 years ago
|
//! sets the step size
|
||
|
void QwtCounter::setStep(double s)
|
||
|
{
|
||
|
QwtDoubleRange::setStep(s);
|
||
|
}
|
||
|
|
||
|
//! returns the minimum value of the range
|
||
|
double QwtCounter::minVal() const
|
||
|
{
|
||
|
return minValue();
|
||
|
}
|
||
|
|
||
|
//! sets the minimum value of the range
|
||
|
void QwtCounter::setMinValue(double m)
|
||
|
{
|
||
|
setRange(m, maxValue(), step());
|
||
|
}
|
||
|
|
||
|
//! returns the maximum value of the range
|
||
|
double QwtCounter::maxVal() const
|
||
|
{
|
||
|
return QwtDoubleRange::maxValue();
|
||
|
}
|
||
|
|
||
|
//! sets the maximum value of the range
|
||
|
void QwtCounter::setMaxValue(double m)
|
||
|
{
|
||
|
setRange(minValue(), m, step());
|
||
|
}
|
||
|
|
||
|
//! set the number of increment steps for button 1
|
||
|
void QwtCounter::setStepButton1(int nSteps)
|
||
|
{
|
||
|
setIncSteps(Button1, nSteps);
|
||
|
}
|
||
|
|
||
|
//! returns the number of increment steps for button 1
|
||
|
int QwtCounter::stepButton1() const
|
||
|
{
|
||
|
return incSteps(Button1);
|
||
|
}
|
||
|
|
||
|
//! set the number of increment steps for button 2
|
||
|
void QwtCounter::setStepButton2(int nSteps)
|
||
|
{
|
||
|
setIncSteps(Button2, nSteps);
|
||
|
}
|
||
|
|
||
|
//! returns the number of increment steps for button 2
|
||
|
int QwtCounter::stepButton2() const
|
||
|
{
|
||
|
return incSteps(Button2);
|
||
|
}
|
||
|
|
||
|
//! set the number of increment steps for button 3
|
||
|
void QwtCounter::setStepButton3(int nSteps)
|
||
|
{
|
||
|
setIncSteps(Button3, nSteps);
|
||
|
}
|
||
|
|
||
|
//! returns the number of increment steps for button 3
|
||
|
int QwtCounter::stepButton3() const
|
||
|
{
|
||
|
return incSteps(Button3);
|
||
|
}
|
||
|
|
||
|
double QwtCounter::value() const
|
||
|
{
|
||
|
return QwtDoubleRange::value();
|
||
|
}
|
||
|
|