Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

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(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 < 0x040000
00056     setWFlags(Qt::WNoAutoErase);
00057     setCursor(Qt::crossCursor);
00058 #else
00059     setAttribute(Qt::WA_PaintOnScreen, true);
00060     setCursor(Qt::CrossCursor);
00061 
00062 #if !defined(Q_WS_MAC) 
00063 #if !defined(Q_WS_WIN) || QT_VERSION > 0x040001 // 4.0.0/4.0.1 are buggy
00064 
00065 #ifdef __GNUC__
00066 #warning Qt::WA_PaintOutsidePaintEvent trouble
00067 #endif
00068 
00069     /*
00070      QPaintEngine::hasFeature(QPaintEngine::PaintOutsidePaintEvent)
00071      is made for whatever, but not for what one could expect. Maybe 
00072      this will be something more usable in later Qt4 releases.
00073      For now we have to know on which platforms it is not supported
00074      */
00075     setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
00076 #endif
00077 #endif
00078 
00079 #endif // >= 0x040000
00080 
00081     setPaintAttribute(PaintCached, true);
00082     setPaintAttribute(PaintPacked, false);
00083 }
00084 
00086 QwtPlotCanvas::~QwtPlotCanvas()
00087 {
00088     delete d_data;
00089 }
00090 
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, delay changing the background mode
00147               until it becomes visible. This tries to avoid looking
00148               through the canvas when the canvas is shown the first 
00149               time.
00150              */
00151 
00152             if ( !on || isVisible() )
00153                 QwtPlotCanvas::setSystemBackground(on);
00154 
00155             break;
00156         }
00157     }
00158 }
00159 
00160 bool QwtPlotCanvas::testPaintAttribute(PaintAttribute attribute) const
00161 {
00162     return (d_data->paintAttributes & attribute) != 0;
00163 }
00164 
00166 QPixmap *QwtPlotCanvas::cache()
00167 {
00168     return d_data->cache;
00169 }
00170 
00172 const QPixmap *QwtPlotCanvas::cache() const
00173 {
00174     return d_data->cache;
00175 }
00176 
00178 void QwtPlotCanvas::invalidateCache()
00179 {
00180     if ( d_data->cache )
00181         *d_data->cache = QPixmap();
00182 }
00183 
00189 void QwtPlotCanvas::setFocusIndicator(FocusIndicator focusIndicator)
00190 {
00191     d_data->focusIndicator = focusIndicator;
00192 }
00193 
00199 QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const
00200 {
00201     return d_data->focusIndicator;
00202 }
00203 
00204 void QwtPlotCanvas::hideEvent(QHideEvent *e)
00205 {
00206     QFrame::hideEvent(e);
00207 
00208     if ( d_data->paintAttributes & PaintPacked )
00209         setSystemBackground(true);
00210 }
00211 
00212 void QwtPlotCanvas::paintEvent(QPaintEvent *event)
00213 {
00214 #if QT_VERSION >= 0x040000
00215     QPainter painter(this);
00216     
00217     if ( !contentsRect().contains( event->rect() ) ) 
00218     {
00219         painter.save();
00220         painter.setClipRegion( event->region() & frameRect() );
00221         drawFrame( &painter );
00222         painter.restore(); 
00223     }
00224 
00225 #if defined(Q_WS_WIN)
00226 
00227 #ifdef __GNUC__
00228 #warning Clipping bugs on Win32
00229 #endif
00230 
00231 #else
00232     painter.setClipRegion(event->region() & contentsRect());
00233 #endif
00234 
00235     drawContents( &painter );
00236 #else // QT_VERSION < 0x040000
00237     QFrame::paintEvent(event);
00238 #endif
00239 
00240     if ( d_data->paintAttributes & PaintPacked )
00241         setSystemBackground(false);
00242 }
00243 
00245 void QwtPlotCanvas::drawContents(QPainter *painter)
00246 {
00247     if ( d_data->paintAttributes & PaintCached && d_data->cache 
00248         && d_data->cache->size() == contentsRect().size() )
00249     {
00250         painter->drawPixmap(contentsRect().topLeft(), *d_data->cache);
00251     }
00252     else
00253         drawCanvas(painter);
00254 
00255     if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
00256         drawFocusIndicator(painter);
00257 }
00258 
00268 void QwtPlotCanvas::drawCanvas(QPainter *painter)
00269 {
00270     if ( !contentsRect().isValid() )
00271         return;
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             QBrush bgBrush;
00293 #if QT_VERSION >= 0x040000
00294                 bgBrush = palette().brush(backgroundRole());
00295 #else
00296             QColorGroup::ColorRole role = 
00297                 QPalette::backgroundRoleFromMode( backgroundMode() );
00298             bgBrush = colorGroup().brush( role );
00299 #endif
00300             bgPainter.setBrush(bgBrush);
00301             bgPainter.drawRect(d_data->cache->rect());
00302         }
00303         else
00304             d_data->cache->fill(this, d_data->cache->rect().topLeft());
00305 
00306         QPainter cachePainter(d_data->cache);
00307         cachePainter.translate(-contentsRect().x(),
00308             -contentsRect().y());
00309 
00310         ((QwtPlot *)parent())->drawCanvas(&cachePainter);
00311 
00312         cachePainter.end();
00313 
00314         painter->drawPixmap(contentsRect(), *d_data->cache);
00315     }
00316     else
00317     {
00318         if ( d_data->paintAttributes & PaintPacked )
00319         {
00320             painter->save();
00321             painter->setPen(Qt::NoPen);
00322 
00323             const QBrush brush =
00324 #if QT_VERSION < 0x040000
00325                 backgroundBrush();
00326 #else
00327                 palette().brush(backgroundRole());
00328 #endif
00329             painter->setBrush(brush);
00330 
00331             painter->drawRect(contentsRect());
00332             painter->restore();
00333         }
00334         ((QwtPlot *)parent())->drawCanvas(painter);
00335     }
00336 }
00337 
00339 void QwtPlotCanvas::drawFocusIndicator(QPainter *painter)
00340 {
00341     const int margin = 1;
00342 
00343     QRect focusRect = contentsRect();
00344     focusRect.setRect(focusRect.x() + margin, focusRect.y() + margin,
00345         focusRect.width() - 2 * margin, focusRect.height() - 2 * margin);
00346 
00347     QwtPainter::drawFocusRect(painter, this, focusRect);
00348 }
00349 
00350 void QwtPlotCanvas::setSystemBackground(bool on)
00351 {
00352 #if QT_VERSION < 0x040000
00353     if ( backgroundMode() == Qt::NoBackground )
00354     {
00355         if ( on )
00356             setBackgroundMode(Qt::PaletteBackground);
00357     }
00358     else
00359     {
00360         if ( !on )
00361             setBackgroundMode(Qt::NoBackground);
00362     }
00363 #else
00364     if ( testAttribute(Qt::WA_NoSystemBackground) == on )
00365         setAttribute(Qt::WA_NoSystemBackground, !on);
00366 #endif
00367 }
00368 

Generated on Wed Aug 31 23:02:29 2005 for Qwt User's Guide by  doxygen 1.4.1