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 
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               If not visible, changing of the background mode
00127               is delayed until it becomes visible. This tries to avoid 
00128               looking through the canvas when the canvas is shown the first 
00129               time.
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         // enable system background to avoid the "looking through
00197         // the canvas" effect, for the next show
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 }

Generated on Mon Jun 11 07:41:38 2007 for Qwt User's Guide by  doxygen 1.4.6