qwt_dial.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_dial.h"
11 #include "qwt_dial_needle.h"
12 #include "qwt_math.h"
13 #include "qwt_scale_map.h"
14 #include "qwt_round_scale_draw.h"
15 #include "qwt_painter.h"
16 #include "qwt.h"
17 
18 #include <qpainter.h>
19 #include <qpalette.h>
20 #include <qpixmap.h>
21 #include <qevent.h>
22 #include <qstyle.h>
23 #include <qstyleoption.h>
24 
25 static inline double qwtAngleDist( double a1, double a2 )
26 {
27  double dist = qAbs( a2 - a1 );
28  if ( dist > 360.0 )
29  dist -= 360.0;
30 
31  return dist;
32 }
33 
34 static inline bool qwtIsOnArc( double angle, double min, double max )
35 {
36  if ( min < max )
37  {
38  return ( angle >= min ) && ( angle <= max );
39  }
40  else
41  {
42  return ( angle >= min ) || ( angle <= max );
43  }
44 }
45 
46 static inline double qwtBoundedAngle( double min, double angle, double max )
47 {
48  double from = qwtNormalizeDegrees( min );
49  double to = qwtNormalizeDegrees( max );
50 
51  double a;
52 
53  if ( qwtIsOnArc( angle, from, to ) )
54  {
55  a = angle;
56  if ( a < min )
57  a += 360.0;
58  }
59  else
60  {
61  if ( qwtAngleDist( angle, from ) <
62  qwtAngleDist( angle, to ) )
63  {
64  a = min;
65  }
66  else
67  {
68  a = max;
69  }
70  }
71 
72  return a;
73 }
74 
76 {
77 public:
80  lineWidth( 0 ),
81  mode( RotateNeedle ),
82  origin( 90.0 ),
83  minScaleArc( 0.0 ),
84  maxScaleArc( 0.0 ),
85  needle( NULL ),
86  arcOffset( 0.0 ),
87  mouseOffset( 0.0 )
88  {
89  }
90 
92  {
93  delete needle;
94  }
96  int lineWidth;
97 
99 
100  double origin;
101  double minScaleArc;
102  double maxScaleArc;
103 
105 
106  double arcOffset;
107  double mouseOffset;
108 
109  QPixmap pixmapCache;
110 };
111 
124 QwtDial::QwtDial( QWidget* parent ):
125  QwtAbstractSlider( parent )
126 {
127  d_data = new PrivateData;
128 
129  setFocusPolicy( Qt::TabFocus );
130 
131  QPalette p = palette();
132  for ( int i = 0; i < QPalette::NColorGroups; i++ )
133  {
134  const QPalette::ColorGroup colorGroup =
135  static_cast<QPalette::ColorGroup>( i );
136 
137  // Base: background color of the circle inside the frame.
138  // WindowText: background color of the circle inside the scale
139 
140  p.setColor( colorGroup, QPalette::WindowText,
141  p.color( colorGroup, QPalette::Base ) );
142  }
143  setPalette( p );
144 
146  scaleDraw->setRadius( 0 );
147 
148  setScaleDraw( scaleDraw );
149 
150  setScaleArc( 0.0, 360.0 ); // scale as a full circle
151 
152  setScaleMaxMajor( 10 );
153  setScaleMaxMinor( 5 );
154 
155  setValue( 0.0 );
156 }
157 
160 {
161  delete d_data;
162 }
163 
171 {
172  if ( shadow != d_data->frameShadow )
173  {
174  invalidateCache();
175 
176  d_data->frameShadow = shadow;
177  if ( lineWidth() > 0 )
178  update();
179  }
180 }
181 
187 {
188  return d_data->frameShadow;
189 }
190 
198 {
199  if ( lineWidth < 0 )
200  lineWidth = 0;
201 
202  if ( d_data->lineWidth != lineWidth )
203  {
204  invalidateCache();
205 
207  update();
208  }
209 }
210 
215 int QwtDial::lineWidth() const
216 {
217  return d_data->lineWidth;
218 }
219 
224 QRect QwtDial::innerRect() const
225 {
226  const int lw = lineWidth();
227  return boundingRect().adjusted( lw, lw, -lw, -lw );
228 }
229 
235 {
236  const QRect cr = contentsRect();
237 
238  const int dim = qMin( cr.width(), cr.height() );
239 
240  QRect inner( 0, 0, dim, dim );
241  inner.moveCenter( cr.center() );
242 
243  return inner;
244 }
245 
251 {
252  QRect rect = innerRect();
253 
254  const QwtAbstractScaleDraw *sd = scaleDraw();
255  if ( sd )
256  {
257  int scaleDist = qwtCeil( sd->extent( font() ) );
258  scaleDist++; // margin
259 
260  rect.adjust( scaleDist, scaleDist, -scaleDist, -scaleDist );
261  }
262 
263  return rect;
264 }
265 
279 {
280  if ( mode != d_data->mode )
281  {
282  invalidateCache();
283 
284  d_data->mode = mode;
285  sliderChange();
286  }
287 }
288 
294 {
295  return d_data->mode;
296 }
297 
302 {
303  d_data->pixmapCache = QPixmap();
304 }
305 
310 void QwtDial::paintEvent( QPaintEvent *event )
311 {
312  QPainter painter( this );
313  painter.setClipRegion( event->region() );
314 
315  QStyleOption opt;
316  opt.initFrom(this);
317  style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
318 
319  if ( d_data->mode == QwtDial::RotateScale )
320  {
321  painter.save();
322  painter.setRenderHint( QPainter::Antialiasing, true );
323 
324  drawContents( &painter );
325 
326  painter.restore();
327  }
328 
329  const QRect r = contentsRect();
330  if ( r.size() != d_data->pixmapCache.size() )
331  {
332  d_data->pixmapCache = QwtPainter::backingStore( this, r.size() );
333  d_data->pixmapCache.fill( Qt::transparent );
334 
335  QPainter p( &d_data->pixmapCache );
336  p.setRenderHint( QPainter::Antialiasing, true );
337  p.translate( -r.topLeft() );
338 
339  if ( d_data->mode != QwtDial::RotateScale )
340  drawContents( &p );
341 
342  if ( lineWidth() > 0 )
343  drawFrame( &p );
344 
346  drawNeedle( &p );
347  }
348 
349  painter.drawPixmap( r.topLeft(), d_data->pixmapCache );
350 
352  drawNeedle( &painter );
353 
354  if ( hasFocus() )
355  drawFocusIndicator( &painter );
356 }
357 
362 void QwtDial::drawFocusIndicator( QPainter *painter ) const
363 {
364  QwtPainter::drawFocusRect( painter, this, boundingRect() );
365 }
366 
373 void QwtDial::drawFrame( QPainter *painter )
374 {
376  palette(), lineWidth(), d_data->frameShadow );
377 }
378 
391 void QwtDial::drawContents( QPainter *painter ) const
392 {
393  if ( testAttribute( Qt::WA_NoSystemBackground ) ||
394  palette().brush( QPalette::Base ) !=
395  palette().brush( QPalette::Window ) )
396  {
397  const QRectF br = boundingRect();
398 
399  painter->save();
400  painter->setPen( Qt::NoPen );
401  painter->setBrush( palette().brush( QPalette::Base ) );
402  painter->drawEllipse( br );
403  painter->restore();
404  }
405 
406  const QRectF insideScaleRect = scaleInnerRect();
407  if ( palette().brush( QPalette::WindowText ) !=
408  palette().brush( QPalette::Base ) )
409  {
410  painter->save();
411  painter->setPen( Qt::NoPen );
412  painter->setBrush( palette().brush( QPalette::WindowText ) );
413  painter->drawEllipse( insideScaleRect );
414  painter->restore();
415  }
416 
417  const QPointF center = insideScaleRect.center();
418  const double radius = 0.5 * insideScaleRect.width();
419 
420  painter->save();
421  drawScale( painter, center, radius );
422  painter->restore();
423 
424  painter->save();
425  drawScaleContents( painter, center, radius );
426  painter->restore();
427 }
428 
438 void QwtDial::drawNeedle( QPainter *painter, const QPointF &center,
439  double radius, double direction, QPalette::ColorGroup colorGroup ) const
440 {
441  if ( d_data->needle )
442  {
443  direction = 360.0 - direction; // counter clockwise
444  d_data->needle->draw( painter, center, radius, direction, colorGroup );
445  }
446 }
447 
448 void QwtDial::drawNeedle( QPainter *painter ) const
449 {
450  if ( !isValid() )
451  return;
452 
453  QPalette::ColorGroup colorGroup;
454  if ( isEnabled() )
455  colorGroup = hasFocus() ? QPalette::Active : QPalette::Inactive;
456  else
457  colorGroup = QPalette::Disabled;
458 
459  const QRectF sr = scaleInnerRect();
460 
461  painter->save();
462  painter->setRenderHint( QPainter::Antialiasing, true );
463  drawNeedle( painter, sr.center(), 0.5 * sr.width(),
464  scaleMap().transform( value() ) + 270.0, colorGroup );
465  painter->restore();
466 }
467 
475 void QwtDial::drawScale( QPainter *painter,
476  const QPointF &center, double radius ) const
477 {
478  QwtRoundScaleDraw *sd = const_cast<QwtRoundScaleDraw *>( scaleDraw() );
479  if ( sd == NULL )
480  return;
481 
482  sd->setRadius( radius );
483  sd->moveCenter( center );
484 
485  QPalette pal = palette();
486 
487  const QColor textColor = pal.color( QPalette::Text );
488  pal.setColor( QPalette::WindowText, textColor ); // ticks, backbone
489 
490  painter->setFont( font() );
491  painter->setPen( QPen( textColor, sd->penWidthF() ) );
492 
493  painter->setBrush( Qt::red );
494  sd->draw( painter, pal );
495 }
496 
506 void QwtDial::drawScaleContents( QPainter *painter,
507  const QPointF &center, double radius ) const
508 {
509  Q_UNUSED(painter);
510  Q_UNUSED(center);
511  Q_UNUSED(radius);
512 }
513 
523 {
524  if ( needle != d_data->needle )
525  {
526  if ( d_data->needle )
527  delete d_data->needle;
528 
529  d_data->needle = needle;
530  update();
531  }
532 }
533 
539 {
540  return d_data->needle;
541 }
542 
548 {
549  return d_data->needle;
550 }
551 
554 {
555  return static_cast<QwtRoundScaleDraw *>( abstractScaleDraw() );
556 }
557 
560 {
561  return static_cast<const QwtRoundScaleDraw *>( abstractScaleDraw() );
562 }
563 
575 {
576  setAbstractScaleDraw( scaleDraw );
577  sliderChange();
578 }
579 
588 void QwtDial::setScaleArc( double minArc, double maxArc )
589 {
590  if ( minArc != 360.0 && minArc != -360.0 )
591  minArc = std::fmod( minArc, 360.0 );
592  if ( maxArc != 360.0 && maxArc != -360.0 )
593  maxArc = std::fmod( maxArc, 360.0 );
594 
595  double minScaleArc = qwtMinF( minArc, maxArc );
596  double maxScaleArc = qwtMaxF( minArc, maxArc );
597 
598  if ( maxScaleArc - minScaleArc > 360.0 )
599  maxScaleArc = minScaleArc + 360.0;
600 
601  if ( ( minScaleArc != d_data->minScaleArc ) ||
602  ( maxScaleArc != d_data->maxScaleArc ) )
603  {
606 
607  invalidateCache();
608  sliderChange();
609  }
610 }
611 
619 {
620  setScaleArc( min, d_data->maxScaleArc );
621 }
622 
627 double QwtDial::minScaleArc() const
628 {
629  return d_data->minScaleArc;
630 }
631 
639 {
640  setScaleArc( d_data->minScaleArc, max );
641 }
642 
647 double QwtDial::maxScaleArc() const
648 {
649  return d_data->maxScaleArc;
650 }
651 
661 {
662  invalidateCache();
663 
664  d_data->origin = origin;
665  sliderChange();
666 }
667 
674 double QwtDial::origin() const
675 {
676  return d_data->origin;
677 }
678 
683 QSize QwtDial::sizeHint() const
684 {
685  int sh = 0;
686  if ( scaleDraw() )
687  sh = qwtCeil( scaleDraw()->extent( font() ) );
688 
689  const int d = 6 * sh + 2 * lineWidth();
690 
691  QSize hint( d, d );
692  if ( !isReadOnly() )
693  hint = qwtExpandedToGlobalStrut( hint );
694 
695  return hint;
696 }
697 
703 {
704  int sh = 0;
705  if ( scaleDraw() )
706  sh = qwtCeil( scaleDraw()->extent( font() ) );
707 
708  const int d = 3 * sh + 2 * lineWidth();
709 
710  return QSize( d, d );
711 }
712 
721 bool QwtDial::isScrollPosition( const QPoint &pos ) const
722 {
723  const QRegion region( innerRect(), QRegion::Ellipse );
724  if ( region.contains( pos ) && ( pos != innerRect().center() ) )
725  {
726  double angle = QLineF( rect().center(), pos ).angle();
727  if ( d_data->mode == QwtDial::RotateScale )
728  angle = 360.0 - angle;
729 
730  double valueAngle =
731  qwtNormalizeDegrees( 90.0 - scaleMap().transform( value() ) );
732 
733  d_data->mouseOffset = qwtNormalizeDegrees( angle - valueAngle );
734  d_data->arcOffset = scaleMap().p1();
735 
736  return true;
737  }
738 
739  return false;
740 }
741 
751 double QwtDial::scrolledTo( const QPoint &pos ) const
752 {
753  double angle = QLineF( rect().center(), pos ).angle();
754  if ( d_data->mode == QwtDial::RotateScale )
755  {
756  angle += scaleMap().p1() - d_data->arcOffset;
757  angle = 360.0 - angle;
758  }
759 
760  angle = qwtNormalizeDegrees( angle - d_data->mouseOffset );
761  angle = qwtNormalizeDegrees( 90.0 - angle );
762 
763  if ( scaleMap().pDist() >= 360.0 )
764  {
765  if ( angle < scaleMap().p1() )
766  angle += 360.0;
767 
768  if ( !wrapping() )
769  {
770  double boundedAngle = angle;
771 
772  const double arc = angle - scaleMap().transform( value() );
773  if ( qAbs( arc ) > 180.0 )
774  {
775  boundedAngle = ( arc > 0 )
776  ? scaleMap().p1() : scaleMap().p2();
777  }
778 
779  d_data->mouseOffset += ( boundedAngle - angle );
780 
781  angle = boundedAngle;
782  }
783  }
784  else
785  {
786  const double boundedAngle =
787  qwtBoundedAngle( scaleMap().p1(), angle, scaleMap().p2() );
788 
789  if ( !wrapping() )
790  d_data->mouseOffset += ( boundedAngle - angle );
791 
792  angle = boundedAngle;
793  }
794 
795  return scaleMap().invTransform( angle );
796 }
797 
804 void QwtDial::changeEvent( QEvent *event )
805 {
806  switch( event->type() )
807  {
808  case QEvent::EnabledChange:
809  case QEvent::FontChange:
810  case QEvent::StyleChange:
811  case QEvent::PaletteChange:
812  case QEvent::LanguageChange:
813  case QEvent::LocaleChange:
814  {
815  invalidateCache();
816  break;
817  }
818  default:
819  break;
820  }
821 
823 }
824 
829 void QwtDial::wheelEvent( QWheelEvent *event )
830 {
831 #if QT_VERSION < 0x050e00
832  const QPoint wheelPos = event->pos();
833 #else
834  const QPoint wheelPos = event->position().toPoint();
835 #endif
836 
837  const QRegion region( innerRect(), QRegion::Ellipse );
838  if ( region.contains( wheelPos ) )
840 }
841 
842 void QwtDial::setAngleRange( double angle, double span )
843 {
844  if ( QwtRoundScaleDraw *sd = scaleDraw() )
845  {
846  angle = qwtNormalizeDegrees( angle - 270.0 );
847  sd->setAngleRange( angle, angle + span );
848  }
849 }
850 
856 {
857  invalidateCache();
859 }
860 
862 {
865 
866  if ( mode() == RotateScale )
867  {
868  const double arc = scaleMap().transform( value() ) - scaleMap().p1();
869  setAngleRange( d_data->origin - arc,
871  }
872 
874 }
875 
876 #if QWT_MOC_INCLUDE
877 #include "moc_qwt_dial.cpp"
878 #endif
A abstract base class for drawing scales.
virtual void drawNeedle(QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const
Definition: qwt_dial.cpp:438
virtual void scaleChange() QWT_OVERRIDE
Definition: qwt_dial.cpp:855
void setAngleRange(double angle, double span)
Definition: qwt_dial.cpp:842
double p1() const
Definition: qwt_scale_map.h:99
virtual void draw(QPainter *, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const
The needle is fixed, the scales are rotating.
Definition: qwt_dial.h:92
The needle is rotating.
Definition: qwt_dial.h:89
double p2() const
void setNeedle(QwtDialNeedle *)
Definition: qwt_dial.cpp:522
virtual void drawFrame(QPainter *)
Definition: qwt_dial.cpp:373
void setLineWidth(int)
Definition: qwt_dial.cpp:197
static void drawFocusRect(QPainter *, const QWidget *)
Draw a focus rectangle on a widget using its style.
void setAbstractScaleDraw(QwtAbstractScaleDraw *)
Set a scale draw.
Mode
Mode controlling whether the needle or the scale is rotating.
Definition: qwt_dial.h:86
int transform(double) const
virtual void sliderChange()
Calling update()
QSize qwtExpandedToGlobalStrut(const QSize &size)
Definition: qwt.cpp:21
QRect boundingRect() const
Definition: qwt_dial.cpp:234
MQTTClient d
Definition: test10.c:1656
QWT_CONSTEXPR float qwtMaxF(float a, float b)
Definition: qwt_math.h:123
static bool qwtIsOnArc(double angle, double min, double max)
Definition: qwt_dial.cpp:34
void setValue(double value)
PrivateData * d_data
Definition: qwt_dial.h:165
static void drawRoundFrame(QPainter *, const QRectF &, const QPalette &, int lineWidth, int frameStyle)
virtual void drawFocusIndicator(QPainter *) const
Definition: qwt_dial.cpp:362
virtual void scaleChange() QWT_OVERRIDE
void setMode(Mode)
Change the mode of the dial.
Definition: qwt_dial.cpp:278
const QwtScaleMap & scaleMap() const
virtual void wheelEvent(QWheelEvent *) QWT_OVERRIDE
virtual double scrolledTo(const QPoint &) const QWT_OVERRIDE
Determine the value for a new position of the slider handle.
Definition: qwt_dial.cpp:751
virtual void setOrigin(double)
Change the origin.
Definition: qwt_dial.cpp:660
virtual QRect scaleInnerRect() const
Definition: qwt_dial.cpp:250
virtual void changeEvent(QEvent *) QWT_OVERRIDE
Definition: qwt_dial.cpp:804
bool wrapping() const
virtual bool isScrollPosition(const QPoint &) const QWT_OVERRIDE
Determine what to do when the user presses a mouse button.
Definition: qwt_dial.cpp:721
virtual void drawContents(QPainter *) const
Draw the contents inside the frame.
Definition: qwt_dial.cpp:391
QWT_CONSTEXPR float qwtMinF(float a, float b)
Definition: qwt_math.h:99
virtual ~QwtDial()
Destructor.
Definition: qwt_dial.cpp:159
virtual void paintEvent(QPaintEvent *) QWT_OVERRIDE
Definition: qwt_dial.cpp:310
double maxScaleArc() const
void moveCenter(double x, double y)
Move the center of the scale draw, leaving the radius unchanged.
void setScaleMaxMajor(int ticks)
Set the maximum number of major tick intervals.
An abstract base class for slider widgets with a scale.
double value() const
int lineWidth() const
Base class for needles that can be used in a QwtDial.
void setMaxScaleArc(double)
Definition: qwt_dial.cpp:638
virtual void wheelEvent(QWheelEvent *) QWT_OVERRIDE
Definition: qwt_dial.cpp:829
double origin() const
#define min(A, B)
Definition: Log.c:64
#define max(A, B)
Definition: Socket.h:88
virtual void sliderChange() QWT_OVERRIDE
Calling update()
Definition: qwt_dial.cpp:861
virtual void drawScale(QPainter *, const QPointF &center, double radius) const
Definition: qwt_dial.cpp:475
Shadow
Frame shadow.
Definition: qwt_dial.h:73
Shadow frameShadow() const
const QwtDialNeedle * needle() const
Definition: qwt_dial.cpp:538
backward::SignalHandling sh
Definition: backward.cpp:30
QwtRoundScaleDraw * scaleDraw()
Definition: qwt_dial.cpp:553
QRect innerRect() const
Definition: qwt_dial.cpp:224
virtual QSize sizeHint() const QWT_OVERRIDE
Definition: qwt_dial.cpp:683
virtual void drawScaleContents(QPainter *painter, const QPointF &center, double radius) const
Definition: qwt_dial.cpp:506
static double qwtBoundedAngle(double min, double angle, double max)
Definition: qwt_dial.cpp:46
const QwtAbstractScaleDraw * abstractScaleDraw() const
void setScaleMaxMinor(int ticks)
Set the maximum number of minor tick intervals.
double invTransform(double p) const
void invalidateCache()
Definition: qwt_dial.cpp:301
QwtDial(QWidget *parent=NULL)
Constructor.
Definition: qwt_dial.cpp:124
A class for drawing round scales.
virtual double extent(const QFont &font) const =0
virtual void draw(QPainter *, const QPalette &) const
Draw the scale.
double minScaleArc() const
virtual void changeEvent(QEvent *) QWT_OVERRIDE
void setFrameShadow(Shadow)
Definition: qwt_dial.cpp:170
void setScaleDraw(QwtRoundScaleDraw *)
Definition: qwt_dial.cpp:574
Mode mode() const
void setScaleArc(double minArc, double maxArc)
Definition: qwt_dial.cpp:588
void setMinScaleArc(double)
Definition: qwt_dial.cpp:618
static double qwtAngleDist(double a1, double a2)
Definition: qwt_dial.cpp:25
void setRadius(double radius)
double transform(double s) const
double qwtNormalizeDegrees(double degrees)
Normalize an angle to be int the range [0.0, 360.0[.
Definition: qwt_math.cpp:35
QwtDial::Mode mode
Definition: qwt_dial.cpp:98
QFrame::Sunken.
Definition: qwt_dial.h:82
virtual QSize minimumSizeHint() const QWT_OVERRIDE
Definition: qwt_dial.cpp:702
int qwtCeil(qreal value)
Definition: qwt_math.h:262
static QPixmap backingStore(QWidget *, const QSize &)
QwtDialNeedle * needle
Definition: qwt_dial.cpp:104


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10