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