00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qpainter.h>
00013 #include <qstyle.h>
00014 #if QT_VERSION >= 0x040000
00015 #include <qstyleoption.h>
00016 #include <qpaintengine.h>
00017 #ifdef Q_WS_X11
00018 #include <qx11info_x11.h>
00019 #endif
00020 #endif
00021 #include <qevent.h>
00022 #include "qwt_painter.h"
00023 #include "qwt_math.h"
00024 #include "qwt_plot.h"
00025 #include "qwt_paint_buffer.h"
00026 #include "qwt_plot_canvas.h"
00027
00028 class QwtPlotCanvas::PrivateData
00029 {
00030 public:
00031 PrivateData():
00032 focusIndicator(CanvasFocusIndicator),
00033 paintAttributes(0),
00034 cache(NULL)
00035 {
00036 }
00037
00038 ~PrivateData()
00039 {
00040 delete cache;
00041 }
00042
00043 FocusIndicator focusIndicator;
00044 int paintAttributes;
00045 QPixmap *cache;
00046 };
00047
00049
00050 QwtPlotCanvas::QwtPlotCanvas(QwtPlot *plot):
00051 QFrame(plot)
00052 {
00053 d_data = new PrivateData;
00054
00055 #if QT_VERSION >= 0x040100
00056 setAutoFillBackground(true);
00057 #endif
00058
00059 #if QT_VERSION < 0x040000
00060 setWFlags(Qt::WNoAutoErase);
00061 setCursor(Qt::crossCursor);
00062 #else
00063 setAttribute(Qt::WA_PaintOnScreen, true);
00064 setCursor(Qt::CrossCursor);
00065 #endif // >= 0x040000
00066
00067 setPaintAttribute(PaintCached, true);
00068 setPaintAttribute(PaintPacked, true);
00069 }
00070
00072 QwtPlotCanvas::~QwtPlotCanvas()
00073 {
00074 delete d_data;
00075 }
00076
00087 void QwtPlotCanvas::setPaintAttribute(PaintAttribute attribute, bool on)
00088 {
00089 if ( bool(d_data->paintAttributes & attribute) == on )
00090 return;
00091
00092 if ( on )
00093 d_data->paintAttributes |= attribute;
00094 else
00095 d_data->paintAttributes &= ~attribute;
00096
00097 switch(attribute)
00098 {
00099 case PaintCached:
00100 {
00101 if ( on )
00102 {
00103 if ( d_data->cache == NULL )
00104 d_data->cache = new QPixmap();
00105
00106 if ( isVisible() )
00107 {
00108 const QRect cr = contentsRect();
00109 *d_data->cache = QPixmap::grabWidget(this,
00110 cr.x(), cr.y(), cr.width(), cr.height() );
00111 }
00112 }
00113 else
00114 {
00115 delete d_data->cache;
00116 d_data->cache = NULL;
00117 }
00118 break;
00119 }
00120 case PaintPacked:
00121 {
00122
00123
00124
00125
00126
00127
00128
00129 if ( on == false || isVisible() )
00130 QwtPlotCanvas::setSystemBackground(!on);
00131
00132 break;
00133 }
00134 }
00135 }
00136
00143 bool QwtPlotCanvas::testPaintAttribute(PaintAttribute attribute) const
00144 {
00145 return (d_data->paintAttributes & attribute) != 0;
00146 }
00147
00149 QPixmap *QwtPlotCanvas::paintCache()
00150 {
00151 return d_data->cache;
00152 }
00153
00155 const QPixmap *QwtPlotCanvas::paintCache() const
00156 {
00157 return d_data->cache;
00158 }
00159
00161 void QwtPlotCanvas::invalidatePaintCache()
00162 {
00163 if ( d_data->cache )
00164 *d_data->cache = QPixmap();
00165 }
00166
00172 void QwtPlotCanvas::setFocusIndicator(FocusIndicator focusIndicator)
00173 {
00174 d_data->focusIndicator = focusIndicator;
00175 }
00176
00182 QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const
00183 {
00184 return d_data->focusIndicator;
00185 }
00186
00187 void QwtPlotCanvas::hideEvent(QHideEvent *e)
00188 {
00189 QFrame::hideEvent(e);
00190
00191 if ( d_data->paintAttributes & PaintPacked )
00192 {
00193
00194
00195
00196 setSystemBackground(true);
00197 }
00198 }
00199
00200 void QwtPlotCanvas::paintEvent(QPaintEvent *event)
00201 {
00202 #if QT_VERSION >= 0x040000
00203 QPainter painter(this);
00204
00205 if ( !contentsRect().contains( event->rect() ) )
00206 {
00207 painter.save();
00208 painter.setClipRegion( event->region() & frameRect() );
00209 drawFrame( &painter );
00210 painter.restore();
00211 }
00212
00213 #if defined(Q_WS_WIN)
00214
00215 #ifdef __GNUC__
00216 #warning Clipping bugs on Win32
00217 #endif
00218
00219 #else
00220 painter.setClipRegion(event->region() & contentsRect());
00221 #endif
00222
00223 drawContents( &painter );
00224 #else // QT_VERSION < 0x040000
00225 QFrame::paintEvent(event);
00226 #endif
00227
00228 if ( d_data->paintAttributes & PaintPacked )
00229 setSystemBackground(false);
00230 }
00231
00233 void QwtPlotCanvas::drawContents(QPainter *painter)
00234 {
00235 if ( d_data->paintAttributes & PaintCached && d_data->cache
00236 && d_data->cache->size() == contentsRect().size() )
00237 {
00238 painter->drawPixmap(contentsRect().topLeft(), *d_data->cache);
00239 }
00240 else
00241 drawCanvas(painter);
00242
00243 if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
00244 drawFocusIndicator(painter);
00245 }
00246
00256 void QwtPlotCanvas::drawCanvas(QPainter *painter)
00257 {
00258 if ( !contentsRect().isValid() )
00259 return;
00260
00261 if ( d_data->paintAttributes & PaintCached && d_data->cache )
00262 {
00263 *d_data->cache = QPixmap(contentsRect().size());
00264
00265 #ifdef Q_WS_X11
00266 #if QT_VERSION >= 0x040000
00267 if ( d_data->cache->x11Info().screen() != x11Info().screen() )
00268 d_data->cache->x11SetScreen(x11Info().screen());
00269 #else
00270 if ( d_data->cache->x11Screen() != x11Screen() )
00271 d_data->cache->x11SetScreen(x11Screen());
00272 #endif
00273 #endif
00274
00275 if ( d_data->paintAttributes & PaintPacked )
00276 {
00277 QPainter bgPainter(d_data->cache);
00278 bgPainter.setPen(Qt::NoPen);
00279
00280 QBrush bgBrush;
00281 #if QT_VERSION >= 0x040000
00282 bgBrush = palette().brush(backgroundRole());
00283 #else
00284 QColorGroup::ColorRole role =
00285 QPalette::backgroundRoleFromMode( backgroundMode() );
00286 bgBrush = colorGroup().brush( role );
00287 #endif
00288 bgPainter.setBrush(bgBrush);
00289 bgPainter.drawRect(d_data->cache->rect());
00290 }
00291 else
00292 d_data->cache->fill(this, d_data->cache->rect().topLeft());
00293
00294 QPainter cachePainter(d_data->cache);
00295 cachePainter.translate(-contentsRect().x(),
00296 -contentsRect().y());
00297
00298 ((QwtPlot *)parent())->drawCanvas(&cachePainter);
00299
00300 cachePainter.end();
00301
00302 painter->drawPixmap(contentsRect(), *d_data->cache);
00303 }
00304 else
00305 {
00306 if ( d_data->paintAttributes & PaintPacked )
00307 {
00308 painter->save();
00309 painter->setPen(Qt::NoPen);
00310
00311 const QBrush brush =
00312 #if QT_VERSION < 0x040000
00313 backgroundBrush();
00314 #else
00315 palette().brush(backgroundRole());
00316 #endif
00317 painter->setBrush(brush);
00318
00319 painter->drawRect(contentsRect());
00320 painter->restore();
00321 }
00322 ((QwtPlot *)parent())->drawCanvas(painter);
00323 }
00324 }
00325
00327 void QwtPlotCanvas::drawFocusIndicator(QPainter *painter)
00328 {
00329 const int margin = 1;
00330
00331 QRect focusRect = contentsRect();
00332 focusRect.setRect(focusRect.x() + margin, focusRect.y() + margin,
00333 focusRect.width() - 2 * margin, focusRect.height() - 2 * margin);
00334
00335 QwtPainter::drawFocusRect(painter, this, focusRect);
00336 }
00337
00338 void QwtPlotCanvas::setSystemBackground(bool on)
00339 {
00340 #if QT_VERSION < 0x040000
00341 if ( backgroundMode() == Qt::NoBackground )
00342 {
00343 if ( on )
00344 setBackgroundMode(Qt::PaletteBackground);
00345 }
00346 else
00347 {
00348 if ( !on )
00349 setBackgroundMode(Qt::NoBackground);
00350 }
00351 #else
00352 if ( testAttribute(Qt::WA_NoSystemBackground) == on )
00353 setAttribute(Qt::WA_NoSystemBackground, !on);
00354 #endif
00355 }