Skip to content
qwt_counter.cpp 17.5 KiB
Newer Older
pixhawk's avatar
pixhawk committed
/* -*- 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
 *****************************************************************************/

Bryant's avatar
Bryant committed
#include "qwt_arrow_button.h"
#include "qwt_math.h"
#include "qwt_counter.h"
pixhawk's avatar
pixhawk committed
#include <qlayout.h>
#include <qlineedit.h>
#include <qvalidator.h>
#include <qevent.h>
#include <qstyle.h>

class QwtCounter::PrivateData
{
public:
    PrivateData():
Bryant's avatar
Bryant committed
        minimum( 0.0 ),
        maximum( 0.0 ),
        singleStep( 1.0 ),
        isValid( false ),
        value( 0.0 ),
        wrapping( false )
    {
pixhawk's avatar
pixhawk committed
        increment[Button1] = 1;
        increment[Button2] = 10;
        increment[Button3] = 100;
    }

    QwtArrowButton *buttonDown[ButtonCnt];
    QwtArrowButton *buttonUp[ButtonCnt];
    QLineEdit *valueEdit;

    int increment[ButtonCnt];
Bryant's avatar
Bryant committed
    int numButtons;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    double minimum;
    double maximum;
    double singleStep;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    bool isValid;
    double value;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    bool wrapping;
};
pixhawk's avatar
pixhawk committed

/*!
Bryant's avatar
Bryant committed
  The counter is initialized with a range is set to [0.0, 1.0] with 
  0.01 as single step size. The value is invalid.

pixhawk's avatar
pixhawk committed
  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
 */
Bryant's avatar
Bryant committed
QwtCounter::QwtCounter( QWidget *parent ):
    QWidget( parent )
pixhawk's avatar
pixhawk committed
{
    initCounter();
}

void QwtCounter::initCounter()
{
    d_data = new PrivateData;

Bryant's avatar
Bryant committed
    QHBoxLayout *layout = new QHBoxLayout( this );
    layout->setSpacing( 0 );
    layout->setMargin( 0 );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    for ( int i = ButtonCnt - 1; i >= 0; i-- )
    {
pixhawk's avatar
pixhawk committed
        QwtArrowButton *btn =
Bryant's avatar
Bryant committed
            new QwtArrowButton( i + 1, Qt::DownArrow, this );
        btn->setFocusPolicy( Qt::NoFocus );
        btn->installEventFilter( this );
        layout->addWidget( btn );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
        connect( btn, SIGNAL( released() ), SLOT( btnReleased() ) );
        connect( btn, SIGNAL( clicked() ), SLOT( btnClicked() ) );
pixhawk's avatar
pixhawk committed

        d_data->buttonDown[i] = btn;
    }

Bryant's avatar
Bryant committed
    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 );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    connect( d_data->valueEdit, SIGNAL( editingFinished() ),
         SLOT( textChanged() ) );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    layout->setStretchFactor( d_data->valueEdit, 10 );

    for ( int i = 0; i < ButtonCnt; i++ )
    {
pixhawk's avatar
pixhawk committed
        QwtArrowButton *btn =
Bryant's avatar
Bryant committed
            new QwtArrowButton( i + 1, Qt::UpArrow, this );
        btn->setFocusPolicy( Qt::NoFocus );
        btn->installEventFilter( this );
        layout->addWidget( btn );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
        connect( btn, SIGNAL( released() ), SLOT( btnReleased() ) );
        connect( btn, SIGNAL( clicked() ), SLOT( btnClicked() ) );
pixhawk's avatar
pixhawk committed
        d_data->buttonUp[i] = btn;
    }

Bryant's avatar
Bryant committed
    setNumButtons( 2 );
    setRange( 0.0, 1.0 );
    setSingleStep( 0.001 );
    setValue( 0.0 );
pixhawk's avatar
pixhawk committed

    setSizePolicy(
Bryant's avatar
Bryant committed
        QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    setFocusProxy( d_data->valueEdit );
    setFocusPolicy( Qt::StrongFocus );
pixhawk's avatar
pixhawk committed
}

//! Destructor
QwtCounter::~QwtCounter()
{
    delete d_data;
}

Bryant's avatar
Bryant committed
/*! 
  Set the counter to be in valid/invalid state

  When the counter is set to invalid, no numbers are displayed and
  the buttons are disabled.

  \param on If true the counter will be set as valid 

  \sa setValue(), isValid()
*/
void QwtCounter::setValid( bool on )
{
    if ( on != d_data->isValid )
    {
        d_data->isValid = on;

        updateButtons();

        if ( d_data->isValid )
        {
            showNumber( value() );
            Q_EMIT valueChanged( value() );
        }
        else
        {
            d_data->valueEdit->setText( QString::null );
        }
    }   
}   

/*! 
  \return True, if the value is valid
  \sa setValid(), setValue()
 */
bool QwtCounter::isValid() const
{
    return d_data->isValid;
}   

/*!
  \brief Allow/disallow the user to manually edit the value

  \param on True disable editing
  \sa isReadOnly()
*/
void QwtCounter::setReadOnly( bool on )
{
    d_data->valueEdit->setReadOnly( on );
}

/*! 
   \return True, when the line line edit is read only. (default is no)
  \sa setReadOnly()
 */
bool QwtCounter::isReadOnly() const
{
    return d_data->valueEdit->isReadOnly();
}

pixhawk's avatar
pixhawk committed
/*!
Bryant's avatar
Bryant committed
  \brief Set a new value without adjusting to the step raster

  The state of the counter is set to be valid.

  \param value New value

  \sa isValid(), value(), valueChanged()
  \warning The value is clipped when it lies outside the range.
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed

void QwtCounter::setValue( double value )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    const double vmin = qMin( d_data->minimum, d_data->maximum );
    const double vmax = qMax( d_data->minimum, d_data->maximum );

    value = qBound( vmin, value, vmax );

    if ( !d_data->isValid || value != d_data->value )
    {
        d_data->isValid = true;
        d_data->value = value;

        showNumber( value );
        updateButtons();
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
        Q_EMIT valueChanged( value );
pixhawk's avatar
pixhawk committed
    }
Bryant's avatar
Bryant committed
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  \return Current value of the counter
  \sa setValue(), valueChanged()
 */
double QwtCounter::value() const
{
    return d_data->value;
pixhawk's avatar
pixhawk committed
}

Bryant's avatar
Bryant committed
/*!
  \brief Set the minimum and maximum values

  The maximum is adjusted if necessary to ensure that the range remains valid.
  The value might be modified to be inside of the range.

  \param min Minimum value
  \param max Maximum value

  \sa minimum(), maximum()
 */
void QwtCounter::setRange( double min, double max )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    max = qMax( min, max );

    if ( d_data->maximum == max && d_data->minimum == min )
pixhawk's avatar
pixhawk committed
        return;

Bryant's avatar
Bryant committed
    d_data->minimum = min;
    d_data->maximum = max;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    setSingleStep( singleStep() );

    const double value = qBound( min, d_data->value, max );

    if ( value != d_data->value )
    {
        d_data->value = value;

        if ( d_data->isValid )
        {
            showNumber( value );
            Q_EMIT valueChanged( value );
        }
    }

    updateButtons();
pixhawk's avatar
pixhawk committed
}

Bryant's avatar
Bryant committed
/*!
  Set the minimum value of the range
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param value Minimum value
  \sa setRange(), setMaximum(), minimum()

  \note The maximum is adjusted if necessary to ensure that the range remains valid.
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::setMinimum( double value )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    setRange( value, maximum() );
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  \return The minimum of the range
  \sa setRange(), setMinimum(), maximum()
*/
double QwtCounter::minimum() const
{
    return d_data->minimum;
pixhawk's avatar
pixhawk committed
}

Bryant's avatar
Bryant committed
/*!
  Set the maximum value of the range

  \param value Maximum value
  \sa setRange(), setMinimum(), maximum()
*/
void QwtCounter::setMaximum( double value )
Bryant's avatar
Bryant committed
    setRange( minimum(), value );
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \return The maximum of the range
  \sa setRange(), setMaximum(), minimum()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
double QwtCounter::maximum() const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    return d_data->maximum;
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \brief Set the step size of the counter
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  A value <= 0.0 disables stepping

  \param stepSize Single step size
  \sa singleStep()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::setSingleStep( double stepSize )
{
    d_data->singleStep = qMax( stepSize, 0.0 );
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  \return Single step size
  \sa setSingleStep()
 */
double QwtCounter::singleStep() const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    return d_data->singleStep;
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  \brief En/Disable wrapping
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  If wrapping is true stepping up from maximum() value will take 
  you to the minimum() value and vice versa. 
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param on En/Disable wrapping
  \sa wrapping()
 */
void QwtCounter::setWrapping( bool on )
{
    d_data->wrapping = on;
pixhawk's avatar
pixhawk committed
}

Bryant's avatar
Bryant committed
/*!
  \return True, when wrapping is set
  \sa setWrapping()
 */
bool QwtCounter::wrapping() const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    return d_data->wrapping;
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  Specify the number of buttons on each side of the label
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param numButtons Number of buttons
  \sa numButtons()
*/
void QwtCounter::setNumButtons( int numButtons )
{
    if ( numButtons < 0 || numButtons > QwtCounter::ButtonCnt )
        return;
Bryant's avatar
Bryant committed
    for ( int i = 0; i < QwtCounter::ButtonCnt; i++ )
    {
        if ( i < numButtons )
        {
            d_data->buttonDown[i]->show();
            d_data->buttonUp[i]->show();
        }
        else
        {
            d_data->buttonDown[i]->hide();
            d_data->buttonUp[i]->hide();
pixhawk's avatar
pixhawk committed
        }
    }

Bryant's avatar
Bryant committed
    d_data->numButtons = numButtons;
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  \return The number of buttons on each side of the widget.
  \sa setNumButtons()
*/
int QwtCounter::numButtons() const
{
    return d_data->numButtons;
pixhawk's avatar
pixhawk committed
}

/*!
  Specify the number of steps by which the value
  is incremented or decremented when a specified button
  is pushed.

Bryant's avatar
Bryant committed
  \param button Button index
  \param numSteps Number of steps

  \sa incSteps()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::setIncSteps( QwtCounter::Button button, int numSteps )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( button >= 0 && button < QwtCounter::ButtonCnt )
        d_data->increment[ button ] = numSteps;
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \return The number of steps by which a specified button increments the value
          or 0 if the button is invalid.
  \param button Button index

  \sa setIncSteps()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
int QwtCounter::incSteps( QwtCounter::Button button ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( button >= 0 && button < QwtCounter::ButtonCnt )
        return d_data->increment[ button ];
pixhawk's avatar
pixhawk committed

    return 0;
}

Bryant's avatar
Bryant committed

pixhawk's avatar
pixhawk committed
/*!
Bryant's avatar
Bryant committed
  Set the number of increment steps for button 1
  \param nSteps Number of steps
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::setStepButton1( int nSteps )
{
    setIncSteps( QwtCounter::Button1, nSteps );
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
//! returns the number of increment steps for button 1
int QwtCounter::stepButton1() const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    return incSteps( QwtCounter::Button1 );
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
  Set the number of increment steps for button 2
  \param nSteps Number of steps
*/
void QwtCounter::setStepButton2( int nSteps )
{
    setIncSteps( QwtCounter::Button2, nSteps );
}

//! returns the number of increment steps for button 2
int QwtCounter::stepButton2() const
{
    return incSteps( QwtCounter::Button2 );
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  Set the number of increment steps for button 3
  \param nSteps Number of steps
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::setStepButton3( int nSteps )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    setIncSteps( QwtCounter::Button3, nSteps );
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
//! returns the number of increment steps for button 3
int QwtCounter::stepButton3() const
{
    return incSteps( QwtCounter::Button3 );
}

//! Set from lineedit
void QwtCounter::textChanged()
{
    bool converted = false;

    const double value = d_data->valueEdit->text().toDouble( &converted );
    if ( converted )
        setValue( value );
}
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
/*!
   Handle QEvent::PolishRequest events
   \param event Event
   \return see QWidget::event()
*/
bool QwtCounter::event( QEvent *event )
{
    if ( event->type() == QEvent::PolishRequest )
    {
        const int w = d_data->valueEdit->fontMetrics().width( "W" ) + 8;
        for ( int i = 0; i < ButtonCnt; i++ )
        {
            d_data->buttonDown[i]->setMinimumWidth( w );
            d_data->buttonUp[i]->setMinimumWidth( w );
        }
    }

    return QWidget::event( event );
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  Handle key events
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  - Ctrl + Qt::Key_Home\n
    Step to minimum()
  - Ctrl + Qt::Key_End\n
    Step to maximum()
  - Qt::Key_Up\n
    Increment by incSteps(QwtCounter::Button1)
  - Qt::Key_Down\n
    Decrement by incSteps(QwtCounter::Button1)
  - Qt::Key_PageUp\n
    Increment by incSteps(QwtCounter::Button2)
  - Qt::Key_PageDown\n
    Decrement by incSteps(QwtCounter::Button2)
  - Shift + Qt::Key_PageUp\n
    Increment by incSteps(QwtCounter::Button3)
  - Shift + Qt::Key_PageDown\n
    Decrement by incSteps(QwtCounter::Button3)
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param event Key event
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::keyPressEvent ( QKeyEvent *event )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    bool accepted = true;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    switch ( event->key() )
    {
        case Qt::Key_Home:
        {
            if ( event->modifiers() & Qt::ControlModifier )
                setValue( minimum() );
            else
                accepted = false;
            break;
        }
        case Qt::Key_End:
        {
            if ( event->modifiers() & Qt::ControlModifier )
                setValue( maximum() );
            else
                accepted = false;
            break;
        }
        case Qt::Key_Up:
        {
            incrementValue( d_data->increment[0] );
            break;
pixhawk's avatar
pixhawk committed
        }
Bryant's avatar
Bryant committed
        case Qt::Key_Down:
        {
            incrementValue( -d_data->increment[0] );
            break;
        }
        case Qt::Key_PageUp:
        case Qt::Key_PageDown:
        {
            int increment = d_data->increment[0];
            if ( d_data->numButtons >= 2 )
                increment = d_data->increment[1];
            if ( d_data->numButtons >= 3 )
            {
                if ( event->modifiers() & Qt::ShiftModifier )
                    increment = d_data->increment[2];
            }
            if ( event->key() == Qt::Key_PageDown )
                increment = -increment;
            incrementValue( increment );
            break;
        }
        default:
        {
            accepted = false;
pixhawk's avatar
pixhawk committed
        }
    }
Bryant's avatar
Bryant committed

    if ( accepted )
    {
        event->accept();
        return;
    }

    QWidget::keyPressEvent ( event );
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  Handle wheel events
  \param event Wheel event
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::wheelEvent( QWheelEvent *event )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    event->accept();

    if ( d_data->numButtons <= 0 )
pixhawk's avatar
pixhawk committed
        return;

Bryant's avatar
Bryant committed
    int increment = d_data->increment[0];
    if ( d_data->numButtons >= 2 )
    {
        if ( event->modifiers() & Qt::ControlModifier )
            increment = d_data->increment[1];
    }
    if ( d_data->numButtons >= 3 )
    {
        if ( event->modifiers() & Qt::ShiftModifier )
            increment = d_data->increment[2];
    }

    for ( int i = 0; i < d_data->numButtons; i++ )
    {
        if ( d_data->buttonDown[i]->geometry().contains( event->pos() ) ||
            d_data->buttonUp[i]->geometry().contains( event->pos() ) )
        {
            increment = d_data->increment[i];
        }
    }

    const int wheel_delta = 120;

#if 1
    int delta = event->delta();
    if ( delta >= 2 * wheel_delta )
        delta /= 2; // Never saw an abs(delta) < 240
#endif

    incrementValue( delta / wheel_delta * increment );
}

void QwtCounter::incrementValue( int numSteps )
{
    const double min = d_data->minimum;
    const double max = d_data->maximum;
    double stepSize = d_data->singleStep;

    if ( !d_data->isValid || min >= max || stepSize <= 0.0 )
        return;


#if 1
    stepSize = qMax( stepSize, 1.0e-10 * ( max - min ) );
#endif

    double value = d_data->value + numSteps * stepSize;

    if ( d_data->wrapping )
    {
        const double range = max - min;

        if ( value < min )
        {
            value += ::ceil( ( min - value ) / range ) * range;
pixhawk's avatar
pixhawk committed
        }
Bryant's avatar
Bryant committed
        else if ( value > max )
        {
            value -= ::ceil( ( value - max ) / range ) * range;
        }
    }
    else
    {
        value = qBound( min, value, max );
pixhawk's avatar
pixhawk committed
    }

Bryant's avatar
Bryant committed
    value = min + qRound( ( value - min ) / stepSize ) * stepSize;

    if ( stepSize > 1e-12 )
    {
        if ( qFuzzyCompare( value + 1.0, 1.0 ) )
        {
            // correct rounding error if value = 0
            value = 0.0;
        }
        else if ( qFuzzyCompare( value, max ) )
        {
            // correct rounding error at the border
            value = max;
        }
    }

    if ( value != d_data->value )
    {
        d_data->value = value;
        showNumber( d_data->value );
        updateButtons();

        Q_EMIT valueChanged( d_data->value );
    }
pixhawk's avatar
pixhawk committed
}

Bryant's avatar
Bryant committed

pixhawk's avatar
pixhawk committed
/*!
Bryant's avatar
Bryant committed
  \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).
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtCounter::updateButtons()
Bryant's avatar
Bryant committed
    if ( d_data->isValid )
    {
        // 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 < QwtCounter::ButtonCnt; i++ )
        {
            d_data->buttonDown[i]->setEnabled( value() > minimum() );
            d_data->buttonUp[i]->setEnabled( value() < maximum() );
        }
    }
    else
    {
        for ( int i = 0; i < QwtCounter::ButtonCnt; i++ )
        {
            d_data->buttonDown[i]->setEnabled( false );
            d_data->buttonUp[i]->setEnabled( false );
        }
    }
pixhawk's avatar
pixhawk committed
}
Bryant's avatar
Bryant committed
/*!
  Display number string
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param number Number
*/
void QwtCounter::showNumber( double number )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    QString text;
    text.setNum( number );
pixhawk's avatar
pixhawk committed

    const int cursorPos = d_data->valueEdit->cursorPosition();
Bryant's avatar
Bryant committed
    d_data->valueEdit->setText( text );
    d_data->valueEdit->setCursorPosition( cursorPos );
pixhawk's avatar
pixhawk committed
}

//!  Button clicked
void QwtCounter::btnClicked()
{
Bryant's avatar
Bryant committed
    for ( int i = 0; i < ButtonCnt; i++ )
    {
pixhawk's avatar
pixhawk committed
        if ( d_data->buttonUp[i] == sender() )
Bryant's avatar
Bryant committed
            incrementValue( d_data->increment[i] );
pixhawk's avatar
pixhawk committed

        if ( d_data->buttonDown[i] == sender() )
Bryant's avatar
Bryant committed
            incrementValue( -d_data->increment[i] );
pixhawk's avatar
pixhawk committed
    }
}

//!  Button released
void QwtCounter::btnReleased()
{
Bryant's avatar
Bryant committed
    Q_EMIT buttonReleased( value() );
pixhawk's avatar
pixhawk committed
}

//! A size hint
QSize QwtCounter::sizeHint() const
{
    QString tmp;

Bryant's avatar
Bryant committed
    int w = tmp.setNum( minimum() ).length();
    int w1 = tmp.setNum( maximum() ).length();
pixhawk's avatar
pixhawk committed
    if ( w1 > w )
        w = w1;
Bryant's avatar
Bryant committed
    w1 = tmp.setNum( minimum() + singleStep() ).length();
pixhawk's avatar
pixhawk committed
    if ( w1 > w )
        w = w1;
Bryant's avatar
Bryant committed
    w1 = tmp.setNum( maximum() - singleStep() ).length();
pixhawk's avatar
pixhawk committed
    if ( w1 > w )
        w = w1;

Bryant's avatar
Bryant committed
    tmp.fill( '9', w );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    QFontMetrics fm( d_data->valueEdit->font() );
    w = fm.width( tmp ) + 2;
pixhawk's avatar
pixhawk committed
    if ( d_data->valueEdit->hasFrame() )
Bryant's avatar
Bryant committed
        w += 2 * style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
pixhawk's avatar
pixhawk committed

    // Now we replace default sizeHint contribution of d_data->valueEdit by
    // what we really need.

    w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();

Bryant's avatar
Bryant committed
    const int h = qMin( QWidget::sizeHint().height(),
        d_data->valueEdit->minimumSizeHint().height() );
    return QSize( w, h );
pixhawk's avatar
pixhawk committed
}