Skip to content
Snippets Groups Projects
qwt_plot_picker.cpp 8.92 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
     *
     * 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_picker.h"
    
    pixhawk's avatar
    pixhawk committed
    #include "qwt_plot.h"
    #include "qwt_scale_div.h"
    #include "qwt_painter.h"
    #include "qwt_scale_map.h"
    
    Bryant's avatar
    Bryant committed
    #include "qwt_picker_machine.h"
    
    pixhawk's avatar
    pixhawk committed
    
    /*!
      \brief Create a plot picker
    
      The picker is set to those x- and y-axis of the plot
      that are enabled. If both or no x-axis are enabled, the picker
      is set to QwtPlot::xBottom. If both or no y-axis are
      enabled, it is set to QwtPlot::yLeft.
    
      \param canvas Plot canvas to observe, also the parent object
    
    
    Bryant's avatar
    Bryant committed
      \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QwtPlotPicker::QwtPlotPicker( QWidget *canvas ):
        QwtPicker( canvas ),
        d_xAxis( -1 ),
        d_yAxis( -1 )
    
    pixhawk's avatar
    pixhawk committed
    {
        if ( !canvas )
            return;
    
        // attach axes
    
        int xAxis = QwtPlot::xBottom;
    
        const QwtPlot *plot = QwtPlotPicker::plot();
    
    Bryant's avatar
    Bryant committed
        if ( !plot->axisEnabled( QwtPlot::xBottom ) &&
            plot->axisEnabled( QwtPlot::xTop ) )
        {
    
    pixhawk's avatar
    pixhawk committed
            xAxis = QwtPlot::xTop;
        }
    
        int yAxis = QwtPlot::yLeft;
    
    Bryant's avatar
    Bryant committed
        if ( !plot->axisEnabled( QwtPlot::yLeft ) &&
            plot->axisEnabled( QwtPlot::yRight ) )
        {
    
    pixhawk's avatar
    pixhawk committed
            yAxis = QwtPlot::yRight;
        }
    
    
    Bryant's avatar
    Bryant committed
        setAxis( xAxis, yAxis );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
      Create a plot picker
    
      \param xAxis Set the x axis of the picker
      \param yAxis Set the y axis of the picker
      \param canvas Plot canvas to observe, also the parent object
    
    
    Bryant's avatar
    Bryant committed
      \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis, QWidget *canvas ):
        QwtPicker( canvas ),
        d_xAxis( xAxis ),
        d_yAxis( yAxis )
    
    pixhawk's avatar
    pixhawk committed
    {
    }
    
    /*!
      Create a plot picker
    
      \param xAxis X axis of the picker
      \param yAxis Y axis of the picker
    
    Bryant's avatar
    Bryant committed
      \param rubberBand Rubber band style
    
    pixhawk's avatar
    pixhawk committed
      \param trackerMode Tracker mode
      \param canvas Plot canvas to observe, also the parent object
    
      \sa QwtPicker, QwtPicker::setSelectionFlags(), QwtPicker::setRubberBand(),
          QwtPicker::setTrackerMode
    
    
    Bryant's avatar
    Bryant committed
      \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis,
            RubberBand rubberBand, DisplayMode trackerMode,
            QWidget *canvas ):
        QwtPicker( rubberBand, trackerMode, canvas ),
        d_xAxis( xAxis ),
        d_yAxis( yAxis )
    
    pixhawk's avatar
    pixhawk committed
    {
    }
    
    
    Bryant's avatar
    Bryant committed
    //! Destructor
    QwtPlotPicker::~QwtPlotPicker()
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
    }
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
    //! \return Observed plot canvas
    QWidget *QwtPlotPicker::canvas()
    {
        return parentWidget();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    Bryant's avatar
    Bryant committed
    //! \return Observed plot canvas
    const QWidget *QwtPlotPicker::canvas() const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        return parentWidget();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    Bryant's avatar
    Bryant committed
    //! \return Plot widget, containing the observed plot canvas
    
    pixhawk's avatar
    pixhawk committed
    QwtPlot *QwtPlotPicker::plot()
    {
    
    Bryant's avatar
    Bryant committed
        QWidget *w = canvas();
        if ( w )
            w = w->parentWidget();
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return qobject_cast<QwtPlot *>( w );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    Bryant's avatar
    Bryant committed
    //! \return Plot widget, containing the observed plot canvas
    
    pixhawk's avatar
    pixhawk committed
    const QwtPlot *QwtPlotPicker::plot() const
    {
    
    Bryant's avatar
    Bryant committed
        const QWidget *w = canvas();
        if ( w )
            w = w->parentWidget();
    
        return qobject_cast<const QwtPlot *>( w );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
    
    Bryant's avatar
    Bryant committed
      \return Normalized bounding rectangle of the axes
    
    pixhawk's avatar
    pixhawk committed
      \sa QwtPlot::autoReplot(), QwtPlot::replot().
    */
    
    Bryant's avatar
    Bryant committed
    QRectF QwtPlotPicker::scaleRect() const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        QRectF rect;
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        if ( plot() )
        {
            const QwtScaleDiv &xs = plot()->axisScaleDiv( xAxis() );
            const QwtScaleDiv &ys = plot()->axisScaleDiv( yAxis() );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
            rect = QRectF( xs.lowerBound(), ys.lowerBound(),
                xs.range(), ys.range() );
            rect = rect.normalized();
    
    pixhawk's avatar
    pixhawk committed
        }
    
        return rect;
    }
    
    /*!
      Set the x and y axes of the picker
    
      \param xAxis X axis
      \param yAxis Y axis
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotPicker::setAxis( int xAxis, int yAxis )
    
    pixhawk's avatar
    pixhawk committed
    {
        const QwtPlot *plt = plot();
        if ( !plt )
            return;
    
    
    Bryant's avatar
    Bryant committed
        if ( xAxis != d_xAxis || yAxis != d_yAxis )
        {
    
    pixhawk's avatar
    pixhawk committed
            d_xAxis = xAxis;
            d_yAxis = yAxis;
        }
    }
    
    //! Return x axis
    int QwtPlotPicker::xAxis() const
    {
        return d_xAxis;
    }
    
    //! Return y axis
    int QwtPlotPicker::yAxis() const
    {
        return d_yAxis;
    }
    
    /*!
      Translate a pixel position into a position string
    
      \param pos Position in pixel coordinates
      \return Position string
    */
    
    Bryant's avatar
    Bryant committed
    QwtText QwtPlotPicker::trackerText( const QPoint &pos ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        return trackerTextF( invTransform( pos ) );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
      \brief Translate a position into a position string
    
      In case of HLineRubberBand the label is the value of the
      y position, in case of VLineRubberBand the value of the x position.
      Otherwise the label contains x and y position separated by a ',' .
    
      The format for the double to string conversion is "%.4f".
    
      \param pos Position
      \return Position string
    */
    
    Bryant's avatar
    Bryant committed
    QwtText QwtPlotPicker::trackerTextF( const QPointF &pos ) const
    
    pixhawk's avatar
    pixhawk committed
    {
        QString text;
    
    
    Bryant's avatar
    Bryant committed
        switch ( rubberBand() )
        {
            case HLineRubberBand:
                text.sprintf( "%.4f", pos.y() );
                break;
            case VLineRubberBand:
                text.sprintf( "%.4f", pos.x() );
                break;
            default:
                text.sprintf( "%.4f, %.4f", pos.x(), pos.y() );
    
    pixhawk's avatar
    pixhawk committed
        }
    
    Bryant's avatar
    Bryant committed
        return QwtText( text );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    Bryant's avatar
    Bryant committed
      Append a point to the selection and update rubber band and tracker.
    
    pixhawk's avatar
    pixhawk committed
      \param pos Additional point
      \sa isActive, begin(), end(), move(), appended()
    
    
      \note The appended(const QPoint &), appended(const QDoublePoint &)
    
    pixhawk's avatar
    pixhawk committed
            signals are emitted.
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotPicker::append( const QPoint &pos )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        QwtPicker::append( pos );
        Q_EMIT appended( invTransform( pos ) );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
      Move the last point of the selection
    
      \param pos New position
      \sa isActive, begin(), end(), append()
    
    
      \note The moved(const QPoint &), moved(const QDoublePoint &)
    
    pixhawk's avatar
    pixhawk committed
            signals are emitted.
    */
    
    Bryant's avatar
    Bryant committed
    void QwtPlotPicker::move( const QPoint &pos )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        QwtPicker::move( pos );
        Q_EMIT moved( invTransform( pos ) );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
      Close a selection setting the state to inactive.
    
      \param ok If true, complete the selection and emit selected signals
                otherwise discard the selection.
    
    Bryant's avatar
    Bryant committed
      \return True if the selection has been accepted, false otherwise
    
    pixhawk's avatar
    pixhawk committed
    */
    
    
    Bryant's avatar
    Bryant committed
    bool QwtPlotPicker::end( bool ok )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        ok = QwtPicker::end( ok );
    
    pixhawk's avatar
    pixhawk committed
        if ( !ok )
            return false;
    
        QwtPlot *plot = QwtPlotPicker::plot();
        if ( !plot )
            return false;
    
    
    Bryant's avatar
    Bryant committed
        const QPolygon points = selection();
        if ( points.count() == 0 )
    
    pixhawk's avatar
    pixhawk committed
            return false;
    
    
    Bryant's avatar
    Bryant committed
        QwtPickerMachine::SelectionType selectionType =
            QwtPickerMachine::NoSelection;
    
        if ( stateMachine() )
            selectionType = stateMachine()->selectionType();
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        switch ( selectionType )
        {
            case QwtPickerMachine::PointSelection:
            {
                const QPointF pos = invTransform( points.first() );
                Q_EMIT selected( pos );
                break;
            }
            case QwtPickerMachine::RectSelection:
            {
                if ( points.count() >= 2 )
                {
                    const QPoint p1 = points.first();
                    const QPoint p2 = points.last();
    
                    const QRect rect = QRect( p1, p2 ).normalized();
                    Q_EMIT selected( invTransform( rect ) );
                }
                break;
            }
            case QwtPickerMachine::PolygonSelection:
            {
                QVector<QPointF> dpa( points.count() );
                for ( int i = 0; i < points.count(); i++ )
                    dpa[i] = invTransform( points[i] );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
                Q_EMIT selected( dpa );
            }
            default:
                break;
    
    pixhawk's avatar
    pixhawk committed
        }
    
        return true;
    }
    
    /*!
        Translate a rectangle from pixel into plot coordinates
    
        \return Rectangle in plot coordinates
    
    Bryant's avatar
    Bryant committed
        \sa transform()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QRectF QwtPlotPicker::invTransform( const QRect &rect ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        const QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
        const QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return QwtScaleMap::invTransform( xMap, yMap, rect );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
        Translate a rectangle from plot into pixel coordinates
        \return Rectangle in pixel coordinates
    
    Bryant's avatar
    Bryant committed
        \sa invTransform()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QRect QwtPlotPicker::transform( const QRectF &rect ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        const QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
        const QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return QwtScaleMap::transform( xMap, yMap, rect ).toRect();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
        Translate a point from pixel into plot coordinates
        \return Point in plot coordinates
    
    Bryant's avatar
    Bryant committed
        \sa transform()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QPointF QwtPlotPicker::invTransform( const QPoint &pos ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
        QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return QPointF(
            xMap.invTransform( pos.x() ),
            yMap.invTransform( pos.y() )
        );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
        Translate a point from plot into pixel coordinates
        \return Point in pixel coordinates
    
    Bryant's avatar
    Bryant committed
        \sa invTransform()
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    QPoint QwtPlotPicker::transform( const QPointF &pos ) const
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
        QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
    
        const QPointF p( xMap.transform( pos.x() ),
            yMap.transform( pos.y() ) );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return p.toPoint();
    
    pixhawk's avatar
    pixhawk committed
    }