地面站终端 App
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

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():
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):
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):
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;
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
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);
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()));
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;
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
void QwtCounter::textChanged()
15 years ago
{
if ( !d_data->editable )
15 years ago
return;
bool converted = false;
const double value = d_data->valueEdit->text().toDouble(&converted);
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
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)
bool QwtCounter::editable() const
{
15 years ago
return d_data->editable;
}
/*!
Handle PolishRequest events
15 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;
switch ( e->key() ) {
case Qt::Key_Home:
15 years ago
#if QT_VERSION >= 0x040000
if ( e->modifiers() & Qt::ControlModifier )
15 years ago
#else
if ( e->state() & Qt::ControlButton )
15 years ago
#endif
setValue(minValue());
else
accepted = false;
break;
case Qt::Key_End:
15 years ago
#if QT_VERSION >= 0x040000
if ( e->modifiers() & Qt::ControlModifier )
15 years ago
#else
if ( e->state() & Qt::ControlButton )
15 years ago
#endif
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
if ( e->modifiers() & Qt::ShiftModifier )
15 years ago
#else
if ( e->state() & Qt::ShiftButton )
15 years ago
#endif
increment = d_data->increment[2];
15 years ago
}
if ( e->key() == Qt::Key_PageDown )
increment = -increment;
incValue(increment);
break;
}
default:
accepted = false;
15 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];
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];
}
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];
}
for ( int i = 0; i < d_data->nButtons; i++ ) {
15 years ago
if ( d_data->buttonDown[i]->geometry().contains(e->pos()) ||
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))
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))
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()
{
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
for ( int i = 0; i < ButtonCnt; i++ ) {
15 years ago
d_data->buttonDown[i]->setEnabled(value() > minValue());
d_data->buttonUp[i]->setEnabled(value() < maxValue());
}
} 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;
for ( int i = 0; i < ButtonCnt; i++ ) {
if ( i < n ) {
15 years ago
d_data->buttonDown[i]->show();
d_data->buttonUp[i]->show();
} 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.
*/
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()
{
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
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();
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();
}
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();
}