# qwt_plot_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 #include "qwt_text.h"
    00011 #include "qwt_plot.h"
    00012 #include "qwt_legend.h"
    00013 #include "qwt_legend_item.h"
    00014 #include "qwt_plot_item.h"
    00015
    00016 class QwtPlotItem::PrivateData
    00017 {
    00018 public:
    00019     PrivateData():
    00020         plot(NULL),
    00021         isVisible(true),
    00022         attributes(0),
    00023 #if QT_VERSION >= 0x040000
    00024         renderHints(0),
    00025 #endif
    00026         z(0.0),
    00027         xAxis(QwtPlot::xBottom),
    00028         yAxis(QwtPlot::yLeft)
    00029     {
    00030     }
    00031
    00032     mutable QwtPlot *plot;
    00033
    00034     bool isVisible;
    00035     int attributes;
    00036 #if QT_VERSION >= 0x040000
    00037     int renderHints;
    00038 #endif
    00039     double z;
    00040
    00041     int xAxis;
    00042     int yAxis;
    00043
    00044     QwtText title;
    00045 };
    00046
    00048 QwtPlotItem::QwtPlotItem(const QwtText &title)
    00049 {
    00050     d_data = new PrivateData;
    00051     d_data->title = title;
    00052 }
    00053
    00055 QwtPlotItem::~QwtPlotItem()
    00056 {
    00057     attach(NULL);
    00058     delete d_data;
    00059 }
    00060
    00071 void QwtPlotItem::attach(QwtPlot *plot)
    00072 {
    00073     if ( plot == d_data->plot )
    00074         return;
    00075
    00076     // remove the item from the previous plot
    00077
    00078     if ( d_data->plot )
    00079     {
    00080         if ( d_data->plot->legend() )
    00081         {
    00082             QWidget *legendItem = d_data->plot->legend()->find(this);
    00083             if ( legendItem )
    00084                 delete legendItem;
    00085         }
    00086
    00087         d_data->plot->attachItem(this, false);
    00088
    00089         if ( d_data->plot->autoReplot() )
    00090             d_data->plot->update();
    00091     }
    00092
    00093     d_data->plot = plot;
    00094
    00095     if ( d_data->plot )
    00096     {
    00097         // insert the item into the current plot
    00098
    00099         d_data->plot->attachItem(this, true);
    00100         itemChanged();
    00101     }
    00102 }
    00103
    00116 int QwtPlotItem::rtti() const
    00117 {
    00118     return Rtti_PlotItem;
    00119 }
    00120
    00122 QwtPlot *QwtPlotItem::plot() const
    00123 {
    00124     return d_data->plot;
    00125 }
    00126
    00132 double QwtPlotItem::z() const
    00133 {
    00134     return d_data->z;
    00135 }
    00136
    00145 void QwtPlotItem::setZ(double z)
    00146 {
    00147     if ( d_data->z != z )
    00148     {
    00149         d_data->z = z;
    00150         if ( d_data->plot )
    00151         {
    00152             // update the z order
    00153             d_data->plot->attachItem(this, false);
    00154             d_data->plot->attachItem(this, true);
    00155         }
    00156         itemChanged();
    00157     }
    00158 }
    00159
    00166 void QwtPlotItem::setTitle(const QString &title)
    00167 {
    00168     setTitle(QwtText(title));
    00169 }
    00170
    00177 void QwtPlotItem::setTitle(const QwtText &title)
    00178 {
    00179     if ( d_data->title != title )
    00180     {
    00181         d_data->title = title;
    00182         itemChanged();
    00183     }
    00184 }
    00185
    00190 const QwtText &QwtPlotItem::title() const
    00191 {
    00192     return d_data->title;
    00193 }
    00194
    00203 void QwtPlotItem::setItemAttribute(ItemAttribute attribute, bool on)
    00204 {
    00205     if ( bool(d_data->attributes & attribute) != on )
    00206     {
    00207         if ( on )
    00208             d_data->attributes |= attribute;
    00209         else
    00210             d_data->attributes &= ~attribute;
    00211
    00212         itemChanged();
    00213     }
    00214 }
    00215
    00223 bool QwtPlotItem::testItemAttribute(ItemAttribute attribute) const
    00224 {
    00225     return d_data->attributes & attribute;
    00226 }
    00227
    00228 #if QT_VERSION >= 0x040000
    00229
    00238 void QwtPlotItem::setRenderHint(RenderHint hint, bool on)
    00239 {
    00240     if ( ((d_data->renderHints & hint) != 0) != on )
    00241     {
    00242         if ( on )
    00243             d_data->renderHints |= hint;
    00244         else
    00245             d_data->renderHints &= ~hint;
    00246
    00247         itemChanged();
    00248     }
    00249 }
    00250
    00258 bool QwtPlotItem::testRenderHint(RenderHint hint) const
    00259 {
    00260     return (d_data->renderHints & hint);
    00261 }
    00262
    00263 #endif
    00264
    00266 void QwtPlotItem::show()
    00267 {
    00268     setVisible(true);
    00269 }
    00270
    00272 void QwtPlotItem::hide()
    00273 {
    00274     setVisible(false);
    00275 }
    00276
    00283 void QwtPlotItem::setVisible(bool on)
    00284 {
    00285     if ( on != d_data->isVisible )
    00286     {
    00287         d_data->isVisible = on;
    00288         itemChanged();
    00289     }
    00290 }
    00291
    00296 bool QwtPlotItem::isVisible() const
    00297 {
    00298     return d_data->isVisible;
    00299 }
    00300
    00307 void QwtPlotItem::itemChanged()
    00308 {
    00309     if ( d_data->plot )
    00310     {
    00311         if ( d_data->plot->legend() )
    00312             updateLegend(d_data->plot->legend());
    00313
    00314         d_data->plot->autoRefresh();
    00315     }
    00316 }
    00317
    00328 void QwtPlotItem::setAxis(int xAxis, int yAxis)
    00329 {
    00330     if (xAxis == QwtPlot::xBottom || xAxis == QwtPlot::xTop )
    00331        d_data->xAxis = xAxis;
    00332
    00333     if (yAxis == QwtPlot::yLeft || yAxis == QwtPlot::yRight )
    00334        d_data->yAxis = yAxis;
    00335
    00336     itemChanged();
    00337 }
    00338
    00347 void QwtPlotItem::setXAxis(int axis)
    00348 {
    00349     if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
    00350     {
    00351        d_data->xAxis = axis;
    00352        itemChanged();
    00353     }
    00354 }
    00355
    00364 void QwtPlotItem::setYAxis(int axis)
    00365 {
    00366     if (axis == QwtPlot::yLeft || axis == QwtPlot::yRight )
    00367     {
    00368        d_data->yAxis = axis;
    00369        itemChanged();
    00370     }
    00371 }
    00372
    00374 int QwtPlotItem::xAxis() const
    00375 {
    00376     return d_data->xAxis;
    00377 }
    00378
    00380 int QwtPlotItem::yAxis() const
    00381 {
    00382     return d_data->yAxis;
    00383 }
    00384
    00388 QwtDoubleRect QwtPlotItem::boundingRect() const
    00389 {
    00390     return QwtDoubleRect(1.0, 1.0, -2.0, -2.0); // invalid
    00391 }
    00392
    00403 QWidget *QwtPlotItem::legendItem() const
    00404 {
    00405     return new QwtLegendItem;
    00406 }
    00407
    00420 void QwtPlotItem::updateLegend(QwtLegend *legend) const
    00421 {
    00422     if ( !legend )
    00423         return;
    00424
    00425     QWidget *lgdItem = legend->find(this);
    00426     if ( testItemAttribute(QwtPlotItem::Legend) )
    00427     {
    00428         if ( lgdItem == NULL )
    00429         {
    00430             lgdItem = legendItem();
    00431             if ( lgdItem )
    00432             {
    00433                 if ( lgdItem->inherits("QwtLegendItem") )
    00434                 {
    00435                     QwtLegendItem *label = (QwtLegendItem *)lgdItem;
    00436                     label->setItemMode(legend->itemMode());
    00437
    00438                     if ( d_data->plot )
    00439                     {
    00440                         QObject::connect(label, SIGNAL(clicked()),
    00441                             d_data->plot, SLOT(legendItemClicked()));
    00442                         QObject::connect(label, SIGNAL(checked(bool)),
    00443                             d_data->plot, SLOT(legendItemChecked(bool)));
    00444                     }
    00445                 }
    00446                 legend->insert(this, lgdItem);
    00447             }
    00448         }
    00449         if ( lgdItem && lgdItem->inherits("QwtLegendItem") )
    00450         {
    00451             QwtLegendItem* label = (QwtLegendItem*)lgdItem;
    00452             if ( label )
    00453                 label->setText(d_data->title);
    00454         }
    00455     }
    00456     else
    00457     {
    00458         delete lgdItem;
    00459     }
    00460 }
    00461
    00475 void QwtPlotItem::updateScaleDiv(const QwtScaleDiv &,
    00476     const QwtScaleDiv &)
    00477 {
    00478 }
    00479
    00488 QwtDoubleRect QwtPlotItem::scaleRect(const QwtScaleMap &xMap,
    00489     const QwtScaleMap &yMap) const
    00490 {
    00491     return QwtDoubleRect(xMap.s1(), yMap.s1(),
    00492         xMap.sDist(), yMap.sDist() );
    00493 }
    00494
    00503 QRect QwtPlotItem::paintRect(const QwtScaleMap &xMap,
    00504     const QwtScaleMap &yMap) const
    00505 {
    00506     const QRect rect( qRound(xMap.p1()), qRound(yMap.p1()),
    00507         qRound(xMap.pDist()), qRound(yMap.pDist()) );
    00508
    00509     return rect;
    00510 }
    00511
    00522 QRect QwtPlotItem::transform(const QwtScaleMap &xMap,
    00523     const QwtScaleMap &yMap, const QwtDoubleRect& rect) const
    00524 {
    00525     int x1 = qRound(xMap.transform(rect.left()));
    00526     int x2 = qRound(xMap.transform(rect.right()));
    00527     int y1 = qRound(yMap.transform(rect.top()));
    00528     int y2 = qRound(yMap.transform(rect.bottom()));
    00529
    00530     if ( x2 < x1 )
    00531         qSwap(x1, x2);
    00532     if ( y2 < y1 )
    00533         qSwap(y1, y2);
    00534
    00535     return QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
    00536 }
    00537
    00547 QwtDoubleRect QwtPlotItem::invTransform(const QwtScaleMap &xMap,
    00548     const QwtScaleMap &yMap, const QRect& rect) const
    00549 {
    00550     const double x1 = xMap.invTransform(rect.left());
    00551     const double x2 = xMap.invTransform(rect.right());
    00552     const double y1 = yMap.invTransform(rect.top());
    00553     const double y2 = yMap.invTransform(rect.bottom());
    00554
    00555     const QwtDoubleRect r(x1, y1, x2 - x1, y2 - y1);
    00556
    00557     return r.normalized();
    00558 }