Newer
Older
/* -*- 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
*****************************************************************************/
// 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(
QStyle::PM_ButtonShiftHorizontal, w);
QStyle::PM_ButtonShiftVertical, w);
#else
QStyleOption option;
option.init(w);
const int ph = w->style()->pixelMetric(
QStyle::PM_ButtonShiftHorizontal, &option, w);
QStyle::PM_ButtonShiftVertical, &option, w);
#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),
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
*/
QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol,
const QPen &curvePen, const QwtText &text,
QWidget *parent):
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
| Qt::TextExpandTabs | Qt::TextWordWrap;
#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()
*/
void QwtLegendItem::setItemMode(QwtLegend::LegendItemMode mode)
{
d_data->itemMode = mode;
d_data->isDown = false;
#if QT_VERSION >= 0x040000
using namespace Qt;
#endif
setFocusPolicy(mode != QwtLegend::ReadOnlyItem ? TabFocus : NoFocus);
setMargin(ButtonFrame + Margin);
updateGeometry();
}
QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
{
return d_data->itemMode;
}
/*!
Set identifier mode.
Default is ShowLine | ShowText.
\param mode Or'd values of IdentifierMode
\sa identifierMode()
*/
void QwtLegendItem::setIdentifierMode(int mode)
{
if ( mode != d_data->identifierMode ) {
d_data->identifierMode = mode;
update();
}
}
/*!
Or'd values of IdentifierMode.
\sa setIdentifierMode(), IdentifierMode
*/
int QwtLegendItem::identifierMode() const
{
return d_data->identifierMode;
}
/*!
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);
if ( width != d_data->identifierWidth ) {
setIndent(margin() + d_data->identifierWidth
+ 2 * d_data->spacing);
}
}
/*!
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);
if ( spacing != d_data->spacing ) {
setIndent(margin() + d_data->identifierWidth
+ 2 * d_data->spacing);
}
}
/*!
Return the spacing
\sa setSpacing(), identifierWidth(), QwtTextLabel::margin()
*/
int QwtLegendItem::spacing() const
{
return d_data->spacing;
}
Set curve symbol.
\param symbol Symbol
\sa symbol()
*/
void QwtLegendItem::setSymbol(const QwtSymbol &symbol)
{
delete d_data->symbol;
d_data->symbol = symbol.clone();
update();
}
const QwtSymbol& QwtLegendItem::symbol() const
{
return *d_data->symbol;
Set curve pen.
\param pen Curve pen
\sa curvePen()
*/
void QwtLegendItem::setCurvePen(const QPen &pen)
d_data->curvePen = pen;
update();
}
}
/*!
\return The curve pen.
\sa setCurvePen()
*/
const QPen& QwtLegendItem::curvePen() const
{
return d_data->curvePen;
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;
if ( (d_data->identifierMode & ShowLine ) && (d_data->curvePen.style() != Qt::NoPen) ) {
QwtPainter::drawLine(painter, rect.left(), rect.center().y(),
rect.right(), rect.center().y());
if ( (d_data->identifierMode & ShowSymbol)
&& (d_data->symbol->style() != QwtSymbol::NoSymbol) ) {
QSize symbolSize =
QwtPainter::metricsMap().screenToLayout(d_data->symbol->size());
// scale the symbol size down if it doesn't fit into rect.
if ( rect.width() < symbolSize.width() ) {
const double ratio =
double(symbolSize.width()) / double(rect.width());
symbolSize.setWidth(rect.width());
symbolSize.setHeight(qRound(symbolSize.height() / ratio));
}
if ( rect.height() < symbolSize.height() ) {
const double ratio =
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
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);
const QRect identifierRect(rect.x() + m, rect.y(),
identifierWidth, rect.height());
drawIdentifier(painter, identifierRect);
// Label
QRect titleRect = rect;
titleRect.setX(identifierRect.right() + 2 * spacing);
text().draw(painter, titleRect);
painter->restore();
}
//! Paint event
void QwtLegendItem::paintEvent(QPaintEvent *e)
{
const QRect cr = contentsRect();
QPainter painter(this);
painter.setClipRegion(e->region());
if ( d_data->isDown ) {
qDrawWinButton(&painter, 0, 0, width(), height(),
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)
{
if ( e->button() == Qt::LeftButton ) {
switch(d_data->itemMode) {
case QwtLegend::ClickableItem: {
setDown(true);
return;
}
case QwtLegend::CheckableItem: {
setDown(!isDown());
return;
}
default:
;
}
}
QwtTextLabel::mousePressEvent(e);
}
//! Handle mouse release events
void QwtLegendItem::mouseReleaseEvent(QMouseEvent *e)
{
if ( e->button() == Qt::LeftButton ) {
switch(d_data->itemMode) {
case QwtLegend::ClickableItem: {
setDown(false);
return;
}
case QwtLegend::CheckableItem: {
return; // do nothing, but accept
}
default:
;
}
}
QwtTextLabel::mouseReleaseEvent(e);
}
//! Handle key press events
void QwtLegendItem::keyPressEvent(QKeyEvent *e)
{
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:
;
}
}
QwtTextLabel::keyPressEvent(e);
}
//! Handle key release events
void QwtLegendItem::keyReleaseEvent(QKeyEvent *e)
{
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:
;
}
}
QwtTextLabel::keyReleaseEvent(e);
}
/*!
Check/Uncheck a the item
\param on check/uncheck
\sa setItemMode()
*/
void QwtLegendItem::setChecked(bool on)
{
if ( d_data->itemMode == QwtLegend::CheckableItem ) {
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();
if ( d_data->itemMode == QwtLegend::ClickableItem ) {
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
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);
}