source: ntrip/trunk/BNC/qwt/qwt_polar_layout.cpp

Last change on this file was 11158, checked in by stuerze, 7 days ago

deprecated functions exchanged libs updated

File size: 11.7 KB
Line 
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
46 if ( plot->plotLayout()->legendPosition() != QwtPolarPlot::ExternalLegend
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
103 QwtPolarPlot::LegendPosition legendPos;
104 double legendRatio;
105
106 unsigned int margin;
107 unsigned int spacing;
108};
109
110/*!
111 \brief Constructor
112 */
113
114QwtPolarLayout::QwtPolarLayout()
115{
116 m_data = new PrivateData;
117
118 setLegendPosition( QwtPolarPlot::BottomLegend );
119 invalidate();
120}
121
122//! Destructor
123QwtPolarLayout::~QwtPolarLayout()
124{
125 delete m_data;
126}
127
128/*!
129 \brief Specify the position of the legend
130 \param pos The legend's position.
131 \param ratio Ratio between legend and the bounding rect
132 of title, canvas and axes. The legend will be shrunk
133 if it would need more space than the given ratio.
134 The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
135 it will be reset to the default ratio.
136 The default vertical/horizontal ratio is 0.33/0.5.
137
138 \sa QwtPolarPlot::setLegendPosition()
139 */
140
141void QwtPolarLayout::setLegendPosition(
142 QwtPolarPlot::LegendPosition pos, double ratio )
143{
144 if ( ratio > 1.0 )
145 ratio = 1.0;
146
147 switch( pos )
148 {
149 case QwtPolarPlot::TopLegend:
150 case QwtPolarPlot::BottomLegend:
151 {
152 if ( ratio <= 0.0 )
153 ratio = 0.33;
154 m_data->legendRatio = ratio;
155 m_data->legendPos = pos;
156 break;
157 }
158 case QwtPolarPlot::LeftLegend:
159 case QwtPolarPlot::RightLegend:
160 {
161 if ( ratio <= 0.0 )
162 ratio = 0.5;
163 m_data->legendRatio = ratio;
164 m_data->legendPos = pos;
165 break;
166 }
167 case QwtPolarPlot::ExternalLegend:
168 {
169 m_data->legendRatio = ratio; // meaningless
170 m_data->legendPos = pos;
171 break;
172 }
173 default:
174 break;
175 }
176}
177
178/*!
179 \brief Specify the position of the legend
180 \param pos The legend's position. Valid values are
181 \c QwtPolarPlot::LeftLegend, \c QwtPolarPlot::RightLegend,
182 \c QwtPolarPlot::TopLegend, \c QwtPolarPlot::BottomLegend.
183
184 \sa QwtPolarPlot::setLegendPosition()
185 */
186void QwtPolarLayout::setLegendPosition( QwtPolarPlot::LegendPosition pos )
187{
188 setLegendPosition( pos, 0.0 );
189}
190
191/*!
192 \return Position of the legend
193 \sa setLegendPosition(), QwtPolarPlot::setLegendPosition(),
194 QwtPolarPlot::legendPosition()
195 */
196QwtPolarPlot::LegendPosition QwtPolarLayout::legendPosition() const
197{
198 return m_data->legendPos;
199}
200
201/*!
202 Specify the relative size of the legend in the plot
203 \param ratio Ratio between legend and the bounding rect
204 of title, canvas and axes. The legend will be shrunk
205 if it would need more space than the given ratio.
206 The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
207 it will be reset to the default ratio.
208 The default vertical/horizontal ratio is 0.33/0.5.
209 */
210void QwtPolarLayout::setLegendRatio( double ratio )
211{
212 setLegendPosition( legendPosition(), ratio );
213}
214
215/*!
216 \return The relative size of the legend in the plot.
217 \sa setLegendPosition()
218 */
219double QwtPolarLayout::legendRatio() const
220{
221 return m_data->legendRatio;
222}
223
224/*!
225 \return Geometry for the title
226 \sa activate(), invalidate()
227 */
228
229const QRectF& QwtPolarLayout::titleRect() const
230{
231 return m_data->titleRect;
232}
233
234/*!
235 \return Geometry for the legend
236 \sa activate(), invalidate()
237 */
238
239const QRectF& QwtPolarLayout::legendRect() const
240{
241 return m_data->legendRect;
242}
243
244/*!
245 \return Geometry for the canvas
246 \sa activate(), invalidate()
247 */
248const QRectF& QwtPolarLayout::canvasRect() const
249{
250 return m_data->canvasRect;
251}
252
253/*!
254 Invalidate the geometry of all components.
255 \sa activate()
256 */
257void QwtPolarLayout::invalidate()
258{
259 m_data->titleRect = m_data->legendRect = m_data->canvasRect = QRect();
260}
261
262/*!
263 Find the geometry for the legend
264 \param options Options how to layout the legend
265 \param rect Rectangle where to place the legend
266 \return Geometry for the legend
267 */
268
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 {
302 case QwtPolarPlot::LeftLegend:
303 {
304 legendRect.setWidth( dim );
305 rect.setLeft( legendRect.right() );
306 break;
307 }
308 case QwtPolarPlot::RightLegend:
309 {
310 legendRect.setX( rect.right() - dim + 1 );
311 legendRect.setWidth( dim );
312 rect.setRight( legendRect.left() );
313 break;
314 }
315 case QwtPolarPlot::TopLegend:
316 {
317 legendRect.setHeight( dim );
318 rect.setTop( legendRect.bottom() );
319 break;
320 }
321 case QwtPolarPlot::BottomLegend:
322 {
323 legendRect.setY( rect.bottom() - dim + 1 );
324 legendRect.setHeight( dim );
325 rect.setBottom( legendRect.top() );
326 break;
327 }
328 case QwtPolarPlot::ExternalLegend:
329 break;
330 }
331
332 return legendRect;
333}
334
335/*!
336 \brief Recalculate the geometry of all components.
337
338 \param plot Plot to be layout
339 \param boundingRect Rect where to place the components
340 \param options Options
341
342 \sa invalidate(), titleRect(), legendRect(), canvasRect()
343 */
344void QwtPolarLayout::activate( const QwtPolarPlot* plot,
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 {
371 case QwtPolarPlot::LeftLegend:
372 rect.setLeft( rect.left() + m_data->spacing );
373 break;
374
375 case QwtPolarPlot::RightLegend:
376 rect.setRight( rect.right() - m_data->spacing );
377 break;
378
379 case QwtPolarPlot::TopLegend:
380 rect.setTop( rect.top() + m_data->spacing );
381 break;
382
383 case QwtPolarPlot::BottomLegend:
384 rect.setBottom( rect.bottom() - m_data->spacing );
385 break;
386
387 case QwtPolarPlot::ExternalLegend:
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}
Note: See TracBrowser for help on using the repository browser.