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_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         symbol = new QwtSymbol();
00059     }
00060 
00061     ~PrivateData()
00062     {
00063         delete symbol;
00064     }
00065 
00066     QwtLegend::LegendItemMode itemMode;
00067     bool isDown;
00068 
00069     int identifierWidth;
00070     int identifierMode;
00071     QwtSymbol *symbol;
00072     QPen curvePen;
00073 
00074     int spacing;
00075 };
00076 
00080 QwtLegendItem::QwtLegendItem(QWidget *parent):
00081     QwtTextLabel(parent)
00082 {
00083     d_data = new PrivateData;
00084     init(QwtText());
00085 }
00086 
00093 QwtLegendItem::QwtLegendItem(const QwtSymbol &symbol, 
00094         const QPen &curvePen, const QwtText &text, 
00095         QWidget *parent):
00096     QwtTextLabel(parent)
00097 {
00098     d_data = new PrivateData;
00099 
00100     delete d_data->symbol;
00101     d_data->symbol = symbol.clone();
00102 
00103     d_data->curvePen = curvePen;
00104 
00105     init(text);
00106 }
00107 
00108 void QwtLegendItem::init(const QwtText &text)
00109 {
00110     setMargin(Margin);
00111     setIndent(margin() + d_data->identifierWidth + 2 * d_data->spacing);
00112     setText(text);
00113 }
00114 
00116 QwtLegendItem::~QwtLegendItem()
00117 {
00118     delete d_data;
00119     d_data = NULL;
00120 }
00121 
00128 void QwtLegendItem::setText(const QwtText &text)
00129 {
00130     const int flags = Qt::AlignLeft | Qt::AlignVCenter
00131 #if QT_VERSION < 0x040000
00132         | Qt::WordBreak | Qt::ExpandTabs;
00133 #else
00134         | Qt::TextExpandTabs | Qt::TextWordWrap;
00135 #endif
00136 
00137     QwtText txt = text;
00138     txt.setRenderFlags(flags);
00139 
00140     QwtTextLabel::setText(txt);
00141 }
00142 
00150 void QwtLegendItem::setItemMode(QwtLegend::LegendItemMode mode) 
00151 { 
00152     d_data->itemMode = mode; 
00153     d_data->isDown = false; 
00154 
00155 #if QT_VERSION >= 0x040000
00156     using namespace Qt;
00157 #endif
00158     setFocusPolicy(mode != QwtLegend::ReadOnlyItem ? TabFocus : NoFocus);
00159     setMargin(ButtonFrame + Margin);
00160 
00161     updateGeometry();
00162 }
00163 
00169 QwtLegend::LegendItemMode QwtLegendItem::itemMode() const 
00170 { 
00171     return d_data->itemMode; 
00172 }
00173 
00181 void QwtLegendItem::setIdentifierMode(int mode)
00182 {
00183     if ( mode != d_data->identifierMode )
00184     {
00185         d_data->identifierMode = mode;
00186         update();
00187     }
00188 }
00189 
00194 int QwtLegendItem::identifierMode() const 
00195 { 
00196     return d_data->identifierMode; 
00197 }
00198 
00207 void QwtLegendItem::setIdentfierWidth(int width)
00208 {
00209     width = qwtMax(width, 0);
00210     if ( width != d_data->identifierWidth )
00211     {
00212         d_data->identifierWidth = width;
00213         setIndent(margin() + d_data->identifierWidth 
00214             + 2 * d_data->spacing);
00215     }
00216 }
00222 int QwtLegendItem::identifierWidth() const
00223 {
00224     return d_data->identifierWidth;
00225 }
00226 
00232 void QwtLegendItem::setSpacing(int spacing)
00233 {
00234     spacing = qwtMax(spacing, 0);
00235     if ( spacing != d_data->spacing )
00236     {
00237         d_data->spacing = spacing;
00238         setIndent(margin() + d_data->identifierWidth 
00239             + 2 * d_data->spacing);
00240     }
00241 }
00242 
00247 int QwtLegendItem::spacing() const
00248 {
00249     return d_data->spacing;
00250 }
00251 
00258 void QwtLegendItem::setSymbol(const QwtSymbol &symbol) 
00259 {
00260     delete d_data->symbol;
00261     d_data->symbol = symbol.clone();
00262     update();
00263 }
00264     
00269 const QwtSymbol& QwtLegendItem::symbol() const 
00270 { 
00271     return *d_data->symbol; 
00272 }
00273     
00274 
00281 void QwtLegendItem::setCurvePen(const QPen &pen) 
00282 {
00283     if ( pen != d_data->curvePen )
00284     {
00285         d_data->curvePen = pen;
00286         update();
00287     }
00288 }
00289 
00294 const QPen& QwtLegendItem::curvePen() const 
00295 { 
00296     return d_data->curvePen; 
00297 }
00298 
00304 void QwtLegendItem::drawIdentifier(
00305     QPainter *painter, const QRect &rect) const
00306 {
00307     if ( rect.isEmpty() )
00308         return;
00309 
00310     if ( (d_data->identifierMode & ShowLine ) && (d_data->curvePen.style() != Qt::NoPen) )
00311     {
00312         painter->save();
00313         painter->setPen(d_data->curvePen);
00314         QwtPainter::drawLine(painter, rect.left(), rect.center().y(), 
00315             rect.right(), rect.center().y());
00316         painter->restore();
00317     }
00318 
00319     if ( (d_data->identifierMode & ShowSymbol) 
00320         && (d_data->symbol->style() != QwtSymbol::NoSymbol) )
00321     {
00322         QSize symbolSize = 
00323             QwtPainter::metricsMap().screenToLayout(d_data->symbol->size());
00324 
00325         // scale the symbol size down if it doesn't fit into rect.
00326 
00327         if ( rect.width() < symbolSize.width() )
00328         {
00329             const double ratio = 
00330                 double(symbolSize.width()) / double(rect.width());
00331             symbolSize.setWidth(rect.width());
00332             symbolSize.setHeight(qRound(symbolSize.height() / ratio));
00333         }
00334         if ( rect.height() < symbolSize.height() )
00335         {
00336             const double ratio = 
00337                 double(symbolSize.width()) / double(rect.width());
00338             symbolSize.setHeight(rect.height());
00339             symbolSize.setWidth(qRound(symbolSize.width() / ratio));
00340         }
00341 
00342         QRect symbolRect;
00343         symbolRect.setSize(symbolSize);
00344         symbolRect.moveCenter(rect.center());
00345 
00346         painter->save();
00347         painter->setBrush(d_data->symbol->brush());
00348         painter->setPen(d_data->symbol->pen());
00349         d_data->symbol->draw(painter, symbolRect);
00350         painter->restore();
00351     }
00352 }
00353 
00360 void QwtLegendItem::drawItem(QPainter *painter, const QRect &rect) const
00361 {
00362     painter->save();
00363 
00364     const QwtMetricsMap &map = QwtPainter::metricsMap();
00365 
00366     const int m = map.screenToLayoutX(margin());
00367     const int spacing = map.screenToLayoutX(d_data->spacing);
00368     const int identifierWidth = map.screenToLayoutX(d_data->identifierWidth);
00369 
00370     const QRect identifierRect(rect.x() + m, rect.y(), 
00371         identifierWidth, rect.height());
00372     drawIdentifier(painter, identifierRect);
00373 
00374     // Label
00375 
00376     QRect titleRect = rect;
00377     titleRect.setX(identifierRect.right() + 2 * spacing);
00378      
00379     text().draw(painter, titleRect);
00380 
00381     painter->restore();
00382 }
00383 
00385 void QwtLegendItem::paintEvent(QPaintEvent *e)
00386 {
00387     const QRect cr = contentsRect();
00388 
00389     QPainter painter(this);
00390     painter.setClipRegion(e->region());
00391 
00392     if ( d_data->isDown )
00393     {
00394         qDrawWinButton(&painter, 0, 0, width(), height(), 
00395 #if QT_VERSION < 0x040000
00396             colorGroup(), 
00397 #else
00398             palette(),
00399 #endif
00400             true);
00401     }
00402 
00403     painter.save();
00404 
00405     if ( d_data->isDown )
00406     {
00407         const QSize shiftSize = buttonShift(this);
00408         painter.translate(shiftSize.width(), shiftSize.height());
00409     }
00410 
00411     painter.setClipRect(cr);
00412 
00413     drawContents(&painter);
00414 
00415     QRect rect = cr;
00416     rect.setX(rect.x() + margin());
00417     if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00418         rect.setX(rect.x() + ButtonFrame);
00419 
00420     rect.setWidth(d_data->identifierWidth);
00421 
00422     drawIdentifier(&painter, rect);
00423 
00424     painter.restore();
00425 }
00426 
00428 void QwtLegendItem::mousePressEvent(QMouseEvent *e)
00429 {
00430     if ( e->button() == Qt::LeftButton )
00431     {
00432         switch(d_data->itemMode)
00433         {
00434             case QwtLegend::ClickableItem:
00435             {
00436                 setDown(true);
00437                 return;
00438             }
00439             case QwtLegend::CheckableItem:
00440             {
00441                 setDown(!isDown());
00442                 return;
00443             }
00444             default:;
00445         }
00446     }
00447     QwtTextLabel::mousePressEvent(e);
00448 }
00449 
00451 void QwtLegendItem::mouseReleaseEvent(QMouseEvent *e)
00452 {
00453     if ( e->button() == Qt::LeftButton )
00454     {
00455         switch(d_data->itemMode)
00456         {
00457             case QwtLegend::ClickableItem:
00458             {
00459                 setDown(false);
00460                 return;
00461             }
00462             case QwtLegend::CheckableItem:
00463             {
00464                 return; // do nothing, but accept
00465             }
00466             default:;
00467         }
00468     }
00469     QwtTextLabel::mouseReleaseEvent(e);
00470 }
00471 
00473 void QwtLegendItem::keyPressEvent(QKeyEvent *e)
00474 {
00475     if ( e->key() == Qt::Key_Space )
00476     {
00477         switch(d_data->itemMode)
00478         {
00479             case QwtLegend::ClickableItem:
00480             {
00481                 if ( !e->isAutoRepeat() )
00482                     setDown(true);
00483                 return;
00484             }
00485             case QwtLegend::CheckableItem:
00486             {
00487                 if ( !e->isAutoRepeat() )
00488                     setDown(!isDown());
00489                 return;
00490             }
00491             default:;
00492         }
00493     }
00494 
00495     QwtTextLabel::keyPressEvent(e);
00496 }
00497 
00499 void QwtLegendItem::keyReleaseEvent(QKeyEvent *e)
00500 {
00501     if ( e->key() == Qt::Key_Space )
00502     {
00503         switch(d_data->itemMode)
00504         {
00505             case QwtLegend::ClickableItem:
00506             {
00507                 if ( !e->isAutoRepeat() )
00508                     setDown(false);
00509                 return;
00510             }
00511             case QwtLegend::CheckableItem:
00512             {
00513                 return; // do nothing, but accept
00514             }
00515             default:;
00516         }
00517     }
00518 
00519     QwtTextLabel::keyReleaseEvent(e);
00520 }
00521 
00528 void QwtLegendItem::setChecked(bool on)
00529 {
00530     if ( d_data->itemMode == QwtLegend::CheckableItem )
00531     {
00532         const bool isBlocked = signalsBlocked();
00533         blockSignals(true);
00534 
00535         setDown(on);
00536 
00537         blockSignals(isBlocked);
00538     }
00539 }
00540 
00542 bool QwtLegendItem::isChecked() const
00543 {
00544     return d_data->itemMode == QwtLegend::CheckableItem && isDown();
00545 }
00546 
00548 void QwtLegendItem::setDown(bool down)
00549 {
00550     if ( down == d_data->isDown )
00551         return;
00552 
00553     d_data->isDown = down;
00554     update();
00555 
00556     if ( d_data->itemMode == QwtLegend::ClickableItem )
00557     {
00558         if ( d_data->isDown )
00559             emit pressed();
00560         else
00561         {
00562             emit released();
00563             emit clicked();
00564         }
00565     }
00566 
00567     if ( d_data->itemMode == QwtLegend::CheckableItem )
00568         emit checked(d_data->isDown);
00569 }
00570 
00572 bool QwtLegendItem::isDown() const
00573 {
00574     return d_data->isDown;
00575 }
00576 
00578 QSize QwtLegendItem::sizeHint() const
00579 {
00580     QSize sz = QwtTextLabel::sizeHint();
00581     if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
00582         sz += buttonShift(this);
00583 
00584     return sz;
00585 }
00586 
00587 void QwtLegendItem::drawText(QPainter *painter, const QRect &rect)
00588 {
00589     QwtTextLabel::drawText(painter, rect);
00590 }

Generated on Sun Mar 22 16:54:07 2009 for Qwt User's Guide by  doxygen 1.5.0