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(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 
00090 void QwtPlotCanvas::setPaintAttribute(PaintAttribute attribute, bool on)
00091 {
00092     if ( bool(d_data->paintAttributes & attribute) == on )
00093         return;
00094 
00095     if ( on )
00096         d_data->paintAttributes |= attribute;
00097     else
00098         d_data->paintAttributes &= ~attribute;
00099 
00100     switch(attribute)
00101     {
00102         case PaintCached:
00103         {
00104             if ( on )
00105             {
00106                 if ( d_data->cache == NULL )
00107                     d_data->cache = new QPixmap();
00108 
00109                 if ( isVisible() )
00110                 {
00111                     const QRect cr = contentsRect();
00112                     *d_data->cache = QPixmap::grabWidget(this,
00113                         cr.x(), cr.y(), cr.width(), cr.height() );
00114                 }
00115             }
00116             else
00117             {
00118                 delete d_data->cache;
00119                 d_data->cache = NULL;
00120             }
00121             break;
00122         }
00123         case PaintPacked:
00124         {
00125             
00126 
00127 
00128 
00129 
00130 
00131 
00132             if ( on == false || isVisible() )
00133                 QwtPlotCanvas::setSystemBackground(!on);
00134 
00135             break;
00136         }
00137     }
00138 }
00139 
00146 bool QwtPlotCanvas::testPaintAttribute(PaintAttribute attribute) const
00147 {
00148     return (d_data->paintAttributes & attribute) != 0;
00149 }
00150 
00152 QPixmap *QwtPlotCanvas::paintCache()
00153 {
00154     return d_data->cache;
00155 }
00156 
00158 const QPixmap *QwtPlotCanvas::paintCache() const
00159 {
00160     return d_data->cache;
00161 }
00162 
00164 void QwtPlotCanvas::invalidatePaintCache()
00165 {
00166     if ( d_data->cache )
00167         *d_data->cache = QPixmap();
00168 }
00169 
00175 void QwtPlotCanvas::setFocusIndicator(FocusIndicator focusIndicator)
00176 {
00177     d_data->focusIndicator = focusIndicator;
00178 }
00179 
00185 QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const
00186 {
00187     return d_data->focusIndicator;
00188 }
00189 
00190 void QwtPlotCanvas::hideEvent(QHideEvent *e)
00191 {
00192     QFrame::hideEvent(e);
00193 
00194     if ( d_data->paintAttributes & PaintPacked )
00195     {
00196         
00197         
00198 
00199         setSystemBackground(true);
00200     }
00201 }
00202 
00203 void QwtPlotCanvas::paintEvent(QPaintEvent *event)
00204 {
00205 #if QT_VERSION >= 0x040000
00206     QPainter painter(this);
00207     
00208     if ( !contentsRect().contains( event->rect() ) ) 
00209     {
00210         painter.save();
00211         painter.setClipRegion( event->region() & frameRect() );
00212         drawFrame( &painter );
00213         painter.restore(); 
00214     }
00215 
00216     painter.setClipRegion(event->region() & contentsRect());
00217 
00218     drawContents( &painter );
00219 #else // QT_VERSION < 0x040000
00220     QFrame::paintEvent(event);
00221 #endif
00222 
00223     if ( d_data->paintAttributes & PaintPacked )
00224         setSystemBackground(false);
00225 }
00226 
00228 void QwtPlotCanvas::drawContents(QPainter *painter)
00229 {
00230     if ( d_data->paintAttributes & PaintCached && d_data->cache 
00231         && d_data->cache->size() == contentsRect().size() )
00232     {
00233         painter->drawPixmap(contentsRect().topLeft(), *d_data->cache);
00234     }
00235     else
00236     {
00237         QwtPlot *plot = ((QwtPlot *)parent());
00238         const bool doAutoReplot = plot->autoReplot();
00239             plot->setAutoReplot(false);
00240 
00241         drawCanvas(painter);
00242 
00243         plot->setAutoReplot(doAutoReplot);
00244     }
00245 
00246     if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
00247         drawFocusIndicator(painter);
00248 }
00249 
00259 void QwtPlotCanvas::drawCanvas(QPainter *painter)
00260 {
00261     if ( !contentsRect().isValid() )
00262         return;
00263 
00264     QBrush bgBrush;
00265 #if QT_VERSION >= 0x040000
00266         bgBrush = palette().brush(backgroundRole());
00267 #else
00268     QColorGroup::ColorRole role = 
00269         QPalette::backgroundRoleFromMode( backgroundMode() );
00270     bgBrush = colorGroup().brush( role );
00271 #endif
00272 
00273     if ( d_data->paintAttributes & PaintCached && d_data->cache )
00274     {
00275         *d_data->cache = QPixmap(contentsRect().size());
00276 
00277 #ifdef Q_WS_X11
00278 #if QT_VERSION >= 0x040000
00279         if ( d_data->cache->x11Info().screen() != x11Info().screen() )
00280             d_data->cache->x11SetScreen(x11Info().screen());
00281 #else
00282         if ( d_data->cache->x11Screen() != x11Screen() )
00283             d_data->cache->x11SetScreen(x11Screen());
00284 #endif
00285 #endif
00286 
00287         if ( d_data->paintAttributes & PaintPacked )
00288         {
00289             QPainter bgPainter(d_data->cache);
00290             bgPainter.setPen(Qt::NoPen);
00291 
00292             bgPainter.setBrush(bgBrush);
00293             bgPainter.drawRect(d_data->cache->rect());
00294         }
00295         else
00296             d_data->cache->fill(this, d_data->cache->rect().topLeft());
00297 
00298         QPainter cachePainter(d_data->cache);
00299         cachePainter.translate(-contentsRect().x(),
00300             -contentsRect().y());
00301 
00302         ((QwtPlot *)parent())->drawCanvas(&cachePainter);
00303 
00304         cachePainter.end();
00305 
00306         painter->drawPixmap(contentsRect(), *d_data->cache);
00307     }
00308     else
00309     {
00310 #if QT_VERSION >= 0x040000
00311         if ( d_data->paintAttributes & PaintPacked )
00312 #endif
00313         {
00314             painter->save();
00315 
00316             painter->setPen(Qt::NoPen);
00317             painter->setBrush(bgBrush);
00318             painter->drawRect(contentsRect());
00319 
00320             painter->restore();
00321         }
00322 
00323         ((QwtPlot *)parent())->drawCanvas(painter);
00324     }
00325 }
00326 
00328 void QwtPlotCanvas::drawFocusIndicator(QPainter *painter)
00329 {
00330     const int margin = 1;
00331 
00332     QRect focusRect = contentsRect();
00333     focusRect.setRect(focusRect.x() + margin, focusRect.y() + margin,
00334         focusRect.width() - 2 * margin, focusRect.height() - 2 * margin);
00335 
00336     QwtPainter::drawFocusRect(painter, this, focusRect);
00337 }
00338 
00339 void QwtPlotCanvas::setSystemBackground(bool on)
00340 {
00341 #if QT_VERSION < 0x040000
00342     if ( backgroundMode() == Qt::NoBackground )
00343     {
00344         if ( on )
00345             setBackgroundMode(Qt::PaletteBackground);
00346     }
00347     else
00348     {
00349         if ( !on )
00350             setBackgroundMode(Qt::NoBackground);
00351     }
00352 #else
00353     if ( testAttribute(Qt::WA_NoSystemBackground) == on )
00354         setAttribute(Qt::WA_NoSystemBackground, !on);
00355 #endif
00356 }