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