Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

qwt_legend_item.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 // vim: expandtab
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     // Qt::TextExpandTabs ???
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         // scale the symbol size down if it doesn't fit into rect.
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     // Label
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 }

Generated on Wed Aug 31 23:02:29 2005 for Qwt User's Guide by  doxygen 1.4.1