⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwt_plot_canvas.cpp

📁 软件无线电的平台
💻 CPP
字号:
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** * Qwt Widget Library * Copyright (C) 1997   Josef Wilgen * Copyright (C) 2002   Uwe Rathmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the Qwt License, Version 1.0 *****************************************************************************/#include <qpainter.h>#include <qstyle.h>#include "qwt_painter.h"#include "qwt_math.h"#include "qwt_plot.h"#include "qwt_paint_buffer.h"#include "qwt_plot_canvas.h"static const int dim = 5000;//! Sets a cross cursor, and an invisible red outlineQwtPlotCanvas::QwtPlotCanvas(QwtPlot *plot):    QFrame(plot, "canvas", WRepaintNoErase|WResizeNoErase),    d_focusIndicator(CanvasFocusIndicator),    d_cacheMode(TRUE),    d_cache(NULL)#ifndef QWT_NO_COMPAT    ,d_outlineEnabled(FALSE),    d_outlineActive(FALSE),    d_mousePressed(FALSE),    d_outline(Qwt::Rect),    d_pen(red)#endif{    setCursor(crossCursor);}/*!  \brief En/Disable caching  When cache mode is enabled the canvas contents are copied to  a pixmap that is used for trivial repaints. Such repaints happen  when a plot gets unhidden, deiconified or changes the focus.  The win of caching depends on the costs of QwtPlot::drawCanvas. In  case of plots with huge data it might be significant. The price of  caching is wasting memory for the cache, what is a pixmap in size  of contentsRect(). In case of QwtPaintBuffer::isEnabled() updating   the cache produces no performance overhead as it reuses the   temporary paintbuffer of the double buffering.    Otherwise canvas updates have to painted twice to widget and cache.  \param on Enable caching, when TRUE  \sa cacheMode(), drawCanvas(), drawContents(), cache()*/void QwtPlotCanvas::setCacheMode(bool on){    if ( d_cacheMode != on )    {        d_cacheMode = on;        if (!d_cacheMode )        {            delete d_cache;            d_cache = NULL;        }    }}/*!  \return Cache mode  \sa setCacheMode*/bool QwtPlotCanvas::cacheMode() const{    return d_cacheMode;}//! Return the paint cache, might be nullQPixmap *QwtPlotCanvas::cache(){    return d_cache;}//! Return the paint cache, might be nullconst QPixmap *QwtPlotCanvas::cache() const{    return d_cache;}/*!  Set the focus indicator  \sa FocusIndicator, focusIndicator*/void QwtPlotCanvas::setFocusIndicator(FocusIndicator focusIndicator){    d_focusIndicator = focusIndicator;}/*!  \return Focus indicator    \sa FocusIndicator, setFocusIndicator*/QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const{    return d_focusIndicator;}//! Requires layout updates of the parent plotvoid QwtPlotCanvas::frameChanged(){    QFrame::frameChanged();    // frame changes change the size of the contents rect, what    // is related to the axes. So we have to update the layout.    ((QwtPlot *)parent())->updateLayout();}//! Redraw the canvas, and focus rectvoid QwtPlotCanvas::drawContents(QPainter *painter){    if ( cacheMode() && d_cache         && d_cache->size() == contentsRect().size() )    {        painter->drawPixmap(contentsRect().topLeft(), *d_cache);    }    else        drawCanvas(painter);#ifndef QWT_NO_COMPAT    if ( d_outlineActive )        drawOutline(*painter); // redraw outline#endif    if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )    {        const int margin = 1;        QRect focusRect = contentsRect();        focusRect.setRect(focusRect.x() + margin, focusRect.y() + margin,            focusRect.width() - 2 * margin, focusRect.height() - 2 * margin);        drawFocusIndicator(painter, focusRect);    }}/*!  Draw the the canvas  Paints all plot items to the contentsRect(), using QwtPlot::drawCanvas  and updates the cache.  \sa QwtPlot::drawCanvas, setCacheMode(), cacheMode()*/void QwtPlotCanvas::drawCanvas(QPainter *painter){    if ( !contentsRect().isValid() )        return;    QRect clipRect = contentsRect();    if ( !cacheMode() || !QwtPaintBuffer::isEnabled() )    {        // If we don磘 need the paint buffer as cache we can        // use the clip for painting to the buffer too.         if ( painter && !painter->clipRegion().isNull() )            clipRect = painter->clipRegion().boundingRect();    }    QwtPaintBuffer paintBuffer(this, clipRect, painter);    ((QwtPlot *)parent())->drawCanvas(paintBuffer.painter());    if ( cacheMode() )    {        if ( d_cache == NULL )            d_cache = new QPixmap(contentsRect().size());        else            d_cache->resize(contentsRect().size());        if ( QwtPaintBuffer::isEnabled() )            *d_cache = paintBuffer.buffer();        else        {            d_cache->fill(this, 0, 0);            QPainter cachePainter(d_cache);            cachePainter.translate(-contentsRect().x(),                -contentsRect().y());            ((QwtPlot *)parent())->drawCanvas(&cachePainter);        }    }}void QwtPlotCanvas::drawFocusIndicator(QPainter *painter, const QRect &rect){#if QT_VERSION < 300        style().drawFocusRect(painter, rect, colorGroup());#else        style().drawPrimitive(QStyle::PE_FocusRect, painter,            rect, colorGroup());#endif}#ifndef QWT_NO_COMPAT//! mousePressEventvoid QwtPlotCanvas::mousePressEvent(QMouseEvent *e){    if (d_outlineActive)    {        QPainter p(this);        drawOutline(p); // Delete active outlines    }    d_outlineActive = FALSE;    //    // store this point as entry point    //    d_lastPoint = e->pos();    d_entryPoint = e->pos();    if (d_outlineEnabled)    {        QPainter p(this);        drawOutline(p); // draw new outline        d_outlineActive = TRUE;    }    d_mousePressed = TRUE;    QMouseEvent m(QEvent::MouseButtonPress,         e->pos() - rect().topLeft(), e->button(), e->state());    emit mousePressed(m);}//! mouseReleaseEventvoid QwtPlotCanvas::mouseReleaseEvent(QMouseEvent *e){    if (d_outlineActive)    {        QPainter p(this);        drawOutline(p);    }    d_outlineActive = FALSE;    d_mousePressed = FALSE;    QMouseEvent m(QEvent::MouseButtonRelease,         e->pos() - rect().topLeft(), e->button(), e->state());    emit mouseReleased(m);}//! mouseMoveEventvoid QwtPlotCanvas::mouseMoveEvent(QMouseEvent *e){    if (d_outlineActive)    {        QPainter p(this);        drawOutline(p);        d_lastPoint = e->pos();        drawOutline(p);    }    QMouseEvent m(QEvent::MouseMove,         e->pos() - rect().topLeft(), e->button(), e->state());    emit mouseMoved(m);}/*!  \brief Enables or disables outline drawing.  When the outline feature is enabled, a shape will be drawn  in the plotting region  when the user presses  or drags the mouse. It can be used to implement crosshairs,  mark a selected region, etc.  \param tf \c TRUE (enabled) or \c FALSE (disabled)  \warning An outline style has to be specified.  \sa QwtPlotCanvas::setOutlineStyle()*/void QwtPlotCanvas::enableOutline(bool tf){    //    //  If the mouse is pressed, erase existing outline    //  or draw new outline if 'tf' changes the 'enabled' state.    //    if ((tf != d_outlineEnabled) && d_mousePressed)    {        QPainter p(this);        drawOutline(p);        d_outlineActive = tf;    }    d_outlineEnabled = tf;}/*!  \return \c TRUE if the outline feature is enabled  \sa QwtPlotCanvas::enableOutline*/bool QwtPlotCanvas::outlineEnabled() const {     return d_outlineEnabled; }/*!  \brief Specify the style of the outline  The outline style determines which kind of shape is drawn  in the plotting region when the user presses a mouse button  or drags the mouse. Valid Styles are:  \param os Outline Style. Valid values are: \c Qwt::HLine, \c Qwt::VLine,            \c Qwt::Cross, \c Qwt::Rect, \c Qwt::Ellipse  <dl>  <dt>Qwt::Cros  <dd>Cross hairs are drawn across the plotting area      when the user presses a mouse button. The lines      intersect at the point where the mouse was pressed      and move with the mouse pointer.  <dt>Qwt::HLine, Qwt::VLine  <dd>A horizontal or vertical line appears when      the user presses a mouse button. This is useful      for moving line markers.  <dt>Qwt::Rect  <dd>A rectangle is displayed when the user drags      the mouse. One corner is fixed at the point where      the mouse was pressed, and the opposite corner moves      with the mouse pointer. This can be used for selecting      regions.  <dt>Qwt::Ellipse  <dd>Similar to Qwt::Rect, but with an ellipse inside      a bounding rectangle.  </dl>  \sa QwtPlotCanvas::enableOutline(), QwtPlotCanvas::outlineStyle()*/void QwtPlotCanvas::setOutlineStyle(Qwt::Shape os){    if (d_outlineActive)    {        QPainter p(this); // erase old outline        drawOutline(p);    }    d_outline = os;    if (d_outlineActive)    {        QPainter p(this);        drawOutline(p); // draw new outline    }}/*!  \return the outline style  \sa QwtPlotCanvas::setOutlineStyle()*/Qwt::Shape QwtPlotCanvas::outlineStyle() const {     return d_outline; }/*!  \brief Specify a pen for the outline  \param pen new pen  \sa QwtPlotCanvas::outlinePen*/void QwtPlotCanvas::setOutlinePen(const QPen &pen){    d_pen = pen;}/*!  \return the pen used to draw outlines  \sa QwtPlotCanvas::setOutlinePen*/const QPen& QwtPlotCanvas::outlinePen() const {     return d_pen; }/*!    draw an outline*/void QwtPlotCanvas::drawOutline(QPainter &p){    const QRect &r = contentsRect();    QColor bg = ((QwtPlot *)parent())->canvasBackground();    QPen pn = d_pen;    pn.setColor(QColor(0, (bg.pixel() ^ d_pen.color().pixel())));    p.setPen(pn);    p.setRasterOp(XorROP);    p.setClipRect(r);    p.setClipping(TRUE);    switch(d_outline)    {        case Qwt::VLine:            QwtPainter::drawLine(&p, d_lastPoint.x(),                 r.top(), d_lastPoint.x(), r.bottom());            break;                case Qwt::HLine:            QwtPainter::drawLine(&p, r.left(),                 d_lastPoint.y(), r.right(), d_lastPoint.y());            break;                case Qwt::Cross:            QwtPainter::drawLine(&p, r.left(),                 d_lastPoint.y(), r.right(), d_lastPoint.y());            QwtPainter::drawLine(&p, d_lastPoint.x(),                 r.top(), d_lastPoint.x(), r.bottom());            break;        case Qwt::Rect:            QwtPainter::drawRect(&p, d_entryPoint.x(), d_entryPoint.y(),               d_lastPoint.x() - d_entryPoint.x() + 1,               d_lastPoint.y() - d_entryPoint.y() + 1);            break;                case Qwt::Ellipse:            p.drawEllipse(d_entryPoint.x(), d_entryPoint.y(),               d_lastPoint.x() - d_entryPoint.x() + 1,               d_lastPoint.y() - d_entryPoint.y() + 1);            break;        default:            break;    }}#endif // !QWT_NO_COMPAT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -