source: ntrip/trunk/BNC/qwtpolar/qwt_polar_canvas.cpp@ 5468

Last change on this file since 5468 was 4272, checked in by mervart, 12 years ago
File size: 7.6 KB
Line 
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_canvas.h"
10#include "qwt_polar_plot.h"
11#include <qpainter.h>
12#include <qevent.h>
13#include <qpixmap.h>
14#include <qstyle.h>
15#include <qstyleoption.h>
16#ifdef Q_WS_X11
17#include <qx11info_x11.h>
18#endif
19
20static inline void qwtDrawStyledBackground(
21 QWidget *widget, QPainter *painter )
22{
23 QStyleOption opt;
24 opt.initFrom( widget );
25 widget->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, widget );
26}
27
28static QWidget *qwtBackgroundWidget( QWidget *w )
29{
30 if ( w->parentWidget() == NULL )
31 return w;
32
33 if ( w->autoFillBackground() )
34 {
35 const QBrush brush = w->palette().brush( w->backgroundRole() );
36 if ( brush.color().alpha() > 0 )
37 return w;
38 }
39
40 if ( w->testAttribute( Qt::WA_StyledBackground ) )
41 {
42 QImage image( 1, 1, QImage::Format_ARGB32 );
43 image.fill( Qt::transparent );
44
45 QPainter painter( &image );
46 painter.translate( -w->rect().center() );
47 qwtDrawStyledBackground( w, &painter );
48 painter.end();
49
50 if ( qAlpha( image.pixel( 0, 0 ) ) != 0 )
51 return w;
52 }
53
54 return qwtBackgroundWidget( w->parentWidget() );
55}
56
57class QwtPolarCanvas::PrivateData
58{
59public:
60 PrivateData():
61 paintAttributes( 0 ),
62 backingStore( NULL )
63 {
64 }
65
66 ~PrivateData()
67 {
68 delete backingStore;
69 }
70
71 QwtPolarCanvas::PaintAttributes paintAttributes;
72 QPixmap *backingStore;
73};
74
75//! Constructor
76QwtPolarCanvas::QwtPolarCanvas( QwtPolarPlot *plot ):
77 QFrame( plot )
78{
79 d_data = new PrivateData;
80
81#ifndef QT_NO_CURSOR
82 setCursor( Qt::CrossCursor );
83#endif
84 setFocusPolicy( Qt::WheelFocus );
85
86 setPaintAttribute( BackingStore, true );
87}
88
89//! Destructor
90QwtPolarCanvas::~QwtPolarCanvas()
91{
92 delete d_data;
93}
94
95//! \return Parent plot widget
96QwtPolarPlot *QwtPolarCanvas::plot()
97{
98 return qobject_cast<QwtPolarPlot *>( parent() );
99}
100
101//! \return Parent plot widget
102const QwtPolarPlot *QwtPolarCanvas::plot() const
103{
104 return qobject_cast<QwtPolarPlot *>( parent() );
105}
106
107/*!
108 \brief Changing the paint attributes
109
110 \param attribute Paint attribute
111 \param on On/Off
112
113 The default setting enables BackingStore
114
115 \sa testPaintAttribute(), paintCache()
116*/
117void QwtPolarCanvas::setPaintAttribute( PaintAttribute attribute, bool on )
118{
119 if ( bool( d_data->paintAttributes & attribute ) == on )
120 return;
121
122 if ( on )
123 d_data->paintAttributes |= attribute;
124 else
125 d_data->paintAttributes &= ~attribute;
126
127 switch( attribute )
128 {
129 case BackingStore:
130 {
131 if ( on )
132 {
133 if ( d_data->backingStore == NULL )
134 d_data->backingStore = new QPixmap();
135
136 if ( isVisible() )
137 {
138 const QRect cr = contentsRect();
139 *d_data->backingStore = QPixmap::grabWidget( this, cr );
140 }
141 }
142 else
143 {
144 delete d_data->backingStore;
145 d_data->backingStore = NULL;
146 }
147 break;
148 }
149 }
150}
151
152/*!
153 Test wether a paint attribute is enabled
154
155 \param attribute Paint attribute
156 \return true if the attribute is enabled
157 \sa setPaintAttribute()
158*/
159bool QwtPolarCanvas::testPaintAttribute( PaintAttribute attribute ) const
160{
161 return ( d_data->paintAttributes & attribute ) != 0;
162}
163
164//! \return Backing store, might be null
165const QPixmap *QwtPolarCanvas::backingStore() const
166{
167 return d_data->backingStore;
168}
169
170//! Invalidate the internal backing store
171void QwtPolarCanvas::invalidateBackingStore()
172{
173 if ( d_data->backingStore )
174 *d_data->backingStore = QPixmap();
175}
176
177/*!
178 Paint event
179 \param event Paint event
180*/
181void QwtPolarCanvas::paintEvent( QPaintEvent *event )
182{
183 QPainter painter( this );
184 painter.setClipRegion( event->region() );
185
186 if ( ( d_data->paintAttributes & BackingStore )
187 && d_data->backingStore != NULL )
188 {
189 QPixmap &bs = *d_data->backingStore;
190 if ( bs.size() != size() )
191 {
192 bs = QPixmap( size() );
193#ifdef Q_WS_X11
194 if ( bs.x11Info().screen() != x11Info().screen() )
195 bs.x11SetScreen( x11Info().screen() );
196#endif
197
198 QPainter p;
199
200 if ( testAttribute( Qt::WA_StyledBackground ) )
201 {
202 p.begin( &bs );
203 qwtDrawStyledBackground( this, &p );
204 }
205 else
206 {
207 if ( autoFillBackground() )
208 {
209 p.begin( &bs );
210 p.fillRect( rect(), palette().brush( backgroundRole() ) );
211 }
212 else
213 {
214 QWidget *bgWidget = qwtBackgroundWidget( plot() );
215 bs.fill( bgWidget, mapTo( bgWidget, rect().topLeft() ) );
216 p.begin( &bs );
217 }
218 }
219
220 plot()->drawCanvas( &p, contentsRect() );
221
222 if ( frameWidth() > 0 )
223 drawFrame( &p );
224 }
225
226 painter.drawPixmap( 0, 0, *d_data->backingStore );
227 }
228 else
229 {
230 qwtDrawStyledBackground( this, &painter );
231
232 plot()->drawCanvas( &painter, contentsRect() );
233
234 if ( frameWidth() > 0 )
235 drawFrame( &painter );
236 }
237}
238
239/*!
240 Resize event
241 \param event Resize event
242*/
243void QwtPolarCanvas::resizeEvent( QResizeEvent *event )
244{
245 QFrame::resizeEvent( event );
246
247 for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
248 plot()->updateScale( scaleId );
249}
250
251/*!
252 Translate a point from widget into plot coordinates
253
254 \param pos Point in widget coordinates of the plot canvas
255 \return Point in plot coordinates
256
257 \sa transform()
258*/
259QwtPointPolar QwtPolarCanvas::invTransform( const QPoint &pos ) const
260{
261 const QwtPolarPlot *pl = plot();
262
263 const QwtScaleMap azimuthMap = pl->scaleMap( QwtPolar::Azimuth );
264 const QwtScaleMap radialMap = pl->scaleMap( QwtPolar::Radius );
265
266 const QPointF center = pl->plotRect().center();
267
268 double dx = pos.x() - center.x();
269 double dy = -( pos.y() - center.y() );
270
271 const QwtPointPolar polarPos = QwtPointPolar( QPoint( dx, dy ) ).normalized();
272
273 double azimuth = azimuthMap.invTransform( polarPos.azimuth() );
274
275 // normalize the azimuth
276 double min = azimuthMap.s1();
277 double max = azimuthMap.s2();
278 if ( max < min )
279 qSwap( min, max );
280
281 if ( azimuth < min )
282 {
283 azimuth += max - min;
284 }
285 else if ( azimuth > max )
286 {
287 azimuth -= max - min;
288 }
289
290 const double radius = radialMap.invTransform( polarPos.radius() );
291
292 return QwtPointPolar( azimuth, radius );
293}
294
295/*!
296 Translate a point from plot into widget coordinates
297
298 \param polarPos Point in plot coordinates
299 \return Point in widget coordinates
300 \sa transform()
301*/
302QPoint QwtPolarCanvas::transform( const QwtPointPolar &polarPos ) const
303{
304 const QwtPolarPlot *pl = plot();
305
306 const QwtScaleMap azimuthMap = pl->scaleMap( QwtPolar::Azimuth );
307 const QwtScaleMap radialMap = pl->scaleMap( QwtPolar::Radius );
308
309 const double radius = radialMap.transform( polarPos.radius() );
310 const double azimuth = azimuthMap.transform( polarPos.azimuth() );
311
312 const QPointF pos = qwtPolar2Pos(
313 pl->plotRect().center(), radius, azimuth );
314
315 return pos.toPoint();
316}
Note: See TracBrowser for help on using the repository browser.