qwt_plot_panner.cpp
/******************************************************************************
* 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_panner.h"
#include "qwt_scale_div.h"
#include "qwt_plot.h"
#include "qwt_scale_map.h"
#include "qwt_painter.h"
#include <qbitmap.h>
#include <qstyle.h>
#include <qstyleoption.h>
#include <qpainter.h>
#include <qpainterpath.h>
static QBitmap qwtBorderMask( const QWidget* canvas, const QSize& size )
{
#if QT_VERSION >= 0x050000
const qreal pixelRatio = QwtPainter::devicePixelRatio( canvas );
#endif
const QRect r( 0, 0, size.width(), size.height() );
QPainterPath borderPath;
( void )QMetaObject::invokeMethod(
const_cast< QWidget* >( canvas ), "borderPath", Qt::DirectConnection,
Q_RETURN_ARG( QPainterPath, borderPath ), Q_ARG( QRect, r ) );
if ( borderPath.isEmpty() )
{
if ( canvas->contentsRect() == canvas->rect() )
return QBitmap();
#if QT_VERSION >= 0x050000
QBitmap mask( size* pixelRatio );
mask.setDevicePixelRatio( pixelRatio );
#else
QBitmap mask( size );
#endif
mask.fill( Qt::color0 );
QPainter painter( &mask );
painter.fillRect( canvas->contentsRect(), Qt::color1 );
return mask;
}
#if QT_VERSION >= 0x050000
QImage image( size* pixelRatio, QImage::Format_ARGB32_Premultiplied );
image.setDevicePixelRatio( pixelRatio );
#else
QImage image( size, QImage::Format_ARGB32_Premultiplied );
#endif
image.fill( Qt::color0 );
QPainter painter( &image );
painter.setClipPath( borderPath );
painter.fillRect( r, Qt::color1 );
// now erase the frame
painter.setCompositionMode( QPainter::CompositionMode_DestinationOut );
if ( canvas->testAttribute(Qt::WA_StyledBackground ) )
{
QStyleOptionFrame opt;
opt.initFrom(canvas);
opt.rect = r;
canvas->style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, canvas );
}
else
{
const QVariant borderRadius = canvas->property( "borderRadius" );
const QVariant frameWidth = canvas->property( "frameWidth" );
if ( borderRadius.canConvert< double >() && frameWidth.canConvert< int >() )
{
const double br = borderRadius.value< double >();
const int fw = frameWidth.value< int >();
if ( br > 0.0 && fw > 0 )
{
painter.setPen( QPen( Qt::color1, fw ) );
painter.setBrush( Qt::NoBrush );
painter.setRenderHint( QPainter::Antialiasing, true );
painter.drawPath( borderPath );
}
}
}
painter.end();
const QImage mask = image.createMaskFromColor(
QColor( Qt::color1 ).rgb(), Qt::MaskOutColor );
return QBitmap::fromImage( mask );
}
class QwtPlotPanner::PrivateData
{
public:
PrivateData()
{
for ( int axis = 0; axis < QwtAxis::AxisPositions; axis++ )
isAxisEnabled[axis] = true;
}
bool isAxisEnabled[QwtAxis::AxisPositions];
};
QwtPlotPanner::QwtPlotPanner( QWidget* canvas )
: QwtPanner( canvas )
{
m_data = new PrivateData();
connect( this, SIGNAL(panned(int,int)),
SLOT(moveCanvas(int,int)) );
}
QwtPlotPanner::~QwtPlotPanner()
{
delete m_data;
}
void QwtPlotPanner::setAxisEnabled( QwtAxisId axisId, bool on )
{
if ( QwtAxis::isValid( axisId ) )
m_data->isAxisEnabled[axisId] = on;
}
bool QwtPlotPanner::isAxisEnabled( QwtAxisId axisId ) const
{
if ( QwtAxis::isValid( axisId ) )
return m_data->isAxisEnabled[axisId];
return true;
}
QWidget* QwtPlotPanner::canvas()
{
return parentWidget();
}
const QWidget* QwtPlotPanner::canvas() const
{
return parentWidget();
}
QwtPlot* QwtPlotPanner::plot()
{
QWidget* w = canvas();
if ( w )
w = w->parentWidget();
return qobject_cast< QwtPlot* >( w );
}
const QwtPlot* QwtPlotPanner::plot() const
{
const QWidget* w = canvas();
if ( w )
w = w->parentWidget();
return qobject_cast< const QwtPlot* >( w );
}
void QwtPlotPanner::moveCanvas( int dx, int dy )
{
if ( dx == 0 && dy == 0 )
return;
QwtPlot* plot = this->plot();
if ( plot == NULL )
return;
const bool doAutoReplot = plot->autoReplot();
plot->setAutoReplot( false );
for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
{
{
const QwtAxisId axisId( axisPos );
if ( !m_data->isAxisEnabled[axisId] )
continue;
const QwtScaleMap map = plot->canvasMap( axisId );
const double p1 = map.transform( plot->axisScaleDiv( axisId ).lowerBound() );
const double p2 = map.transform( plot->axisScaleDiv( axisId ).upperBound() );
double d1, d2;
if ( QwtAxis::isXAxis( axisPos ) )
{
d1 = map.invTransform( p1 - dx );
d2 = map.invTransform( p2 - dx );
}
else
{
d1 = map.invTransform( p1 - dy );
d2 = map.invTransform( p2 - dy );
}
plot->setAxisScale( axisId, d1, d2 );
}
}
plot->setAutoReplot( doAutoReplot );
plot->replot();
}
QBitmap QwtPlotPanner::contentsMask() const
{
if ( canvas() )
return qwtBorderMask( canvas(), size() );
return QwtPanner::contentsMask();
}
QPixmap QwtPlotPanner::grab() const
{
const QWidget* cv = canvas();
if ( cv && cv->inherits( "QGLWidget" ) )
{
// we can't grab from a QGLWidget
QPixmap pm( cv->size() );
QwtPainter::fillPixmap( cv, pm );
QPainter painter( &pm );
const_cast< QwtPlot* >( plot() )->drawCanvas( &painter );
return pm;
}
return QwtPanner::grab();
}
#if QWT_MOC_INCLUDE
#include "moc_qwt_plot_panner.cpp"
#endif
QwtPainter::fillPixmap
static void fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())
Definition: qwt_painter.cpp:1311
QwtPainter::devicePixelRatio
static qreal devicePixelRatio(const QPaintDevice *)
Definition: qwt_painter.cpp:1491
QwtPanner
QwtPanner provides panning of a widget.
Definition: qwt_panner.h:36
QwtPanner::contentsMask
virtual QBitmap contentsMask() const
Calculate a mask for the contents of the panned widget.
Definition: qwt_panner.cpp:297
QwtPanner::grab
virtual QPixmap grab() const
Definition: qwt_panner.cpp:306
QwtPanner::panned
void panned(int dx, int dy)
QwtPlot
A 2-D plotting widget.
Definition: qwt_plot.h:79
QwtPlot::setAxisScale
void setAxisScale(QwtAxisId, double min, double max, double stepSize=0)
Disable autoscaling and specify a fixed scale for a selected axis.
Definition: qwt_plot_axis.cpp:473
QwtPlot::autoReplot
bool autoReplot() const
Definition: qwt_plot.cpp:319
QwtPlot::replot
virtual void replot()
Redraw the plot.
Definition: qwt_plot.cpp:545
QwtPlot::setAutoReplot
void setAutoReplot(bool=true)
Set or reset the autoReplot option.
Definition: qwt_plot.cpp:310
QwtPlot::canvasMap
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition: qwt_plot.cpp:800
QwtPlot::axisScaleDiv
const QwtScaleDiv & axisScaleDiv(QwtAxisId) const
Return the scale division of a specified axis.
Definition: qwt_plot_axis.cpp:283
QwtPlotPanner::canvas
QWidget * canvas()
Return observed plot canvas.
Definition: qwt_plot_panner.cpp:177
QwtPlotPanner::contentsMask
virtual QBitmap contentsMask() const override
Definition: qwt_plot_panner.cpp:267
QwtPlotPanner::QwtPlotPanner
QwtPlotPanner(QWidget *)
A panner for the canvas of a QwtPlot.
Definition: qwt_plot_panner.cpp:128
QwtPlotPanner::setAxisEnabled
void setAxisEnabled(QwtAxisId axisId, bool on)
En/Disable an axis.
Definition: qwt_plot_panner.cpp:154
QwtPlotPanner::~QwtPlotPanner
virtual ~QwtPlotPanner()
Destructor.
Definition: qwt_plot_panner.cpp:138
QwtPlotPanner::moveCanvas
virtual void moveCanvas(int dx, int dy)
Definition: qwt_plot_panner.cpp:216
QwtPlotPanner::isAxisEnabled
bool isAxisEnabled(QwtAxisId) const
Definition: qwt_plot_panner.cpp:168
QwtPlotPanner::plot
QwtPlot * plot()
Return plot widget, containing the observed plot canvas.
Definition: qwt_plot_panner.cpp:189
QwtPlotPanner::grab
virtual QPixmap grab() const override
Definition: qwt_plot_panner.cpp:278
QwtScaleDiv::lowerBound
double lowerBound() const
Definition: qwt_scale_div.cpp:131
QwtScaleDiv::upperBound
double upperBound() const
Definition: qwt_scale_div.cpp:151
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtScaleMap::invTransform
double invTransform(double p) const
Definition: qwt_scale_map.h:154
QwtAxis::isValid
bool isValid(int axisPos)
Definition: qwt_axis.h:45
QwtAxis::isXAxis
bool isXAxis(int axisPos)
Definition: qwt_axis.h:51