11#include "qwt_round_scale_draw.h" 
   12#include "qwt_painter.h" 
   13#include "qwt_scale_map.h" 
   20#include <qstyleoption.h> 
   25static QSize qwtKnobSizeHint( 
const QwtKnob* knob, 
int min )
 
   29        knobWidth = qMax( 3 * knob->
markerSize(), min );
 
   32    const int extent = qwtCeil( knob->
scaleDraw()->
extent( knob->font() ) );
 
   33    const int d = 2 * ( extent + 4 ) + knobWidth;
 
   35    const QMargins m = knob->contentsMargins();
 
   36    return QSize( d + m.left() + m.right(), d + m.top() + m.bottom() );
 
   39static inline double qwtToScaleAngle( 
double angle )
 
   44    double a = 90.0 - angle;
 
   47    else if ( a >= 180.0 )
 
   53static double qwtToDegrees( 
double value )
 
   55    return qwtNormalizeDegrees( 90.0 - value );
 
   58class QwtKnob::PrivateData
 
   69        , alignment( Qt::AlignCenter )
 
   84    Qt::Alignment alignment;
 
  106    m_data = 
new PrivateData;
 
  115    setSizePolicy( QSizePolicy::MinimumExpanding,
 
  116        QSizePolicy::MinimumExpanding );
 
 
  146    return m_data->knobStyle;
 
 
  170    return m_data->markerStyle;
 
 
  187    angle = qBound( 10.0, angle, 360.0 );
 
  189    if ( angle != m_data->totalAngle )
 
  191        m_data->totalAngle = angle;
 
  194            0.5 * m_data->totalAngle );
 
 
  207    return m_data->totalAngle;
 
 
  223    if ( 
numTurns == 1 && m_data->totalAngle <= 360.0 )
 
  226    const double angle = 
numTurns * 360.0;
 
  227    if ( angle != m_data->totalAngle )
 
  229        m_data->totalAngle = angle;
 
  232            0.5 * m_data->totalAngle );
 
 
  247    return qwtCeil( m_data->totalAngle / 360.0 );
 
 
  294    const QRect cr = contentsRect();
 
  296    const int extent = qwtCeil( 
scaleDraw()->extent( font() ) );
 
  297    const int d = extent + m_data->scaleDist;
 
  299    int w = m_data->knobWidth;
 
  302        const int dim = qMin( cr.width(), cr.height() );
 
  308    QRect r( 0, 0, w, w );
 
  310    if ( m_data->alignment & Qt::AlignLeft )
 
  312        r.moveLeft( cr.left() + d );
 
  314    else if ( m_data->alignment & Qt::AlignRight )
 
  316        r.moveRight( cr.right() - d );
 
  320        r.moveCenter( QPoint( cr.center().x(), r.center().y() ) );
 
  323    if ( m_data->alignment & Qt::AlignTop )
 
  325        r.moveTop( cr.top() + d );
 
  327    else if ( m_data->alignment & Qt::AlignBottom )
 
  329        r.moveBottom( cr.bottom() - d );
 
  333        r.moveCenter( QPoint( r.center().x(), cr.center().y() ) );
 
 
  351    const QRegion region( kr, QRegion::Ellipse );
 
  352    if ( region.contains( pos ) && ( pos != kr.center() ) )
 
  354        const double angle = QLineF( kr.center(), pos ).angle();
 
  357        m_data->mouseOffset = qwtNormalizeDegrees( angle - valueAngle );
 
 
  375    double angle = QLineF( rect().center(), pos ).angle();
 
  376    angle = qwtNormalizeDegrees( angle - m_data->mouseOffset );
 
  380        angle = qwtToDegrees( angle );
 
  386        double valueAngle = qwtNormalizeDegrees( v );
 
  387        if ( qAbs( valueAngle - angle ) > 180.0 )
 
  389            numTurns += ( angle > valueAngle ) ? -1 : 1;
 
  396            const double boundedAngle =
 
  399            m_data->mouseOffset += ( boundedAngle - angle );
 
  400            angle = boundedAngle;
 
  405        angle = qwtToScaleAngle( angle );
 
  413            if ( ( currentAngle > 90.0 ) && ( boundedAngle < -90.0 ) )
 
  415            else if ( ( currentAngle < -90.0 ) && ( boundedAngle > 90.0 ) )
 
  418            m_data->mouseOffset += ( boundedAngle - angle );
 
  421        angle = boundedAngle;
 
 
  433    switch( event->type() )
 
  435        case QEvent::StyleChange:
 
  436        case QEvent::FontChange:
 
 
  455    QPainter painter( 
this );
 
  456    painter.setClipRegion( event->region() );
 
  460    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, 
this);
 
  462    painter.setRenderHint( QPainter::Antialiasing, 
true );
 
  464    if ( !
knobRect.contains( event->region().boundingRect() ) )
 
  477    painter.setRenderHint( QPainter::Antialiasing, 
false );
 
 
  492    dim -= m_data->borderWidth * 0.5;
 
  494    QRectF aRect( 0, 0, dim, dim );
 
  495    aRect.moveCenter( 
knobRect.center() );
 
  497    QPen pen( Qt::NoPen );
 
  498    if ( m_data->borderWidth > 0 )
 
  500        QColor c1 = palette().color( QPalette::Light );
 
  501        QColor c2 = palette().color( QPalette::Dark );
 
  503        QLinearGradient gradient( aRect.topLeft(), aRect.bottomRight() );
 
  504        gradient.setColorAt( 0.0, c1 );
 
  505        gradient.setColorAt( 0.3, c1 );
 
  506        gradient.setColorAt( 0.7, c2 );
 
  507        gradient.setColorAt( 1.0, c2 );
 
  509        pen = QPen( gradient, m_data->borderWidth );
 
  513    switch( m_data->knobStyle )
 
  517            double off = 0.3 * 
knobRect.width();
 
  518            QRadialGradient gradient( 
knobRect.center(),
 
  521            gradient.setColorAt( 0.0, palette().color( QPalette::Midlight ) );
 
  522            gradient.setColorAt( 1.0, palette().color( QPalette::Button ) );
 
  524            brush = QBrush( gradient );
 
  536            const QColor c = palette().color( QPalette::Button );
 
  537            gradient.setColorAt(0, c.lighter(110) );
 
  538            gradient.setColorAt( 0.5, c);
 
  539            gradient.setColorAt( 0.501, c.darker(102) );
 
  540            gradient.setColorAt(1, c.darker(115) );
 
  542            brush = QBrush( gradient );
 
  548            QLinearGradient gradient(
 
  550            gradient.setColorAt( 0.0, palette().color( QPalette::Mid ) );
 
  551            gradient.setColorAt( 0.5, palette().color( QPalette::Button ) );
 
  552            gradient.setColorAt( 1.0, palette().color( QPalette::Midlight ) );
 
  553            brush = QBrush( gradient );
 
  559            brush = palette().brush( QPalette::Button );
 
  562    painter->setPen( pen );
 
  563    painter->setBrush( brush );
 
  564    painter->drawEllipse( aRect );
 
 
  577    const QRectF& rect, 
double angle )
 const 
  582    const double radians = qwtRadians( angle );
 
  583    const double sinA = -qFastSin( radians );
 
  584    const double cosA = qFastCos( radians );
 
  586    const double xm = rect.center().x();
 
  587    const double ym = rect.center().y();
 
  588    const double margin = 4.0;
 
  590    double radius = 0.5 * ( rect.width() - m_data->borderWidth ) - margin;
 
  598    switch ( m_data->markerStyle )
 
  603            const double dotWidth = qwtMinF( 
markerSize, radius );
 
  605            const double dotCenterDist = radius - 0.5 * dotWidth;
 
  606            if ( dotCenterDist > 0.0 )
 
  608                const QPointF center( xm - sinA * dotCenterDist,
 
  609                    ym - cosA * dotCenterDist );
 
  611                QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth );
 
  612                ellipse.moveCenter( center );
 
  614                QColor c1 = palette().color( QPalette::Light );
 
  615                QColor c2 = palette().color( QPalette::Mid );
 
  617                if ( m_data->markerStyle == 
Notch )
 
  620                QLinearGradient gradient(
 
  621                    ellipse.topLeft(), ellipse.bottomRight() );
 
  622                gradient.setColorAt( 0.0, c1 );
 
  623                gradient.setColorAt( 1.0, c2 );
 
  625                painter->setPen( Qt::NoPen );
 
  626                painter->setBrush( gradient );
 
  628                painter->drawEllipse( ellipse );
 
  634            const double dotWidth = qwtMinF( 
markerSize, radius);
 
  636            const double dotCenterDist = radius - 0.5 * dotWidth;
 
  637            if ( dotCenterDist > 0.0 )
 
  639                const QPointF center( xm - sinA * dotCenterDist,
 
  640                    ym - cosA * dotCenterDist );
 
  642                QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth );
 
  643                ellipse.moveCenter( center );
 
  645                painter->setPen( Qt::NoPen );
 
  646                painter->setBrush( palette().color( QPalette::ButtonText ) );
 
  647                painter->drawEllipse( ellipse );
 
  654            const double rb = qwtMaxF( radius - 
markerSize, 1.0 );
 
  655            const double re = radius;
 
  657            const QLineF line( xm - sinA * rb, ym - cosA * rb,
 
  658                xm - sinA * re, ym - cosA * re );
 
  660            QPen pen( palette().color( QPalette::ButtonText ), 0 );
 
  661            pen.setCapStyle( Qt::FlatCap );
 
  662            painter->setPen( pen );
 
  663            painter->drawLine ( line );
 
  669            const double rb = qwtMaxF( radius - 
markerSize, 1.0 );
 
  670            const double re = radius;
 
  672            painter->translate( rect.center() );
 
  673            painter->rotate( angle - 90.0 );
 
  676            polygon += QPointF( re, 0.0 );
 
  677            polygon += QPointF( rb, 0.5 * ( re - rb ) );
 
  678            polygon += QPointF( rb, -0.5 * ( re - rb ) );
 
  680            painter->setPen( Qt::NoPen );
 
  681            painter->setBrush( palette().color( QPalette::ButtonText ) );
 
  682            painter->drawPolygon( polygon );
 
  684            painter->resetTransform();
 
 
  699    const QRect cr = contentsRect();
 
  701    int w = m_data->knobWidth;
 
  704        w = qMin( cr.width(), cr.height() );
 
  708        const int extent = qCeil( 
scaleDraw()->extent( font() ) );
 
  709        w += 2 * ( extent + m_data->scaleDist );
 
  712    QRect focusRect( 0, 0, w, w );
 
  713    focusRect.moveCenter( cr.center() );
 
 
  745    return m_data->alignment;
 
 
  761    width = qMax( width, 0 );
 
  763    if ( width != m_data->knobWidth )
 
  765        QSizePolicy::Policy policy;
 
  767            policy = QSizePolicy::Minimum;
 
  769            policy = QSizePolicy::MinimumExpanding;
 
  771        setSizePolicy( policy, policy );
 
  773        m_data->knobWidth = width;
 
 
  783    return m_data->knobWidth;
 
 
  801    return m_data->borderWidth;
 
 
  814    if ( m_data->markerSize != size )
 
  816        m_data->markerSize = size;
 
 
  827    return m_data->markerSize;
 
 
  835    const QSize hint = qwtKnobSizeHint( 
this, 50 );
 
  836    return qwtExpandedToGlobalStrut( hint );
 
 
  845    return qwtKnobSizeHint( 
this, 20 );
 
 
  848#include "moc_qwt_knob.cpp" 
virtual void draw(QPainter *, const QPalette &) const
Draw the scale.
const QwtScaleMap & scaleMap() const
const QwtAbstractScaleDraw * abstractScaleDraw() const
int transform(double) const
void setAbstractScaleDraw(QwtAbstractScaleDraw *)
Set a scale draw.
void setScale(double lowerBound, double upperBound)
Specify a scale.
An abstract base class for slider widgets with a scale.
void setValue(double value)
double value() const
Returns the current value.
virtual double scrolledTo(const QPoint &) const override
Determine the value for a new position of the mouse.
virtual ~QwtKnob()
Destructor.
void setKnobWidth(int)
Change the knob's width.
void setKnobStyle(KnobStyle)
Set the knob type.
int knobWidth() const
Return the width of the knob.
Qt::Alignment alignment() const
virtual bool isScrollPosition(const QPoint &) const override
Determine what to do when the user presses a mouse button.
@ Dot
Paint a circle in QPalette::ButtonText color.
@ Tick
Paint a single tick in QPalette::ButtonText color.
@ Triangle
Paint a triangle in QPalette::ButtonText color.
@ NoMarker
Don't paint any marker.
const QwtRoundScaleDraw * scaleDraw() const
QwtKnob(QWidget *parent=NULL)
Constructor.
void setTotalAngle(double angle)
Set the total angle by which the knob can be turned.
void setMarkerSize(int)
Set the size of the marker.
virtual void drawFocusIndicator(QPainter *) const
void setNumTurns(int)
Set the number of turns.
MarkerStyle markerStyle() const
virtual void changeEvent(QEvent *) override
void setMarkerStyle(MarkerStyle)
Set the marker type of the knob.
KnobStyle knobStyle() const
double totalAngle() const
void setAlignment(Qt::Alignment)
Set the alignment of the knob.
virtual void paintEvent(QPaintEvent *) override
virtual void drawMarker(QPainter *, const QRectF &, double angle) const
Draw the marker at the knob's front.
virtual void drawKnob(QPainter *, const QRectF &) const
Draw the knob.
KnobStyle
Style of the knob surface.
@ Flat
Fill the knob with a brush from QPalette::Button.
@ Raised
Build a gradient from QPalette::Midlight and QPalette::Button.
int borderWidth() const
Return the border width.
virtual QSize minimumSizeHint() const override
void setBorderWidth(int)
Set the knob's border width.
virtual QSize sizeHint() const override
void setScaleDraw(QwtRoundScaleDraw *)
static void drawFocusRect(QPainter *, const QWidget *)
Draw a focus rectangle on a widget using its style.
A class for drawing round scales.
virtual double extent(const QFont &) const override
void setRadius(double radius)
void setAngleRange(double angle1, double angle2)
Adjust the baseline circle segment for round scales.
void moveCenter(double x, double y)
Move the center of the scale draw, leaving the radius unchanged.
double transform(double s) const
double invTransform(double p) const