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_text.h"
00021 #include "qwt_painter.h"
00022 #include "qwt_symbol.h"
00023 #include "qwt_legend_item.h"
00024
00025 static const int IdentifierWidth = 8;
00026 static const int Margin = 2;
00027 static const int ButtonFrame = 2;
00028
00029 static QSize buttonShift(const QwtLegendItem *w)
00030 {
00031 #if QT_VERSION < 0x040000
00032 const int ph = w->style().pixelMetric(
00033 QStyle::PM_ButtonShiftHorizontal, w);
00034 const int pv = w->style().pixelMetric(
00035 QStyle::PM_ButtonShiftVertical, w);
00036 #else
00037 QStyleOption option;
00038 option.init(w);
00039
00040 const int ph = w->style()->pixelMetric(
00041 QStyle::PM_ButtonShiftHorizontal, &option, w);
00042 const int pv = w->style()->pixelMetric(
00043 QStyle::PM_ButtonShiftVertical, &option, w);
00044 #endif
00045 return QSize(ph, pv);
00046 }
00047
00048 class QwtLegendItem::PrivateData
00049 {
00050 public:
00051 PrivateData():
00052 itemMode(QwtLegend::ReadOnlyItem),
00053 isDown(false),
00054 identifierMode(QwtLegendItem::ShowLine | QwtLegendItem::ShowText),
00055 curvePen(Qt::NoPen)
00056 {
00057 }
00058
00059 QwtLegend::LegendItemMode itemMode;
00060 bool isDown;
00061
00062 int identifierMode;
00063 QwtSymbol symbol;
00064 QPen curvePen;
00065 };
00066
00071 QwtLegendItem::QwtLegendItem(QWidget *parent):
00072 QLabel(parent)
00073 {
00074 d_data = new PrivateData;
00075
00076 init();
00077 }
00078
00086 QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol,
00087 const QPen &curvePen, const QString &text,
00088 QWidget *parent):
00089 QLabel(text, parent)
00090 {
00091 d_data = new PrivateData;
00092
00093 d_data->symbol = symbol;
00094 d_data->curvePen = curvePen;
00095
00096 init();
00097 }
00098
00099 void QwtLegendItem::init()
00100 {
00101 #if QT_VERSION < 0x040000
00102 setAlignment(Qt::AlignLeft | Qt::AlignVCenter
00103 | Qt::ExpandTabs | Qt::WordBreak);
00104 #else
00105
00106 setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
00107 setWordWrap(true);
00108 #endif
00109
00110 setIndent(Margin + IdentifierWidth + 2 * Margin);
00111 setMargin(Margin);
00112 }
00113
00114 QwtLegendItem::~QwtLegendItem()
00115 {
00116 delete d_data;
00117 d_data = NULL;
00118 }
00119
00120 void QwtLegendItem::setItemMode(QwtLegend::LegendItemMode mode)
00121 {
00122 d_data->itemMode = mode;
00123 d_data->isDown = false;
00124
00125 #if QT_VERSION >= 0x040000
00126 using namespace Qt;
00127 #endif
00128 setFocusPolicy(mode != QwtLegend::ReadOnlyItem ? TabFocus : NoFocus);
00129 setMargin(Margin + ButtonFrame);
00130
00131 updateGeometry();
00132 }
00133
00134 QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
00135 {
00136 return d_data->itemMode;
00137 }
00138
00145 void QwtLegendItem::setTitle(const QString &title)
00146 {
00147 setText(title);
00148 }
00149
00154 QString QwtLegendItem::title() const
00155 {
00156 return text();
00157 }
00158
00163 QwtText *QwtLegendItem::titleText() const
00164 {
00165 return QwtText::makeText(text(), textFormat(),
00166 alignment(), font());
00167 }
00168
00176 void QwtLegendItem::setIdentifierMode(int mode)
00177 {
00178 if ( mode != d_data->identifierMode )
00179 {
00180 d_data->identifierMode = mode;
00181 update();
00182 }
00183 }
00184
00189 int QwtLegendItem::identifierMode() const
00190 {
00191 return d_data->identifierMode;
00192 }
00193
00200 void QwtLegendItem::setSymbol(const QwtSymbol &symbol)
00201 {
00202 if ( symbol != d_data->symbol )
00203 {
00204 d_data->symbol = symbol;
00205 update();
00206 }
00207 }
00208
00213 const QwtSymbol& QwtLegendItem::symbol() const
00214 {
00215 return d_data->symbol;
00216 }
00217
00218
00225 void QwtLegendItem::setCurvePen(const QPen &pen)
00226 {
00227 if ( pen != d_data->curvePen )
00228 {
00229 d_data->curvePen = pen;
00230 update();
00231 }
00232 }
00233
00238 const QPen& QwtLegendItem::curvePen() const
00239 {
00240 return d_data->curvePen;
00241 }
00242
00248 void QwtLegendItem::drawIdentifier(
00249 QPainter *painter, const QRect &rect) const
00250 {
00251 if ( rect.isEmpty() )
00252 return;
00253
00254 if ( (d_data->identifierMode & ShowLine ) && (d_data->curvePen.style() != Qt::NoPen) )
00255 {
00256 painter->save();
00257 painter->setPen(d_data->curvePen);
00258 QwtPainter::drawLine(painter, rect.left(), rect.center().y(),
00259 rect.right(), rect.center().y());
00260 painter->restore();
00261 }
00262
00263 if ( (d_data->identifierMode & ShowSymbol)
00264 && (d_data->symbol.style() != QwtSymbol::None) )
00265 {
00266 QSize symbolSize =
00267 QwtPainter::metricsMap().screenToLayout(d_data->symbol.size());
00268
00269
00270
00271 if ( rect.width() < symbolSize.width() )
00272 {
00273 const double ratio =
00274 double(symbolSize.width()) / double(rect.width());
00275 symbolSize.setWidth(rect.width());
00276 symbolSize.setHeight(qRound(symbolSize.height() / ratio));
00277 }
00278 if ( rect.height() < symbolSize.height() )
00279 {
00280 const double ratio =
00281 double(symbolSize.width()) / double(rect.width());
00282 symbolSize.setHeight(rect.height());
00283 symbolSize.setWidth(qRound(symbolSize.width() / ratio));
00284 }
00285
00286 QRect symbolRect;
00287 symbolRect.setSize(symbolSize);
00288 symbolRect.moveCenter(rect.center());
00289
00290 painter->save();
00291 painter->setBrush(d_data->symbol.brush());
00292 painter->setPen(d_data->symbol.pen());
00293 d_data->symbol.draw(painter, symbolRect);
00294 painter->restore();
00295 }
00296 }
00297
00304 void QwtLegendItem::drawItem(QPainter *painter, const QRect &rect) const
00305 {
00306 painter->save();
00307
00308 const QwtMetricsMap &map = QwtPainter::metricsMap();
00309
00310 const int margin = map.screenToLayoutX(Margin);
00311
00312 const QRect identifierRect(rect.x() + margin, rect.y(),
00313 map.screenToLayoutX(IdentifierWidth), rect.height());
00314 drawIdentifier(painter, identifierRect);
00315
00316
00317
00318 QwtText *txt = titleText();
00319 if ( txt )
00320 {
00321 QRect titleRect = rect;
00322 titleRect.setX(identifierRect.right() + 2 * margin);
00323
00324 txt->draw(painter, titleRect);
00325 delete txt;
00326 }
00327 painter->restore();
00328 }
00329
00330 void QwtLegendItem::paintEvent(QPaintEvent *e)
00331 {
00332 const QRect cr = contentsRect();
00333
00334 #if QT_VERSION >= 0x040000
00335 QLabel::paintEvent(e);
00336 #endif
00337
00338 QPainter painter(this);
00339 painter.setClipRegion(e->region());
00340
00341 if ( d_data->isDown )
00342 {
00343 qDrawWinButton(&painter, 0, 0, width(), height(),
00344 #if QT_VERSION < 0x040000
00345 colorGroup(),
00346 #else
00347 palette(),
00348 #endif
00349 true);
00350 }
00351
00352 painter.save();
00353
00354 if ( d_data->isDown )
00355 {
00356 const QSize shiftSize = buttonShift(this);
00357 painter.translate(shiftSize.width(), shiftSize.height());
00358 }
00359
00360 painter.setClipRect(cr);
00361
00362 #if QT_VERSION < 0x040000
00363 QLabel::drawContents(&painter);
00364 #endif
00365
00366 QRect rect = cr;
00367 rect.setX(rect.x() + Margin);
00368 if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00369 rect.setX(rect.x() + ButtonFrame);
00370
00371 rect.setWidth(IdentifierWidth);
00372
00373 drawIdentifier(&painter, rect);
00374
00375 painter.restore();
00376
00377 if ( hasFocus() )
00378 {
00379 #if QT_VERSION < 0x040000
00380 painter.drawWinFocusRect(cr);
00381 #else
00382 QStyleOptionFocusRect option;
00383 option.init(this);
00384 option.backgroundColor = palette().color(QPalette::Background);
00385
00386 const int m = Margin + ButtonFrame;
00387 option.rect = QRect( cr.x() + Margin, cr.y() + m,
00388 cr.width() - 2 * m, cr.height() - 2 * m);
00389
00390 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option,
00391 &painter, this);
00392 #endif
00393 }
00394 }
00395
00396 void QwtLegendItem::mousePressEvent(QMouseEvent *e)
00397 {
00398 if ( e->button() != Qt::LeftButton )
00399 return;
00400
00401 switch(d_data->itemMode)
00402 {
00403 case QwtLegend::ClickableItem:
00404 {
00405 setDown(true);
00406 break;
00407 }
00408 case QwtLegend::CheckableItem:
00409 {
00410 setDown(!isDown());
00411 break;
00412 }
00413 default:;
00414 }
00415 }
00416
00417 void QwtLegendItem::mouseReleaseEvent(QMouseEvent *e)
00418 {
00419 if ( !e->button() == Qt::LeftButton )
00420 return;
00421
00422 if ( d_data->itemMode == QwtLegend::ClickableItem )
00423 setDown(false);
00424 }
00425
00426 void QwtLegendItem::keyPressEvent(QKeyEvent *e)
00427 {
00428 if ( e->key() != Qt::Key_Space || e->isAutoRepeat() )
00429 return;
00430
00431 switch(d_data->itemMode)
00432 {
00433 case QwtLegend::ClickableItem:
00434 {
00435 setDown(true);
00436 break;
00437 }
00438 case QwtLegend::CheckableItem:
00439 {
00440 setDown(!isDown());
00441 break;
00442 }
00443 default:;
00444 }
00445 }
00446
00447 void QwtLegendItem::keyReleaseEvent(QKeyEvent *e)
00448 {
00449 if ( e->key() != Qt::Key_Space || e->isAutoRepeat() )
00450 return;
00451
00452 if ( d_data->itemMode == QwtLegend::ClickableItem )
00453 setDown(false);
00454 }
00455
00456 void QwtLegendItem::setChecked(bool on)
00457 {
00458 if ( d_data->itemMode == QwtLegend::CheckableItem )
00459 {
00460 const bool isBlocked = signalsBlocked();
00461 blockSignals(true);
00462
00463 setDown(on);
00464
00465 blockSignals(isBlocked);
00466 }
00467 }
00468
00469 bool QwtLegendItem::isChecked() const
00470 {
00471 return d_data->itemMode == QwtLegend::CheckableItem && isDown();
00472 }
00473
00474 void QwtLegendItem::setDown(bool down)
00475 {
00476 if ( down == d_data->isDown )
00477 return;
00478
00479 d_data->isDown = down;
00480 update();
00481
00482 if ( d_data->itemMode == QwtLegend::ClickableItem )
00483 {
00484 if ( d_data->isDown )
00485 emit pressed();
00486 else
00487 {
00488 emit released();
00489 emit clicked();
00490 }
00491 }
00492
00493 if ( d_data->itemMode == QwtLegend::CheckableItem )
00494 emit checked(d_data->isDown);
00495 }
00496
00497 bool QwtLegendItem::isDown() const
00498 {
00499 return d_data->isDown;
00500 }
00501
00502 QSize QwtLegendItem::sizeHint() const
00503 {
00504 QSize sz = QLabel::sizeHint();
00505 if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00506 sz += buttonShift(this);
00507
00508 return sz;
00509 }