qt_demoe/third/3rd_qwt/qwt_plot_zoneitem.cpp

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;
}