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

Generated on Mon Jan 30 22:16:25 2006 for Qwt User's Guide by  doxygen 1.4.4