316 lines
7.0 KiB
C++
316 lines
7.0 KiB
C++
/* -*- 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_zoneitem.h"
|
|
#include "qwt_painter.h"
|
|
#include "qwt_scale_map.h"
|
|
#include <qpainter.h>
|
|
|
|
class QwtPlotZoneItem::PrivateData
|
|
{
|
|
public:
|
|
PrivateData():
|
|
orientation( Qt::Vertical ),
|
|
pen( Qt::NoPen )
|
|
{
|
|
QColor c( Qt::darkGray );
|
|
c.setAlpha( 100 );
|
|
brush = QBrush( c );
|
|
}
|
|
|
|
Qt::Orientation orientation;
|
|
QPen pen;
|
|
QBrush brush;
|
|
QwtInterval interval;
|
|
};
|
|
|
|
/*!
|
|
\brief Constructor
|
|
|
|
Initializes the zone with no pen and a semi transparent gray brush
|
|
|
|
Sets the following item attributes:
|
|
|
|
- QwtPlotItem::AutoScale: false
|
|
- QwtPlotItem::Legend: false
|
|
|
|
The z value is initialized by 5
|
|
|
|
\sa QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
|
|
*/
|
|
QwtPlotZoneItem::QwtPlotZoneItem():
|
|
QwtPlotItem( QwtText( "Zone" ) )
|
|
{
|
|
d_data = new PrivateData;
|
|
|
|
setItemAttribute( QwtPlotItem::AutoScale, false );
|
|
setItemAttribute( QwtPlotItem::Legend, false );
|
|
|
|
setZ( 5 );
|
|
}
|
|
|
|
//! Destructor
|
|
QwtPlotZoneItem::~QwtPlotZoneItem()
|
|
{
|
|
delete d_data;
|
|
}
|
|
|
|
//! \return QwtPlotItem::Rtti_PlotZone
|
|
int QwtPlotZoneItem::rtti() const
|
|
{
|
|
return QwtPlotItem::Rtti_PlotZone;
|
|
}
|
|
|
|
/*!
|
|
Build and assign a pen
|
|
|
|
In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
|
|
non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
|
|
to hide this incompatibility.
|
|
|
|
\param color Pen color
|
|
\param width Pen width
|
|
\param style Pen style
|
|
|
|
\sa pen(), brush()
|
|
*/
|
|
void QwtPlotZoneItem::setPen( const QColor &color, qreal width, Qt::PenStyle style )
|
|
{
|
|
setPen( QPen( color, width, style ) );
|
|
}
|
|
|
|
/*!
|
|
\brief Assign a pen
|
|
|
|
The pen is used to draw the border lines of the zone
|
|
|
|
\param pen Pen
|
|
\sa pen(), setBrush()
|
|
*/
|
|
void QwtPlotZoneItem::setPen( const QPen &pen )
|
|
{
|
|
if ( d_data->pen != pen )
|
|
{
|
|
d_data->pen = pen;
|
|
itemChanged();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Pen used to draw the border lines
|
|
\sa setPen(), brush()
|
|
*/
|
|
const QPen &QwtPlotZoneItem::pen() const
|
|
{
|
|
return d_data->pen;
|
|
}
|
|
|
|
/*!
|
|
\brief Assign a brush
|
|
|
|
The brush is used to fill the zone
|
|
|
|
\param brush Brush
|
|
\sa pen(), setBrush()
|
|
*/
|
|
void QwtPlotZoneItem::setBrush( const QBrush &brush )
|
|
{
|
|
if ( d_data->brush != brush )
|
|
{
|
|
d_data->brush = brush;
|
|
itemChanged();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Brush used to fill the zone
|
|
\sa setPen(), brush()
|
|
*/
|
|
const QBrush &QwtPlotZoneItem::brush() const
|
|
{
|
|
return d_data->brush;
|
|
}
|
|
|
|
/*!
|
|
\brief Set the orientation of the zone
|
|
|
|
A horizontal zone highlights an interval of the y axis,
|
|
a vertical zone of the x axis. It is unbounded in the
|
|
opposite direction.
|
|
|
|
\sa orientation(), QwtPlotItem::setAxes()
|
|
*/
|
|
void QwtPlotZoneItem::setOrientation( Qt::Orientation orientation )
|
|
{
|
|
if ( d_data->orientation != orientation )
|
|
{
|
|
d_data->orientation = orientation;
|
|
itemChanged();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Orientation of the zone
|
|
\sa setOrientation()
|
|
*/
|
|
Qt::Orientation QwtPlotZoneItem::orientation()
|
|
{
|
|
return d_data->orientation;
|
|
}
|
|
|
|
/*!
|
|
Set the interval of the zone
|
|
|
|
For a horizontal zone the interval is related to the y axis,
|
|
for a vertical zone it is related to the x axis.
|
|
|
|
\param min Minimum of the interval
|
|
\param max Maximum of the interval
|
|
|
|
\sa interval(), setOrientation()
|
|
*/
|
|
void QwtPlotZoneItem::setInterval( double min, double max )
|
|
{
|
|
setInterval( QwtInterval( min, max ) );
|
|
}
|
|
|
|
/*!
|
|
Set the interval of the zone
|
|
|
|
For a horizontal zone the interval is related to the y axis,
|
|
for a vertical zone it is related to the x axis.
|
|
|
|
\param interval Zone interval
|
|
|
|
\sa interval(), setOrientation()
|
|
*/
|
|
void QwtPlotZoneItem::setInterval( const QwtInterval &interval )
|
|
{
|
|
if ( d_data->interval != interval )
|
|
{
|
|
d_data->interval = interval;
|
|
itemChanged();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\return Zone interval
|
|
\sa setInterval(), orientation()
|
|
*/
|
|
QwtInterval QwtPlotZoneItem::interval() const
|
|
{
|
|
return d_data->interval;
|
|
}
|
|
|
|
/*!
|
|
Draw the zone
|
|
|
|
\param painter Painter
|
|
\param xMap x Scale Map
|
|
\param yMap y Scale Map
|
|
\param canvasRect Contents rectangle of the canvas in painter coordinates
|
|
*/
|
|
|
|
void QwtPlotZoneItem::draw( QPainter *painter,
|
|
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
|
|
const QRectF &canvasRect ) const
|
|
{
|
|
if ( !d_data->interval.isValid() )
|
|
return;
|
|
|
|
QPen pen = d_data->pen;
|
|
pen.setCapStyle( Qt::FlatCap );
|
|
|
|
const bool doAlign = QwtPainter::roundingAlignment( painter );
|
|
|
|
if ( d_data->orientation == Qt::Horizontal )
|
|
{
|
|
double y1 = yMap.transform( d_data->interval.minValue() );
|
|
double y2 = yMap.transform( d_data->interval.maxValue() );
|
|
|
|
if ( doAlign )
|
|
{
|
|
y1 = qRound( y1 );
|
|
y2 = qRound( y2 );
|
|
}
|
|
|
|
QRectF r( canvasRect.left(), y1, canvasRect.width(), y2 - y1 );
|
|
r = r.normalized();
|
|
|
|
if ( ( d_data->brush.style() != Qt::NoBrush ) && ( y1 != y2 ) )
|
|
{
|
|
QwtPainter::fillRect( painter, r, d_data->brush );
|
|
}
|
|
|
|
if ( d_data->pen.style() != Qt::NoPen )
|
|
{
|
|
painter->setPen( d_data->pen );
|
|
|
|
QwtPainter::drawLine( painter, r.left(), r.top(), r.right(), r.top() );
|
|
QwtPainter::drawLine( painter, r.left(), r.bottom(), r.right(), r.bottom() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
double x1 = xMap.transform( d_data->interval.minValue() );
|
|
double x2 = xMap.transform( d_data->interval.maxValue() );
|
|
|
|
if ( doAlign )
|
|
{
|
|
x1 = qRound( x1 );
|
|
x2 = qRound( x2 );
|
|
}
|
|
|
|
QRectF r( x1, canvasRect.top(), x2 - x1, canvasRect.height() );
|
|
r = r.normalized();
|
|
|
|
if ( ( d_data->brush.style() != Qt::NoBrush ) && ( x1 != x2 ) )
|
|
{
|
|
QwtPainter::fillRect( painter, r, d_data->brush );
|
|
}
|
|
|
|
if ( d_data->pen.style() != Qt::NoPen )
|
|
{
|
|
painter->setPen( d_data->pen );
|
|
|
|
QwtPainter::drawLine( painter, r.left(), r.top(), r.left(), r.bottom() );
|
|
QwtPainter::drawLine( painter, r.right(), r.top(), r.right(), r.bottom() );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
The bounding rectangle is build from the interval in one direction
|
|
and something invalid for the opposite direction.
|
|
|
|
\return An invalid rectangle with valid boundaries in one direction
|
|
*/
|
|
QRectF QwtPlotZoneItem::boundingRect() const
|
|
{
|
|
QRectF br = QwtPlotItem::boundingRect();
|
|
|
|
const QwtInterval &intv = d_data->interval;
|
|
|
|
if ( intv.isValid() )
|
|
{
|
|
if ( d_data->orientation == Qt::Horizontal )
|
|
{
|
|
br.setTop( intv.minValue() );
|
|
br.setBottom( intv.maxValue() );
|
|
}
|
|
else
|
|
{
|
|
br.setLeft( intv.minValue() );
|
|
br.setRight( intv.maxValue() );
|
|
}
|
|
}
|
|
|
|
return br;
|
|
}
|