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     }
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         // scale the symbol size down if it doesn't fit into rect.
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     // Label
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 }

Generated on Mon Feb 26 21:22:37 2007 for Qwt User's Guide by  doxygen 1.4.6