彻底改版2.0
This commit is contained in:
822
third/3rd_qwt/qwt_abstract_slider.cpp
Normal file
822
third/3rd_qwt/qwt_abstract_slider.cpp
Normal file
@@ -0,0 +1,822 @@
|
||||
/* -*- 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
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qwt_abstract_slider.h"
|
||||
#include "qwt_abstract_scale_draw.h"
|
||||
#include "qwt_math.h"
|
||||
#include "qwt_scale_map.h"
|
||||
#include <qevent.h>
|
||||
|
||||
#if QT_VERSION < 0x040601
|
||||
#define qFabs(x) ::fabs(x)
|
||||
#endif
|
||||
|
||||
static double qwtAlignToScaleDiv(
|
||||
const QwtAbstractSlider *slider, double value )
|
||||
{
|
||||
const QwtScaleDiv &sd = slider->scaleDiv();
|
||||
|
||||
const int tValue = slider->transform( value );
|
||||
|
||||
if ( tValue == slider->transform( sd.lowerBound() ) )
|
||||
return sd.lowerBound();
|
||||
|
||||
if ( tValue == slider->transform( sd.upperBound() ) )
|
||||
return sd.upperBound();
|
||||
|
||||
for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
|
||||
{
|
||||
const QList<double> ticks = sd.ticks( i );
|
||||
for ( int j = 0; j < ticks.size(); j++ )
|
||||
{
|
||||
if ( slider->transform( ticks[ j ] ) == tValue )
|
||||
return ticks[ j ];
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
class QwtAbstractSlider::PrivateData
|
||||
{
|
||||
public:
|
||||
PrivateData():
|
||||
isScrolling( false ),
|
||||
isTracking( true ),
|
||||
pendingValueChanged( false ),
|
||||
readOnly( false ),
|
||||
totalSteps( 100 ),
|
||||
singleSteps( 1 ),
|
||||
pageSteps( 10 ),
|
||||
stepAlignment( true ),
|
||||
isValid( false ),
|
||||
value( 0.0 ),
|
||||
wrapping( false ),
|
||||
invertedControls( false )
|
||||
{
|
||||
}
|
||||
|
||||
bool isScrolling;
|
||||
bool isTracking;
|
||||
bool pendingValueChanged;
|
||||
|
||||
bool readOnly;
|
||||
|
||||
uint totalSteps;
|
||||
uint singleSteps;
|
||||
uint pageSteps;
|
||||
bool stepAlignment;
|
||||
|
||||
bool isValid;
|
||||
double value;
|
||||
|
||||
bool wrapping;
|
||||
bool invertedControls;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Constructor
|
||||
|
||||
The scale is initialized to [0.0, 100.0], the
|
||||
number of steps is set to 100 with 1 and 10 and single
|
||||
an page step sizes. Step alignment is enabled.
|
||||
|
||||
The initial value is invalid.
|
||||
|
||||
\param parent Parent widget
|
||||
*/
|
||||
QwtAbstractSlider::QwtAbstractSlider( QWidget *parent ):
|
||||
QwtAbstractScale( parent )
|
||||
{
|
||||
d_data = new QwtAbstractSlider::PrivateData;
|
||||
|
||||
setScale( 0.0, 100.0 );
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
QwtAbstractSlider::~QwtAbstractSlider()
|
||||
{
|
||||
delete d_data;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the value to be valid/invalid
|
||||
|
||||
\param on When true, the value is invalidated
|
||||
|
||||
\sa setValue()
|
||||
*/
|
||||
void QwtAbstractSlider::setValid( bool on )
|
||||
{
|
||||
if ( on != d_data->isValid )
|
||||
{
|
||||
d_data->isValid = on;
|
||||
sliderChange();
|
||||
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
}
|
||||
}
|
||||
|
||||
//! \return True, when the value is invalid
|
||||
bool QwtAbstractSlider::isValid() const
|
||||
{
|
||||
return d_data->isValid;
|
||||
}
|
||||
|
||||
/*!
|
||||
En/Disable read only mode
|
||||
|
||||
In read only mode the slider can't be controlled by mouse
|
||||
or keyboard.
|
||||
|
||||
\param on Enables in case of true
|
||||
\sa isReadOnly()
|
||||
|
||||
\warning The focus policy is set to Qt::StrongFocus or Qt::NoFocus
|
||||
*/
|
||||
void QwtAbstractSlider::setReadOnly( bool on )
|
||||
{
|
||||
if ( d_data->readOnly != on )
|
||||
{
|
||||
d_data->readOnly = on;
|
||||
setFocusPolicy( on ? Qt::StrongFocus : Qt::NoFocus );
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
In read only mode the slider can't be controlled by mouse
|
||||
or keyboard.
|
||||
|
||||
\return true if read only
|
||||
\sa setReadOnly()
|
||||
*/
|
||||
bool QwtAbstractSlider::isReadOnly() const
|
||||
{
|
||||
return d_data->readOnly;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Enables or disables tracking.
|
||||
|
||||
If tracking is enabled, the slider emits the valueChanged()
|
||||
signal while the movable part of the slider is being dragged.
|
||||
If tracking is disabled, the slider emits the valueChanged() signal
|
||||
only when the user releases the slider.
|
||||
|
||||
Tracking is enabled by default.
|
||||
\param on \c true (enable) or \c false (disable) tracking.
|
||||
|
||||
\sa isTracking(), sliderMoved()
|
||||
*/
|
||||
void QwtAbstractSlider::setTracking( bool on )
|
||||
{
|
||||
d_data->isTracking = on;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return True, when tracking has been enabled
|
||||
\sa setTracking()
|
||||
*/
|
||||
bool QwtAbstractSlider::isTracking() const
|
||||
{
|
||||
return d_data->isTracking;
|
||||
}
|
||||
|
||||
/*!
|
||||
Mouse press event handler
|
||||
\param event Mouse event
|
||||
*/
|
||||
void QwtAbstractSlider::mousePressEvent( QMouseEvent *event )
|
||||
{
|
||||
if ( isReadOnly() )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !d_data->isValid || lowerBound() == upperBound() )
|
||||
return;
|
||||
|
||||
d_data->isScrolling = isScrollPosition( event->pos() );
|
||||
|
||||
if ( d_data->isScrolling )
|
||||
{
|
||||
d_data->pendingValueChanged = false;
|
||||
|
||||
Q_EMIT sliderPressed();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Mouse Move Event handler
|
||||
\param event Mouse event
|
||||
*/
|
||||
void QwtAbstractSlider::mouseMoveEvent( QMouseEvent *event )
|
||||
{
|
||||
if ( isReadOnly() )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( d_data->isValid && d_data->isScrolling )
|
||||
{
|
||||
double value = scrolledTo( event->pos() );
|
||||
if ( value != d_data->value )
|
||||
{
|
||||
value = boundedValue( value );
|
||||
|
||||
if ( d_data->stepAlignment )
|
||||
{
|
||||
value = alignedValue( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = qwtAlignToScaleDiv( this, value );
|
||||
}
|
||||
|
||||
if ( value != d_data->value )
|
||||
{
|
||||
d_data->value = value;
|
||||
|
||||
sliderChange();
|
||||
|
||||
Q_EMIT sliderMoved( d_data->value );
|
||||
|
||||
if ( d_data->isTracking )
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
else
|
||||
d_data->pendingValueChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Mouse Release Event handler
|
||||
\param event Mouse event
|
||||
*/
|
||||
void QwtAbstractSlider::mouseReleaseEvent( QMouseEvent *event )
|
||||
{
|
||||
if ( isReadOnly() )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( d_data->isScrolling && d_data->isValid )
|
||||
{
|
||||
d_data->isScrolling = false;
|
||||
|
||||
if ( d_data->pendingValueChanged )
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
|
||||
Q_EMIT sliderReleased();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Wheel Event handler
|
||||
|
||||
In/decreases the value by s number of steps. The direction
|
||||
depends on the invertedControls() property.
|
||||
|
||||
When the control or shift modifier is pressed the wheel delta
|
||||
( divided by 120 ) is mapped to an increment according to
|
||||
pageSteps(). Otherwise it is mapped to singleSteps().
|
||||
|
||||
\param event Wheel event
|
||||
*/
|
||||
void QwtAbstractSlider::wheelEvent( QWheelEvent *event )
|
||||
{
|
||||
if ( isReadOnly() )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !d_data->isValid || d_data->isScrolling )
|
||||
return;
|
||||
|
||||
int numSteps = 0;
|
||||
|
||||
if ( ( event->modifiers() & Qt::ControlModifier) ||
|
||||
( event->modifiers() & Qt::ShiftModifier ) )
|
||||
{
|
||||
// one page regardless of delta
|
||||
numSteps = d_data->pageSteps;
|
||||
if ( event->delta() < 0 )
|
||||
numSteps = -numSteps;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int numTurns = ( event->delta() / 120 );
|
||||
numSteps = numTurns * d_data->singleSteps;
|
||||
}
|
||||
|
||||
if ( d_data->invertedControls )
|
||||
numSteps = -numSteps;
|
||||
|
||||
const double value = incrementedValue( d_data->value, numSteps );
|
||||
if ( value != d_data->value )
|
||||
{
|
||||
d_data->value = value;
|
||||
sliderChange();
|
||||
|
||||
Q_EMIT sliderMoved( d_data->value );
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Handles key events
|
||||
|
||||
QwtAbstractSlider handles the following keys:
|
||||
|
||||
- Qt::Key_Left\n
|
||||
Add/Subtract singleSteps() in direction to lowerBound();
|
||||
- Qt::Key_Right\n
|
||||
Add/Subtract singleSteps() in direction to upperBound();
|
||||
- Qt::Key_Down\n
|
||||
Subtract singleSteps(), when invertedControls() is false
|
||||
- Qt::Key_Up\n
|
||||
Add singleSteps(), when invertedControls() is false
|
||||
- Qt::Key_PageDown\n
|
||||
Subtract pageSteps(), when invertedControls() is false
|
||||
- Qt::Key_PageUp\n
|
||||
Add pageSteps(), when invertedControls() is false
|
||||
- Qt::Key_Home\n
|
||||
Set the value to the minimum()
|
||||
- Qt::Key_End\n
|
||||
Set the value to the maximum()
|
||||
|
||||
\param event Key event
|
||||
\sa isReadOnly()
|
||||
*/
|
||||
void QwtAbstractSlider::keyPressEvent( QKeyEvent *event )
|
||||
{
|
||||
if ( isReadOnly() )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !d_data->isValid || d_data->isScrolling )
|
||||
return;
|
||||
|
||||
int numSteps = 0;
|
||||
double value = d_data->value;
|
||||
|
||||
switch ( event->key() )
|
||||
{
|
||||
case Qt::Key_Left:
|
||||
{
|
||||
numSteps = -static_cast<int>( d_data->singleSteps );
|
||||
if ( isInverted() )
|
||||
numSteps = -numSteps;
|
||||
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Right:
|
||||
{
|
||||
numSteps = d_data->singleSteps;
|
||||
if ( isInverted() )
|
||||
numSteps = -numSteps;
|
||||
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Down:
|
||||
{
|
||||
numSteps = -static_cast<int>( d_data->singleSteps );
|
||||
if ( d_data->invertedControls )
|
||||
numSteps = -numSteps;
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Up:
|
||||
{
|
||||
numSteps = d_data->singleSteps;
|
||||
if ( d_data->invertedControls )
|
||||
numSteps = -numSteps;
|
||||
|
||||
break;
|
||||
}
|
||||
case Qt::Key_PageUp:
|
||||
{
|
||||
numSteps = d_data->pageSteps;
|
||||
if ( d_data->invertedControls )
|
||||
numSteps = -numSteps;
|
||||
break;
|
||||
}
|
||||
case Qt::Key_PageDown:
|
||||
{
|
||||
numSteps = -static_cast<int>( d_data->pageSteps );
|
||||
if ( d_data->invertedControls )
|
||||
numSteps = -numSteps;
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Home:
|
||||
{
|
||||
value = minimum();
|
||||
break;
|
||||
}
|
||||
case Qt::Key_End:
|
||||
{
|
||||
value = maximum();
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
if ( numSteps != 0 )
|
||||
{
|
||||
value = incrementedValue( d_data->value, numSteps );
|
||||
}
|
||||
|
||||
if ( value != d_data->value )
|
||||
{
|
||||
d_data->value = value;
|
||||
sliderChange();
|
||||
|
||||
Q_EMIT sliderMoved( d_data->value );
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Set the number of steps
|
||||
|
||||
The range of the slider is divided into a number of steps from
|
||||
which the value increments according to user inputs depend.
|
||||
|
||||
The default setting is 100.
|
||||
|
||||
\param stepCount Number of steps
|
||||
|
||||
\sa totalSteps(), setSingleSteps(), setPageSteps()
|
||||
*/
|
||||
void QwtAbstractSlider::setTotalSteps( uint stepCount )
|
||||
{
|
||||
d_data->totalSteps = stepCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Number of steps
|
||||
\sa setTotalSteps(), singleSteps(), pageSteps()
|
||||
*/
|
||||
uint QwtAbstractSlider::totalSteps() const
|
||||
{
|
||||
return d_data->totalSteps;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Set the number of steps for a single increment
|
||||
|
||||
The range of the slider is divided into a number of steps from
|
||||
which the value increments according to user inputs depend.
|
||||
|
||||
\param stepCount Number of steps
|
||||
|
||||
\sa singleSteps(), setTotalSteps(), setPageSteps()
|
||||
*/
|
||||
|
||||
void QwtAbstractSlider::setSingleSteps( uint stepCount )
|
||||
{
|
||||
d_data->singleSteps = stepCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Number of steps
|
||||
\sa setSingleSteps(), totalSteps(), pageSteps()
|
||||
*/
|
||||
uint QwtAbstractSlider::singleSteps() const
|
||||
{
|
||||
return d_data->singleSteps;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Set the number of steps for a page increment
|
||||
|
||||
The range of the slider is divided into a number of steps from
|
||||
which the value increments according to user inputs depend.
|
||||
|
||||
\param stepCount Number of steps
|
||||
|
||||
\sa pageSteps(), setTotalSteps(), setSingleSteps()
|
||||
*/
|
||||
|
||||
void QwtAbstractSlider::setPageSteps( uint stepCount )
|
||||
{
|
||||
d_data->pageSteps = stepCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Number of steps
|
||||
\sa setPageSteps(), totalSteps(), singleSteps()
|
||||
*/
|
||||
uint QwtAbstractSlider::pageSteps() const
|
||||
{
|
||||
return d_data->pageSteps;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Enable step alignment
|
||||
|
||||
When step alignment is enabled values resulting from slider
|
||||
movements are aligned to the step size.
|
||||
|
||||
\param on Enable step alignment when true
|
||||
\sa stepAlignment()
|
||||
*/
|
||||
void QwtAbstractSlider::setStepAlignment( bool on )
|
||||
{
|
||||
if ( on != d_data->stepAlignment )
|
||||
{
|
||||
d_data->stepAlignment = on;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\return True, when step alignment is enabled
|
||||
\sa setStepAlignment()
|
||||
*/
|
||||
bool QwtAbstractSlider::stepAlignment() const
|
||||
{
|
||||
return d_data->stepAlignment;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the slider to the specified value
|
||||
|
||||
\param value New value
|
||||
\sa setValid(), sliderChange(), valueChanged()
|
||||
*/
|
||||
void QwtAbstractSlider::setValue( double value )
|
||||
{
|
||||
value = qBound( minimum(), value, maximum() );
|
||||
|
||||
const bool changed = ( d_data->value != value ) || !d_data->isValid;
|
||||
|
||||
d_data->value = value;
|
||||
d_data->isValid = true;
|
||||
|
||||
if ( changed )
|
||||
{
|
||||
sliderChange();
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns the current value.
|
||||
double QwtAbstractSlider::value() const
|
||||
{
|
||||
return d_data->value;
|
||||
}
|
||||
|
||||
/*!
|
||||
If wrapping is true stepping up from upperBound() value will
|
||||
take you to the minimum() value and vice versa.
|
||||
|
||||
\param on En/Disable wrapping
|
||||
\sa wrapping()
|
||||
*/
|
||||
void QwtAbstractSlider::setWrapping( bool on )
|
||||
{
|
||||
d_data->wrapping = on;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return True, when wrapping is set
|
||||
\sa setWrapping()
|
||||
*/
|
||||
bool QwtAbstractSlider::wrapping() const
|
||||
{
|
||||
return d_data->wrapping;
|
||||
}
|
||||
|
||||
/*!
|
||||
Invert wheel and key events
|
||||
|
||||
Usually scrolling the mouse wheel "up" and using keys like page
|
||||
up will increase the slider's value towards its maximum.
|
||||
When invertedControls() is enabled the value is scrolled
|
||||
towards its minimum.
|
||||
|
||||
Inverting the controls might be f.e. useful for a vertical slider
|
||||
with an inverted scale ( decreasing from top to bottom ).
|
||||
|
||||
\param on Invert controls, when true
|
||||
|
||||
\sa invertedControls(), keyEvent(), wheelEvent()
|
||||
*/
|
||||
void QwtAbstractSlider::setInvertedControls( bool on )
|
||||
{
|
||||
d_data->invertedControls = on;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return True, when the controls are inverted
|
||||
\sa setInvertedControls()
|
||||
*/
|
||||
bool QwtAbstractSlider::invertedControls() const
|
||||
{
|
||||
return d_data->invertedControls;
|
||||
}
|
||||
|
||||
/*!
|
||||
Increment the slider
|
||||
|
||||
The step size depends on the number of totalSteps()
|
||||
|
||||
\param stepCount Number of steps
|
||||
\sa setTotalSteps(), incrementedValue()
|
||||
*/
|
||||
void QwtAbstractSlider::incrementValue( int stepCount )
|
||||
{
|
||||
const double value = incrementedValue(
|
||||
d_data->value, stepCount );
|
||||
|
||||
if ( value != d_data->value )
|
||||
{
|
||||
d_data->value = value;
|
||||
sliderChange();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Increment a value
|
||||
|
||||
\param value Value
|
||||
\param stepCount Number of steps
|
||||
|
||||
\return Incremented value
|
||||
*/
|
||||
double QwtAbstractSlider::incrementedValue(
|
||||
double value, int stepCount ) const
|
||||
{
|
||||
if ( d_data->totalSteps == 0 )
|
||||
return value;
|
||||
|
||||
const QwtTransform *transformation =
|
||||
scaleMap().transformation();
|
||||
|
||||
if ( transformation == NULL )
|
||||
{
|
||||
const double range = maximum() - minimum();
|
||||
value += stepCount * range / d_data->totalSteps;
|
||||
}
|
||||
else
|
||||
{
|
||||
QwtScaleMap map = scaleMap();
|
||||
map.setPaintInterval( 0, d_data->totalSteps );
|
||||
|
||||
// we need equidant steps according to
|
||||
// paint device coordinates
|
||||
const double range = transformation->transform( maximum() )
|
||||
- transformation->transform( minimum() );
|
||||
|
||||
const double stepSize = range / d_data->totalSteps;
|
||||
|
||||
double v = transformation->transform( value );
|
||||
|
||||
v = qRound( v / stepSize ) * stepSize;
|
||||
v += stepCount * range / d_data->totalSteps;
|
||||
|
||||
value = transformation->invTransform( v );
|
||||
}
|
||||
|
||||
value = boundedValue( value );
|
||||
|
||||
if ( d_data->stepAlignment )
|
||||
value = alignedValue( value );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
double QwtAbstractSlider::boundedValue( double value ) const
|
||||
{
|
||||
const double vmin = minimum();
|
||||
const double vmax = maximum();
|
||||
|
||||
if ( d_data->wrapping && vmin != vmax )
|
||||
{
|
||||
const int fullCircle = 360 * 16;
|
||||
|
||||
const double pd = scaleMap().pDist();
|
||||
if ( int( pd / fullCircle ) * fullCircle == pd )
|
||||
{
|
||||
// full circle scales: min and max are the same
|
||||
const double range = vmax - vmin;
|
||||
|
||||
if ( value < vmin )
|
||||
{
|
||||
value += ::ceil( ( vmin - value ) / range ) * range;
|
||||
}
|
||||
else if ( value > vmax )
|
||||
{
|
||||
value -= ::ceil( ( value - vmax ) / range ) * range;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( value < vmin )
|
||||
value = vmax;
|
||||
else if ( value > vmax )
|
||||
value = vmin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = qBound( vmin, value, vmax );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
double QwtAbstractSlider::alignedValue( double value ) const
|
||||
{
|
||||
if ( d_data->totalSteps == 0 )
|
||||
return value;
|
||||
|
||||
double stepSize;
|
||||
|
||||
if ( scaleMap().transformation() == NULL )
|
||||
{
|
||||
stepSize = ( maximum() - minimum() ) / d_data->totalSteps;
|
||||
if ( stepSize > 0.0 )
|
||||
{
|
||||
value = lowerBound() +
|
||||
qRound( ( value - lowerBound() ) / stepSize ) * stepSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stepSize = ( scaleMap().p2() - scaleMap().p1() ) / d_data->totalSteps;
|
||||
|
||||
if ( stepSize > 0.0 )
|
||||
{
|
||||
double v = scaleMap().transform( value );
|
||||
|
||||
v = scaleMap().p1() +
|
||||
qRound( ( v - scaleMap().p1() ) / stepSize ) * stepSize;
|
||||
|
||||
value = scaleMap().invTransform( v );
|
||||
}
|
||||
}
|
||||
|
||||
if ( qAbs( stepSize ) > 1e-12 )
|
||||
{
|
||||
if ( qFuzzyCompare( value + 1.0, 1.0 ) )
|
||||
{
|
||||
// correct rounding error if value = 0
|
||||
value = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// correct rounding error at the border
|
||||
if ( qFuzzyCompare( value, upperBound() ) )
|
||||
value = upperBound();
|
||||
else if ( qFuzzyCompare( value, lowerBound() ) )
|
||||
value = lowerBound();
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
Update the slider according to modifications of the scale
|
||||
*/
|
||||
void QwtAbstractSlider::scaleChange()
|
||||
{
|
||||
const double value = qBound( minimum(), d_data->value, maximum() );
|
||||
|
||||
const bool changed = ( value != d_data->value );
|
||||
if ( changed )
|
||||
{
|
||||
d_data->value = value;
|
||||
}
|
||||
|
||||
if ( d_data->isValid || changed )
|
||||
Q_EMIT valueChanged( d_data->value );
|
||||
|
||||
updateGeometry();
|
||||
update();
|
||||
}
|
||||
|
||||
//! Calling update()
|
||||
void QwtAbstractSlider::sliderChange()
|
||||
{
|
||||
update();
|
||||
}
|
||||
Reference in New Issue
Block a user