Skip to content
qwt_plot.cpp 30 KiB
Newer Older
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
 *****************************************************************************/

#include "qwt_plot.h"
#include "qwt_plot_dict.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_widget.h"
#include "qwt_scale_engine.h"
#include "qwt_text_label.h"
#include "qwt_legend.h"
Bryant's avatar
Bryant committed
#include "qwt_legend_data.h"
pixhawk's avatar
pixhawk committed
#include "qwt_plot_canvas.h"
Bryant's avatar
Bryant committed
#include <qmath.h>
#include <qpainter.h>
#include <qpointer.h>
#include <qpaintengine.h>
#include <qapplication.h>
#include <qevent.h>

static inline void qwtEnableLegendItems( QwtPlot *plot, bool on )
{
    if ( on )
    {
        QObject::connect( 
            plot, SIGNAL( legendDataChanged(
                const QVariant &, const QList<QwtLegendData> & ) ),
            plot, SLOT( updateLegendItems( 
                const QVariant &, const QList<QwtLegendData> & ) ) );
    }
    else
    {
        QObject::disconnect( 
            plot, SIGNAL( legendDataChanged(
                const QVariant &, const QList<QwtLegendData> & ) ),
            plot, SLOT( updateLegendItems( 
                const QVariant &, const QList<QwtLegendData> & ) ) );
    }
}

static void qwtSetTabOrder( 
    QWidget *first, QWidget *second, bool withChildren )
{
    QList<QWidget *> tabChain;
    tabChain += first;
    tabChain += second;

    if ( withChildren )
    {
        QList<QWidget *> children = second->findChildren<QWidget *>();

        QWidget *w = second->nextInFocusChain();
        while ( children.contains( w ) )
        {
            children.removeAll( w );

            tabChain += w;
            w = w->nextInFocusChain();
        }
    }

    for ( int i = 0; i < tabChain.size() - 1; i++ )
    {
        QWidget *from = tabChain[i];
        QWidget *to = tabChain[i+1];

        const Qt::FocusPolicy policy1 = from->focusPolicy();
        const Qt::FocusPolicy policy2 = to->focusPolicy();

        QWidget *proxy1 = from->focusProxy();
        QWidget *proxy2 = to->focusProxy();

        from->setFocusPolicy( Qt::TabFocus );
        from->setFocusProxy( NULL);

        to->setFocusPolicy( Qt::TabFocus );
        to->setFocusProxy( NULL);

        QWidget::setTabOrder( from, to );

        from->setFocusPolicy( policy1 );
        from->setFocusProxy( proxy1);

        to->setFocusPolicy( policy2 );
        to->setFocusProxy( proxy2 );
    }
}
pixhawk's avatar
pixhawk committed

class QwtPlot::PrivateData
{
public:
Bryant's avatar
Bryant committed
    QPointer<QwtTextLabel> titleLabel;
    QPointer<QwtTextLabel> footerLabel;
    QPointer<QWidget> canvas;
    QPointer<QwtAbstractLegend> legend;
pixhawk's avatar
pixhawk committed
    QwtPlotLayout *layout;

    bool autoReplot;
};

/*!
  \brief Constructor
  \param parent Parent widget
 */
Bryant's avatar
Bryant committed
QwtPlot::QwtPlot( QWidget *parent ):
    QFrame( parent )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    initPlot( QwtText() );
pixhawk's avatar
pixhawk committed
}

/*!
  \brief Constructor
  \param title Title text
  \param parent Parent widget
 */
Bryant's avatar
Bryant committed
QwtPlot::QwtPlot( const QwtText &title, QWidget *parent ):
    QFrame( parent )
Bryant's avatar
Bryant committed
    initPlot( title );
pixhawk's avatar
pixhawk committed

//! Destructor
QwtPlot::~QwtPlot()
{
Bryant's avatar
Bryant committed
    detachItems( QwtPlotItem::Rtti_PlotItem, autoDelete() );
pixhawk's avatar
pixhawk committed

    delete d_data->layout;
    deleteAxesData();
    delete d_data;
}

/*!
  \brief Initializes a QwtPlot instance
  \param title Title text
 */
Bryant's avatar
Bryant committed
void QwtPlot::initPlot( const QwtText &title )
pixhawk's avatar
pixhawk committed
{
    d_data = new PrivateData;

    d_data->layout = new QwtPlotLayout;
    d_data->autoReplot = false;

Bryant's avatar
Bryant committed
    // title
    d_data->titleLabel = new QwtTextLabel( this );
    d_data->titleLabel->setObjectName( "QwtPlotTitle" );
    d_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    QwtText text( title );
    text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
    d_data->titleLabel->setText( text );

    // footer
    d_data->footerLabel = new QwtTextLabel( this );
    d_data->footerLabel->setObjectName( "QwtPlotFooter" );

    QwtText footer;
    footer.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
    d_data->footerLabel->setText( footer );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    // legend
pixhawk's avatar
pixhawk committed
    d_data->legend = NULL;

Bryant's avatar
Bryant committed
    // axis
pixhawk's avatar
pixhawk committed
    initAxesData();

Bryant's avatar
Bryant committed
    // canvas
    d_data->canvas = new QwtPlotCanvas( this );
    d_data->canvas->setObjectName( "QwtPlotCanvas" );
    d_data->canvas->installEventFilter( this );

    setSizePolicy( QSizePolicy::MinimumExpanding,
        QSizePolicy::MinimumExpanding );

    resize( 200, 200 );

    QList<QWidget *> focusChain;
    focusChain << this << d_data->titleLabel << axisWidget( xTop )
        << axisWidget( yLeft ) << d_data->canvas << axisWidget( yRight )
        << axisWidget( xBottom ) << d_data->footerLabel;

    for ( int i = 0; i < focusChain.size() - 1; i++ )
        qwtSetTabOrder( focusChain[i], focusChain[i+1], false );

    qwtEnableLegendItems( this, true );
}

/*!
  \brief Set the drawing canvas of the plot widget

  QwtPlot invokes methods of the canvas as meta methods ( see QMetaObject ).
  In opposite to using conventional C++ techniques like virtual methods
  they allow to use canvas implementations that are derived from 
  QWidget or QGLWidget.

  The following meta methods could be implemented:
Loading
Loading full blame...