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.
564 lines
0 B
564 lines
0 B
15 years ago
|
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
||
|
* Qwt Widget Library
|
||
|
* Copyright (C) 1997 Josef Wilgen
|
||
|
* Copyright (C) 2002 Uwe Rathmann
|
||
14 years ago
|
*
|
||
15 years ago
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the Qwt License, Version 1.0
|
||
|
*****************************************************************************/
|
||
|
|
||
|
// vim: expandtab
|
||
|
|
||
|
#include <qpainter.h>
|
||
|
#include <qdrawutil.h>
|
||
|
#include <qstyle.h>
|
||
|
#include <qpen.h>
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
#include <qevent.h>
|
||
|
#include <qstyleoption.h>
|
||
|
#endif
|
||
|
#include "qwt_math.h"
|
||
|
#include "qwt_painter.h"
|
||
|
#include "qwt_symbol.h"
|
||
|
#include "qwt_legend_item.h"
|
||
|
|
||
|
static const int ButtonFrame = 2;
|
||
|
static const int Margin = 2;
|
||
|
|
||
|
static QSize buttonShift(const QwtLegendItem *w)
|
||
|
{
|
||
|
#if QT_VERSION < 0x040000
|
||
|
const int ph = w->style().pixelMetric(
|
||
14 years ago
|
QStyle::PM_ButtonShiftHorizontal, w);
|
||
15 years ago
|
const int pv = w->style().pixelMetric(
|
||
14 years ago
|
QStyle::PM_ButtonShiftVertical, w);
|
||
15 years ago
|
#else
|
||
|
QStyleOption option;
|
||
|
option.init(w);
|
||
|
|
||
|
const int ph = w->style()->pixelMetric(
|
||
14 years ago
|
QStyle::PM_ButtonShiftHorizontal, &option, w);
|
||
15 years ago
|
const int pv = w->style()->pixelMetric(
|
||
14 years ago
|
QStyle::PM_ButtonShiftVertical, &option, w);
|
||
15 years ago
|
#endif
|
||
|
return QSize(ph, pv);
|
||
|
}
|
||
|
|
||
|
class QwtLegendItem::PrivateData
|
||
|
{
|
||
|
public:
|
||
|
PrivateData():
|
||
|
itemMode(QwtLegend::ReadOnlyItem),
|
||
|
isDown(false),
|
||
|
identifierWidth(8),
|
||
|
identifierMode(QwtLegendItem::ShowLine | QwtLegendItem::ShowText),
|
||
|
curvePen(Qt::NoPen),
|
||
14 years ago
|
spacing(Margin) {
|
||
15 years ago
|
symbol = new QwtSymbol();
|
||
|
}
|
||
|
|
||
14 years ago
|
~PrivateData() {
|
||
15 years ago
|
delete symbol;
|
||
|
}
|
||
|
|
||
|
QwtLegend::LegendItemMode itemMode;
|
||
|
bool isDown;
|
||
|
|
||
|
int identifierWidth;
|
||
|
int identifierMode;
|
||
|
QwtSymbol *symbol;
|
||
|
QPen curvePen;
|
||
|
|
||
|
int spacing;
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
\param parent Parent widget
|
||
|
*/
|
||
|
QwtLegendItem::QwtLegendItem(QWidget *parent):
|
||
|
QwtTextLabel(parent)
|
||
|
{
|
||
|
d_data = new PrivateData;
|
||
|
init(QwtText());
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\param symbol Curve symbol
|
||
|
\param curvePen Curve pen
|
||
|
\param text Label text
|
||
|
\param parent Parent widget
|
||
|
*/
|
||
14 years ago
|
QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol,
|
||
|
const QPen &curvePen, const QwtText &text,
|
||
|
QWidget *parent):
|
||
15 years ago
|
QwtTextLabel(parent)
|
||
|
{
|
||
|
d_data = new PrivateData;
|
||
|
|
||
|
delete d_data->symbol;
|
||
|
d_data->symbol = symbol.clone();
|
||
|
|
||
|
d_data->curvePen = curvePen;
|
||
|
|
||
|
init(text);
|
||
|
}
|
||
|
|
||
|
void QwtLegendItem::init(const QwtText &text)
|
||
|
{
|
||
|
setMargin(Margin);
|
||
|
setIndent(margin() + d_data->identifierWidth + 2 * d_data->spacing);
|
||
|
setText(text);
|
||
|
}
|
||
|
|
||
|
//! Destructor
|
||
|
QwtLegendItem::~QwtLegendItem()
|
||
|
{
|
||
|
delete d_data;
|
||
|
d_data = NULL;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Set the text to the legend item
|
||
|
|
||
|
\param text Text label
|
||
|
\sa QwtTextLabel::text()
|
||
|
*/
|
||
|
void QwtLegendItem::setText(const QwtText &text)
|
||
|
{
|
||
|
const int flags = Qt::AlignLeft | Qt::AlignVCenter
|
||
|
#if QT_VERSION < 0x040000
|
||
14 years ago
|
| Qt::WordBreak | Qt::ExpandTabs;
|
||
15 years ago
|
#else
|
||
14 years ago
|
| Qt::TextExpandTabs | Qt::TextWordWrap;
|
||
15 years ago
|
#endif
|
||
|
|
||
|
QwtText txt = text;
|
||
|
txt.setRenderFlags(flags);
|
||
|
|
||
|
QwtTextLabel::setText(txt);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Set the item mode
|
||
|
The default is QwtLegend::ReadOnlyItem
|
||
|
|
||
|
\param mode Item mode
|
||
|
\sa itemMode()
|
||
|
*/
|
||
14 years ago
|
void QwtLegendItem::setItemMode(QwtLegend::LegendItemMode mode)
|
||
|
{
|
||
|
d_data->itemMode = mode;
|
||
|
d_data->isDown = false;
|
||
15 years ago
|
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
using namespace Qt;
|
||
|
#endif
|
||
|
setFocusPolicy(mode != QwtLegend::ReadOnlyItem ? TabFocus : NoFocus);
|
||
|
setMargin(ButtonFrame + Margin);
|
||
|
|
||
|
updateGeometry();
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Return the item mode
|
||
|
|
||
|
\sa setItemMode()
|
||
|
*/
|
||
14 years ago
|
QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
|
||
|
{
|
||
|
return d_data->itemMode;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
Set identifier mode.
|
||
|
Default is ShowLine | ShowText.
|
||
|
\param mode Or'd values of IdentifierMode
|
||
|
|
||
|
\sa identifierMode()
|
||
|
*/
|
||
|
void QwtLegendItem::setIdentifierMode(int mode)
|
||
|
{
|
||
14 years ago
|
if ( mode != d_data->identifierMode ) {
|
||
15 years ago
|
d_data->identifierMode = mode;
|
||
|
update();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Or'd values of IdentifierMode.
|
||
|
\sa setIdentifierMode(), IdentifierMode
|
||
|
*/
|
||
14 years ago
|
int QwtLegendItem::identifierMode() const
|
||
|
{
|
||
|
return d_data->identifierMode;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
Set the width for the identifier
|
||
|
Default is 8 pixels
|
||
|
|
||
|
\param width New width
|
||
|
|
||
|
\sa identifierMode(), identifierWidth
|
||
|
*/
|
||
|
void QwtLegendItem::setIdentfierWidth(int width)
|
||
|
{
|
||
|
width = qwtMax(width, 0);
|
||
14 years ago
|
if ( width != d_data->identifierWidth ) {
|
||
15 years ago
|
d_data->identifierWidth = width;
|
||
14 years ago
|
setIndent(margin() + d_data->identifierWidth
|
||
|
+ 2 * d_data->spacing);
|
||
15 years ago
|
}
|
||
|
}
|
||
|
/*!
|
||
|
Return the width of the identifier
|
||
|
|
||
|
\sa setIdentfierWidth
|
||
|
*/
|
||
|
int QwtLegendItem::identifierWidth() const
|
||
|
{
|
||
|
return d_data->identifierWidth;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Change the spacing
|
||
|
\param spacing Spacing
|
||
|
\sa spacing(), identifierWidth(), QwtTextLabel::margin()
|
||
|
*/
|
||
|
void QwtLegendItem::setSpacing(int spacing)
|
||
|
{
|
||
|
spacing = qwtMax(spacing, 0);
|
||
14 years ago
|
if ( spacing != d_data->spacing ) {
|
||
15 years ago
|
d_data->spacing = spacing;
|
||
14 years ago
|
setIndent(margin() + d_data->identifierWidth
|
||
|
+ 2 * d_data->spacing);
|
||
15 years ago
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Return the spacing
|
||
|
\sa setSpacing(), identifierWidth(), QwtTextLabel::margin()
|
||
|
*/
|
||
|
int QwtLegendItem::spacing() const
|
||
|
{
|
||
|
return d_data->spacing;
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Set curve symbol.
|
||
|
\param symbol Symbol
|
||
|
|
||
|
\sa symbol()
|
||
|
*/
|
||
14 years ago
|
void QwtLegendItem::setSymbol(const QwtSymbol &symbol)
|
||
15 years ago
|
{
|
||
|
delete d_data->symbol;
|
||
|
d_data->symbol = symbol.clone();
|
||
|
update();
|
||
|
}
|
||
14 years ago
|
|
||
15 years ago
|
/*!
|
||
|
\return The curve symbol.
|
||
|
\sa setSymbol()
|
||
|
*/
|
||
14 years ago
|
const QwtSymbol& QwtLegendItem::symbol() const
|
||
|
{
|
||
|
return *d_data->symbol;
|
||
15 years ago
|
}
|
||
|
|
||
14 years ago
|
|
||
|
/*!
|
||
15 years ago
|
Set curve pen.
|
||
|
\param pen Curve pen
|
||
|
|
||
|
\sa curvePen()
|
||
|
*/
|
||
14 years ago
|
void QwtLegendItem::setCurvePen(const QPen &pen)
|
||
15 years ago
|
{
|
||
14 years ago
|
if ( pen != d_data->curvePen ) {
|
||
15 years ago
|
d_data->curvePen = pen;
|
||
|
update();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return The curve pen.
|
||
|
\sa setCurvePen()
|
||
|
*/
|
||
14 years ago
|
const QPen& QwtLegendItem::curvePen() const
|
||
|
{
|
||
|
return d_data->curvePen;
|
||
15 years ago
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Paint the identifier to a given rect.
|
||
|
\param painter Painter
|
||
|
\param rect Rect where to paint
|
||
|
*/
|
||
|
void QwtLegendItem::drawIdentifier(
|
||
|
QPainter *painter, const QRect &rect) const
|
||
|
{
|
||
|
if ( rect.isEmpty() )
|
||
|
return;
|
||
|
|
||
14 years ago
|
if ( (d_data->identifierMode & ShowLine ) && (d_data->curvePen.style() != Qt::NoPen) ) {
|
||
15 years ago
|
painter->save();
|
||
|
painter->setPen(d_data->curvePen);
|
||
14 years ago
|
QwtPainter::drawLine(painter, rect.left(), rect.center().y(),
|
||
|
rect.right(), rect.center().y());
|
||
15 years ago
|
painter->restore();
|
||
|
}
|
||
|
|
||
14 years ago
|
if ( (d_data->identifierMode & ShowSymbol)
|
||
|
&& (d_data->symbol->style() != QwtSymbol::NoSymbol) ) {
|
||
|
QSize symbolSize =
|
||
15 years ago
|
QwtPainter::metricsMap().screenToLayout(d_data->symbol->size());
|
||
|
|
||
|
// scale the symbol size down if it doesn't fit into rect.
|
||
|
|
||
14 years ago
|
if ( rect.width() < symbolSize.width() ) {
|
||
|
const double ratio =
|
||
15 years ago
|
double(symbolSize.width()) / double(rect.width());
|
||
|
symbolSize.setWidth(rect.width());
|
||
|
symbolSize.setHeight(qRound(symbolSize.height() / ratio));
|
||
|
}
|
||
14 years ago
|
if ( rect.height() < symbolSize.height() ) {
|
||
|
const double ratio =
|
||
15 years ago
|
double(symbolSize.width()) / double(rect.width());
|
||
|
symbolSize.setHeight(rect.height());
|
||
|
symbolSize.setWidth(qRound(symbolSize.width() / ratio));
|
||
|
}
|
||
|
|
||
|
QRect symbolRect;
|
||
|
symbolRect.setSize(symbolSize);
|
||
|
symbolRect.moveCenter(rect.center());
|
||
|
|
||
|
painter->save();
|
||
|
painter->setBrush(d_data->symbol->brush());
|
||
|
painter->setPen(d_data->symbol->pen());
|
||
|
d_data->symbol->draw(painter, symbolRect);
|
||
|
painter->restore();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Draw the legend item to a given rect.
|
||
|
\param painter Painter
|
||
|
\param rect Rect where to paint the button
|
||
|
*/
|
||
|
|
||
|
void QwtLegendItem::drawItem(QPainter *painter, const QRect &rect) const
|
||
|
{
|
||
|
painter->save();
|
||
|
|
||
|
const QwtMetricsMap &map = QwtPainter::metricsMap();
|
||
|
|
||
|
const int m = map.screenToLayoutX(margin());
|
||
|
const int spacing = map.screenToLayoutX(d_data->spacing);
|
||
|
const int identifierWidth = map.screenToLayoutX(d_data->identifierWidth);
|
||
|
|
||
14 years ago
|
const QRect identifierRect(rect.x() + m, rect.y(),
|
||
|
identifierWidth, rect.height());
|
||
15 years ago
|
drawIdentifier(painter, identifierRect);
|
||
|
|
||
|
// Label
|
||
|
|
||
|
QRect titleRect = rect;
|
||
|
titleRect.setX(identifierRect.right() + 2 * spacing);
|
||
14 years ago
|
|
||
15 years ago
|
text().draw(painter, titleRect);
|
||
|
|
||
|
painter->restore();
|
||
|
}
|
||
|
|
||
|
//! Paint event
|
||
|
void QwtLegendItem::paintEvent(QPaintEvent *e)
|
||
|
{
|
||
|
const QRect cr = contentsRect();
|
||
|
|
||
|
QPainter painter(this);
|
||
|
painter.setClipRegion(e->region());
|
||
|
|
||
14 years ago
|
if ( d_data->isDown ) {
|
||
|
qDrawWinButton(&painter, 0, 0, width(), height(),
|
||
15 years ago
|
#if QT_VERSION < 0x040000
|
||
14 years ago
|
colorGroup(),
|
||
15 years ago
|
#else
|
||
14 years ago
|
palette(),
|
||
15 years ago
|
#endif
|
||
14 years ago
|
true);
|
||
15 years ago
|
}
|
||
|
|
||
|
painter.save();
|
||
|
|
||
14 years ago
|
if ( d_data->isDown ) {
|
||
15 years ago
|
const QSize shiftSize = buttonShift(this);
|
||
|
painter.translate(shiftSize.width(), shiftSize.height());
|
||
|
}
|
||
|
|
||
|
painter.setClipRect(cr);
|
||
|
|
||
|
drawContents(&painter);
|
||
|
|
||
|
QRect rect = cr;
|
||
|
rect.setX(rect.x() + margin());
|
||
|
if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
|
||
|
rect.setX(rect.x() + ButtonFrame);
|
||
|
|
||
|
rect.setWidth(d_data->identifierWidth);
|
||
|
|
||
|
drawIdentifier(&painter, rect);
|
||
|
|
||
|
painter.restore();
|
||
|
}
|
||
|
|
||
|
//! Handle mouse press events
|
||
|
void QwtLegendItem::mousePressEvent(QMouseEvent *e)
|
||
|
{
|
||
14 years ago
|
if ( e->button() == Qt::LeftButton ) {
|
||
|
switch(d_data->itemMode) {
|
||
|
case QwtLegend::ClickableItem: {
|
||
|
setDown(true);
|
||
|
return;
|
||
|
}
|
||
|
case QwtLegend::CheckableItem: {
|
||
|
setDown(!isDown());
|
||
|
return;
|
||
|
}
|
||
|
default:
|
||
|
;
|
||
15 years ago
|
}
|
||
|
}
|
||
|
QwtTextLabel::mousePressEvent(e);
|
||
|
}
|
||
|
|
||
|
//! Handle mouse release events
|
||
|
void QwtLegendItem::mouseReleaseEvent(QMouseEvent *e)
|
||
|
{
|
||
14 years ago
|
if ( e->button() == Qt::LeftButton ) {
|
||
|
switch(d_data->itemMode) {
|
||
|
case QwtLegend::ClickableItem: {
|
||
|
setDown(false);
|
||
|
return;
|
||
|
}
|
||
|
case QwtLegend::CheckableItem: {
|
||
|
return; // do nothing, but accept
|
||
|
}
|
||
|
default:
|
||
|
;
|
||
15 years ago
|
}
|
||
|
}
|
||
|
QwtTextLabel::mouseReleaseEvent(e);
|
||
|
}
|
||
|
|
||
|
//! Handle key press events
|
||
|
void QwtLegendItem::keyPressEvent(QKeyEvent *e)
|
||
|
{
|
||
14 years ago
|
if ( e->key() == Qt::Key_Space ) {
|
||
|
switch(d_data->itemMode) {
|
||
|
case QwtLegend::ClickableItem: {
|
||
|
if ( !e->isAutoRepeat() )
|
||
|
setDown(true);
|
||
|
return;
|
||
|
}
|
||
|
case QwtLegend::CheckableItem: {
|
||
|
if ( !e->isAutoRepeat() )
|
||
|
setDown(!isDown());
|
||
|
return;
|
||
|
}
|
||
|
default:
|
||
|
;
|
||
15 years ago
|
}
|
||
|
}
|
||
|
|
||
|
QwtTextLabel::keyPressEvent(e);
|
||
|
}
|
||
|
|
||
|
//! Handle key release events
|
||
|
void QwtLegendItem::keyReleaseEvent(QKeyEvent *e)
|
||
|
{
|
||
14 years ago
|
if ( e->key() == Qt::Key_Space ) {
|
||
|
switch(d_data->itemMode) {
|
||
|
case QwtLegend::ClickableItem: {
|
||
|
if ( !e->isAutoRepeat() )
|
||
|
setDown(false);
|
||
|
return;
|
||
|
}
|
||
|
case QwtLegend::CheckableItem: {
|
||
|
return; // do nothing, but accept
|
||
|
}
|
||
|
default:
|
||
|
;
|
||
15 years ago
|
}
|
||
|
}
|
||
|
|
||
|
QwtTextLabel::keyReleaseEvent(e);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Check/Uncheck a the item
|
||
|
|
||
|
\param on check/uncheck
|
||
|
\sa setItemMode()
|
||
|
*/
|
||
|
void QwtLegendItem::setChecked(bool on)
|
||
|
{
|
||
14 years ago
|
if ( d_data->itemMode == QwtLegend::CheckableItem ) {
|
||
15 years ago
|
const bool isBlocked = signalsBlocked();
|
||
|
blockSignals(true);
|
||
|
|
||
|
setDown(on);
|
||
|
|
||
|
blockSignals(isBlocked);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//! Return true, if the item is checked
|
||
|
bool QwtLegendItem::isChecked() const
|
||
|
{
|
||
|
return d_data->itemMode == QwtLegend::CheckableItem && isDown();
|
||
|
}
|
||
|
|
||
|
//! Set the item being down
|
||
|
void QwtLegendItem::setDown(bool down)
|
||
|
{
|
||
|
if ( down == d_data->isDown )
|
||
|
return;
|
||
|
|
||
|
d_data->isDown = down;
|
||
|
update();
|
||
|
|
||
14 years ago
|
if ( d_data->itemMode == QwtLegend::ClickableItem ) {
|
||
15 years ago
|
if ( d_data->isDown )
|
||
|
emit pressed();
|
||
14 years ago
|
else {
|
||
15 years ago
|
emit released();
|
||
|
emit clicked();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( d_data->itemMode == QwtLegend::CheckableItem )
|
||
|
emit checked(d_data->isDown);
|
||
|
}
|
||
|
|
||
|
//! Return true, if the item is down
|
||
|
bool QwtLegendItem::isDown() const
|
||
|
{
|
||
|
return d_data->isDown;
|
||
|
}
|
||
|
|
||
|
//! Return a size hint
|
||
|
QSize QwtLegendItem::sizeHint() const
|
||
|
{
|
||
|
QSize sz = QwtTextLabel::sizeHint();
|
||
|
if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
|
||
|
sz += buttonShift(this);
|
||
|
|
||
|
return sz;
|
||
|
}
|
||
|
|
||
|
void QwtLegendItem::drawText(QPainter *painter, const QRect &rect)
|
||
|
{
|
||
|
QwtTextLabel::drawText(painter, rect);
|
||
|
}
|