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(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
00071
00072
00073
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
00147
00148
00149
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