You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
421 lines
8.9 KiB
421 lines
8.9 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 ); |
|
}
|
|
|