qwt_polar_layout.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * QwtPolar Widget Library
3  * Copyright (C) 2008 Uwe Rathmann
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the Qwt License, Version 1.0
7  *****************************************************************************/
8 
9 #include "qwt_polar_layout.h"
10 #include "qwt_polar_plot.h"
11 #include "qwt_polar_canvas.h"
12 #include "qwt_text.h"
13 #include "qwt_text_label.h"
14 #include "qwt_legend.h"
15 
17 {
18 public:
19  void init( const QwtPolarPlot *, const QRectF &rect );
20 
21  struct t_legendData
22  {
26  QSizeF hint;
27  } legend;
28 
29  struct t_titleData
30  {
33  } title;
34 
35  struct t_canvasData
36  {
38  } canvas;
39 };
40 
42  const QwtPolarPlot *plot, const QRectF &rect )
43 {
44  // legend
45 
47  && plot->legend() )
48  {
49  legend.frameWidth = plot->legend()->frameWidth();
51  plot->legend()->scrollExtent( Qt::Horizontal );
53  plot->legend()->scrollExtent( Qt::Vertical );
54 
55  const QSizeF hint = plot->legend()->sizeHint();
56 
57  double w = qMin( hint.width(), rect.width() );
58  double h = plot->legend()->heightForWidth( w );
59  if ( h == 0.0 )
60  h = hint.height();
61 
62  if ( h > rect.height() )
63  w += legend.hScrollExtent;
64 
65  legend.hint = QSizeF( w, h );
66  }
67 
68  // title
69 
70  title.frameWidth = 0;
71  title.text = QwtText();
72 
73  if ( plot->titleLabel() )
74  {
75  const QwtTextLabel *label = plot->titleLabel();
76  title.text = label->text();
78  title.text.setFont( label->font() );
79 
80  title.frameWidth = plot->titleLabel()->frameWidth();
81  }
82 
83  // canvas
84 
85  canvas.frameWidth = plot->canvas()->frameWidth();
86 }
87 
89 {
90 public:
92  margin( 0 ),
93  spacing( 0 )
94  {
95  }
96 
97  QRectF titleRect;
98  QRectF legendRect;
99  QRectF canvasRect;
100 
102 
104  double legendRatio;
105 
106  unsigned int margin;
107  unsigned int spacing;
108 };
109 
115 {
116  d_data = new PrivateData;
117 
119  invalidate();
120 }
121 
124 {
125  delete d_data;
126 }
127 
142  QwtPolarPlot::LegendPosition pos, double ratio )
143 {
144  if ( ratio > 1.0 )
145  ratio = 1.0;
146 
147  switch( pos )
148  {
151  {
152  if ( ratio <= 0.0 )
153  ratio = 0.33;
154  d_data->legendRatio = ratio;
155  d_data->legendPos = pos;
156  break;
157  }
160  {
161  if ( ratio <= 0.0 )
162  ratio = 0.5;
163  d_data->legendRatio = ratio;
164  d_data->legendPos = pos;
165  break;
166  }
168  {
169  d_data->legendRatio = ratio; // meaningless
170  d_data->legendPos = pos;
171  break;
172  }
173  default:
174  break;
175  }
176 }
177 
187 {
188  setLegendPosition( pos, 0.0 );
189 }
190 
197 {
198  return d_data->legendPos;
199 }
200 
210 void QwtPolarLayout::setLegendRatio( double ratio )
211 {
212  setLegendPosition( legendPosition(), ratio );
213 }
214 
220 {
221  return d_data->legendRatio;
222 }
223 
229 const QRectF &QwtPolarLayout::titleRect() const
230 {
231  return d_data->titleRect;
232 }
233 
239 const QRectF &QwtPolarLayout::legendRect() const
240 {
241  return d_data->legendRect;
242 }
243 
248 const QRectF &QwtPolarLayout::canvasRect() const
249 {
250  return d_data->canvasRect;
251 }
252 
258 {
260 }
261 
269 QRectF QwtPolarLayout::layoutLegend( Options options, QRectF &rect ) const
270 {
271  const QSizeF hint( d_data->layoutData.legend.hint );
272 
273  int dim;
276  {
277  // We don't allow vertical legends to take more than
278  // half of the available space.
279 
280  dim = qMin( double( hint.width() ), rect.width() * d_data->legendRatio );
281 
282  if ( !( options & IgnoreScrollbars ) )
283  {
284  if ( hint.height() > rect.height() )
285  {
286  // The legend will need additional
287  // space for the vertical scrollbar.
288 
290  }
291  }
292  }
293  else
294  {
295  dim = qMin( double( hint.height() ), rect.height() * d_data->legendRatio );
296  dim = qMax( dim, d_data->layoutData.legend.vScrollExtent );
297  }
298 
299  QRectF legendRect = rect;
300  switch( d_data->legendPos )
301  {
303  {
304  legendRect.setWidth( dim );
305  rect.setLeft( legendRect.right() );
306  break;
307  }
309  {
310  legendRect.setX( rect.right() - dim + 1 );
311  legendRect.setWidth( dim );
312  rect.setRight( legendRect.left() );
313  break;
314  }
316  {
317  legendRect.setHeight( dim );
318  rect.setTop( legendRect.bottom() );
319  break;
320  }
322  {
323  legendRect.setY( rect.bottom() - dim + 1 );
324  legendRect.setHeight( dim );
325  rect.setBottom( legendRect.top() );
326  break;
327  }
329  break;
330  }
331 
332  return legendRect;
333 }
334 
345  const QRectF &boundingRect, Options options )
346 {
347  invalidate();
348 
349  QRectF rect( boundingRect ); // undistributed rest of the plot rect
350  rect.adjust( d_data->margin, d_data->margin,
351  -d_data->margin, -d_data->margin );
352 
353  // We extract all layout relevant data from the widgets
354  // and save them to d_data->layoutData.
355 
356  d_data->layoutData.init( plot, rect );
357  if ( !( options & IgnoreLegend )
359  && plot->legend() && !plot->legend()->isEmpty() )
360  {
361  d_data->legendRect = layoutLegend( options, rect );
363  !( options & IgnoreFrames ) )
364  {
365  // In case of a frame we have to insert a spacing.
366  // Otherwise the leading of the font separates
367  // legend and scale/canvas
368 
369  switch( d_data->legendPos )
370  {
372  rect.setLeft( rect.left() + d_data->spacing );
373  break;
374 
376  rect.setRight( rect.right() - d_data->spacing );
377  break;
378 
380  rect.setTop( rect.top() + d_data->spacing );
381  break;
382 
384  rect.setBottom( rect.bottom() - d_data->spacing );
385  break;
386 
388  break; // suppress compiler warning
389  }
390  }
391  }
392 
393  if ( !( options & IgnoreTitle ) &&
395  {
396  int h = d_data->layoutData.title.text.heightForWidth( rect.width() );
397  if ( !( options & IgnoreFrames ) )
398  h += 2 * d_data->layoutData.title.frameWidth;
399 
400  d_data->titleRect = QRectF( rect.x(), rect.y(), rect.width(), h );
401 
402  // subtract title
403  rect.setTop( rect.top() + h + d_data->spacing );
404  }
405 
406  if ( plot->zoomPos().radius() > 0.0 || plot->zoomFactor() < 1.0 )
407  {
408  // In zoomed state we have no idea about the geometry that
409  // is best for the plot. So we use the complete rectangle
410  // accepting, that there might a lot of space wasted
411  // around the plot.
412 
413  d_data->canvasRect = rect;
414  }
415  else
416  {
417  // In full state we know, that we want
418  // to display something circular.
419 
420  const int dim = qMin( rect.width(), rect.height() );
421 
422  d_data->canvasRect.setX( rect.center().x() - dim / 2 );
423  d_data->canvasRect.setY( rect.y() );
424  d_data->canvasRect.setSize( QSize( dim, dim ) );
425  }
426 
427  if ( !d_data->legendRect.isEmpty() )
428  {
431  {
432  // We prefer to align the legend to the canvas - not to
433  // the complete plot - if possible.
434 
435  if ( d_data->layoutData.legend.hint.height()
436  < d_data->canvasRect.height() )
437  {
438  d_data->legendRect.setY( d_data->canvasRect.y() );
439  d_data->legendRect.setHeight( d_data->canvasRect.height() );
440  }
441  }
442  }
443 }
const QRectF & legendRect() const
A plotting widget, displaying a polar coordinate system.
const QRectF & canvasRect() const
The legend will be between canvas and title.
double zoomFactor() const
void init(const QwtPolarPlot *, const QRectF &rect)
struct QwtPolarLayout::LayoutData::t_legendData legend
void setFont(const QFont &)
Definition: qwt_text.cpp:306
QRectF layoutLegend(Options options, QRectF &) const
QwtPolarLayout * plotLayout()
A Widget which displays a QwtText.
QwtPolarCanvas * canvas()
The legend will be below the canvas.
const QRectF & titleRect() const
double radius() const
Returns the radius.
QwtPolarLayout()
Constructor.
virtual void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
const QwtText & text() const
Return the text.
QwtPointPolar zoomPos() const
The legend will be right from the canvas.
QwtPolarPlot::LegendPosition legendPosition() const
virtual void invalidate()
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_text.cpp:459
double heightForWidth(double width) const
Definition: qwt_text.cpp:499
virtual bool isEmpty() const =0
virtual ~QwtPolarLayout()
Destructor.
bool isEmpty() const
Definition: qwt_text.cpp:716
void setLegendRatio(double ratio)
QwtTextLabel * titleLabel()
A class representing a text.
Definition: qwt_text.h:51
struct QwtPolarLayout::LayoutData::t_canvasData canvas
QwtPolarPlot::LegendPosition legendPos
QwtPolarLayout::LayoutData layoutData
QwtAbstractLegend * legend()
The legend will be left from the canvas.
void setLegendPosition(QwtPolarPlot::LegendPosition pos, double ratio)
Specify the position of the legend.
struct QwtPolarLayout::LayoutData::t_titleData title
Ignore the dimension of the scrollbars.
The text has an individual font.
Definition: qwt_text.h:117
virtual int scrollExtent(Qt::Orientation) const
double legendRatio() const
PrivateData * d_data
struct Options options


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