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 Tue Nov 16 21:12:20 2004 for Qwt User's Guide by doxygen 1.3.8