You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
7.0 KiB
315 lines
7.0 KiB
/* -*- 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; |
|
}
|
|
|