source: ntrip/trunk/BNC/qwt/qwt_plot_item.cpp@ 7905

Last change on this file since 7905 was 4271, checked in by mervart, 12 years ago
File size: 11.3 KB
Line 
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_plot_item.h"
11#include "qwt_text.h"
12#include "qwt_plot.h"
13#include "qwt_legend.h"
14#include "qwt_legend_item.h"
15#include "qwt_scale_div.h"
16#include <qpainter.h>
17
18class QwtPlotItem::PrivateData
19{
20public:
21 PrivateData():
22 plot( NULL ),
23 isVisible( true ),
24 attributes( 0 ),
25 renderHints( 0 ),
26 z( 0.0 ),
27 xAxis( QwtPlot::xBottom ),
28 yAxis( QwtPlot::yLeft )
29 {
30 }
31
32 mutable QwtPlot *plot;
33
34 bool isVisible;
35 QwtPlotItem::ItemAttributes attributes;
36 QwtPlotItem::RenderHints renderHints;
37 double z;
38
39 int xAxis;
40 int yAxis;
41
42 QwtText title;
43};
44
45/*!
46 Constructor
47 \param title Title of the item
48*/
49QwtPlotItem::QwtPlotItem( const QwtText &title )
50{
51 d_data = new PrivateData;
52 d_data->title = title;
53}
54
55//! Destroy the QwtPlotItem
56QwtPlotItem::~QwtPlotItem()
57{
58 attach( NULL );
59 delete d_data;
60}
61
62/*!
63 \brief Attach the item to a plot.
64
65 This method will attach a QwtPlotItem to the QwtPlot argument. It will first
66 detach the QwtPlotItem from any plot from a previous call to attach (if
67 necessary). If a NULL argument is passed, it will detach from any QwtPlot it
68 was attached to.
69
70 \param plot Plot widget
71 \sa detach()
72*/
73void QwtPlotItem::attach( QwtPlot *plot )
74{
75 if ( plot == d_data->plot )
76 return;
77
78 // remove the item from the previous plot
79
80 if ( d_data->plot )
81 {
82 if ( d_data->plot->legend() )
83 d_data->plot->legend()->remove( this );
84
85 d_data->plot->attachItem( this, false );
86
87 if ( d_data->plot->autoReplot() )
88 d_data->plot->update();
89 }
90
91 d_data->plot = plot;
92
93 if ( d_data->plot )
94 {
95 // insert the item into the current plot
96
97 d_data->plot->attachItem( this, true );
98 itemChanged();
99 }
100}
101
102/*!
103 \brief This method detaches a QwtPlotItem from any
104 QwtPlot it has been associated with.
105
106 detach() is equivalent to calling attach( NULL )
107 \sa attach()
108*/
109void QwtPlotItem::detach()
110{
111 attach( NULL );
112}
113
114/*!
115 Return rtti for the specific class represented. QwtPlotItem is simply
116 a virtual interface class, and base classes will implement this method
117 with specific rtti values so a user can differentiate them.
118
119 The rtti value is useful for environments, where the
120 runtime type information is disabled and it is not possible
121 to do a dynamic_cast<...>.
122
123 \return rtti value
124 \sa RttiValues
125*/
126int QwtPlotItem::rtti() const
127{
128 return Rtti_PlotItem;
129}
130
131//! Return attached plot
132QwtPlot *QwtPlotItem::plot() const
133{
134 return d_data->plot;
135}
136
137/*!
138 Plot items are painted in increasing z-order.
139
140 \return setZ(), QwtPlotDict::itemList()
141*/
142double QwtPlotItem::z() const
143{
144 return d_data->z;
145}
146
147/*!
148 \brief Set the z value
149
150 Plot items are painted in increasing z-order.
151
152 \param z Z-value
153 \sa z(), QwtPlotDict::itemList()
154*/
155void QwtPlotItem::setZ( double z )
156{
157 if ( d_data->z != z )
158 {
159 if ( d_data->plot ) // update the z order
160 d_data->plot->attachItem( this, false );
161
162 d_data->z = z;
163
164 if ( d_data->plot )
165 d_data->plot->attachItem( this, true );
166
167 itemChanged();
168 }
169}
170
171/*!
172 Set a new title
173
174 \param title Title
175 \sa title()
176*/
177void QwtPlotItem::setTitle( const QString &title )
178{
179 setTitle( QwtText( title ) );
180}
181
182/*!
183 Set a new title
184
185 \param title Title
186 \sa title()
187*/
188void QwtPlotItem::setTitle( const QwtText &title )
189{
190 if ( d_data->title != title )
191 {
192 d_data->title = title;
193 itemChanged();
194 }
195}
196
197/*!
198 \return Title of the item
199 \sa setTitle()
200*/
201const QwtText &QwtPlotItem::title() const
202{
203 return d_data->title;
204}
205
206/*!
207 Toggle an item attribute
208
209 \param attribute Attribute type
210 \param on true/false
211
212 \sa testItemAttribute(), ItemAttribute
213*/
214void QwtPlotItem::setItemAttribute( ItemAttribute attribute, bool on )
215{
216 if ( bool( d_data->attributes & attribute ) != on )
217 {
218 if ( on )
219 d_data->attributes |= attribute;
220 else
221 d_data->attributes &= ~attribute;
222
223 itemChanged();
224 }
225}
226
227/*!
228 Test an item attribute
229
230 \param attribute Attribute type
231 \return true/false
232 \sa setItemAttribute(), ItemAttribute
233*/
234bool QwtPlotItem::testItemAttribute( ItemAttribute attribute ) const
235{
236 return ( d_data->attributes & attribute );
237}
238
239/*!
240 Toggle an render hint
241
242 \param hint Render hint
243 \param on true/false
244
245 \sa testRenderHint(), RenderHint
246*/
247void QwtPlotItem::setRenderHint( RenderHint hint, bool on )
248{
249 if ( ( ( d_data->renderHints & hint ) != 0 ) != on )
250 {
251 if ( on )
252 d_data->renderHints |= hint;
253 else
254 d_data->renderHints &= ~hint;
255
256 itemChanged();
257 }
258}
259
260/*!
261 Test a render hint
262
263 \param hint Render hint
264 \return true/false
265 \sa setRenderHint(), RenderHint
266*/
267bool QwtPlotItem::testRenderHint( RenderHint hint ) const
268{
269 return ( d_data->renderHints & hint );
270}
271
272//! Show the item
273void QwtPlotItem::show()
274{
275 setVisible( true );
276}
277
278//! Hide the item
279void QwtPlotItem::hide()
280{
281 setVisible( false );
282}
283
284/*!
285 Show/Hide the item
286
287 \param on Show if true, otherwise hide
288 \sa isVisible(), show(), hide()
289*/
290void QwtPlotItem::setVisible( bool on )
291{
292 if ( on != d_data->isVisible )
293 {
294 d_data->isVisible = on;
295 itemChanged();
296 }
297}
298
299/*!
300 \return true if visible
301 \sa setVisible(), show(), hide()
302*/
303bool QwtPlotItem::isVisible() const
304{
305 return d_data->isVisible;
306}
307
308/*!
309 Update the legend and call QwtPlot::autoRefresh for the
310 parent plot.
311
312 \sa updateLegend()
313*/
314void QwtPlotItem::itemChanged()
315{
316 if ( d_data->plot )
317 {
318 if ( d_data->plot->legend() )
319 updateLegend( d_data->plot->legend() );
320
321 d_data->plot->autoRefresh();
322 }
323}
324
325/*!
326 Set X and Y axis
327
328 The item will painted according to the coordinates its Axes.
329
330 \param xAxis X Axis
331 \param yAxis Y Axis
332
333 \sa setXAxis(), setYAxis(), xAxis(), yAxis()
334*/
335void QwtPlotItem::setAxes( int xAxis, int yAxis )
336{
337 if ( xAxis == QwtPlot::xBottom || xAxis == QwtPlot::xTop )
338 d_data->xAxis = xAxis;
339
340 if ( yAxis == QwtPlot::yLeft || yAxis == QwtPlot::yRight )
341 d_data->yAxis = yAxis;
342
343 itemChanged();
344}
345
346/*!
347 Set the X axis
348
349 The item will painted according to the coordinates its Axes.
350
351 \param axis X Axis
352 \sa setAxes(), setYAxis(), xAxis()
353*/
354void QwtPlotItem::setXAxis( int axis )
355{
356 if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
357 {
358 d_data->xAxis = axis;
359 itemChanged();
360 }
361}
362
363/*!
364 Set the Y axis
365
366 The item will painted according to the coordinates its Axes.
367
368 \param axis Y Axis
369 \sa setAxes(), setXAxis(), yAxis()
370*/
371void QwtPlotItem::setYAxis( int axis )
372{
373 if ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight )
374 {
375 d_data->yAxis = axis;
376 itemChanged();
377 }
378}
379
380//! Return xAxis
381int QwtPlotItem::xAxis() const
382{
383 return d_data->xAxis;
384}
385
386//! Return yAxis
387int QwtPlotItem::yAxis() const
388{
389 return d_data->yAxis;
390}
391
392/*!
393 \return An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0)
394*/
395QRectF QwtPlotItem::boundingRect() const
396{
397 return QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid
398}
399
400/*!
401 \brief Allocate the widget that represents the item on the legend
402
403 The default implementation returns a QwtLegendItem(), but an item
404 could be represented by any type of widget,
405 by overloading legendItem() and updateLegend().
406
407 \return QwtLegendItem()
408 \sa updateLegend() QwtLegend()
409*/
410QWidget *QwtPlotItem::legendItem() const
411{
412 QwtLegendItem *item = new QwtLegendItem;
413 if ( d_data->plot )
414 {
415 QObject::connect( item, SIGNAL( clicked() ),
416 d_data->plot, SLOT( legendItemClicked() ) );
417 QObject::connect( item, SIGNAL( checked( bool ) ),
418 d_data->plot, SLOT( legendItemChecked( bool ) ) );
419 }
420 return item;
421}
422
423/*!
424 \brief Update the widget that represents the item on the legend
425
426 updateLegend() is called from itemChanged() to adopt the widget
427 representing the item on the legend to its new configuration.
428
429 The default implementation updates a QwtLegendItem(),
430 but an item could be represented by any type of widget,
431 by overloading legendItem() and updateLegend().
432
433 \param legend Legend
434
435 \sa legendItem(), itemChanged(), QwtLegend()
436*/
437void QwtPlotItem::updateLegend( QwtLegend *legend ) const
438{
439 if ( legend == NULL )
440 return;
441
442 QWidget *lgdItem = legend->find( this );
443 if ( testItemAttribute( QwtPlotItem::Legend ) )
444 {
445 if ( lgdItem == NULL )
446 {
447 lgdItem = legendItem();
448 if ( lgdItem )
449 legend->insert( this, lgdItem );
450 }
451
452 QwtLegendItem *label = qobject_cast<QwtLegendItem *>( lgdItem );
453 if ( label )
454 {
455 // paint the identifier
456 const QSize sz = label->identifierSize();
457
458 QPixmap identifier( sz.width(), sz.height() );
459 identifier.fill( Qt::transparent );
460
461 QPainter painter( &identifier );
462 painter.setRenderHint( QPainter::Antialiasing,
463 testRenderHint( QwtPlotItem::RenderAntialiased ) );
464 drawLegendIdentifier( &painter,
465 QRect( 0, 0, sz.width(), sz.height() ) );
466 painter.end();
467
468 const bool doUpdate = label->updatesEnabled();
469 if ( doUpdate )
470 label->setUpdatesEnabled( false );
471
472 label->setText( title() );
473 label->setIdentifier( identifier );
474 label->setItemMode( legend->itemMode() );
475
476 if ( doUpdate )
477 label->setUpdatesEnabled( true );
478
479 label->update();
480 }
481 }
482 else
483 {
484 if ( lgdItem )
485 {
486 lgdItem->hide();
487 lgdItem->deleteLater();
488 }
489 }
490}
491
492/*!
493 \brief Update the item to changes of the axes scale division
494
495 Update the item, when the axes of plot have changed.
496 The default implementation does nothing, but items that depend
497 on the scale division (like QwtPlotGrid()) have to reimplement
498 updateScaleDiv()
499
500 \param xScaleDiv Scale division of the x-axis
501 \param yScaleDiv Scale division of the y-axis
502
503 \sa QwtPlot::updateAxes()
504*/
505void QwtPlotItem::updateScaleDiv( const QwtScaleDiv &xScaleDiv,
506 const QwtScaleDiv &yScaleDiv )
507{
508 Q_UNUSED( xScaleDiv );
509 Q_UNUSED( yScaleDiv );
510}
511
512/*!
513 \brief Calculate the bounding scale rect of 2 maps
514
515 \param xMap X map
516 \param yMap X map
517
518 \return Bounding scale rect of the scale maps, normalized
519*/
520QRectF QwtPlotItem::scaleRect( const QwtScaleMap &xMap,
521 const QwtScaleMap &yMap ) const
522{
523 return QRectF( xMap.s1(), yMap.s1(),
524 xMap.sDist(), yMap.sDist() );
525}
526
527/*!
528 \brief Calculate the bounding paint rect of 2 maps
529
530 \param xMap X map
531 \param yMap X map
532
533 \return Bounding paint rect of the scale maps, normalized
534*/
535QRectF QwtPlotItem::paintRect( const QwtScaleMap &xMap,
536 const QwtScaleMap &yMap ) const
537{
538 const QRectF rect( xMap.p1(), yMap.p1(),
539 xMap.pDist(), yMap.pDist() );
540
541 return rect;
542}
Note: See TracBrowser for help on using the repository browser.