Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
qwt_polar_layout.cpp
1/******************************************************************************
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
16class QwtPolarLayout::LayoutData
17{
18 public:
19 void init( const QwtPolarPlot*, const QRectF& rect );
20
21 struct t_legendData
22 {
23 int frameWidth;
24 int hScrollExtent;
25 int vScrollExtent;
26 QSizeF hint;
27 } legend;
28
29 struct t_titleData
30 {
31 QwtText text;
32 int frameWidth;
33 } title;
34
35 struct t_canvasData
36 {
37 int frameWidth;
38 } canvas;
39};
40
41void QwtPolarLayout::LayoutData::init(
42 const QwtPolarPlot* plot, const QRectF& rect )
43{
44 // legend
45
47 && plot->legend() )
48 {
49 legend.frameWidth = plot->legend()->frameWidth();
50 legend.hScrollExtent =
51 plot->legend()->scrollExtent( Qt::Horizontal );
52 legend.vScrollExtent =
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();
77 if ( !( title.text.testPaintAttribute( QwtText::PaintUsingTextFont ) ) )
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
88class QwtPolarLayout::PrivateData
89{
90 public:
91 PrivateData()
92 : margin( 0 )
93 , spacing( 0 )
94 {
95 }
96
97 QRectF titleRect;
98 QRectF legendRect;
99 QRectF canvasRect;
100
101 QwtPolarLayout::LayoutData layoutData;
102
104 double legendRatio;
105
106 unsigned int margin;
107 unsigned int spacing;
108};
109
115{
116 m_data = new PrivateData;
117
119 invalidate();
120}
121
124{
125 delete m_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 m_data->legendRatio = ratio;
155 m_data->legendPos = pos;
156 break;
157 }
160 {
161 if ( ratio <= 0.0 )
162 ratio = 0.5;
163 m_data->legendRatio = ratio;
164 m_data->legendPos = pos;
165 break;
166 }
168 {
169 m_data->legendRatio = ratio; // meaningless
170 m_data->legendPos = pos;
171 break;
172 }
173 default:
174 break;
175 }
176}
177
190
197{
198 return m_data->legendPos;
199}
200
211{
213}
214
220{
221 return m_data->legendRatio;
222}
223
229const QRectF& QwtPolarLayout::titleRect() const
230{
231 return m_data->titleRect;
232}
233
239const QRectF& QwtPolarLayout::legendRect() const
240{
241 return m_data->legendRect;
242}
243
248const QRectF& QwtPolarLayout::canvasRect() const
249{
250 return m_data->canvasRect;
251}
252
258{
259 m_data->titleRect = m_data->legendRect = m_data->canvasRect = QRect();
260}
261
269QRectF QwtPolarLayout::layoutLegend( Options options, QRectF& rect ) const
270{
271 const QSizeF hint( m_data->layoutData.legend.hint );
272
273 int dim;
274 if ( m_data->legendPos == QwtPolarPlot::LeftLegend
275 || m_data->legendPos == QwtPolarPlot::RightLegend )
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() * m_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
289 dim += m_data->layoutData.legend.hScrollExtent;
290 }
291 }
292 }
293 else
294 {
295 dim = qMin( double( hint.height() ), rect.height() * m_data->legendRatio );
296 dim = qMax( dim, m_data->layoutData.legend.vScrollExtent );
297 }
298
299 QRectF legendRect = rect;
300 switch( m_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( m_data->margin, m_data->margin,
351 -m_data->margin, -m_data->margin );
352
353 // We extract all layout relevant data from the widgets
354 // and save them to m_data->layoutData.
355
356 m_data->layoutData.init( plot, rect );
357 if ( !( options & IgnoreLegend )
358 && m_data->legendPos != QwtPolarPlot::ExternalLegend
359 && plot->legend() && !plot->legend()->isEmpty() )
360 {
361 m_data->legendRect = layoutLegend( options, rect );
362 if ( m_data->layoutData.legend.frameWidth &&
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( m_data->legendPos )
370 {
372 rect.setLeft( rect.left() + m_data->spacing );
373 break;
374
376 rect.setRight( rect.right() - m_data->spacing );
377 break;
378
380 rect.setTop( rect.top() + m_data->spacing );
381 break;
382
384 rect.setBottom( rect.bottom() - m_data->spacing );
385 break;
386
388 break; // suppress compiler warning
389 }
390 }
391 }
392
393 if ( !( options & IgnoreTitle ) &&
394 !m_data->layoutData.title.text.isEmpty() )
395 {
396 int h = m_data->layoutData.title.text.heightForWidth( rect.width() );
397 if ( !( options & IgnoreFrames ) )
398 h += 2 * m_data->layoutData.title.frameWidth;
399
400 m_data->titleRect = QRectF( rect.x(), rect.y(), rect.width(), h );
401
402 // subtract title
403 rect.setTop( rect.top() + h + m_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 m_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 m_data->canvasRect.setX( rect.center().x() - dim / 2 );
423 m_data->canvasRect.setY( rect.y() );
424 m_data->canvasRect.setSize( QSize( dim, dim ) );
425 }
426
427 if ( !m_data->legendRect.isEmpty() )
428 {
429 if ( m_data->legendPos == QwtPolarPlot::LeftLegend
430 || m_data->legendPos == QwtPolarPlot::RightLegend )
431 {
432 // We prefer to align the legend to the canvas - not to
433 // the complete plot - if possible.
434
435 if ( m_data->layoutData.legend.hint.height()
436 < m_data->canvasRect.height() )
437 {
438 m_data->legendRect.setY( m_data->canvasRect.y() );
439 m_data->legendRect.setHeight( m_data->canvasRect.height() );
440 }
441 }
442 }
443}
virtual int scrollExtent(Qt::Orientation) const
virtual bool isEmpty() const =0
double radius() const
Returns the radius.
const QRectF & legendRect() const
virtual ~QwtPolarLayout()
Destructor.
QRectF layoutLegend(Options options, QRectF &) const
void setLegendRatio(double ratio)
double legendRatio() const
void setLegendPosition(QwtPolarPlot::LegendPosition pos, double ratio)
Specify the position of the legend.
virtual void invalidate()
QwtPolarPlot::LegendPosition legendPosition() const
virtual void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
QwtPolarLayout()
Constructor.
const QRectF & titleRect() const
@ IgnoreLegend
Ignore the legend.
@ IgnoreScrollbars
Ignore the dimension of the scrollbars.
@ IgnoreTitle
Ignore the title.
@ IgnoreFrames
Ignore all frames.
QFlags< Option > Options
const QRectF & canvasRect() const
A plotting widget, displaying a polar coordinate system.
QwtPolarLayout * plotLayout()
QwtPointPolar zoomPos() const
double zoomFactor() const
QwtAbstractLegend * legend()
QwtPolarCanvas * canvas()
@ BottomLegend
The legend will be below the canvas.
@ LeftLegend
The legend will be left from the canvas.
@ TopLegend
The legend will be between canvas and title.
@ RightLegend
The legend will be right from the canvas.
QwtTextLabel * titleLabel()
A class representing a text.
Definition qwt_text.h:52
bool testPaintAttribute(PaintAttribute) const
Definition qwt_text.cpp:482
@ PaintUsingTextFont
The text has an individual font.
Definition qwt_text.h:117
bool isEmpty() const
Definition qwt_text.cpp:739
void setFont(const QFont &)
Definition qwt_text.cpp:329
double heightForWidth(double width) const
Definition qwt_text.cpp:522
A Widget which displays a QwtText.
const QwtText & text() const
Return the text.