| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 | /* -*- 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 "qwt_plot_canvas.h"#include "qwt_painter.h"#include "qwt_math.h"#include "qwt_plot.h"#include <qpainter.h>#include <qstyle.h>#include <qstyleoption.h>#include <qpaintengine.h>#ifdef Q_WS_X11#include <qx11info_x11.h>#endif#include <qevent.h>class QwtPlotCanvas::PrivateData{public:    PrivateData():        focusIndicator( NoFocusIndicator ),        paintAttributes( 0 ),        cache( NULL )    {    }    ~PrivateData()    {        delete cache;    }    FocusIndicator focusIndicator;    int paintAttributes;    QPixmap *cache;};//! Sets a cross cursor, enables QwtPlotCanvas::PaintCachedQwtPlotCanvas::QwtPlotCanvas( QwtPlot *plot ):    QFrame( plot ){    d_data = new PrivateData;    setAutoFillBackground( true );#ifndef QT_NO_CURSOR    setCursor( Qt::CrossCursor );#endif    setPaintAttribute( PaintCached, true );    setPaintAttribute( PaintPacked, true );}//! DestructorQwtPlotCanvas::~QwtPlotCanvas(){    delete d_data;}//! Return parent plot widgetQwtPlot *QwtPlotCanvas::plot(){    return qobject_cast<QwtPlot *>( parentWidget() );}//! Return parent plot widgetconst QwtPlot *QwtPlotCanvas::plot() const{    return qobject_cast<const QwtPlot *>( parentWidget() );}/*!  \brief Changing the paint attributes  \param attribute Paint attribute  \param on On/Off  The default setting enables PaintCached and PaintPacked  \sa testPaintAttribute(), drawCanvas(), drawContents(), paintCache()*/void QwtPlotCanvas::setPaintAttribute( PaintAttribute attribute, bool on ){    if ( bool( d_data->paintAttributes & attribute ) == on )        return;    if ( on )        d_data->paintAttributes |= attribute;    else        d_data->paintAttributes &= ~attribute;    switch ( attribute )    {        case PaintCached:        {            if ( on )            {                if ( d_data->cache == NULL )                    d_data->cache = new QPixmap();                if ( isVisible() )                {                    const QRect cr = contentsRect();                    *d_data->cache = QPixmap::grabWidget( this,                        cr.x(), cr.y(), cr.width(), cr.height() );                }            }            else            {                delete d_data->cache;                d_data->cache = NULL;            }            break;        }        case PaintPacked:        {            /*              If not visible, changing of the background mode              is delayed until it becomes visible. This tries to avoid              looking through the canvas when the canvas is shown the first              time.             */            if ( on == false || isVisible() )                QwtPlotCanvas::setSystemBackground( !on );            break;        }    }}/*!  Test wether a paint attribute is enabled  \param attribute Paint attribute  \return true if the attribute is enabled  \sa setPaintAttribute()*/bool QwtPlotCanvas::testPaintAttribute( PaintAttribute attribute ) const{    return ( d_data->paintAttributes & attribute ) != 0;}//! Return the paint cache, might be nullQPixmap *QwtPlotCanvas::paintCache(){    return d_data->cache;}//! Return the paint cache, might be nullconst QPixmap *QwtPlotCanvas::paintCache() const{    return d_data->cache;}//! Invalidate the internal paint cachevoid QwtPlotCanvas::invalidatePaintCache(){    if ( d_data->cache )        *d_data->cache = QPixmap();}/*!  Set the focus indicator  \sa FocusIndicator, focusIndicator()*/void QwtPlotCanvas::setFocusIndicator( FocusIndicator focusIndicator ){    d_data->focusIndicator = focusIndicator;}/*!  \return Focus indicator  \sa FocusIndicator, setFocusIndicator()*/QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const{    return d_data->focusIndicator;}/*!  Hide event  \param event Hide event*/void QwtPlotCanvas::hideEvent( QHideEvent *event ){    QFrame::hideEvent( event );    if ( d_data->paintAttributes & PaintPacked )    {        // enable system background to avoid the "looking through        // the canvas" effect, for the next show        setSystemBackground( true );    }}/*!  Paint event  \param event Paint event*/void QwtPlotCanvas::paintEvent( QPaintEvent *event ){    QPainter painter( this );    if ( !contentsRect().contains( event->rect() ) )    {        painter.save();        painter.setClipRegion( event->region() & frameRect() );        drawFrame( &painter );        painter.restore();    }    painter.setClipRegion( event->region() & contentsRect() );    drawContents( &painter );    if ( d_data->paintAttributes & PaintPacked )        setSystemBackground( false );}/*!  Redraw the canvas, and focus rect  \param painter Painter*/void QwtPlotCanvas::drawContents( QPainter *painter ){    if ( d_data->paintAttributes & PaintCached && d_data->cache        && d_data->cache->size() == contentsRect().size() )    {        painter->drawPixmap( contentsRect().topLeft(), *d_data->cache );    }    else    {        QwtPlot *plot = ( ( QwtPlot * )parent() );        const bool doAutoReplot = plot->autoReplot();        plot->setAutoReplot( false );        drawCanvas( painter );        plot->setAutoReplot( doAutoReplot );    }    if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )        drawFocusIndicator( painter );}/*!  Draw the the canvas  Paints all plot items to the contentsRect(), using QwtPlot::drawCanvas  and updates the paint cache.  \param painter Painter  \sa QwtPlot::drawCanvas(), setPaintAttributes(), testPaintAttributes()*/void QwtPlotCanvas::drawCanvas( QPainter *painter ){    if ( !contentsRect().isValid() )        return;    QBrush bgBrush = palette().brush( backgroundRole() );    if ( d_data->paintAttributes & PaintCached && d_data->cache )    {        *d_data->cache = QPixmap( contentsRect().size() );#ifdef Q_WS_X11        if ( d_data->cache->x11Info().screen() != x11Info().screen() )            d_data->cache->x11SetScreen( x11Info().screen() );#endif        if ( d_data->paintAttributes & PaintPacked )        {            QPainter bgPainter( d_data->cache );            bgPainter.setPen( Qt::NoPen );            bgPainter.setBrush( bgBrush );            bgPainter.drawRect( d_data->cache->rect() );        }        else            d_data->cache->fill( this, d_data->cache->rect().topLeft() );        QPainter cachePainter( d_data->cache );        cachePainter.translate( -contentsRect().x(),            -contentsRect().y() );        ( ( QwtPlot * )parent() )->drawCanvas( &cachePainter );        cachePainter.end();        painter->drawPixmap( contentsRect(), *d_data->cache );    }    else    {        if ( d_data->paintAttributes & PaintPacked )        {            painter->save();            painter->setPen( Qt::NoPen );            painter->setBrush( bgBrush );            painter->drawRect( contentsRect() );            painter->restore();        }        ( ( QwtPlot * )parent() )->drawCanvas( painter );    }}/*!  Draw the focus indication  \param painter Painter*/void QwtPlotCanvas::drawFocusIndicator( QPainter *painter ){    const int margin = 1;    QRect focusRect = contentsRect();    focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,        focusRect.width() - 2 * margin, focusRect.height() - 2 * margin );    QwtPainter::drawFocusRect( painter, this, focusRect );}void QwtPlotCanvas::setSystemBackground( bool on ){    if ( testAttribute( Qt::WA_NoSystemBackground ) == on )        setAttribute( Qt::WA_NoSystemBackground, !on );}/*!   Invalidate the paint cache and repaint the canvas   \sa invalidatePaintCache()*/void QwtPlotCanvas::replot(){    invalidatePaintCache();    /*      In case of cached or packed painting the canvas      is repainted completely and doesn't need to be erased.     */    const bool erase =        !testPaintAttribute( QwtPlotCanvas::PaintPacked )        && !testPaintAttribute( QwtPlotCanvas::PaintCached );    const bool noBackgroundMode = testAttribute( Qt::WA_NoBackground );    if ( !erase && !noBackgroundMode )        setAttribute( Qt::WA_NoBackground, true );    repaint( contentsRect() );    if ( !erase && !noBackgroundMode )        setAttribute( Qt::WA_NoBackground, false );}
 |