00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qpainter.h>
00013 #include <qdrawutil.h>
00014 #include <qstyle.h>
00015 #include <qpen.h>
00016 #if QT_VERSION >= 0x040000
00017 #include <qevent.h>
00018 #include <qstyleoption.h>
00019 #endif
00020 #include "qwt_math.h"
00021 #include "qwt_painter.h"
00022 #include "qwt_symbol.h"
00023 #include "qwt_legend_item.h"
00024
00025 static const int ButtonFrame = 2;
00026 static const int Margin = 2;
00027
00028 static QSize buttonShift(const QwtLegendItem *w)
00029 {
00030 #if QT_VERSION < 0x040000
00031 const int ph = w->style().pixelMetric(
00032 QStyle::PM_ButtonShiftHorizontal, w);
00033 const int pv = w->style().pixelMetric(
00034 QStyle::PM_ButtonShiftVertical, w);
00035 #else
00036 QStyleOption option;
00037 option.init(w);
00038
00039 const int ph = w->style()->pixelMetric(
00040 QStyle::PM_ButtonShiftHorizontal, &option, w);
00041 const int pv = w->style()->pixelMetric(
00042 QStyle::PM_ButtonShiftVertical, &option, w);
00043 #endif
00044 return QSize(ph, pv);
00045 }
00046
00047 class QwtLegendItem::PrivateData
00048 {
00049 public:
00050 PrivateData():
00051 itemMode(QwtLegend::ReadOnlyItem),
00052 isDown(false),
00053 identifierWidth(8),
00054 identifierMode(QwtLegendItem::ShowLine | QwtLegendItem::ShowText),
00055 curvePen(Qt::NoPen),
00056 spacing(Margin)
00057 {
00058 }
00059
00060 QwtLegend::LegendItemMode itemMode;
00061 bool isDown;
00062
00063 int identifierWidth;
00064 int identifierMode;
00065 QwtSymbol symbol;
00066 QPen curvePen;
00067
00068 int spacing;
00069 };
00070
00074 QwtLegendItem::QwtLegendItem(QWidget *parent):
00075 QwtTextLabel(parent)
00076 {
00077 d_data = new PrivateData;
00078 init(QwtText());
00079 }
00080
00087 QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol,
00088 const QPen &curvePen, const QwtText &text,
00089 QWidget *parent):
00090 QwtTextLabel(parent)
00091 {
00092 d_data = new PrivateData;
00093
00094 d_data->symbol = symbol;
00095 d_data->curvePen = curvePen;
00096
00097 init(text);
00098 }
00099
00100 void QwtLegendItem::init(const QwtText &text)
00101 {
00102 setMargin(Margin);
00103 setIndent(margin() + d_data->identifierWidth + 2 * d_data->spacing);
00104 setText(text);
00105 }
00106
00108 QwtLegendItem::~QwtLegendItem()
00109 {
00110 delete d_data;
00111 d_data = NULL;
00112 }
00113
00120 void QwtLegendItem::setText(const QwtText &text)
00121 {
00122 const int flags = Qt::AlignLeft | Qt::AlignVCenter
00123 #if QT_VERSION < 0x040000
00124 | Qt::WordBreak | Qt::ExpandTabs;
00125 #else
00126 | Qt::TextExpandTabs | Qt::TextWordWrap;
00127 #endif
00128
00129 QwtText txt = text;
00130 txt.setRenderFlags(flags);
00131
00132 QwtTextLabel::setText(txt);
00133 }
00134
00142 void QwtLegendItem::setItemMode(QwtLegend::LegendItemMode mode)
00143 {
00144 d_data->itemMode = mode;
00145 d_data->isDown = false;
00146
00147 #if QT_VERSION >= 0x040000
00148 using namespace Qt;
00149 #endif
00150 setFocusPolicy(mode != QwtLegend::ReadOnlyItem ? TabFocus : NoFocus);
00151 setMargin(ButtonFrame + Margin);
00152
00153 updateGeometry();
00154 }
00155
00161 QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
00162 {
00163 return d_data->itemMode;
00164 }
00165
00173 void QwtLegendItem::setIdentifierMode(int mode)
00174 {
00175 if ( mode != d_data->identifierMode )
00176 {
00177 d_data->identifierMode = mode;
00178 update();
00179 }
00180 }
00181
00186 int QwtLegendItem::identifierMode() const
00187 {
00188 return d_data->identifierMode;
00189 }
00190
00199 void QwtLegendItem::setIdentfierWidth(int width)
00200 {
00201 width = qwtMax(width, 0);
00202 if ( width != d_data->identifierWidth )
00203 {
00204 d_data->identifierWidth = width;
00205 setIndent(margin() + d_data->identifierWidth
00206 + 2 * d_data->spacing);
00207 }
00208 }
00214 int QwtLegendItem::identifierWidth() const
00215 {
00216 return d_data->identifierWidth;
00217 }
00218
00224 void QwtLegendItem::setSpacing(int spacing)
00225 {
00226 spacing = qwtMax(spacing, 0);
00227 if ( spacing != d_data->spacing )
00228 {
00229 d_data->spacing = spacing;
00230 setIndent(margin() + d_data->identifierWidth
00231 + 2 * d_data->spacing);
00232 }
00233 }
00234
00239 int QwtLegendItem::spacing() const
00240 {
00241 return d_data->spacing;
00242 }
00243
00250 void QwtLegendItem::setSymbol(const QwtSymbol &symbol)
00251 {
00252 if ( symbol != d_data->symbol )
00253 {
00254 d_data->symbol = symbol;
00255 update();
00256 }
00257 }
00258
00263 const QwtSymbol& QwtLegendItem::symbol() const
00264 {
00265 return d_data->symbol;
00266 }
00267
00268
00275 void QwtLegendItem::setCurvePen(const QPen &pen)
00276 {
00277 if ( pen != d_data->curvePen )
00278 {
00279 d_data->curvePen = pen;
00280 update();
00281 }
00282 }
00283
00288 const QPen& QwtLegendItem::curvePen() const
00289 {
00290 return d_data->curvePen;
00291 }
00292
00298 void QwtLegendItem::drawIdentifier(
00299 QPainter *painter, const QRect &rect) const
00300 {
00301 if ( rect.isEmpty() )
00302 return;
00303
00304 if ( (d_data->identifierMode & ShowLine ) && (d_data->curvePen.style() != Qt::NoPen) )
00305 {
00306 painter->save();
00307 painter->setPen(d_data->curvePen);
00308 QwtPainter::drawLine(painter, rect.left(), rect.center().y(),
00309 rect.right(), rect.center().y());
00310 painter->restore();
00311 }
00312
00313 if ( (d_data->identifierMode & ShowSymbol)
00314 && (d_data->symbol.style() != QwtSymbol::NoSymbol) )
00315 {
00316 QSize symbolSize =
00317 QwtPainter::metricsMap().screenToLayout(d_data->symbol.size());
00318
00319
00320
00321 if ( rect.width() < symbolSize.width() )
00322 {
00323 const double ratio =
00324 double(symbolSize.width()) / double(rect.width());
00325 symbolSize.setWidth(rect.width());
00326 symbolSize.setHeight(qRound(symbolSize.height() / ratio));
00327 }
00328 if ( rect.height() < symbolSize.height() )
00329 {
00330 const double ratio =
00331 double(symbolSize.width()) / double(rect.width());
00332 symbolSize.setHeight(rect.height());
00333 symbolSize.setWidth(qRound(symbolSize.width() / ratio));
00334 }
00335
00336 QRect symbolRect;
00337 symbolRect.setSize(symbolSize);
00338 symbolRect.moveCenter(rect.center());
00339
00340 painter->save();
00341 painter->setBrush(d_data->symbol.brush());
00342 painter->setPen(d_data->symbol.pen());
00343 d_data->symbol.draw(painter, symbolRect);
00344 painter->restore();
00345 }
00346 }
00347
00354 void QwtLegendItem::drawItem(QPainter *painter, const QRect &rect) const
00355 {
00356 painter->save();
00357
00358 const QwtMetricsMap &map = QwtPainter::metricsMap();
00359
00360 const int m = map.screenToLayoutX(margin());
00361 const int spacing = map.screenToLayoutX(d_data->spacing);
00362 const int identifierWidth = map.screenToLayoutX(d_data->identifierWidth);
00363
00364 const QRect identifierRect(rect.x() + m, rect.y(),
00365 identifierWidth, rect.height());
00366 drawIdentifier(painter, identifierRect);
00367
00368
00369
00370 QRect titleRect = rect;
00371 titleRect.setX(identifierRect.right() + 2 * spacing);
00372
00373 text().draw(painter, titleRect);
00374
00375 painter->restore();
00376 }
00377
00378 void QwtLegendItem::paintEvent(QPaintEvent *e)
00379 {
00380 const QRect cr = contentsRect();
00381
00382 QPainter painter(this);
00383 painter.setClipRegion(e->region());
00384
00385 if ( d_data->isDown )
00386 {
00387 qDrawWinButton(&painter, 0, 0, width(), height(),
00388 #if QT_VERSION < 0x040000
00389 colorGroup(),
00390 #else
00391 palette(),
00392 #endif
00393 true);
00394 }
00395
00396 painter.save();
00397
00398 if ( d_data->isDown )
00399 {
00400 const QSize shiftSize = buttonShift(this);
00401 painter.translate(shiftSize.width(), shiftSize.height());
00402 }
00403
00404 painter.setClipRect(cr);
00405
00406 drawContents(&painter);
00407
00408 QRect rect = cr;
00409 rect.setX(rect.x() + margin());
00410 if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00411 rect.setX(rect.x() + ButtonFrame);
00412
00413 rect.setWidth(d_data->identifierWidth);
00414
00415 drawIdentifier(&painter, rect);
00416
00417 painter.restore();
00418 }
00419
00420 void QwtLegendItem::mousePressEvent(QMouseEvent *e)
00421 {
00422 if ( e->button() != Qt::LeftButton )
00423 return;
00424
00425 switch(d_data->itemMode)
00426 {
00427 case QwtLegend::ClickableItem:
00428 {
00429 setDown(true);
00430 break;
00431 }
00432 case QwtLegend::CheckableItem:
00433 {
00434 setDown(!isDown());
00435 break;
00436 }
00437 default:;
00438 }
00439 }
00440
00441 void QwtLegendItem::mouseReleaseEvent(QMouseEvent *e)
00442 {
00443 if ( !e->button() == Qt::LeftButton )
00444 return;
00445
00446 if ( d_data->itemMode == QwtLegend::ClickableItem )
00447 setDown(false);
00448 }
00449
00450 void QwtLegendItem::keyPressEvent(QKeyEvent *e)
00451 {
00452 if ( e->key() != Qt::Key_Space || e->isAutoRepeat() )
00453 return;
00454
00455 switch(d_data->itemMode)
00456 {
00457 case QwtLegend::ClickableItem:
00458 {
00459 setDown(true);
00460 break;
00461 }
00462 case QwtLegend::CheckableItem:
00463 {
00464 setDown(!isDown());
00465 break;
00466 }
00467 default:;
00468 }
00469 }
00470
00471 void QwtLegendItem::keyReleaseEvent(QKeyEvent *e)
00472 {
00473 if ( e->key() != Qt::Key_Space || e->isAutoRepeat() )
00474 return;
00475
00476 if ( d_data->itemMode == QwtLegend::ClickableItem )
00477 setDown(false);
00478 }
00479
00480 void QwtLegendItem::setChecked(bool on)
00481 {
00482 if ( d_data->itemMode == QwtLegend::CheckableItem )
00483 {
00484 const bool isBlocked = signalsBlocked();
00485 blockSignals(true);
00486
00487 setDown(on);
00488
00489 blockSignals(isBlocked);
00490 }
00491 }
00492
00493 bool QwtLegendItem::isChecked() const
00494 {
00495 return d_data->itemMode == QwtLegend::CheckableItem && isDown();
00496 }
00497
00498 void QwtLegendItem::setDown(bool down)
00499 {
00500 if ( down == d_data->isDown )
00501 return;
00502
00503 d_data->isDown = down;
00504 update();
00505
00506 if ( d_data->itemMode == QwtLegend::ClickableItem )
00507 {
00508 if ( d_data->isDown )
00509 emit pressed();
00510 else
00511 {
00512 emit released();
00513 emit clicked();
00514 }
00515 }
00516
00517 if ( d_data->itemMode == QwtLegend::CheckableItem )
00518 emit checked(d_data->isDown);
00519 }
00520
00521 bool QwtLegendItem::isDown() const
00522 {
00523 return d_data->isDown;
00524 }
00525
00526 QSize QwtLegendItem::sizeHint() const
00527 {
00528 QSize sz = QwtTextLabel::sizeHint();
00529 if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00530 sz += buttonShift(this);
00531
00532 return sz;
00533 }
00534
00535 void QwtLegendItem::drawText(QPainter *painter, const QRect &rect)
00536 {
00537 QwtTextLabel::drawText(painter, rect);
00538 }