Skip to content
Snippets Groups Projects
  • Bryant's avatar
    c96458cf
    Update Qwt to 6.1. · c96458cf
    Bryant authored
    We also document how we got the source code and keep our modifications out of the Qwt directory.
    c96458cf
    History
    Update Qwt to 6.1.
    Bryant authored
    We also document how we got the source code and keep our modifications out of the Qwt directory.
qwt_legend_label.cpp 8.91 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_legend_label.h"
#include "qwt_legend_data.h"
#include "qwt_math.h"
#include "qwt_painter.h"
#include "qwt_symbol.h"
#include "qwt_graphic.h"
#include <qpainter.h>
#include <qdrawutil.h>
#include <qstyle.h>
#include <qpen.h>
#include <qevent.h>
#include <qstyleoption.h>
#include <qapplication.h>

static const int ButtonFrame = 2;
static const int Margin = 2;

static QSize buttonShift( const QwtLegendLabel *w )
{
    QStyleOption option;
    option.init( w );

    const int ph = w->style()->pixelMetric(
        QStyle::PM_ButtonShiftHorizontal, &option, w );
    const int pv = w->style()->pixelMetric(
        QStyle::PM_ButtonShiftVertical, &option, w );
    return QSize( ph, pv );
}

class QwtLegendLabel::PrivateData
{
public:
    PrivateData():
        itemMode( QwtLegendData::ReadOnly ),
        isDown( false ),
        spacing( Margin )
    {
    }

    QwtLegendData::Mode itemMode;
    QwtLegendData legendData;
    bool isDown;

    QPixmap icon;

    int spacing;
};

/*!
  Set the attributes of the legend label

  \param legendData Attributes of the label
  \sa data()
 */
void QwtLegendLabel::setData( const QwtLegendData &legendData )
{
    d_data->legendData = legendData;

    const bool doUpdate = updatesEnabled();
    setUpdatesEnabled( false );
    setText( legendData.title() );
    setIcon( legendData.icon().toPixmap() );

    if ( legendData.hasRole( QwtLegendData::ModeRole ) )
        setItemMode( legendData.mode() );

    if ( doUpdate )
    {
        setUpdatesEnabled( true );
        update();
    }
}

/*!
  \return Attributes of the label
  \sa setData(), QwtPlotItem::legendData()
 */
const QwtLegendData &QwtLegendLabel::data() const
{
    return d_data->legendData;
}

/*!
  \param parent Parent widget
*/
QwtLegendLabel::QwtLegendLabel( QWidget *parent ):
    QwtTextLabel( parent )
{
    d_data = new PrivateData;
    setMargin( Margin );
    setIndent( Margin );
}

//! Destructor
QwtLegendLabel::~QwtLegendLabel()
{
    delete d_data;
    d_data = NULL;
}

/*!
   Set the text to the legend item

   \param text Text label
    \sa QwtTextLabel::text()
*/
void QwtLegendLabel::setText( const QwtText &text )
{
    const int flags = Qt::AlignLeft | Qt::AlignVCenter
        | Qt::TextExpandTabs | Qt::TextWordWrap;

    QwtText txt = text;
    txt.setRenderFlags( flags );

    QwtTextLabel::setText( txt );
}

/*!
   Set the item mode
   The default is QwtLegendData::ReadOnly

   \param mode Item mode
   \sa itemMode()
*/
void QwtLegendLabel::setItemMode( QwtLegendData::Mode mode )
{
    if ( mode != d_data->itemMode )
    {
        d_data->itemMode = mode;
        d_data->isDown = false;

        setFocusPolicy( ( mode != QwtLegendData::ReadOnly ) 
            ? Qt::TabFocus : Qt::NoFocus );
        setMargin( ButtonFrame + Margin );

        updateGeometry();
    }
}

/*!
   \return Item mode
   \sa setItemMode()
*/
QwtLegendData::Mode QwtLegendLabel::itemMode() const
{
    return d_data->itemMode;
}

/*!
  Assign the icon

  \param icon Pixmap representing a plot item

  \sa icon(), QwtPlotItem::legendIcon()
*/
void QwtLegendLabel::setIcon( const QPixmap &icon )
{
    d_data->icon = icon;

    int indent = margin() + d_data->spacing;
    if ( icon.width() > 0 )
        indent += icon.width() + d_data->spacing;

    setIndent( indent );
}

/*!
  \return Pixmap representing a plot item
  \sa setIcon()
*/
QPixmap QwtLegendLabel::icon() const
{
    return d_data->icon;
}

/*!
   \brief Change the spacing between icon and text

   \param spacing Spacing
   \sa spacing(), QwtTextLabel::margin()
*/
void QwtLegendLabel::setSpacing( int spacing )
{
    spacing = qMax( spacing, 0 );
    if ( spacing != d_data->spacing )
    {
        d_data->spacing = spacing;

        int indent = margin() + d_data->spacing;
        if ( d_data->icon.width() > 0 )
            indent += d_data->icon.width() + d_data->spacing;

        setIndent( indent );
    }
}

/*!
   \return Spacing between icon and text
   \sa setSpacing(), QwtTextLabel::margin()
*/
int QwtLegendLabel::spacing() const
{
    return d_data->spacing;
}

/*!
    Check/Uncheck a the item

    \param on check/uncheck
    \sa setItemMode()
*/
void QwtLegendLabel::setChecked( bool on )
{
    if ( d_data->itemMode == QwtLegendData::Checkable )
    {
        const bool isBlocked = signalsBlocked();
        blockSignals( true );

        setDown( on );

        blockSignals( isBlocked );
    }
}

//! Return true, if the item is checked
bool QwtLegendLabel::isChecked() const
{
    return d_data->itemMode == QwtLegendData::Checkable && isDown();
}

//! Set the item being down
void QwtLegendLabel::setDown( bool down )
{
    if ( down == d_data->isDown )
        return;

    d_data->isDown = down;
    update();

    if ( d_data->itemMode == QwtLegendData::Clickable )
    {
        if ( d_data->isDown )
            Q_EMIT pressed();
        else
        {
            Q_EMIT released();
            Q_EMIT clicked();
        }
    }

    if ( d_data->itemMode == QwtLegendData::Checkable )
        Q_EMIT checked( d_data->isDown );
}

//! Return true, if the item is down
bool QwtLegendLabel::isDown() const
{
    return d_data->isDown;
}

//! Return a size hint
QSize QwtLegendLabel::sizeHint() const
{
    QSize sz = QwtTextLabel::sizeHint();
    sz.setHeight( qMax( sz.height(), d_data->icon.height() + 4 ) );

    if ( d_data->itemMode != QwtLegendData::ReadOnly )
    {
        sz += buttonShift( this );
        sz = sz.expandedTo( QApplication::globalStrut() );
    }

    return sz;
}

//! Paint event
void QwtLegendLabel::paintEvent( QPaintEvent *e )
{
    const QRect cr = contentsRect();

    QPainter painter( this );
    painter.setClipRegion( e->region() );

    if ( d_data->isDown )
    {
        qDrawWinButton( &painter, 0, 0, width(), height(),
            palette(), true );
    }

    painter.save();

    if ( d_data->isDown )
    {
        const QSize shiftSize = buttonShift( this );
        painter.translate( shiftSize.width(), shiftSize.height() );
    }

    painter.setClipRect( cr );

    drawContents( &painter );

    if ( !d_data->icon.isNull() )
    {
        QRect iconRect = cr;
        iconRect.setX( iconRect.x() + margin() );
        if ( d_data->itemMode != QwtLegendData::ReadOnly )
            iconRect.setX( iconRect.x() + ButtonFrame );

        iconRect.setSize( d_data->icon.size() );
        iconRect.moveCenter( QPoint( iconRect.center().x(), cr.center().y() ) );

        painter.drawPixmap( iconRect, d_data->icon );
    }

    painter.restore();
}

//! Handle mouse press events
void QwtLegendLabel::mousePressEvent( QMouseEvent *e )
{
    if ( e->button() == Qt::LeftButton )
    {
        switch ( d_data->itemMode )
        {
            case QwtLegendData::Clickable:
            {
                setDown( true );
                return;
            }
            case QwtLegendData::Checkable:
            {
                setDown( !isDown() );
                return;
            }
            default:;
        }
    }
    QwtTextLabel::mousePressEvent( e );
}
//! Handle mouse release events
void QwtLegendLabel::mouseReleaseEvent( QMouseEvent *e )
{
    if ( e->button() == Qt::LeftButton )
    {
        switch ( d_data->itemMode )
        {
            case QwtLegendData::Clickable:
            {
                setDown( false );
                return;
            }
            case QwtLegendData::Checkable:
            {
                return; // do nothing, but accept
            }
            default:;
        }
    }
    QwtTextLabel::mouseReleaseEvent( e );
}

//! Handle key press events
void QwtLegendLabel::keyPressEvent( QKeyEvent *e )
{
    if ( e->key() == Qt::Key_Space )
    {
        switch ( d_data->itemMode )
        {
            case QwtLegendData::Clickable:
            {
                if ( !e->isAutoRepeat() )
                    setDown( true );
                return;
            }
            case QwtLegendData::Checkable:
            {
                if ( !e->isAutoRepeat() )
                    setDown( !isDown() );
                return;
            }
            default:;
        }
    }

    QwtTextLabel::keyPressEvent( e );
}

//! Handle key release events
void QwtLegendLabel::keyReleaseEvent( QKeyEvent *e )
{
    if ( e->key() == Qt::Key_Space )
    {
        switch ( d_data->itemMode )
        {
            case QwtLegendData::Clickable:
            {
                if ( !e->isAutoRepeat() )
                    setDown( false );
                return;
            }
            case QwtLegendData::Checkable:
            {
                return; // do nothing, but accept
            }
            default:;
        }
    }

    QwtTextLabel::keyReleaseEvent( e );
}