qwt_plot_canvas.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 // vim: expandtab
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(NoFocusIndicator),
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 #ifndef QT_NO_CURSOR
00062     setCursor(Qt::crossCursor);
00063 #endif
00064 #else
00065 #ifndef QT_NO_CURSOR
00066     setCursor(Qt::CrossCursor);
00067 #endif
00068 #endif // >= 0x040000
00069 
00070     setPaintAttribute(PaintCached, true);
00071     setPaintAttribute(PaintPacked, true);
00072 }
00073 
00075 QwtPlotCanvas::~QwtPlotCanvas()
00076 {
00077     delete d_data;
00078 }
00079 
00081 QwtPlot *QwtPlotCanvas::plot()
00082 {
00083     QWidget *w = parentWidget();
00084     if ( w && w->inherits("QwtPlot") )
00085         return (QwtPlot *)w;
00086 
00087     return NULL;
00088 }
00089 
00091 const QwtPlot *QwtPlotCanvas::plot() const
00092 {
00093     const QWidget *w = parentWidget();
00094     if ( w && w->inherits("QwtPlot") )
00095         return (QwtPlot *)w;
00096 
00097     return NULL;
00098 }
00099 
00110 void QwtPlotCanvas::setPaintAttribute(PaintAttribute attribute, bool on)
00111 {
00112     if ( bool(d_data->paintAttributes & attribute) == on )
00113         return;
00114 
00115     if ( on )
00116         d_data->paintAttributes |= attribute;
00117     else
00118         d_data->paintAttributes &= ~attribute;
00119 
00120     switch(attribute)
00121     {
00122         case PaintCached:
00123         {
00124             if ( on )
00125             {
00126                 if ( d_data->cache == NULL )
00127                     d_data->cache = new QPixmap();
00128 
00129                 if ( isVisible() )
00130                 {
00131                     const QRect cr = contentsRect();
00132                     *d_data->cache = QPixmap::grabWidget(this,
00133                         cr.x(), cr.y(), cr.width(), cr.height() );
00134                 }
00135             }
00136             else
00137             {
00138                 delete d_data->cache;
00139                 d_data->cache = NULL;
00140             }
00141             break;
00142         }
00143         case PaintPacked:
00144         {
00145             /*
00146               If not visible, changing of the background mode
00147               is delayed until it becomes visible. This tries to avoid 
00148               looking through the canvas when the canvas is shown the first 
00149               time.
00150              */
00151 
00152             if ( on == false || isVisible() )
00153                 QwtPlotCanvas::setSystemBackground(!on);
00154 
00155             break;
00156         }
00157     }
00158 }
00159 
00167 bool QwtPlotCanvas::testPaintAttribute(PaintAttribute attribute) const
00168 {
00169     return (d_data->paintAttributes & attribute) != 0;
00170 }
00171 
00173 QPixmap *QwtPlotCanvas::paintCache()
00174 {
00175     return d_data->cache;
00176 }
00177 
00179 const QPixmap *QwtPlotCanvas::paintCache() const
00180 {
00181     return d_data->cache;
00182 }
00183 
00185 void QwtPlotCanvas::invalidatePaintCache()
00186 {
00187     if ( d_data->cache )
00188         *d_data->cache = QPixmap();
00189 }
00190 
00196 void QwtPlotCanvas::setFocusIndicator(FocusIndicator focusIndicator)
00197 {
00198     d_data->focusIndicator = focusIndicator;
00199 }
00200 
00206 QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const
00207 {
00208     return d_data->focusIndicator;
00209 }
00210 
00211 void QwtPlotCanvas::hideEvent(QHideEvent *e)
00212 {
00213     QFrame::hideEvent(e);
00214 
00215     if ( d_data->paintAttributes & PaintPacked )
00216     {
00217         // enable system background to avoid the "looking through
00218         // the canvas" effect, for the next show
00219 
00220         setSystemBackground(true);
00221     }
00222 }
00223 
00225 void QwtPlotCanvas::paintEvent(QPaintEvent *event)
00226 {
00227 #if QT_VERSION >= 0x040000
00228     QPainter painter(this);
00229     
00230     if ( !contentsRect().contains( event->rect() ) ) 
00231     {
00232         painter.save();
00233         painter.setClipRegion( event->region() & frameRect() );
00234         drawFrame( &painter );
00235         painter.restore(); 
00236     }
00237 
00238     painter.setClipRegion(event->region() & contentsRect());
00239 
00240     drawContents( &painter );
00241 #else // QT_VERSION < 0x040000
00242     QFrame::paintEvent(event);
00243 #endif
00244 
00245     if ( d_data->paintAttributes & PaintPacked )
00246         setSystemBackground(false);
00247 }
00248 
00250 void QwtPlotCanvas::drawContents(QPainter *painter)
00251 {
00252     if ( d_data->paintAttributes & PaintCached && d_data->cache 
00253         && d_data->cache->size() == contentsRect().size() )
00254     {
00255         painter->drawPixmap(contentsRect().topLeft(), *d_data->cache);
00256     }
00257     else
00258     {
00259         QwtPlot *plot = ((QwtPlot *)parent());
00260         const bool doAutoReplot = plot->autoReplot();
00261         plot->setAutoReplot(false);
00262 
00263         drawCanvas(painter);
00264 
00265         plot->setAutoReplot(doAutoReplot);
00266     }
00267 
00268     if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
00269         drawFocusIndicator(painter);
00270 }
00271 
00281 void QwtPlotCanvas::drawCanvas(QPainter *painter)
00282 {
00283     if ( !contentsRect().isValid() )
00284         return;
00285 
00286     QBrush bgBrush;
00287 #if QT_VERSION >= 0x040000
00288         bgBrush = palette().brush(backgroundRole());
00289 #else
00290     QColorGroup::ColorRole role = 
00291         QPalette::backgroundRoleFromMode( backgroundMode() );
00292     bgBrush = colorGroup().brush( role );
00293 #endif
00294 
00295     if ( d_data->paintAttributes & PaintCached && d_data->cache )
00296     {
00297         *d_data->cache = QPixmap(contentsRect().size());
00298 
00299 #ifdef Q_WS_X11
00300 #if QT_VERSION >= 0x040000
00301         if ( d_data->cache->x11Info().screen() != x11Info().screen() )
00302             d_data->cache->x11SetScreen(x11Info().screen());
00303 #else
00304         if ( d_data->cache->x11Screen() != x11Screen() )
00305             d_data->cache->x11SetScreen(x11Screen());
00306 #endif
00307 #endif
00308 
00309         if ( d_data->paintAttributes & PaintPacked )
00310         {
00311             QPainter bgPainter(d_data->cache);
00312             bgPainter.setPen(Qt::NoPen);
00313 
00314             bgPainter.setBrush(bgBrush);
00315             bgPainter.drawRect(d_data->cache->rect());
00316         }
00317         else
00318             d_data->cache->fill(this, d_data->cache->rect().topLeft());
00319 
00320         QPainter cachePainter(d_data->cache);
00321         cachePainter.translate(-contentsRect().x(),
00322             -contentsRect().y());
00323 
00324         ((QwtPlot *)parent())->drawCanvas(&cachePainter);
00325 
00326         cachePainter.end();
00327 
00328         painter->drawPixmap(contentsRect(), *d_data->cache);
00329     }
00330     else
00331     {
00332 #if QT_VERSION >= 0x040000
00333         if ( d_data->paintAttributes & PaintPacked )
00334 #endif
00335         {
00336             painter->save();
00337 
00338             painter->setPen(Qt::NoPen);
00339             painter->setBrush(bgBrush);
00340             painter->drawRect(contentsRect());
00341 
00342             painter->restore();
00343         }
00344 
00345         ((QwtPlot *)parent())->drawCanvas(painter);
00346     }
00347 }
00348 
00350 void QwtPlotCanvas::drawFocusIndicator(QPainter *painter)
00351 {
00352     const int margin = 1;
00353 
00354     QRect focusRect = contentsRect();
00355     focusRect.setRect(focusRect.x() + margin, focusRect.y() + margin,
00356         focusRect.width() - 2 * margin, focusRect.height() - 2 * margin);
00357 
00358     QwtPainter::drawFocusRect(painter, this, focusRect);
00359 }
00360 
00361 void QwtPlotCanvas::setSystemBackground(bool on)
00362 {
00363 #if QT_VERSION < 0x040000
00364     if ( backgroundMode() == Qt::NoBackground )
00365     {
00366         if ( on )
00367             setBackgroundMode(Qt::PaletteBackground);
00368     }
00369     else
00370     {
00371         if ( !on )
00372             setBackgroundMode(Qt::NoBackground);
00373     }
00374 #else
00375     if ( testAttribute(Qt::WA_NoSystemBackground) == on )
00376         setAttribute(Qt::WA_NoSystemBackground, !on);
00377 #endif
00378 }

Generated on Sun Mar 22 16:54:07 2009 for Qwt User's Guide by  doxygen 1.5.0