Main Page | Class Hierarchy | Alphabetical List | Class List | 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 #include <qevent.h>
00015 #include "qwt_painter.h"
00016 #include "qwt_math.h"
00017 #include "qwt_plot.h"
00018 #include "qwt_paint_buffer.h"
00019 #include "qwt_plot_canvas.h"
00020 
00021 static const int dim = 5000;
00022 
00024 
00025 QwtPlotCanvas::QwtPlotCanvas(QwtPlot *plot):
00026     QFrame(plot, "canvas", Qt::WRepaintNoErase|Qt::WResizeNoErase),
00027     d_focusIndicator(CanvasFocusIndicator),
00028     d_cacheMode(TRUE),
00029     d_cache(NULL)
00030 #ifndef QWT_NO_COMPAT
00031     ,d_outlineEnabled(FALSE),
00032     d_outlineActive(FALSE),
00033     d_mousePressed(FALSE),
00034     d_outline(Qwt::Rect),
00035     d_pen(Qt::red)
00036 #endif
00037 {
00038     setCursor(Qt::crossCursor);
00039 }
00040 
00042 QwtPlotCanvas::~QwtPlotCanvas()
00043 {
00044     delete d_cache;
00045 }
00046 
00066 void QwtPlotCanvas::setCacheMode(bool on)
00067 {
00068     if ( d_cacheMode != on )
00069     {
00070         d_cacheMode = on;
00071         if (!d_cacheMode )
00072         {
00073             delete d_cache;
00074             d_cache = NULL;
00075         }
00076     }
00077 }
00078 
00083 bool QwtPlotCanvas::cacheMode() const
00084 {
00085     return d_cacheMode;
00086 }
00087 
00089 QPixmap *QwtPlotCanvas::cache()
00090 {
00091     return d_cache;
00092 }
00093 
00095 const QPixmap *QwtPlotCanvas::cache() const
00096 {
00097     return d_cache;
00098 }
00099 
00101 void QwtPlotCanvas::invalidateCache()
00102 {
00103     if ( d_cache )
00104         d_cache->resize(0, 0);
00105 }
00106 
00112 void QwtPlotCanvas::setFocusIndicator(FocusIndicator focusIndicator)
00113 {
00114     d_focusIndicator = focusIndicator;
00115 }
00116 
00122 QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const
00123 {
00124     return d_focusIndicator;
00125 }
00126 
00128 void QwtPlotCanvas::frameChanged()
00129 {
00130     QFrame::frameChanged();
00131 
00132     // frame changes change the size of the contents rect, what
00133     // is related to the axes. So we have to update the layout.
00134 
00135     ((QwtPlot *)parent())->updateLayout();
00136 }
00137 
00139 void QwtPlotCanvas::drawContents(QPainter *painter)
00140 {
00141     if ( cacheMode() && d_cache 
00142         && d_cache->size() == contentsRect().size() )
00143     {
00144         painter->drawPixmap(contentsRect().topLeft(), *d_cache);
00145     }
00146     else
00147         drawCanvas(painter);
00148 
00149 #ifndef QWT_NO_COMPAT
00150     if ( d_outlineActive )
00151         drawOutline(*painter); // redraw outline
00152 #endif
00153 
00154     if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
00155     {
00156         const int margin = 1;
00157         QRect focusRect = contentsRect();
00158         focusRect.setRect(focusRect.x() + margin, focusRect.y() + margin,
00159             focusRect.width() - 2 * margin, focusRect.height() - 2 * margin);
00160 
00161         drawFocusIndicator(painter, focusRect);
00162     }
00163 }
00164 
00174 void QwtPlotCanvas::drawCanvas(QPainter *painter)
00175 {
00176     if ( !contentsRect().isValid() )
00177         return;
00178 
00179     QRect clipRect = contentsRect();
00180     if ( !cacheMode() || !QwtPaintBuffer::isEnabled() )
00181     {
00182         // If we donīt need the paint buffer as cache we can
00183         // use the clip for painting to the buffer too. 
00184 
00185         if ( painter && !painter->clipRegion().isNull() )
00186             clipRect = painter->clipRegion().boundingRect();
00187     }
00188 
00189     QwtPaintBuffer paintBuffer(this, clipRect, painter);
00190     ((QwtPlot *)parent())->drawCanvas(paintBuffer.painter());
00191 
00192     if ( cacheMode() )
00193     {
00194         if ( d_cache == NULL )
00195         {
00196             d_cache = new QPixmap(contentsRect().size());
00197 #if QT_VERSION >= 300
00198 #ifdef Q_WS_X11
00199             if ( d_cache->x11Screen() != x11Screen() )
00200                 d_cache->x11SetScreen(x11Screen());
00201 #endif
00202 #endif
00203         }
00204         else
00205             d_cache->resize(contentsRect().size());
00206 
00207         if ( QwtPaintBuffer::isEnabled() )
00208             *d_cache = paintBuffer.buffer();
00209         else
00210         {
00211             d_cache->fill(this, 0, 0);
00212             QPainter cachePainter(d_cache);
00213             cachePainter.translate(-contentsRect().x(),
00214                 -contentsRect().y());
00215             ((QwtPlot *)parent())->drawCanvas(&cachePainter);
00216         }
00217     }
00218 }
00219 
00221 void QwtPlotCanvas::drawFocusIndicator(QPainter *painter, const QRect &rect)
00222 {
00223 #if QT_VERSION < 300
00224         style().drawFocusRect(painter, rect, colorGroup());
00225 #else
00226         style().drawPrimitive(QStyle::PE_FocusRect, painter,
00227             rect, colorGroup());
00228 #endif
00229 }
00230 
00231 #ifndef QWT_NO_COMPAT
00232 
00234 void QwtPlotCanvas::mousePressEvent(QMouseEvent *e)
00235 {
00236     if (d_outlineActive)
00237     {
00238         QPainter p(this);
00239         drawOutline(p); // Delete active outlines
00240     }
00241 
00242     d_outlineActive = FALSE;
00243 
00244     //
00245     // store this point as entry point
00246     //
00247     d_lastPoint = e->pos();
00248     d_entryPoint = e->pos();
00249 
00250     if (d_outlineEnabled)
00251     {
00252         QPainter p(this);
00253         drawOutline(p); // draw new outline
00254         d_outlineActive = TRUE;
00255     }
00256 
00257     d_mousePressed = TRUE;
00258 
00259     QMouseEvent m(QEvent::MouseButtonPress, 
00260         e->pos() - rect().topLeft(), e->button(), e->state());
00261 
00262     emit mousePressed(m);
00263 }
00264 
00266 void QwtPlotCanvas::mouseReleaseEvent(QMouseEvent *e)
00267 {
00268     if (d_outlineActive)
00269     {
00270         QPainter p(this);
00271         drawOutline(p);
00272     }
00273 
00274     d_outlineActive = FALSE;
00275     d_mousePressed = FALSE;
00276 
00277     QMouseEvent m(QEvent::MouseButtonRelease, 
00278         e->pos() - rect().topLeft(), e->button(), e->state());
00279 
00280     emit mouseReleased(m);
00281 }
00282 
00284 void QwtPlotCanvas::mouseMoveEvent(QMouseEvent *e)
00285 {
00286     if (d_outlineActive)
00287     {
00288         QPainter p(this);
00289         drawOutline(p);
00290         d_lastPoint = e->pos();
00291         drawOutline(p);
00292     }
00293 
00294     QMouseEvent m(QEvent::MouseMove, 
00295         e->pos() - rect().topLeft(), e->button(), e->state());
00296 
00297     emit mouseMoved(m);
00298 }
00299 
00315 void QwtPlotCanvas::enableOutline(bool tf)
00316 {
00317 
00318     //
00319     //  If the mouse is pressed, erase existing outline
00320     //  or draw new outline if 'tf' changes the 'enabled' state.
00321     //
00322     if ((tf != d_outlineEnabled) && d_mousePressed)
00323     {
00324         QPainter p(this);
00325         drawOutline(p);
00326         d_outlineActive = tf;
00327     }
00328     d_outlineEnabled = tf;
00329 }
00330 
00340 bool QwtPlotCanvas::outlineEnabled() const 
00341 { 
00342     return d_outlineEnabled; 
00343 }
00344 
00379 void QwtPlotCanvas::setOutlineStyle(Qwt::Shape os)
00380 {
00381     if (d_outlineActive)
00382     {
00383         QPainter p(this); // erase old outline
00384         drawOutline(p);
00385     }
00386 
00387     d_outline = os;
00388 
00389     if (d_outlineActive)
00390     {
00391         QPainter p(this);
00392         drawOutline(p); // draw new outline
00393     }
00394 }
00395 
00404 Qwt::Shape QwtPlotCanvas::outlineStyle() const 
00405 { 
00406     return d_outline; 
00407 }
00408 
00419 void QwtPlotCanvas::setOutlinePen(const QPen &pen)
00420 {
00421     d_pen = pen;
00422 }
00423 
00433 const QPen& QwtPlotCanvas::outlinePen() const 
00434 { 
00435     return d_pen; 
00436 }
00437 
00444 void QwtPlotCanvas::drawOutline(QPainter &p)
00445 {
00446     const QRect &r = contentsRect();
00447 
00448     QColor bg = ((QwtPlot *)parent())->canvasBackground();
00449 
00450     QPen pn = d_pen;
00451     pn.setColor(QColor(bg.rgb() ^ d_pen.color().rgb()));
00452 
00453     p.setPen(pn);
00454     p.setRasterOp(XorROP);
00455     p.setClipRect(r);
00456     p.setClipping(TRUE);
00457 
00458     switch(d_outline)
00459     {
00460         case Qwt::VLine:
00461             QwtPainter::drawLine(&p, d_lastPoint.x(), 
00462                 r.top(), d_lastPoint.x(), r.bottom());
00463             break;
00464         
00465         case Qwt::HLine:
00466             QwtPainter::drawLine(&p, r.left(), 
00467                 d_lastPoint.y(), r.right(), d_lastPoint.y());
00468             break;
00469         
00470         case Qwt::Cross:
00471             QwtPainter::drawLine(&p, r.left(), 
00472                 d_lastPoint.y(), r.right(), d_lastPoint.y());
00473             QwtPainter::drawLine(&p, d_lastPoint.x(), 
00474                 r.top(), d_lastPoint.x(), r.bottom());
00475             break;
00476 
00477         case Qwt::Rect:
00478             QwtPainter::drawRect(&p, d_entryPoint.x(), d_entryPoint.y(),
00479                d_lastPoint.x() - d_entryPoint.x() + 1,
00480                d_lastPoint.y() - d_entryPoint.y() + 1);
00481             break;
00482         
00483         case Qwt::Ellipse:
00484             p.drawEllipse(d_entryPoint.x(), d_entryPoint.y(),
00485                d_lastPoint.x() - d_entryPoint.x() + 1,
00486                d_lastPoint.y() - d_entryPoint.y() + 1);
00487             break;
00488 
00489         default:
00490             break;
00491     }
00492 }
00493 
00494 #endif // !QWT_NO_COMPAT
00495 
00496 // Local Variables:
00497 // mode: C++
00498 // c-file-style: "stroustrup"
00499 // indent-tabs-mode: nil
00500 // End:
00501 

Generated on Sun Nov 21 11:12:43 2004 for Qwt User's Guide by doxygen 1.3.5