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