qwt_scale_widget.cpp
Go to the documentation of this file.
1 /******************************************************************************
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_scale_widget.h"
11 #include "qwt_painter.h"
12 #include "qwt_color_map.h"
13 #include "qwt_scale_map.h"
14 #include "qwt_math.h"
15 #include "qwt_scale_div.h"
16 #include "qwt_text.h"
17 #include "qwt_interval.h"
18 #include "qwt_scale_engine.h"
19 
20 #include <qpainter.h>
21 #include <qevent.h>
22 #include <qstyle.h>
23 #include <qstyleoption.h>
24 #include <qapplication.h>
25 #include <qmargins.h>
26 
28 {
29  public:
31  : scaleDraw( NULL )
32  {
33  colorBar.colorMap = NULL;
34  }
35 
37  {
38  delete scaleDraw;
39  delete colorBar.colorMap;
40  }
41 
43 
44  int borderDist[2];
45  int minBorderDist[2];
47  int margin;
48 
50  int spacing;
52 
53  QwtScaleWidget::LayoutFlags layoutFlags;
54 
55  struct t_colorBar
56  {
57  bool isEnabled;
58  int width;
61  } colorBar;
62 };
63 
69  : QWidget( parent )
70 {
72 }
73 
80  : QWidget( parent )
81 {
82  initScale( align );
83 }
84 
87 {
88  delete m_data;
89 }
90 
93 {
94  m_data = new PrivateData;
95 
96  if ( align == QwtScaleDraw::RightScale )
98 
99  m_data->borderDist[0] = 0;
100  m_data->borderDist[1] = 0;
101  m_data->minBorderDist[0] = 0;
102  m_data->minBorderDist[1] = 0;
103  m_data->margin = 4;
104  m_data->titleOffset = 0;
105  m_data->spacing = 2;
106 
108  m_data->scaleDraw->setAlignment( align );
109  m_data->scaleDraw->setLength( 10 );
110 
112  QwtLinearScaleEngine().divideScale( 0.0, 100.0, 10, 5 ) );
113 
115  m_data->colorBar.isEnabled = false;
116  m_data->colorBar.width = 10;
117 
118  const int flags = Qt::AlignHCenter
119  | Qt::TextExpandTabs | Qt::TextWordWrap;
120  m_data->title.setRenderFlags( flags );
121  m_data->title.setFont( font() );
122 
123  QSizePolicy policy( QSizePolicy::MinimumExpanding,
124  QSizePolicy::Fixed );
125  if ( m_data->scaleDraw->orientation() == Qt::Vertical )
126  policy.transpose();
127 
128  setSizePolicy( policy );
129 
130  setAttribute( Qt::WA_WState_OwnSizePolicy, false );
131 }
132 
142 {
143  if ( ( ( m_data->layoutFlags & flag ) != 0 ) != on )
144  {
145  if ( on )
146  m_data->layoutFlags |= flag;
147  else
148  m_data->layoutFlags &= ~flag;
149 
150  update();
151  }
152 }
153 
162 {
163  return ( m_data->layoutFlags & flag );
164 }
165 
172 void QwtScaleWidget::setTitle( const QString& title )
173 {
174  if ( m_data->title.text() != title )
175  {
176  m_data->title.setText( title );
177  layoutScale();
178  }
179 }
180 
191 {
192  QwtText t = title;
193  const int flags = title.renderFlags() & ~( Qt::AlignTop | Qt::AlignBottom );
194  t.setRenderFlags( flags );
195 
196  if ( t != m_data->title )
197  {
198  m_data->title = t;
199  layoutScale();
200  }
201 }
202 
210 {
211  if ( m_data->scaleDraw )
212  m_data->scaleDraw->setAlignment( alignment );
213 
214  if ( !testAttribute( Qt::WA_WState_OwnSizePolicy ) )
215  {
216  QSizePolicy policy( QSizePolicy::MinimumExpanding,
217  QSizePolicy::Fixed );
218  if ( m_data->scaleDraw->orientation() == Qt::Vertical )
219  policy.transpose();
220 
221  setSizePolicy( policy );
222 
223  setAttribute( Qt::WA_WState_OwnSizePolicy, false );
224  }
225 
226  layoutScale();
227 }
228 
229 
235 {
236  if ( !scaleDraw() )
238 
239  return scaleDraw()->alignment();
240 }
241 
250 void QwtScaleWidget::setBorderDist( int dist1, int dist2 )
251 {
252  if ( dist1 != m_data->borderDist[0] || dist2 != m_data->borderDist[1] )
253  {
254  m_data->borderDist[0] = dist1;
255  m_data->borderDist[1] = dist2;
256  layoutScale();
257  }
258 }
259 
266 {
267  margin = qMax( 0, margin );
268  if ( margin != m_data->margin )
269  {
270  m_data->margin = margin;
271  layoutScale();
272  }
273 }
274 
281 {
282  spacing = qMax( 0, spacing );
283  if ( spacing != m_data->spacing )
284  {
286  layoutScale();
287  }
288 }
289 
296 {
297  m_data->scaleDraw->setLabelAlignment( alignment );
298  layoutScale();
299 }
300 
308 void QwtScaleWidget::setLabelRotation( double rotation )
309 {
310  m_data->scaleDraw->setLabelRotation( rotation );
311  layoutScale();
312 }
313 
326 {
327  if ( ( scaleDraw == NULL ) || ( scaleDraw == m_data->scaleDraw ) )
328  return;
329 
330  const QwtScaleDraw* sd = m_data->scaleDraw;
331  if ( sd )
332  {
333  scaleDraw->setAlignment( sd->alignment() );
334  scaleDraw->setScaleDiv( sd->scaleDiv() );
335 
336  QwtTransform* transform = NULL;
337  if ( sd->scaleMap().transformation() )
338  transform = sd->scaleMap().transformation()->copy();
339 
340  scaleDraw->setTransformation( transform );
341  }
342 
343  delete m_data->scaleDraw;
345 
346  layoutScale();
347 }
348 
354 {
355  return m_data->scaleDraw;
356 }
357 
363 {
364  return m_data->scaleDraw;
365 }
366 
372 {
373  return m_data->title;
374 }
375 
381 {
382  return m_data->borderDist[0];
383 }
384 
390 {
391  return m_data->borderDist[1];
392 }
393 
399 {
400  return m_data->margin;
401 }
402 
408 {
409  return m_data->spacing;
410 }
411 
415 void QwtScaleWidget::paintEvent( QPaintEvent* event )
416 {
417  QPainter painter( this );
418  painter.setClipRegion( event->region() );
419 
420  QStyleOption opt;
421  opt.initFrom(this);
422  style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
423 
424  draw( &painter );
425 }
426 
430 void QwtScaleWidget::draw( QPainter* painter ) const
431 {
432  m_data->scaleDraw->draw( painter, palette() );
433 
434  if ( m_data->colorBar.isEnabled && m_data->colorBar.width > 0 &&
436  {
437  drawColorBar( painter, colorBarRect( contentsRect() ) );
438  }
439 
440  QRect r = contentsRect();
441  if ( m_data->scaleDraw->orientation() == Qt::Horizontal )
442  {
443  r.setLeft( r.left() + m_data->borderDist[0] );
444  r.setWidth( r.width() - m_data->borderDist[1] );
445  }
446  else
447  {
448  r.setTop( r.top() + m_data->borderDist[0] );
449  r.setHeight( r.height() - m_data->borderDist[1] );
450  }
451 
452  if ( !m_data->title.isEmpty() )
453  drawTitle( painter, m_data->scaleDraw->alignment(), r );
454 }
455 
462 QRectF QwtScaleWidget::colorBarRect( const QRectF& rect ) const
463 {
464  QRectF cr = rect;
465 
466  if ( m_data->scaleDraw->orientation() == Qt::Horizontal )
467  {
468  cr.setLeft( cr.left() + m_data->borderDist[0] );
469  cr.setWidth( cr.width() - m_data->borderDist[1] + 1 );
470  }
471  else
472  {
473  cr.setTop( cr.top() + m_data->borderDist[0] );
474  cr.setHeight( cr.height() - m_data->borderDist[1] + 1 );
475  }
476 
477  switch ( m_data->scaleDraw->alignment() )
478  {
480  {
481  cr.setLeft( cr.right() - m_data->margin
482  - m_data->colorBar.width );
483  cr.setWidth( m_data->colorBar.width );
484  break;
485  }
486 
488  {
489  cr.setLeft( cr.left() + m_data->margin );
490  cr.setWidth( m_data->colorBar.width );
491  break;
492  }
493 
495  {
496  cr.setTop( cr.top() + m_data->margin );
497  cr.setHeight( m_data->colorBar.width );
498  break;
499  }
500 
502  {
503  cr.setTop( cr.bottom() - m_data->margin
504  - m_data->colorBar.width );
505  cr.setHeight( m_data->colorBar.width );
506  break;
507  }
508  }
509 
510  return cr;
511 }
512 
519 void QwtScaleWidget::changeEvent( QEvent* event )
520 {
521  if ( event->type() == QEvent::LocaleChange )
522  {
524  }
525 
526  QWidget::changeEvent( event );
527 }
528 
533 void QwtScaleWidget::resizeEvent( QResizeEvent* event )
534 {
535  Q_UNUSED( event );
536  layoutScale( false );
537 }
538 
547 void QwtScaleWidget::layoutScale( bool update_geometry )
548 {
549  int bd0, bd1;
550  getBorderDistHint( bd0, bd1 );
551  if ( m_data->borderDist[0] > bd0 )
552  bd0 = m_data->borderDist[0];
553  if ( m_data->borderDist[1] > bd1 )
554  bd1 = m_data->borderDist[1];
555 
556  int colorBarWidth = 0;
558  colorBarWidth = m_data->colorBar.width + m_data->spacing;
559 
560  const QRectF r = contentsRect();
561  double x, y, length;
562 
563  if ( m_data->scaleDraw->orientation() == Qt::Vertical )
564  {
565  y = r.top() + bd0;
566  length = r.height() - ( bd0 + bd1 );
567 
569  x = r.right() - 1.0 - m_data->margin - colorBarWidth;
570  else
571  x = r.left() + m_data->margin + colorBarWidth;
572  }
573  else
574  {
575  x = r.left() + bd0;
576  length = r.width() - ( bd0 + bd1 );
577 
579  y = r.top() + m_data->margin + colorBarWidth;
580  else
581  y = r.bottom() - 1.0 - m_data->margin - colorBarWidth;
582  }
583 
584  m_data->scaleDraw->move( x, y );
585  m_data->scaleDraw->setLength( length );
586 
587  const int extent = qwtCeil( m_data->scaleDraw->extent( font() ) );
588 
590  m_data->margin + m_data->spacing + colorBarWidth + extent;
591 
592  if ( update_geometry )
593  {
594  updateGeometry();
595 
596 #if 1
597  /*
598  for some reason updateGeometry does not send a LayoutRequest event
599  when the parent is not visible and has no layout
600  */
601 
602  if ( QWidget* w = parentWidget() )
603  {
604  if ( !w->isVisible() && w->layout() == NULL )
605  {
606  if ( w->testAttribute( Qt::WA_WState_Polished ) )
607  QApplication::postEvent( w, new QEvent( QEvent::LayoutRequest ) );
608  }
609  }
610 #endif
611 
612  update();
613  }
614 }
615 
624 void QwtScaleWidget::drawColorBar( QPainter* painter, const QRectF& rect ) const
625 {
626  if ( !m_data->colorBar.interval.isValid() )
627  return;
628 
629  const QwtScaleDraw* sd = m_data->scaleDraw;
630 
633  sd->orientation(), rect );
634 }
635 
644 void QwtScaleWidget::drawTitle( QPainter* painter,
645  QwtScaleDraw::Alignment align, const QRectF& rect ) const
646 {
647  QRectF r = rect;
648  double angle;
649  int flags = m_data->title.renderFlags() &
650  ~( Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter );
651 
652  switch ( align )
653  {
655  angle = -90.0;
656  flags |= Qt::AlignTop;
657  r.setRect( r.left(), r.bottom(),
658  r.height(), r.width() - m_data->titleOffset );
659  break;
660 
662  angle = -90.0;
663  flags |= Qt::AlignTop;
664  r.setRect( r.left() + m_data->titleOffset, r.bottom(),
665  r.height(), r.width() - m_data->titleOffset );
666  break;
667 
669  angle = 0.0;
670  flags |= Qt::AlignBottom;
671  r.setTop( r.top() + m_data->titleOffset );
672  break;
673 
675  default:
676  angle = 0.0;
677  flags |= Qt::AlignTop;
678  r.setBottom( r.bottom() - m_data->titleOffset );
679  break;
680  }
681 
683  {
684  if ( align == QwtScaleDraw::LeftScale
685  || align == QwtScaleDraw::RightScale )
686  {
687  angle = -angle;
688  r.setRect( r.x() + r.height(), r.y() - r.width(),
689  r.width(), r.height() );
690  }
691  }
692 
693  painter->save();
694  painter->setFont( font() );
695  painter->setPen( palette().color( QPalette::Text ) );
696 
697  painter->translate( r.x(), r.y() );
698  if ( angle != 0.0 )
699  painter->rotate( angle );
700 
702  title.setRenderFlags( flags );
703  title.draw( painter, QRectF( 0.0, 0.0, r.width(), r.height() ) );
704 
705  painter->restore();
706 }
707 
717 {
718  layoutScale();
719 }
720 
725 {
726  return minimumSizeHint();
727 }
728 
733 {
734  const Qt::Orientation o = m_data->scaleDraw->orientation();
735 
736  // Border Distance cannot be less than the scale borderDistHint
737  // Note, the borderDistHint is already included in minHeight/minWidth
738  int length = 0;
739  int mbd1, mbd2;
740  getBorderDistHint( mbd1, mbd2 );
741  length += qMax( 0, m_data->borderDist[0] - mbd1 );
742  length += qMax( 0, m_data->borderDist[1] - mbd2 );
743  length += m_data->scaleDraw->minLength( font() );
744 
745  int dim = dimForLength( length, font() );
746  if ( length < dim )
747  {
748  // compensate for long titles
749  length = dim;
750  dim = dimForLength( length, font() );
751  }
752 
753  QSize size( length + 2, dim );
754  if ( o == Qt::Vertical )
755  size.transpose();
756 
757  const QMargins m = contentsMargins();
758  return size + QSize( m.left() + m.right(), m.top() + m.bottom() );
759 }
760 
768 {
769  return qwtCeil( m_data->title.heightForWidth( width, font() ) );
770 }
771 
781 int QwtScaleWidget::dimForLength( int length, const QFont& scaleFont ) const
782 {
783  const int extent = qwtCeil( m_data->scaleDraw->extent( scaleFont ) );
784 
785  int dim = m_data->margin + extent + 1;
786 
787  if ( !m_data->title.isEmpty() )
788  dim += titleHeightForWidth( length ) + m_data->spacing;
789 
791  dim += m_data->colorBar.width + m_data->spacing;
792 
793  return dim;
794 }
795 
814 void QwtScaleWidget::getBorderDistHint( int& start, int& end ) const
815 {
816  m_data->scaleDraw->getBorderDistHint( font(), start, end );
817 
818  if ( start < m_data->minBorderDist[0] )
819  start = m_data->minBorderDist[0];
820 
821  if ( end < m_data->minBorderDist[1] )
822  end = m_data->minBorderDist[1];
823 }
824 
835 void QwtScaleWidget::setMinBorderDist( int start, int end )
836 {
837  m_data->minBorderDist[0] = start;
838  m_data->minBorderDist[1] = end;
839 }
840 
852 void QwtScaleWidget::getMinBorderDist( int& start, int& end ) const
853 {
854  start = m_data->minBorderDist[0];
855  end = m_data->minBorderDist[1];
856 }
857 
867 {
869  if ( sd->scaleDiv() != scaleDiv )
870  {
871  sd->setScaleDiv( scaleDiv );
872  layoutScale();
873 
874  Q_EMIT scaleDivChanged();
875  }
876 }
877 
885 {
886  m_data->scaleDraw->setTransformation( transformation );
887  layoutScale();
888 }
889 
895 {
896  if ( on != m_data->colorBar.isEnabled )
897  {
898  m_data->colorBar.isEnabled = on;
899  layoutScale();
900  }
901 }
902 
908 {
909  return m_data->colorBar.isEnabled;
910 }
911 
919 {
920  if ( width != m_data->colorBar.width )
921  {
922  m_data->colorBar.width = width;
923  if ( isColorBarEnabled() )
924  layoutScale();
925  }
926 }
927 
933 {
934  return m_data->colorBar.width;
935 }
936 
942 {
943  return m_data->colorBar.interval;
944 }
945 
956  const QwtInterval& interval, QwtColorMap* colorMap )
957 {
958  m_data->colorBar.interval = interval;
959 
960  if ( colorMap != m_data->colorBar.colorMap )
961  {
962  delete m_data->colorBar.colorMap;
964  }
965 
966  if ( isColorBarEnabled() )
967  layoutScale();
968 }
969 
975 {
976  return m_data->colorBar.colorMap;
977 }
978 
979 #if QWT_MOC_INCLUDE
980 #include "moc_qwt_scale_widget.cpp"
981 #endif
Definition: core.h:1869
bool isValid() const
Definition: qwt_interval.h:210
void getMinBorderDist(int &start, int &end) const
int titleHeightForWidth(int width) const
Find the height of the title for a given width.
void scaleDivChanged()
Signal emitted, whenever the scale division changes.
int dimForLength(int length, const QFont &scaleFont) const
Find the minimum dimension for a given length. dim is the height, length the width seen in direction ...
virtual void draw(QPainter *, const QPalette &) const
Draw the scale.
void setAlignment(Alignment)
void setLength(double length)
void setColorBarEnabled(bool)
virtual ~QwtScaleWidget()
Destructor.
void setFont(const QFont &)
Definition: qwt_text.cpp:329
void setColorMap(const QwtInterval &, QwtColorMap *)
void initScale(QwtScaleDraw::Alignment)
Initialize the scale.
A class representing an interval.
Definition: qwt_interval.h:22
void setRenderFlags(int)
Change the render flags.
Definition: qwt_text.cpp:304
void setText(const QString &, QwtText::TextFormat textFormat=AutoText)
Definition: qwt_text.cpp:277
QwtScaleWidget::LayoutFlags layoutFlags
double heightForWidth(double width) const
Definition: qwt_text.cpp:522
The scale is above.
int endBorderDist() const
static void drawColorBar(QPainter *, const QwtColorMap &, const QwtInterval &, const QwtScaleMap &, Qt::Orientation, const QRectF &)
void draw(QPainter *) const
draw the scale
virtual QwtTransform * copy() const =0
Virtualized copy operation.
void getBorderDistHint(int &start, int &end) const
Calculate a hint for the border distances.
void setScaleDiv(const QwtScaleDiv &)
Assign a scale division.
void setLabelAlignment(Qt::Alignment)
Change the alignment for the labels.
QString text() const
Definition: qwt_text.cpp:289
A class representing a scale division.
Definition: qwt_scale_div.h:33
void drawColorBar(QPainter *, const QRectF &) const
void setMargin(int)
Specify the margin to the colorBar/base line.
void setLabelRotation(double rotation)
Change the rotation for the labels. See QwtScaleDraw::setLabelRotation().
LayoutFlag
Layout flags of the title.
Alignment alignment() const
void setAlignment(QwtScaleDraw::Alignment)
virtual QSize minimumSizeHint() const QWT_OVERRIDE
const QwtTransform * transformation() const
Get the transformation.
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
int minLength(const QFont &) const
void draw(QPainter *painter, const QRectF &rect) const
Definition: qwt_text.cpp:615
Qt::Orientation orientation() const
virtual QSize sizeHint() const QWT_OVERRIDE
The scale is left.
void setTitle(const QString &title)
bool isEmpty() const
Definition: qwt_text.cpp:739
const QwtScaleDiv & scaleDiv() const
virtual void paintEvent(QPaintEvent *) QWT_OVERRIDE
paintEvent
struct QwtScaleWidget::PrivateData::t_colorBar colorBar
bool testLayoutFlag(LayoutFlag) const
A transformation between coordinate systems.
Definition: qwt_transform.h:35
virtual void resizeEvent(QResizeEvent *) QWT_OVERRIDE
A class representing a text.
Definition: qwt_text.h:51
void setMinBorderDist(int start, int end)
QwtColorMap is used to map values into colors.
Definition: qwt_color_map.h:37
void getBorderDistHint(const QFont &, int &start, int &end) const
Determine the minimum border distance.
void setScaleDiv(const QwtScaleDiv &)
void setColorBarWidth(int)
void setLabelRotation(double rotation)
QwtScaleDraw::Alignment alignment() const
virtual void changeEvent(QEvent *) QWT_OVERRIDE
QwtLinearColorMap builds a color map from color stops.
Definition: qwt_color_map.h:98
const QwtScaleDraw * scaleDraw() const
bool isColorBarEnabled() const
color
Definition: color.h:23
void setBorderDist(int dist1, int dist2)
QwtScaleWidget(QWidget *parent=NULL)
Create a scale with the position QwtScaleWidget::Left.
void setLayoutFlag(LayoutFlag, bool on)
The scale is right.
QwtText title() const
const QwtColorMap * colorMap() const
QRectF colorBarRect(const QRectF &) const
virtual double extent(const QFont &) const QWT_OVERRIDE
void setTransformation(QwtTransform *)
void layoutScale(bool update_geometry=true)
A class for drawing scales.
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1485
const QwtScaleMap & scaleMap() const
A scale engine for linear scales.
int startBorderDist() const
void setTransformation(QwtTransform *)
void setScaleDraw(QwtScaleDraw *)
void drawTitle(QPainter *, QwtScaleDraw::Alignment, const QRectF &rect) const
PrivateData * m_data
void scaleChange()
Notify a change of the scale.
QwtInterval colorBarInterval() const
int renderFlags() const
Definition: qwt_text.cpp:317
void setLabelAlignment(Qt::Alignment)
Change the label flags.
QwtInterval normalized() const
Normalize the limits of the interval.
int qwtCeil(qreal value)
Definition: qwt_math.h:262
int colorBarWidth() const
The scale is below.
void setSpacing(int)
Specify the distance between color bar, scale and title.
void move(double x, double y)


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:01:39