彻底改版2.0
This commit is contained in:
871
third/3rd_qwt/qwt_dial.cpp
Normal file
871
third/3rd_qwt/qwt_dial.cpp
Normal file
@@ -0,0 +1,871 @@
|
||||
/* -*- 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_dial.h"
|
||||
#include "qwt_dial_needle.h"
|
||||
#include "qwt_math.h"
|
||||
#include "qwt_scale_engine.h"
|
||||
#include "qwt_scale_map.h"
|
||||
#include "qwt_round_scale_draw.h"
|
||||
#include "qwt_painter.h"
|
||||
#include <qpainter.h>
|
||||
#include <qpalette.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qevent.h>
|
||||
#include <qalgorithms.h>
|
||||
#include <qmath.h>
|
||||
#include <qstyle.h>
|
||||
#include <qstyleoption.h>
|
||||
#include <qapplication.h>
|
||||
|
||||
static inline double qwtAngleDist( double a1, double a2 )
|
||||
{
|
||||
double dist = qAbs( a2 - a1 );
|
||||
if ( dist > 360.0 )
|
||||
dist -= 360.0;
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
static inline bool qwtIsOnArc( double angle, double min, double max )
|
||||
{
|
||||
if ( min < max )
|
||||
{
|
||||
return ( angle >= min ) && ( angle <= max );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( angle >= min ) || ( angle <= max );
|
||||
}
|
||||
}
|
||||
|
||||
static inline double qwtBoundedAngle( double min, double angle, double max )
|
||||
{
|
||||
double from = qwtNormalizeDegrees( min );
|
||||
double to = qwtNormalizeDegrees( max );
|
||||
|
||||
double a;
|
||||
|
||||
if ( qwtIsOnArc( angle, from, to ) )
|
||||
{
|
||||
a = angle;
|
||||
if ( a < min )
|
||||
a += 360.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( qwtAngleDist( angle, from ) <
|
||||
qwtAngleDist( angle, to ) )
|
||||
{
|
||||
a = min;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = max;
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
class QwtDial::PrivateData
|
||||
{
|
||||
public:
|
||||
PrivateData():
|
||||
frameShadow( Sunken ),
|
||||
lineWidth( 0 ),
|
||||
mode( RotateNeedle ),
|
||||
origin( 90.0 ),
|
||||
minScaleArc( 0.0 ),
|
||||
maxScaleArc( 0.0 ),
|
||||
needle( NULL ),
|
||||
arcOffset( 0.0 ),
|
||||
mouseOffset( 0.0 )
|
||||
{
|
||||
}
|
||||
|
||||
~PrivateData()
|
||||
{
|
||||
delete needle;
|
||||
}
|
||||
Shadow frameShadow;
|
||||
int lineWidth;
|
||||
|
||||
QwtDial::Mode mode;
|
||||
|
||||
double origin;
|
||||
double minScaleArc;
|
||||
double maxScaleArc;
|
||||
|
||||
QwtDialNeedle *needle;
|
||||
|
||||
double arcOffset;
|
||||
double mouseOffset;
|
||||
|
||||
QPixmap pixmapCache;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Constructor
|
||||
\param parent Parent widget
|
||||
|
||||
Create a dial widget with no needle. The scale is initialized
|
||||
to [ 0.0, 360.0 ] and 360 steps ( QwtAbstractSlider::setTotalSteps() ).
|
||||
The origin of the scale is at 90°,
|
||||
|
||||
The value is set to 0.0.
|
||||
|
||||
The default mode is QwtDial::RotateNeedle.
|
||||
*/
|
||||
QwtDial::QwtDial( QWidget* parent ):
|
||||
QwtAbstractSlider( parent )
|
||||
{
|
||||
d_data = new PrivateData;
|
||||
|
||||
setFocusPolicy( Qt::TabFocus );
|
||||
|
||||
QPalette p = palette();
|
||||
for ( int i = 0; i < QPalette::NColorGroups; i++ )
|
||||
{
|
||||
const QPalette::ColorGroup colorGroup =
|
||||
static_cast<QPalette::ColorGroup>( i );
|
||||
|
||||
// Base: background color of the circle inside the frame.
|
||||
// WindowText: background color of the circle inside the scale
|
||||
|
||||
p.setColor( colorGroup, QPalette::WindowText,
|
||||
p.color( colorGroup, QPalette::Base ) );
|
||||
}
|
||||
setPalette( p );
|
||||
|
||||
QwtRoundScaleDraw* scaleDraw = new QwtRoundScaleDraw();
|
||||
scaleDraw->setRadius( 0 );
|
||||
|
||||
setScaleDraw( scaleDraw );
|
||||
|
||||
setScaleArc( 0.0, 360.0 ); // scale as a full circle
|
||||
|
||||
setScaleMaxMajor( 10 );
|
||||
setScaleMaxMinor( 5 );
|
||||
|
||||
setValue( 0.0 );
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
QwtDial::~QwtDial()
|
||||
{
|
||||
delete d_data;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the frame shadow value from the frame style.
|
||||
|
||||
\param shadow Frame shadow
|
||||
\sa setLineWidth(), QFrame::setFrameShadow()
|
||||
*/
|
||||
void QwtDial::setFrameShadow( Shadow shadow )
|
||||
{
|
||||
if ( shadow != d_data->frameShadow )
|
||||
{
|
||||
invalidateCache();
|
||||
|
||||
d_data->frameShadow = shadow;
|
||||
if ( lineWidth() > 0 )
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Frame shadow
|
||||
/sa setFrameShadow(), lineWidth(), QFrame::frameShadow()
|
||||
*/
|
||||
QwtDial::Shadow QwtDial::frameShadow() const
|
||||
{
|
||||
return d_data->frameShadow;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the line width of the frame
|
||||
|
||||
\param lineWidth Line width
|
||||
\sa setFrameShadow()
|
||||
*/
|
||||
void QwtDial::setLineWidth( int lineWidth )
|
||||
{
|
||||
if ( lineWidth < 0 )
|
||||
lineWidth = 0;
|
||||
|
||||
if ( d_data->lineWidth != lineWidth )
|
||||
{
|
||||
invalidateCache();
|
||||
|
||||
d_data->lineWidth = lineWidth;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Line width of the frame
|
||||
\sa setLineWidth(), frameShadow(), lineWidth()
|
||||
*/
|
||||
int QwtDial::lineWidth() const
|
||||
{
|
||||
return d_data->lineWidth;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return bounding rectangle of the circle inside the frame
|
||||
\sa setLineWidth(), scaleInnerRect(), boundingRect()
|
||||
*/
|
||||
QRect QwtDial::innerRect() const
|
||||
{
|
||||
const int lw = lineWidth();
|
||||
return boundingRect().adjusted( lw, lw, -lw, -lw );
|
||||
}
|
||||
|
||||
/*!
|
||||
\return bounding rectangle of the dial including the frame
|
||||
\sa setLineWidth(), scaleInnerRect(), innerRect()
|
||||
*/
|
||||
QRect QwtDial::boundingRect() const
|
||||
{
|
||||
const QRect cr = contentsRect();
|
||||
|
||||
const int dim = qMin( cr.width(), cr.height() );
|
||||
|
||||
QRect inner( 0, 0, dim, dim );
|
||||
inner.moveCenter( cr.center() );
|
||||
|
||||
return inner;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return rectangle inside the scale
|
||||
\sa setLineWidth(), boundingRect(), innerRect()
|
||||
*/
|
||||
QRect QwtDial::scaleInnerRect() const
|
||||
{
|
||||
QRect rect = innerRect();
|
||||
|
||||
const QwtAbstractScaleDraw *sd = scaleDraw();
|
||||
if ( sd )
|
||||
{
|
||||
int scaleDist = qCeil( sd->extent( font() ) );
|
||||
scaleDist++; // margin
|
||||
|
||||
rect.adjust( scaleDist, scaleDist, -scaleDist, -scaleDist );
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Change the mode of the dial.
|
||||
\param mode New mode
|
||||
|
||||
In case of QwtDial::RotateNeedle the needle is rotating, in case of
|
||||
QwtDial::RotateScale, the needle points to origin()
|
||||
and the scale is rotating.
|
||||
|
||||
The default mode is QwtDial::RotateNeedle.
|
||||
|
||||
\sa mode(), setValue(), setOrigin()
|
||||
*/
|
||||
void QwtDial::setMode( Mode mode )
|
||||
{
|
||||
if ( mode != d_data->mode )
|
||||
{
|
||||
invalidateCache();
|
||||
|
||||
d_data->mode = mode;
|
||||
sliderChange();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Mode of the dial.
|
||||
\sa setMode(), origin(), setScaleArc(), value()
|
||||
*/
|
||||
QwtDial::Mode QwtDial::mode() const
|
||||
{
|
||||
return d_data->mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
Invalidate the internal caches used to speed up repainting
|
||||
*/
|
||||
void QwtDial::invalidateCache()
|
||||
{
|
||||
d_data->pixmapCache = QPixmap();
|
||||
}
|
||||
|
||||
/*!
|
||||
Paint the dial
|
||||
\param event Paint event
|
||||
*/
|
||||
void QwtDial::paintEvent( QPaintEvent *event )
|
||||
{
|
||||
QPainter painter( this );
|
||||
painter.setClipRegion( event->region() );
|
||||
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
|
||||
|
||||
if ( d_data->mode == QwtDial::RotateScale )
|
||||
{
|
||||
painter.save();
|
||||
painter.setRenderHint( QPainter::Antialiasing, true );
|
||||
|
||||
drawContents( &painter );
|
||||
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
const QRect r = contentsRect();
|
||||
if ( r.size() != d_data->pixmapCache.size() )
|
||||
{
|
||||
d_data->pixmapCache = QwtPainter::backingStore( this, r.size() );
|
||||
d_data->pixmapCache.fill( Qt::transparent );
|
||||
|
||||
QPainter p( &d_data->pixmapCache );
|
||||
p.setRenderHint( QPainter::Antialiasing, true );
|
||||
p.translate( -r.topLeft() );
|
||||
|
||||
if ( d_data->mode != QwtDial::RotateScale )
|
||||
drawContents( &p );
|
||||
|
||||
if ( lineWidth() > 0 )
|
||||
drawFrame( &p );
|
||||
|
||||
if ( d_data->mode != QwtDial::RotateNeedle )
|
||||
drawNeedle( &p );
|
||||
}
|
||||
|
||||
painter.drawPixmap( r.topLeft(), d_data->pixmapCache );
|
||||
|
||||
if ( d_data->mode == QwtDial::RotateNeedle )
|
||||
drawNeedle( &painter );
|
||||
|
||||
if ( hasFocus() )
|
||||
drawFocusIndicator( &painter );
|
||||
}
|
||||
|
||||
/*!
|
||||
Draw the focus indicator
|
||||
\param painter Painter
|
||||
*/
|
||||
void QwtDial::drawFocusIndicator( QPainter *painter ) const
|
||||
{
|
||||
QwtPainter::drawFocusRect( painter, this, boundingRect() );
|
||||
}
|
||||
|
||||
/*!
|
||||
Draw the frame around the dial
|
||||
|
||||
\param painter Painter
|
||||
\sa lineWidth(), frameShadow()
|
||||
*/
|
||||
void QwtDial::drawFrame( QPainter *painter )
|
||||
{
|
||||
QwtPainter::drawRoundFrame( painter, boundingRect(),
|
||||
palette(), lineWidth(), d_data->frameShadow );
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Draw the contents inside the frame
|
||||
|
||||
QPalette::Window is the background color outside of the frame.
|
||||
QPalette::Base is the background color inside the frame.
|
||||
QPalette::WindowText is the background color inside the scale.
|
||||
|
||||
\param painter Painter
|
||||
|
||||
\sa boundingRect(), innerRect(),
|
||||
scaleInnerRect(), QWidget::setPalette()
|
||||
*/
|
||||
void QwtDial::drawContents( QPainter *painter ) const
|
||||
{
|
||||
if ( testAttribute( Qt::WA_NoSystemBackground ) ||
|
||||
palette().brush( QPalette::Base ) !=
|
||||
palette().brush( QPalette::Window ) )
|
||||
{
|
||||
const QRectF br = boundingRect();
|
||||
|
||||
painter->save();
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( palette().brush( QPalette::Base ) );
|
||||
painter->drawEllipse( br );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
const QRectF insideScaleRect = scaleInnerRect();
|
||||
if ( palette().brush( QPalette::WindowText ) !=
|
||||
palette().brush( QPalette::Base ) )
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( palette().brush( QPalette::WindowText ) );
|
||||
painter->drawEllipse( insideScaleRect );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
const QPointF center = insideScaleRect.center();
|
||||
const double radius = 0.5 * insideScaleRect.width();
|
||||
|
||||
painter->save();
|
||||
drawScale( painter, center, radius );
|
||||
painter->restore();
|
||||
|
||||
painter->save();
|
||||
drawScaleContents( painter, center, radius );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
/*!
|
||||
Draw the needle
|
||||
|
||||
\param painter Painter
|
||||
\param center Center of the dial
|
||||
\param radius Length for the needle
|
||||
\param direction Direction of the needle in degrees, counter clockwise
|
||||
\param colorGroup ColorGroup
|
||||
*/
|
||||
void QwtDial::drawNeedle( QPainter *painter, const QPointF ¢er,
|
||||
double radius, double direction, QPalette::ColorGroup colorGroup ) const
|
||||
{
|
||||
if ( d_data->needle )
|
||||
{
|
||||
direction = 360.0 - direction; // counter clockwise
|
||||
d_data->needle->draw( painter, center, radius, direction, colorGroup );
|
||||
}
|
||||
}
|
||||
|
||||
void QwtDial::drawNeedle( QPainter *painter ) const
|
||||
{
|
||||
if ( !isValid() )
|
||||
return;
|
||||
|
||||
QPalette::ColorGroup colorGroup;
|
||||
if ( isEnabled() )
|
||||
colorGroup = hasFocus() ? QPalette::Active : QPalette::Inactive;
|
||||
else
|
||||
colorGroup = QPalette::Disabled;
|
||||
|
||||
const QRectF sr = scaleInnerRect();
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint( QPainter::Antialiasing, true );
|
||||
drawNeedle( painter, sr.center(), 0.5 * sr.width(),
|
||||
scaleMap().transform( value() ) + 270.0, colorGroup );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
/*!
|
||||
Draw the scale
|
||||
|
||||
\param painter Painter
|
||||
\param center Center of the dial
|
||||
\param radius Radius of the scale
|
||||
*/
|
||||
void QwtDial::drawScale( QPainter *painter,
|
||||
const QPointF ¢er, double radius ) const
|
||||
{
|
||||
QwtRoundScaleDraw *sd = const_cast<QwtRoundScaleDraw *>( scaleDraw() );
|
||||
if ( sd == NULL )
|
||||
return;
|
||||
|
||||
sd->setRadius( radius );
|
||||
sd->moveCenter( center );
|
||||
|
||||
QPalette pal = palette();
|
||||
|
||||
const QColor textColor = pal.color( QPalette::Text );
|
||||
pal.setColor( QPalette::WindowText, textColor ); // ticks, backbone
|
||||
|
||||
painter->setFont( font() );
|
||||
painter->setPen( QPen( textColor, sd->penWidth() ) );
|
||||
|
||||
painter->setBrush( Qt::red );
|
||||
sd->draw( painter, pal );
|
||||
}
|
||||
|
||||
/*!
|
||||
Draw the contents inside the scale
|
||||
|
||||
Paints nothing.
|
||||
|
||||
\param painter Painter
|
||||
\param center Center of the contents circle
|
||||
\param radius Radius of the contents circle
|
||||
*/
|
||||
void QwtDial::drawScaleContents( QPainter *painter,
|
||||
const QPointF ¢er, double radius ) const
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(center);
|
||||
Q_UNUSED(radius);
|
||||
}
|
||||
|
||||
/*!
|
||||
Set a needle for the dial
|
||||
|
||||
\param needle Needle
|
||||
|
||||
\warning The needle will be deleted, when a different needle is
|
||||
set or in ~QwtDial()
|
||||
*/
|
||||
void QwtDial::setNeedle( QwtDialNeedle *needle )
|
||||
{
|
||||
if ( needle != d_data->needle )
|
||||
{
|
||||
if ( d_data->needle )
|
||||
delete d_data->needle;
|
||||
|
||||
d_data->needle = needle;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\return needle
|
||||
\sa setNeedle()
|
||||
*/
|
||||
const QwtDialNeedle *QwtDial::needle() const
|
||||
{
|
||||
return d_data->needle;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return needle
|
||||
\sa setNeedle()
|
||||
*/
|
||||
QwtDialNeedle *QwtDial::needle()
|
||||
{
|
||||
return d_data->needle;
|
||||
}
|
||||
|
||||
//! \return the scale draw
|
||||
QwtRoundScaleDraw *QwtDial::scaleDraw()
|
||||
{
|
||||
return static_cast<QwtRoundScaleDraw *>( abstractScaleDraw() );
|
||||
}
|
||||
|
||||
//! \return the scale draw
|
||||
const QwtRoundScaleDraw *QwtDial::scaleDraw() const
|
||||
{
|
||||
return static_cast<const QwtRoundScaleDraw *>( abstractScaleDraw() );
|
||||
}
|
||||
|
||||
/*!
|
||||
Set an individual scale draw
|
||||
|
||||
The motivation for setting a scale draw is often
|
||||
to overload QwtRoundScaleDraw::label() to return
|
||||
individual tick labels.
|
||||
|
||||
\param scaleDraw Scale draw
|
||||
\warning The previous scale draw is deleted
|
||||
*/
|
||||
void QwtDial::setScaleDraw( QwtRoundScaleDraw *scaleDraw )
|
||||
{
|
||||
setAbstractScaleDraw( scaleDraw );
|
||||
sliderChange();
|
||||
}
|
||||
|
||||
/*!
|
||||
Change the arc of the scale
|
||||
|
||||
\param minArc Lower limit
|
||||
\param maxArc Upper limit
|
||||
|
||||
\sa minScaleArc(), maxScaleArc()
|
||||
*/
|
||||
void QwtDial::setScaleArc( double minArc, double maxArc )
|
||||
{
|
||||
if ( minArc != 360.0 && minArc != -360.0 )
|
||||
minArc = ::fmod( minArc, 360.0 );
|
||||
if ( maxArc != 360.0 && maxArc != -360.0 )
|
||||
maxArc = ::fmod( maxArc, 360.0 );
|
||||
|
||||
double minScaleArc = qMin( minArc, maxArc );
|
||||
double maxScaleArc = qMax( minArc, maxArc );
|
||||
|
||||
if ( maxScaleArc - minScaleArc > 360.0 )
|
||||
maxScaleArc = minScaleArc + 360.0;
|
||||
|
||||
if ( ( minScaleArc != d_data->minScaleArc ) ||
|
||||
( maxScaleArc != d_data->maxScaleArc ) )
|
||||
{
|
||||
d_data->minScaleArc = minScaleArc;
|
||||
d_data->maxScaleArc = maxScaleArc;
|
||||
|
||||
invalidateCache();
|
||||
sliderChange();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the lower limit for the scale arc
|
||||
|
||||
\param min Lower limit of the scale arc
|
||||
\sa setScaleArc(), setMaxScaleArc()
|
||||
*/
|
||||
void QwtDial::setMinScaleArc( double min )
|
||||
{
|
||||
setScaleArc( min, d_data->maxScaleArc );
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Lower limit of the scale arc
|
||||
\sa setScaleArc()
|
||||
*/
|
||||
double QwtDial::minScaleArc() const
|
||||
{
|
||||
return d_data->minScaleArc;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the upper limit for the scale arc
|
||||
|
||||
\param max Upper limit of the scale arc
|
||||
\sa setScaleArc(), setMinScaleArc()
|
||||
*/
|
||||
void QwtDial::setMaxScaleArc( double max )
|
||||
{
|
||||
setScaleArc( d_data->minScaleArc, max );
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Upper limit of the scale arc
|
||||
\sa setScaleArc()
|
||||
*/
|
||||
double QwtDial::maxScaleArc() const
|
||||
{
|
||||
return d_data->maxScaleArc;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Change the origin
|
||||
|
||||
The origin is the angle where scale and needle is relative to.
|
||||
|
||||
\param origin New origin
|
||||
\sa origin()
|
||||
*/
|
||||
void QwtDial::setOrigin( double origin )
|
||||
{
|
||||
invalidateCache();
|
||||
|
||||
d_data->origin = origin;
|
||||
sliderChange();
|
||||
}
|
||||
|
||||
/*!
|
||||
The origin is the angle where scale and needle is relative to.
|
||||
|
||||
\return Origin of the dial
|
||||
\sa setOrigin()
|
||||
*/
|
||||
double QwtDial::origin() const
|
||||
{
|
||||
return d_data->origin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Size hint
|
||||
\sa minimumSizeHint()
|
||||
*/
|
||||
QSize QwtDial::sizeHint() const
|
||||
{
|
||||
int sh = 0;
|
||||
if ( scaleDraw() )
|
||||
sh = qCeil( scaleDraw()->extent( font() ) );
|
||||
|
||||
const int d = 6 * sh + 2 * lineWidth();
|
||||
|
||||
QSize hint( d, d );
|
||||
if ( !isReadOnly() )
|
||||
hint = hint.expandedTo( QApplication::globalStrut() );
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return Minimum size hint
|
||||
\sa sizeHint()
|
||||
*/
|
||||
QSize QwtDial::minimumSizeHint() const
|
||||
{
|
||||
int sh = 0;
|
||||
if ( scaleDraw() )
|
||||
sh = qCeil( scaleDraw()->extent( font() ) );
|
||||
|
||||
const int d = 3 * sh + 2 * lineWidth();
|
||||
|
||||
return QSize( d, d );
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Determine what to do when the user presses a mouse button.
|
||||
|
||||
\param pos Mouse position
|
||||
|
||||
\retval True, when the inner circle contains pos
|
||||
\sa scrolledTo()
|
||||
*/
|
||||
bool QwtDial::isScrollPosition( const QPoint &pos ) const
|
||||
{
|
||||
const QRegion region( innerRect(), QRegion::Ellipse );
|
||||
if ( region.contains( pos ) && ( pos != innerRect().center() ) )
|
||||
{
|
||||
double angle = QLineF( rect().center(), pos ).angle();
|
||||
if ( d_data->mode == QwtDial::RotateScale )
|
||||
angle = 360.0 - angle;
|
||||
|
||||
double valueAngle =
|
||||
qwtNormalizeDegrees( 90.0 - scaleMap().transform( value() ) );
|
||||
|
||||
d_data->mouseOffset = qwtNormalizeDegrees( angle - valueAngle );
|
||||
d_data->arcOffset = scaleMap().p1();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Determine the value for a new position of the
|
||||
slider handle.
|
||||
|
||||
\param pos Mouse position
|
||||
|
||||
\return Value for the mouse position
|
||||
\sa isScrollPosition()
|
||||
*/
|
||||
double QwtDial::scrolledTo( const QPoint &pos ) const
|
||||
{
|
||||
double angle = QLineF( rect().center(), pos ).angle();
|
||||
if ( d_data->mode == QwtDial::RotateScale )
|
||||
{
|
||||
angle += scaleMap().p1() - d_data->arcOffset;
|
||||
angle = 360.0 - angle;
|
||||
}
|
||||
|
||||
angle = qwtNormalizeDegrees( angle - d_data->mouseOffset );
|
||||
angle = qwtNormalizeDegrees( 90.0 - angle );
|
||||
|
||||
if ( scaleMap().pDist() >= 360.0 )
|
||||
{
|
||||
if ( angle < scaleMap().p1() )
|
||||
angle += 360.0;
|
||||
|
||||
if ( !wrapping() )
|
||||
{
|
||||
double boundedAngle = angle;
|
||||
|
||||
const double arc = angle - scaleMap().transform( value() );
|
||||
if ( qAbs( arc ) > 180.0 )
|
||||
{
|
||||
boundedAngle = ( arc > 0 )
|
||||
? scaleMap().p1() : scaleMap().p2();
|
||||
}
|
||||
|
||||
d_data->mouseOffset += ( boundedAngle - angle );
|
||||
|
||||
angle = boundedAngle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double boundedAngle =
|
||||
qwtBoundedAngle( scaleMap().p1(), angle, scaleMap().p2() );
|
||||
|
||||
if ( !wrapping() )
|
||||
d_data->mouseOffset += ( boundedAngle - angle );
|
||||
|
||||
angle = boundedAngle;
|
||||
}
|
||||
|
||||
return scaleMap().invTransform( angle );
|
||||
}
|
||||
|
||||
/*!
|
||||
Change Event handler
|
||||
\param event Change event
|
||||
|
||||
Invalidates internal paint caches if necessary
|
||||
*/
|
||||
void QwtDial::changeEvent( QEvent *event )
|
||||
{
|
||||
switch( event->type() )
|
||||
{
|
||||
case QEvent::EnabledChange:
|
||||
case QEvent::FontChange:
|
||||
case QEvent::StyleChange:
|
||||
case QEvent::PaletteChange:
|
||||
case QEvent::LanguageChange:
|
||||
case QEvent::LocaleChange:
|
||||
{
|
||||
invalidateCache();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QwtAbstractSlider::changeEvent( event );
|
||||
}
|
||||
|
||||
/*!
|
||||
Wheel Event handler
|
||||
\param event Wheel event
|
||||
*/
|
||||
void QwtDial::wheelEvent( QWheelEvent *event )
|
||||
{
|
||||
const QRegion region( innerRect(), QRegion::Ellipse );
|
||||
if ( region.contains( event->pos() ) )
|
||||
QwtAbstractSlider::wheelEvent( event );
|
||||
}
|
||||
|
||||
void QwtDial::setAngleRange( double angle, double span )
|
||||
{
|
||||
QwtRoundScaleDraw *sd = const_cast<QwtRoundScaleDraw *>( scaleDraw() );
|
||||
if ( sd )
|
||||
{
|
||||
angle = qwtNormalizeDegrees( angle - 270.0 );
|
||||
sd->setAngleRange( angle, angle + span );
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Invalidate the internal caches and call
|
||||
QwtAbstractSlider::scaleChange()
|
||||
*/
|
||||
void QwtDial::scaleChange()
|
||||
{
|
||||
invalidateCache();
|
||||
QwtAbstractSlider::scaleChange();
|
||||
}
|
||||
|
||||
void QwtDial::sliderChange()
|
||||
{
|
||||
setAngleRange( d_data->origin + d_data->minScaleArc,
|
||||
d_data->maxScaleArc - d_data->minScaleArc );
|
||||
|
||||
if ( mode() == RotateScale )
|
||||
{
|
||||
const double arc = scaleMap().transform( value() ) - scaleMap().p1();
|
||||
setAngleRange( d_data->origin - arc,
|
||||
d_data->maxScaleArc - d_data->minScaleArc );
|
||||
}
|
||||
|
||||
QwtAbstractSlider::sliderChange();
|
||||
}
|
||||
Reference in New Issue
Block a user