856 lines
20 KiB
C++
856 lines
20 KiB
C++
/* -*- 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_knob.h"
|
|
#include "qwt_round_scale_draw.h"
|
|
#include "qwt_math.h"
|
|
#include "qwt_painter.h"
|
|
#include "qwt_scale_map.h"
|
|
#include <qpainter.h>
|
|
#include <qpalette.h>
|
|
#include <qstyle.h>
|
|
#include <qstyleoption.h>
|
|
#include <qevent.h>
|
|
#include <qmath.h>
|
|
#include <qapplication.h>
|
|
|
|
#if QT_VERSION < 0x040601
|
|
#define qAtan2(y, x) ::atan2(y, x)
|
|
#define qFabs(x) ::fabs(x)
|
|
#define qFastCos(x) qCos(x)
|
|
#define qFastSin(x) qSin(x)
|
|
#endif
|
|
|
|
static QSize qwtKnobSizeHint( const QwtKnob *knob, int min )
|
|
{
|
|
int knobWidth = knob->knobWidth();
|
|
if ( knobWidth <= 0 )
|
|
knobWidth = qMax( 3 * knob->markerSize(), min );
|
|
|
|
// Add the scale radial thickness to the knobWidth
|
|
const int extent = qCeil( knob->scaleDraw()->extent( knob->font() ) );
|
|
const int d = 2 * ( extent + 4 ) + knobWidth;
|
|
|
|
int left, right, top, bottom;
|
|
knob->getContentsMargins( &left, &top, &right, &bottom );
|
|
|
|
return QSize( d + left + right, d + top + bottom );
|
|
}
|
|
|
|
static inline double qwtToScaleAngle( double angle )
|
|
{
|
|
// the map is counter clockwise with the origin
|
|
// at 90° using angles from -180° -> 180°
|
|
|
|
double a = 90.0 - angle;
|
|
if ( a <= -180.0 )
|
|
a += 360.0;
|
|
else if ( a >= 180.0 )
|
|
a -= 360.0;
|
|
|
|
return a;
|
|
}
|
|
|
|
static double qwtToDegrees( double value )
|
|
{
|
|
return qwtNormalizeDegrees( 90.0 - value );
|
|
}
|
|
|
|
class QwtKnob::PrivateData
|
|
{
|
|
public:
|
|
PrivateData():
|
|
knobStyle( QwtKnob::Raised ),
|
|
markerStyle( QwtKnob::Notch ),
|
|
borderWidth( 2 ),
|
|
borderDist( 4 ),
|
|
scaleDist( 4 ),
|
|
maxScaleTicks( 11 ),
|
|
knobWidth( 0 ),
|
|
alignment( Qt::AlignCenter ),
|
|
markerSize( 8 ),
|
|
totalAngle( 270.0 ),
|
|
mouseOffset( 0.0 )
|
|
{
|
|
}
|
|
|
|
QwtKnob::KnobStyle knobStyle;
|
|
QwtKnob::MarkerStyle markerStyle;
|
|
|
|
int borderWidth;
|
|
int borderDist;
|
|
int scaleDist;
|
|
int maxScaleTicks;
|
|
int knobWidth;
|
|
Qt::Alignment alignment;
|
|
int markerSize;
|
|
|
|
double totalAngle;
|
|
|
|
double mouseOffset;
|
|
};
|
|
|
|
/*!
|
|
\brief Constructor
|
|
|
|
Construct a knob with an angle of 270°. The style is
|
|
QwtKnob::Raised and the marker style is QwtKnob::Notch.
|
|
The width of the knob is set to 50 pixels.
|
|
|
|
\param parent Parent widget
|
|
|
|
\sa setTotalAngle()
|
|
*/
|
|
QwtKnob::QwtKnob( QWidget* parent ):
|
|
QwtAbstractSlider( parent )
|
|
{
|
|
d_data = new PrivateData;
|
|
|
|
setScaleDraw( new QwtRoundScaleDraw() );
|
|
|
|
setTotalAngle( 270.0 );
|
|
|
|
setScale( 0.0, 10.0 );
|
|
setValue( 0.0 );
|
|
|
|
setSizePolicy( QSizePolicy::MinimumExpanding,
|
|
QSizePolicy::MinimumExpanding );
|
|
}
|
|
|
|
//! Destructor
|
|
QwtKnob::~QwtKnob()
|
|
{
|
|
delete d_data;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the knob type
|
|
|
|
\param knobStyle Knob type
|
|
\sa knobStyle(), setBorderWidth()
|
|
*/
|
|
void QwtKnob::setKnobStyle( KnobStyle knobStyle )
|
|
{
|
|
if ( d_data->knobStyle != knobStyle )
|
|
{
|
|
d_data->knobStyle = knobStyle;
|
|
update();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Marker type of the knob
|
|
\sa setKnobStyle(), setBorderWidth()
|
|
*/
|
|
QwtKnob::KnobStyle QwtKnob::knobStyle() const
|
|
{
|
|
return d_data->knobStyle;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the marker type of the knob
|
|
|
|
\param markerStyle Marker type
|
|
\sa markerStyle(), setMarkerSize()
|
|
*/
|
|
void QwtKnob::setMarkerStyle( MarkerStyle markerStyle )
|
|
{
|
|
if ( d_data->markerStyle != markerStyle )
|
|
{
|
|
d_data->markerStyle = markerStyle;
|
|
update();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Marker type of the knob
|
|
\sa setMarkerStyle(), setMarkerSize()
|
|
*/
|
|
QwtKnob::MarkerStyle QwtKnob::markerStyle() const
|
|
{
|
|
return d_data->markerStyle;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the total angle by which the knob can be turned
|
|
\param angle Angle in degrees.
|
|
|
|
The angle has to be between [10, 360] degrees. Angles above
|
|
360 ( so that the knob can be turned several times around its axis )
|
|
have to be set using setNumTurns().
|
|
|
|
The default angle is 270 degrees.
|
|
|
|
\sa totalAngle(), setNumTurns()
|
|
*/
|
|
void QwtKnob::setTotalAngle ( double angle )
|
|
{
|
|
angle = qBound( 10.0, angle, 360.0 );
|
|
|
|
if ( angle != d_data->totalAngle )
|
|
{
|
|
d_data->totalAngle = angle;
|
|
|
|
scaleDraw()->setAngleRange( -0.5 * d_data->totalAngle,
|
|
0.5 * d_data->totalAngle );
|
|
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return the total angle
|
|
\sa setTotalAngle(), setNumTurns(), numTurns()
|
|
*/
|
|
double QwtKnob::totalAngle() const
|
|
{
|
|
return d_data->totalAngle;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the number of turns
|
|
|
|
When numTurns > 1 the knob can be turned several times around its axis
|
|
- otherwise the total angle is floored to 360°.
|
|
|
|
\sa numTurns(), totalAngle(), setTotalAngle()
|
|
*/
|
|
|
|
void QwtKnob::setNumTurns( int numTurns )
|
|
{
|
|
numTurns = qMax( numTurns, 1 );
|
|
|
|
if ( numTurns == 1 && d_data->totalAngle <= 360.0 )
|
|
return;
|
|
|
|
const double angle = numTurns * 360.0;
|
|
if ( angle != d_data->totalAngle )
|
|
{
|
|
d_data->totalAngle = angle;
|
|
|
|
scaleDraw()->setAngleRange( -0.5 * d_data->totalAngle,
|
|
0.5 * d_data->totalAngle );
|
|
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Number of turns.
|
|
|
|
When the total angle is below 360° numTurns() is ceiled to 1.
|
|
\sa setNumTurns(), setTotalAngle(), totalAngle()
|
|
*/
|
|
int QwtKnob::numTurns() const
|
|
{
|
|
return qCeil( d_data->totalAngle / 360.0 );
|
|
}
|
|
|
|
/*!
|
|
Change the scale draw of the knob
|
|
|
|
For changing the labels of the scales, it
|
|
is necessary to derive from QwtRoundScaleDraw and
|
|
overload QwtRoundScaleDraw::label().
|
|
|
|
\sa scaleDraw()
|
|
*/
|
|
void QwtKnob::setScaleDraw( QwtRoundScaleDraw *scaleDraw )
|
|
{
|
|
setAbstractScaleDraw( scaleDraw );
|
|
setTotalAngle( d_data->totalAngle );
|
|
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
|
|
/*!
|
|
\return the scale draw of the knob
|
|
\sa setScaleDraw()
|
|
*/
|
|
const QwtRoundScaleDraw *QwtKnob::scaleDraw() const
|
|
{
|
|
return static_cast<const QwtRoundScaleDraw *>( abstractScaleDraw() );
|
|
}
|
|
|
|
/*!
|
|
\return the scale draw of the knob
|
|
\sa setScaleDraw()
|
|
*/
|
|
QwtRoundScaleDraw *QwtKnob::scaleDraw()
|
|
{
|
|
return static_cast<QwtRoundScaleDraw *>( abstractScaleDraw() );
|
|
}
|
|
|
|
/*!
|
|
Calculate the bounding rectangle of the knob without the scale
|
|
|
|
\return Bounding rectangle of the knob
|
|
\sa knobWidth(), alignment(), QWidget::contentsRect()
|
|
*/
|
|
QRect QwtKnob::knobRect() const
|
|
{
|
|
const QRect cr = contentsRect();
|
|
|
|
const int extent = qCeil( scaleDraw()->extent( font() ) );
|
|
const int d = extent + d_data->scaleDist;
|
|
|
|
int w = d_data->knobWidth;
|
|
if ( w <= 0 )
|
|
{
|
|
const int dim = qMin( cr.width(), cr.height() );
|
|
|
|
w = dim - 2 * ( d );
|
|
w = qMax( 0, w );
|
|
}
|
|
|
|
QRect r( 0, 0, w, w );
|
|
|
|
if ( d_data->alignment & Qt::AlignLeft )
|
|
{
|
|
r.moveLeft( cr.left() + d );
|
|
}
|
|
else if ( d_data->alignment & Qt::AlignRight )
|
|
{
|
|
r.moveRight( cr.right() - d );
|
|
}
|
|
else
|
|
{
|
|
r.moveCenter( QPoint( cr.center().x(), r.center().y() ) );
|
|
}
|
|
|
|
if ( d_data->alignment & Qt::AlignTop )
|
|
{
|
|
r.moveTop( cr.top() + d );
|
|
}
|
|
else if ( d_data->alignment & Qt::AlignBottom )
|
|
{
|
|
r.moveBottom( cr.bottom() - d );
|
|
}
|
|
else
|
|
{
|
|
r.moveCenter( QPoint( r.center().x(), cr.center().y() ) );
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
/*!
|
|
\brief Determine what to do when the user presses a mouse button.
|
|
|
|
\param pos Mouse position
|
|
|
|
\retval True, when pos is inside the circle of the knob.
|
|
\sa scrolledTo()
|
|
*/
|
|
bool QwtKnob::isScrollPosition( const QPoint &pos ) const
|
|
{
|
|
const QRect kr = knobRect();
|
|
|
|
const QRegion region( kr, QRegion::Ellipse );
|
|
if ( region.contains( pos ) && ( pos != kr.center() ) )
|
|
{
|
|
const double angle = QLineF( kr.center(), pos ).angle();
|
|
const double valueAngle = qwtToDegrees( scaleMap().transform( value() ) );
|
|
|
|
d_data->mouseOffset = qwtNormalizeDegrees( angle - valueAngle );
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*!
|
|
\brief Determine the value for a new position of the mouse
|
|
|
|
\param pos Mouse position
|
|
|
|
\return Value for the mouse position
|
|
\sa isScrollPosition()
|
|
*/
|
|
double QwtKnob::scrolledTo( const QPoint &pos ) const
|
|
{
|
|
double angle = QLineF( rect().center(), pos ).angle();
|
|
angle = qwtNormalizeDegrees( angle - d_data->mouseOffset );
|
|
|
|
if ( scaleMap().pDist() > 360.0 )
|
|
{
|
|
angle = qwtToDegrees( angle );
|
|
|
|
const double v = scaleMap().transform( value() );
|
|
|
|
int numTurns = qFloor( ( v - scaleMap().p1() ) / 360.0 );
|
|
|
|
double valueAngle = qwtNormalizeDegrees( v );
|
|
if ( qAbs( valueAngle - angle ) > 180.0 )
|
|
{
|
|
numTurns += ( angle > valueAngle ) ? -1 : 1;
|
|
}
|
|
|
|
angle += scaleMap().p1() + numTurns * 360.0;
|
|
|
|
if ( !wrapping() )
|
|
{
|
|
const double boundedAngle =
|
|
qBound( scaleMap().p1(), angle, scaleMap().p2() );
|
|
|
|
d_data->mouseOffset += ( boundedAngle - angle );
|
|
angle = boundedAngle;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
angle = qwtToScaleAngle( angle );
|
|
|
|
double boundedAngle = qBound( scaleMap().p1(), angle, scaleMap().p2() );
|
|
|
|
if ( !wrapping() )
|
|
{
|
|
const double currentAngle = scaleMap().transform( value() );
|
|
|
|
if ( ( currentAngle > 90.0 ) && ( boundedAngle < -90.0 ) )
|
|
boundedAngle = scaleMap().p2();
|
|
else if ( ( currentAngle < -90.0 ) && ( boundedAngle > 90.0 ) )
|
|
boundedAngle = scaleMap().p1();
|
|
|
|
d_data->mouseOffset += ( boundedAngle - angle );
|
|
}
|
|
|
|
angle = boundedAngle;
|
|
}
|
|
|
|
return scaleMap().invTransform( angle );
|
|
}
|
|
|
|
/*!
|
|
Handle QEvent::StyleChange and QEvent::FontChange;
|
|
\param event Change event
|
|
*/
|
|
void QwtKnob::changeEvent( QEvent *event )
|
|
{
|
|
switch( event->type() )
|
|
{
|
|
case QEvent::StyleChange:
|
|
case QEvent::FontChange:
|
|
{
|
|
updateGeometry();
|
|
update();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Repaint the knob
|
|
\param event Paint event
|
|
*/
|
|
void QwtKnob::paintEvent( QPaintEvent *event )
|
|
{
|
|
const QRectF knobRect = this->knobRect();
|
|
|
|
QPainter painter( this );
|
|
painter.setClipRegion( event->region() );
|
|
|
|
QStyleOption opt;
|
|
opt.init(this);
|
|
style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
|
|
|
|
painter.setRenderHint( QPainter::Antialiasing, true );
|
|
|
|
if ( !knobRect.contains( event->region().boundingRect() ) )
|
|
{
|
|
scaleDraw()->setRadius( 0.5 * knobRect.width() + d_data->scaleDist );
|
|
scaleDraw()->moveCenter( knobRect.center() );
|
|
|
|
scaleDraw()->draw( &painter, palette() );
|
|
}
|
|
|
|
drawKnob( &painter, knobRect );
|
|
|
|
drawMarker( &painter, knobRect,
|
|
qwtNormalizeDegrees( scaleMap().transform( value() ) ) );
|
|
|
|
painter.setRenderHint( QPainter::Antialiasing, false );
|
|
|
|
if ( hasFocus() )
|
|
drawFocusIndicator( &painter );
|
|
}
|
|
|
|
/*!
|
|
\brief Draw the knob
|
|
|
|
\param painter painter
|
|
\param knobRect Bounding rectangle of the knob (without scale)
|
|
*/
|
|
void QwtKnob::drawKnob( QPainter *painter, const QRectF &knobRect ) const
|
|
{
|
|
double dim = qMin( knobRect.width(), knobRect.height() );
|
|
dim -= d_data->borderWidth * 0.5;
|
|
|
|
QRectF aRect( 0, 0, dim, dim );
|
|
aRect.moveCenter( knobRect.center() );
|
|
|
|
QPen pen( Qt::NoPen );
|
|
if ( d_data->borderWidth > 0 )
|
|
{
|
|
QColor c1 = palette().color( QPalette::Light );
|
|
QColor c2 = palette().color( QPalette::Dark );
|
|
|
|
QLinearGradient gradient( aRect.topLeft(), aRect.bottomRight() );
|
|
gradient.setColorAt( 0.0, c1 );
|
|
gradient.setColorAt( 0.3, c1 );
|
|
gradient.setColorAt( 0.7, c2 );
|
|
gradient.setColorAt( 1.0, c2 );
|
|
|
|
pen = QPen( gradient, d_data->borderWidth );
|
|
}
|
|
|
|
QBrush brush;
|
|
switch( d_data->knobStyle )
|
|
{
|
|
case QwtKnob::Raised:
|
|
{
|
|
double off = 0.3 * knobRect.width();
|
|
QRadialGradient gradient( knobRect.center(),
|
|
knobRect.width(), knobRect.topLeft() + QPointF( off, off ) );
|
|
|
|
gradient.setColorAt( 0.0, palette().color( QPalette::Midlight ) );
|
|
gradient.setColorAt( 1.0, palette().color( QPalette::Button ) );
|
|
|
|
brush = QBrush( gradient );
|
|
|
|
break;
|
|
}
|
|
case QwtKnob::Styled:
|
|
{
|
|
QRadialGradient gradient(knobRect.center().x() - knobRect.width() / 3,
|
|
knobRect.center().y() - knobRect.height() / 2,
|
|
knobRect.width() * 1.3,
|
|
knobRect.center().x(),
|
|
knobRect.center().y() - knobRect.height() / 2);
|
|
|
|
const QColor c = palette().color( QPalette::Button );
|
|
gradient.setColorAt(0, c.lighter(110));
|
|
gradient.setColorAt(qreal(0.5), c);
|
|
gradient.setColorAt(qreal(0.501), c.darker(102));
|
|
gradient.setColorAt(1, c.darker(115));
|
|
|
|
brush = QBrush( gradient );
|
|
|
|
break;
|
|
}
|
|
case QwtKnob::Sunken:
|
|
{
|
|
QLinearGradient gradient(
|
|
knobRect.topLeft(), knobRect.bottomRight() );
|
|
gradient.setColorAt( 0.0, palette().color( QPalette::Mid ) );
|
|
gradient.setColorAt( 0.5, palette().color( QPalette::Button ) );
|
|
gradient.setColorAt( 1.0, palette().color( QPalette::Midlight ) );
|
|
brush = QBrush( gradient );
|
|
|
|
break;
|
|
}
|
|
case QwtKnob::Flat:
|
|
default:
|
|
brush = palette().brush( QPalette::Button );
|
|
}
|
|
|
|
painter->setPen( pen );
|
|
painter->setBrush( brush );
|
|
painter->drawEllipse( aRect );
|
|
}
|
|
|
|
|
|
/*!
|
|
\brief Draw the marker at the knob's front
|
|
|
|
\param painter Painter
|
|
\param rect Bounding rectangle of the knob without scale
|
|
\param angle Angle of the marker in degrees
|
|
( clockwise, 0 at the 12 o'clock position )
|
|
*/
|
|
void QwtKnob::drawMarker( QPainter *painter,
|
|
const QRectF &rect, double angle ) const
|
|
{
|
|
if ( d_data->markerStyle == NoMarker || !isValid() )
|
|
return;
|
|
|
|
const double radians = qwtRadians( angle );
|
|
const double sinA = -qFastSin( radians );
|
|
const double cosA = qFastCos( radians );
|
|
|
|
const double xm = rect.center().x();
|
|
const double ym = rect.center().y();
|
|
const double margin = 4.0;
|
|
|
|
double radius = 0.5 * ( rect.width() - d_data->borderWidth ) - margin;
|
|
if ( radius < 1.0 )
|
|
radius = 1.0;
|
|
|
|
int markerSize = d_data->markerSize;
|
|
if ( markerSize <= 0 )
|
|
markerSize = qRound( 0.4 * radius );
|
|
|
|
switch ( d_data->markerStyle )
|
|
{
|
|
case Notch:
|
|
case Nub:
|
|
{
|
|
const double dotWidth =
|
|
qMin( double( markerSize ), radius);
|
|
|
|
const double dotCenterDist = radius - 0.5 * dotWidth;
|
|
if ( dotCenterDist > 0.0 )
|
|
{
|
|
const QPointF center( xm - sinA * dotCenterDist,
|
|
ym - cosA * dotCenterDist );
|
|
|
|
QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth );
|
|
ellipse.moveCenter( center );
|
|
|
|
QColor c1 = palette().color( QPalette::Light );
|
|
QColor c2 = palette().color( QPalette::Mid );
|
|
|
|
if ( d_data->markerStyle == Notch )
|
|
qSwap( c1, c2 );
|
|
|
|
QLinearGradient gradient(
|
|
ellipse.topLeft(), ellipse.bottomRight() );
|
|
gradient.setColorAt( 0.0, c1 );
|
|
gradient.setColorAt( 1.0, c2 );
|
|
|
|
painter->setPen( Qt::NoPen );
|
|
painter->setBrush( gradient );
|
|
|
|
painter->drawEllipse( ellipse );
|
|
}
|
|
break;
|
|
}
|
|
case Dot:
|
|
{
|
|
const double dotWidth =
|
|
qMin( double( markerSize ), radius);
|
|
|
|
const double dotCenterDist = radius - 0.5 * dotWidth;
|
|
if ( dotCenterDist > 0.0 )
|
|
{
|
|
const QPointF center( xm - sinA * dotCenterDist,
|
|
ym - cosA * dotCenterDist );
|
|
|
|
QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth );
|
|
ellipse.moveCenter( center );
|
|
|
|
painter->setPen( Qt::NoPen );
|
|
painter->setBrush( palette().color( QPalette::ButtonText ) );
|
|
painter->drawEllipse( ellipse );
|
|
}
|
|
|
|
break;
|
|
}
|
|
case Tick:
|
|
{
|
|
const double rb = qMax( radius - markerSize, 1.0 );
|
|
const double re = radius;
|
|
|
|
const QLineF line( xm - sinA * rb, ym - cosA * rb,
|
|
xm - sinA * re, ym - cosA * re );
|
|
|
|
QPen pen( palette().color( QPalette::ButtonText ), 0 );
|
|
pen.setCapStyle( Qt::FlatCap );
|
|
painter->setPen( pen );
|
|
painter->drawLine ( line );
|
|
|
|
break;
|
|
}
|
|
case Triangle:
|
|
{
|
|
const double rb = qMax( radius - markerSize, 1.0 );
|
|
const double re = radius;
|
|
|
|
painter->translate( rect.center() );
|
|
painter->rotate( angle - 90.0 );
|
|
|
|
QPolygonF polygon;
|
|
polygon += QPointF( re, 0.0 );
|
|
polygon += QPointF( rb, 0.5 * ( re - rb ) );
|
|
polygon += QPointF( rb, -0.5 * ( re - rb ) );
|
|
|
|
painter->setPen( Qt::NoPen );
|
|
painter->setBrush( palette().color( QPalette::ButtonText ) );
|
|
painter->drawPolygon( polygon );
|
|
|
|
painter->resetTransform();
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Draw the focus indicator
|
|
\param painter Painter
|
|
*/
|
|
void QwtKnob::drawFocusIndicator( QPainter *painter ) const
|
|
{
|
|
const QRect cr = contentsRect();
|
|
|
|
int w = d_data->knobWidth;
|
|
if ( w <= 0 )
|
|
{
|
|
w = qMin( cr.width(), cr.height() );
|
|
}
|
|
else
|
|
{
|
|
const int extent = qCeil( scaleDraw()->extent( font() ) );
|
|
w += 2 * ( extent + d_data->scaleDist );
|
|
}
|
|
|
|
QRect focusRect( 0, 0, w, w );
|
|
focusRect.moveCenter( cr.center() );
|
|
|
|
QwtPainter::drawFocusRect( painter, this, focusRect );
|
|
}
|
|
|
|
/*!
|
|
\brief Set the alignment of the knob
|
|
|
|
Similar to a QLabel::alignment() the flags decide how
|
|
to align the knob inside of contentsRect().
|
|
|
|
The default setting is Qt::AlignCenter
|
|
|
|
\param alignment Or'd alignment flags
|
|
|
|
\sa alignment(), setKnobWidth(), knobRect()
|
|
*/
|
|
void QwtKnob::setAlignment( Qt::Alignment alignment )
|
|
{
|
|
if ( d_data->alignment != alignment )
|
|
{
|
|
d_data->alignment = alignment;
|
|
update();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Alignment of the knob inside of contentsRect()
|
|
\sa setAlignment(), knobWidth(), knobRect()
|
|
*/
|
|
Qt::Alignment QwtKnob::alignment() const
|
|
{
|
|
return d_data->alignment;
|
|
}
|
|
|
|
/*!
|
|
\brief Change the knob's width.
|
|
|
|
Setting a fixed value for the diameter of the knob
|
|
is helpful for aligning several knobs in a row.
|
|
|
|
\param width New width
|
|
|
|
\sa knobWidth(), setAlignment()
|
|
\note Modifies the sizePolicy()
|
|
*/
|
|
void QwtKnob::setKnobWidth( int width )
|
|
{
|
|
width = qMax( width, 0 );
|
|
|
|
if ( width != d_data->knobWidth )
|
|
{
|
|
QSizePolicy::Policy policy;
|
|
if ( width > 0 )
|
|
policy = QSizePolicy::Minimum;
|
|
else
|
|
policy = QSizePolicy::MinimumExpanding;
|
|
|
|
setSizePolicy( policy, policy );
|
|
|
|
d_data->knobWidth = width;
|
|
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
}
|
|
|
|
//! Return the width of the knob
|
|
int QwtKnob::knobWidth() const
|
|
{
|
|
return d_data->knobWidth;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the knob's border width
|
|
\param borderWidth new border width
|
|
*/
|
|
void QwtKnob::setBorderWidth( int borderWidth )
|
|
{
|
|
d_data->borderWidth = qMax( borderWidth, 0 );
|
|
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
|
|
//! Return the border width
|
|
int QwtKnob::borderWidth() const
|
|
{
|
|
return d_data->borderWidth;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the size of the marker
|
|
|
|
When setting a size <= 0 the marker will
|
|
automatically scaled to 40% of the radius of the knob.
|
|
|
|
\sa markerSize(), markerStyle()
|
|
*/
|
|
void QwtKnob::setMarkerSize( int size )
|
|
{
|
|
if ( d_data->markerSize != size )
|
|
{
|
|
d_data->markerSize = size;
|
|
update();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Marker size
|
|
\sa setMarkerSize()
|
|
*/
|
|
int QwtKnob::markerSize() const
|
|
{
|
|
return d_data->markerSize;
|
|
}
|
|
|
|
/*!
|
|
\return sizeHint()
|
|
*/
|
|
QSize QwtKnob::sizeHint() const
|
|
{
|
|
const QSize hint = qwtKnobSizeHint( this, 50 );
|
|
return hint.expandedTo( QApplication::globalStrut() );
|
|
}
|
|
|
|
/*!
|
|
\return Minimum size hint
|
|
\sa sizeHint()
|
|
*/
|
|
QSize QwtKnob::minimumSizeHint() const
|
|
{
|
|
return qwtKnobSizeHint( this, 20 );
|
|
}
|