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_painter.h"
00021 #include "qwt_symbol.h"
00022 #include "qwt_legend_item.h"
00023
00024 static const int IdentifierWidth = 8;
00025 static const int Margin = 2;
00026 static const int ButtonFrame = 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 identifierMode(QwtLegendItem::ShowLine | QwtLegendItem::ShowText),
00054 curvePen(Qt::NoPen)
00055 {
00056 }
00057
00058 QwtLegend::LegendItemMode itemMode;
00059 bool isDown;
00060
00061 int identifierMode;
00062 QwtSymbol symbol;
00063 QPen curvePen;
00064 };
00065
00069 QwtLegendItem::QwtLegendItem(QWidget *parent):
00070 QwtTextLabel(parent)
00071 {
00072 d_data = new PrivateData;
00073 init(QwtText());
00074 }
00075
00082 QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol,
00083 const QPen &curvePen, const QwtText &text,
00084 QWidget *parent):
00085 QwtTextLabel(parent)
00086 {
00087 d_data = new PrivateData;
00088
00089 d_data->symbol = symbol;
00090 d_data->curvePen = curvePen;
00091
00092 init(text);
00093 }
00094
00095 void QwtLegendItem::init(const QwtText &text)
00096 {
00097 setIndent(Margin + IdentifierWidth + 2 * Margin);
00098 setMargin(Margin);
00099 setText(text);
00100 }
00101
00102 QwtLegendItem::~QwtLegendItem()
00103 {
00104 delete d_data;
00105 d_data = NULL;
00106 }
00107
00108 void QwtLegendItem::setText(const QwtText &text)
00109 {
00110 const int flags = Qt::AlignLeft | Qt::AlignVCenter
00111 #if QT_VERSION < 0x040000
00112 | Qt::WordBreak | Qt::ExpandTabs;
00113 #else
00114 | Qt::TextExpandTabs | Qt::TextWordWrap;
00115 #endif
00116
00117 QwtText txt = text;
00118 txt.setFlags(flags);
00119
00120 QwtTextLabel::setText(txt);
00121 }
00122
00123 void QwtLegendItem::setItemMode(QwtLegend::LegendItemMode mode)
00124 {
00125 d_data->itemMode = mode;
00126 d_data->isDown = false;
00127
00128 #if QT_VERSION >= 0x040000
00129 using namespace Qt;
00130 #endif
00131 setFocusPolicy(mode != QwtLegend::ReadOnlyItem ? TabFocus : NoFocus);
00132 setMargin(Margin + ButtonFrame);
00133
00134 updateGeometry();
00135 }
00136
00137 QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
00138 {
00139 return d_data->itemMode;
00140 }
00141
00149 void QwtLegendItem::setIdentifierMode(int mode)
00150 {
00151 if ( mode != d_data->identifierMode )
00152 {
00153 d_data->identifierMode = mode;
00154 update();
00155 }
00156 }
00157
00162 int QwtLegendItem::identifierMode() const
00163 {
00164 return d_data->identifierMode;
00165 }
00166
00173 void QwtLegendItem::setSymbol(const QwtSymbol &symbol)
00174 {
00175 if ( symbol != d_data->symbol )
00176 {
00177 d_data->symbol = symbol;
00178 update();
00179 }
00180 }
00181
00186 const QwtSymbol& QwtLegendItem::symbol() const
00187 {
00188 return d_data->symbol;
00189 }
00190
00191
00198 void QwtLegendItem::setCurvePen(const QPen &pen)
00199 {
00200 if ( pen != d_data->curvePen )
00201 {
00202 d_data->curvePen = pen;
00203 update();
00204 }
00205 }
00206
00211 const QPen& QwtLegendItem::curvePen() const
00212 {
00213 return d_data->curvePen;
00214 }
00215
00221 void QwtLegendItem::drawIdentifier(
00222 QPainter *painter, const QRect &rect) const
00223 {
00224 if ( rect.isEmpty() )
00225 return;
00226
00227 if ( (d_data->identifierMode & ShowLine ) && (d_data->curvePen.style() != Qt::NoPen) )
00228 {
00229 painter->save();
00230 painter->setPen(d_data->curvePen);
00231 QwtPainter::drawLine(painter, rect.left(), rect.center().y(),
00232 rect.right(), rect.center().y());
00233 painter->restore();
00234 }
00235
00236 if ( (d_data->identifierMode & ShowSymbol)
00237 && (d_data->symbol.style() != QwtSymbol::None) )
00238 {
00239 QSize symbolSize =
00240 QwtPainter::metricsMap().screenToLayout(d_data->symbol.size());
00241
00242
00243
00244 if ( rect.width() < symbolSize.width() )
00245 {
00246 const double ratio =
00247 double(symbolSize.width()) / double(rect.width());
00248 symbolSize.setWidth(rect.width());
00249 symbolSize.setHeight(qRound(symbolSize.height() / ratio));
00250 }
00251 if ( rect.height() < symbolSize.height() )
00252 {
00253 const double ratio =
00254 double(symbolSize.width()) / double(rect.width());
00255 symbolSize.setHeight(rect.height());
00256 symbolSize.setWidth(qRound(symbolSize.width() / ratio));
00257 }
00258
00259 QRect symbolRect;
00260 symbolRect.setSize(symbolSize);
00261 symbolRect.moveCenter(rect.center());
00262
00263 painter->save();
00264 painter->setBrush(d_data->symbol.brush());
00265 painter->setPen(d_data->symbol.pen());
00266 d_data->symbol.draw(painter, symbolRect);
00267 painter->restore();
00268 }
00269 }
00270
00277 void QwtLegendItem::drawItem(QPainter *painter, const QRect &rect) const
00278 {
00279 painter->save();
00280
00281 const QwtMetricsMap &map = QwtPainter::metricsMap();
00282
00283 const int margin = map.screenToLayoutX(Margin);
00284
00285 const QRect identifierRect(rect.x() + margin, rect.y(),
00286 map.screenToLayoutX(IdentifierWidth), rect.height());
00287 drawIdentifier(painter, identifierRect);
00288
00289
00290
00291 QRect titleRect = rect;
00292 titleRect.setX(identifierRect.right() + 2 * margin);
00293
00294 text().draw(painter, titleRect);
00295
00296 painter->restore();
00297 }
00298
00299 void QwtLegendItem::paintEvent(QPaintEvent *e)
00300 {
00301 const QRect cr = contentsRect();
00302
00303 QPainter painter(this);
00304 painter.setClipRegion(e->region());
00305
00306 if ( d_data->isDown )
00307 {
00308 qDrawWinButton(&painter, 0, 0, width(), height(),
00309 #if QT_VERSION < 0x040000
00310 colorGroup(),
00311 #else
00312 palette(),
00313 #endif
00314 true);
00315 }
00316
00317 painter.save();
00318
00319 if ( d_data->isDown )
00320 {
00321 const QSize shiftSize = buttonShift(this);
00322 painter.translate(shiftSize.width(), shiftSize.height());
00323 }
00324
00325 painter.setClipRect(cr);
00326
00327 drawContents(&painter);
00328
00329 QRect rect = cr;
00330 rect.setX(rect.x() + Margin);
00331 if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00332 rect.setX(rect.x() + ButtonFrame);
00333
00334 rect.setWidth(IdentifierWidth);
00335
00336 drawIdentifier(&painter, rect);
00337
00338 painter.restore();
00339 }
00340
00341 void QwtLegendItem::mousePressEvent(QMouseEvent *e)
00342 {
00343 if ( e->button() != Qt::LeftButton )
00344 return;
00345
00346 switch(d_data->itemMode)
00347 {
00348 case QwtLegend::ClickableItem:
00349 {
00350 setDown(true);
00351 break;
00352 }
00353 case QwtLegend::CheckableItem:
00354 {
00355 setDown(!isDown());
00356 break;
00357 }
00358 default:;
00359 }
00360 }
00361
00362 void QwtLegendItem::mouseReleaseEvent(QMouseEvent *e)
00363 {
00364 if ( !e->button() == Qt::LeftButton )
00365 return;
00366
00367 if ( d_data->itemMode == QwtLegend::ClickableItem )
00368 setDown(false);
00369 }
00370
00371 void QwtLegendItem::keyPressEvent(QKeyEvent *e)
00372 {
00373 if ( e->key() != Qt::Key_Space || e->isAutoRepeat() )
00374 return;
00375
00376 switch(d_data->itemMode)
00377 {
00378 case QwtLegend::ClickableItem:
00379 {
00380 setDown(true);
00381 break;
00382 }
00383 case QwtLegend::CheckableItem:
00384 {
00385 setDown(!isDown());
00386 break;
00387 }
00388 default:;
00389 }
00390 }
00391
00392 void QwtLegendItem::keyReleaseEvent(QKeyEvent *e)
00393 {
00394 if ( e->key() != Qt::Key_Space || e->isAutoRepeat() )
00395 return;
00396
00397 if ( d_data->itemMode == QwtLegend::ClickableItem )
00398 setDown(false);
00399 }
00400
00401 void QwtLegendItem::setChecked(bool on)
00402 {
00403 if ( d_data->itemMode == QwtLegend::CheckableItem )
00404 {
00405 const bool isBlocked = signalsBlocked();
00406 blockSignals(true);
00407
00408 setDown(on);
00409
00410 blockSignals(isBlocked);
00411 }
00412 }
00413
00414 bool QwtLegendItem::isChecked() const
00415 {
00416 return d_data->itemMode == QwtLegend::CheckableItem && isDown();
00417 }
00418
00419 void QwtLegendItem::setDown(bool down)
00420 {
00421 if ( down == d_data->isDown )
00422 return;
00423
00424 d_data->isDown = down;
00425 update();
00426
00427 if ( d_data->itemMode == QwtLegend::ClickableItem )
00428 {
00429 if ( d_data->isDown )
00430 emit pressed();
00431 else
00432 {
00433 emit released();
00434 emit clicked();
00435 }
00436 }
00437
00438 if ( d_data->itemMode == QwtLegend::CheckableItem )
00439 emit checked(d_data->isDown);
00440 }
00441
00442 bool QwtLegendItem::isDown() const
00443 {
00444 return d_data->isDown;
00445 }
00446
00447 QSize QwtLegendItem::sizeHint() const
00448 {
00449 QSize sz = QwtTextLabel::sizeHint();
00450 if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00451 sz += buttonShift(this);
00452
00453 return sz;
00454 }
00455
00456 void QwtLegendItem::drawText(QPainter *painter, const QRect &rect)
00457 {
00458 QwtTextLabel::drawText(painter, rect);
00459 }