Skip to content
Snippets Groups Projects
qwt_plot_grid.cpp 9.62 KiB
Newer Older
  • Learn to ignore specific revisions
  • pixhawk's avatar
    pixhawk committed
    /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
     * Qwt Widget Library
     * Copyright (C) 1997   Josef Wilgen
     * Copyright (C) 2002   Uwe Rathmann
    
    pixhawk's avatar
    pixhawk committed
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the Qwt License, Version 1.0
     *****************************************************************************/
    
    
    Bryant's avatar
    Bryant committed
    #include "qwt_plot_grid.h"
    
    pixhawk's avatar
    pixhawk committed
    #include "qwt_painter.h"
    #include "qwt_text.h"
    #include "qwt_scale_map.h"
    #include "qwt_scale_div.h"
    
    Bryant's avatar
    Bryant committed
    #include "qwt_math.h"
    #include <qpainter.h>
    #include <qpen.h>
    
    pixhawk's avatar
    pixhawk committed
    
    class QwtPlotGrid::PrivateData
    {
    public:
        PrivateData():
    
    Bryant's avatar
    Bryant committed
            xEnabled( true ),
            yEnabled( true ),
            xMinEnabled( false ),
            yMinEnabled( false )
        {
    
    pixhawk's avatar
    pixhawk committed
        }
    
        bool xEnabled;
        bool yEnabled;
        bool xMinEnabled;
        bool yMinEnabled;
    
        QwtScaleDiv xScaleDiv;
        QwtScaleDiv yScaleDiv;
    
    
    Bryant's avatar
    Bryant committed
        QPen majorPen;
        QPen minorPen;
    
    pixhawk's avatar
    pixhawk committed
    };
    
    //! Enables major grid, disables minor grid
    QwtPlotGrid::QwtPlotGrid():
    
    Bryant's avatar
    Bryant committed
        QwtPlotItem( QwtText( "Grid" ) )
    
    pixhawk's avatar
    pixhawk committed
    {
        d_data = new PrivateData;
    
    Bryant's avatar
    Bryant committed
    
        setItemInterest( QwtPlotItem::ScaleInterest, true );
        setZ( 10.0 );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    //! Destructor
    QwtPlotGrid::~QwtPlotGrid()
    {
        delete d_data;
    }
    
    //! \return QwtPlotItem::Rtti_PlotGrid
    int QwtPlotGrid::rtti() const
    {
        return QwtPlotItem::Rtti_PlotGrid;
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \brief Enable or disable vertical grid lines
      \param on Enable (true) or disable
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
      \sa Minor grid lines can be enabled or disabled with
    
    pixhawk's avatar
    pixhawk committed
          enableXMin()
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::enableX( bool on )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->xEnabled != on )
        {
            d_data->xEnabled = on;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \brief Enable or disable horizontal grid lines
      \param on Enable (true) or disable
      \sa Minor grid lines can be enabled or disabled with enableYMin()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::enableY( bool on )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->yEnabled != on )
        {
            d_data->yEnabled = on;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \brief Enable or disable  minor vertical grid lines.
      \param on Enable (true) or disable
    
    pixhawk's avatar
    pixhawk committed
      \sa enableX()
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::enableXMin( bool on )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->xMinEnabled != on )
        {
            d_data->xMinEnabled = on;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \brief Enable or disable minor horizontal grid lines
      \param on Enable (true) or disable
    
    pixhawk's avatar
    pixhawk committed
      \sa enableY()
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::enableYMin( bool on )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->yMinEnabled != on )
        {
            d_data->yMinEnabled = on;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      Assign an x axis scale division
    
    
    pixhawk's avatar
    pixhawk committed
      \param scaleDiv Scale division
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::setXDiv( const QwtScaleDiv &scaleDiv )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->xScaleDiv != scaleDiv )
        {
    
    pixhawk's avatar
    pixhawk committed
            d_data->xScaleDiv = scaleDiv;
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      Assign a y axis division
    
      \param scaleDiv Scale division
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::setYDiv( const QwtScaleDiv &scaleDiv )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->yScaleDiv != scaleDiv )
        {
            d_data->yScaleDiv = scaleDiv;
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      Build and assign a pen for both major and minor grid lines
    
      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 QwtPlotGrid::setPen( const QColor &color, qreal width, Qt::PenStyle style )
    {
        setPen( QPen( color, width, style ) );
    }
    
    /*!
      Assign a pen for both major and minor grid lines
    
      \param pen Pen
      \sa setMajorPen(), setMinorPen()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::setPen( const QPen &pen )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->majorPen != pen || d_data->minorPen != pen )
        {
            d_data->majorPen = pen;
            d_data->minorPen = pen;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      Build and assign a pen for both major grid lines
    
      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 QwtPlotGrid::setMajorPen( const QColor &color, qreal width, Qt::PenStyle style )
    {
        setMajorPen( QPen( color, width, style ) );
    }
    
    /*!
      Assign a pen for the major grid lines
    
      \param pen Pen
      \sa majorPen(), setMinorPen(), setPen()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::setMajorPen( const QPen &pen )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->majorPen != pen )
        {
            d_data->majorPen = pen;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      Build and assign a pen for the minor grid lines
    
      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 QwtPlotGrid::setMinorPen( const QColor &color, qreal width, Qt::PenStyle style )
    {
        setMinorPen( QPen( color, width, style ) );
    }
    
    /*!
      Assign a pen for the minor grid lines
    
      \param pen Pen
      \sa minorPen(), setMajorPen(), setPen()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::setMinorPen( const QPen &pen )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        if ( d_data->minorPen != pen )
        {
            d_data->minorPen = pen;
    
            legendChanged();
    
    pixhawk's avatar
    pixhawk committed
            itemChanged();
        }
    }
    
    /*!
      \brief Draw the grid
    
    
      The grid is drawn into the bounding rectangle such that
    
    Bryant's avatar
    Bryant committed
      grid lines begin and end at the rectangle's borders. The X and Y
    
    pixhawk's avatar
    pixhawk committed
      maps are used to map the scale divisions into the drawing region
      screen.
    
    Bryant's avatar
    Bryant committed
    
    
    pixhawk's avatar
    pixhawk committed
      \param painter  Painter
      \param xMap X axis map
    
      \param yMap Y axis
    
    Bryant's avatar
    Bryant committed
      \param canvasRect Contents rectangle of the plot canvas
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::draw( QPainter *painter,
        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
        const QRectF &canvasRect ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        //  draw minor grid lines
        QPen minorPen = d_data->minorPen;
        minorPen.setCapStyle( Qt::FlatCap );
    
        painter->setPen( minorPen );
    
        if ( d_data->xEnabled && d_data->xMinEnabled )
        {
            drawLines( painter, canvasRect, Qt::Vertical, xMap,
                d_data->xScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
            drawLines( painter, canvasRect, Qt::Vertical, xMap,
                d_data->xScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
    
    pixhawk's avatar
    pixhawk committed
        }
    
    
    Bryant's avatar
    Bryant committed
        if ( d_data->yEnabled && d_data->yMinEnabled )
        {
            drawLines( painter, canvasRect, Qt::Horizontal, yMap,
                d_data->yScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
            drawLines( painter, canvasRect, Qt::Horizontal, yMap,
                d_data->yScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
    
    pixhawk's avatar
    pixhawk committed
        }
    
    
    Bryant's avatar
    Bryant committed
        //  draw major grid lines
        QPen majorPen = d_data->majorPen;
        majorPen.setCapStyle( Qt::FlatCap );
    
    Bryant's avatar
    Bryant committed
        painter->setPen( majorPen );
    
        if ( d_data->xEnabled )
        {
            drawLines( painter, canvasRect, Qt::Vertical, xMap,
                d_data->xScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
    
    pixhawk's avatar
    pixhawk committed
        }
    
    
    Bryant's avatar
    Bryant committed
        if ( d_data->yEnabled )
        {
            drawLines( painter, canvasRect, Qt::Horizontal, yMap,
                d_data->yScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
    
    pixhawk's avatar
    pixhawk committed
        }
    }
    
    
    Bryant's avatar
    Bryant committed
    void QwtPlotGrid::drawLines( QPainter *painter, const QRectF &canvasRect,
        Qt::Orientation orientation, const QwtScaleMap &scaleMap,
        const QList<double> &values ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        const double x1 = canvasRect.left();
        const double x2 = canvasRect.right() - 1.0;
        const double y1 = canvasRect.top();
        const double y2 = canvasRect.bottom() - 1.0;
    
        const bool doAlign = QwtPainter::roundingAlignment( painter );
    
        for ( int i = 0; i < values.count(); i++ )
        {
            double value = scaleMap.transform( values[i] );
            if ( doAlign )
                value = qRound( value );
    
            if ( orientation == Qt::Horizontal )
            {
                if ( qwtFuzzyGreaterOrEqual( value, y1 ) &&
                    qwtFuzzyLessOrEqual( value, y2 ) )
                {
                    QwtPainter::drawLine( painter, x1, value, x2, value );
                }
            }
            else
            {
                if ( qwtFuzzyGreaterOrEqual( value, x1 ) &&
                    qwtFuzzyLessOrEqual( value, x2 ) )
                {
                    QwtPainter::drawLine( painter, value, y1, value, y2 );
                }
    
    pixhawk's avatar
    pixhawk committed
            }
        }
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \return the pen for the major grid lines
      \sa setMajorPen(), setMinorPen(), setPen()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    const QPen &QwtPlotGrid::majorPen() const
    
    Bryant's avatar
    Bryant committed
        return d_data->majorPen;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \return the pen for the minor grid lines
      \sa setMinorPen(), setMajorPen(), setPen()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    const QPen &QwtPlotGrid::minorPen() const
    
    Bryant's avatar
    Bryant committed
        return d_data->minorPen;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    pixhawk's avatar
    pixhawk committed
    /*!
    
    Bryant's avatar
    Bryant committed
      \return true if vertical grid lines are enabled
    
    pixhawk's avatar
    pixhawk committed
      \sa enableX()
    */
    bool QwtPlotGrid::xEnabled() const
    
    {
        return d_data->xEnabled;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \return true if minor vertical grid lines are enabled
    
    pixhawk's avatar
    pixhawk committed
      \sa enableXMin()
    */
    
    bool QwtPlotGrid::xMinEnabled() const
    {
        return d_data->xMinEnabled;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \return true if horizontal grid lines are enabled
    
    pixhawk's avatar
    pixhawk committed
      \sa enableY()
    */
    
    bool QwtPlotGrid::yEnabled() const
    {
        return d_data->yEnabled;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \return true if minor horizontal grid lines are enabled
    
    pixhawk's avatar
    pixhawk committed
      \sa enableYMin()
    */
    
    bool QwtPlotGrid::yMinEnabled() const
    
    pixhawk's avatar
    pixhawk committed
    {
    
        return d_data->yMinEnabled;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    pixhawk's avatar
    pixhawk committed
    /*! \return the scale division of the x axis */
    
    const QwtScaleDiv &QwtPlotGrid::xScaleDiv() const
    {
        return d_data->xScaleDiv;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*! \return the scale division of the y axis */
    
    const QwtScaleDiv &QwtPlotGrid::yScaleDiv() const
    {
        return d_data->yScaleDiv;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    Bryant's avatar
    Bryant committed
    /*!
       Update the grid to changes of the axes scale division
    
       \param xScaleDiv Scale division of the x-axis
       \param yScaleDiv Scale division of the y-axis
    
       \sa QwtPlot::updateAxes()
    */
    void QwtPlotGrid::updateScaleDiv( const QwtScaleDiv& xScaleDiv,
        const QwtScaleDiv& yScaleDiv )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        setXDiv( xScaleDiv );
        setYDiv( yScaleDiv );
    
    pixhawk's avatar
    pixhawk committed
    }