# 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
    00064 void QwtPlotItem::attach(QwtPlot *plot)
    00065 {
    00066     if ( plot == d_data->plot )
    00067         return;
    00068
    00069     // remove the item from the previous plot
    00070
    00071     if ( d_data->plot )
    00072     {
    00073         if ( d_data->plot->legend() )
    00074         {
    00075             QWidget *legendItem = d_data->plot->legend()->find(this);
    00076             if ( legendItem )
    00077                 delete legendItem;
    00078         }
    00079
    00080         d_data->plot->attachItem(this, false);
    00081
    00082         if ( d_data->plot->autoReplot() )
    00083             d_data->plot->update();
    00084     }
    00085
    00086     d_data->plot = plot;
    00087
    00088     if ( d_data->plot )
    00089     {
    00090         // insert the item into the current plot
    00091
    00092         d_data->plot->attachItem(this, true);
    00093         itemChanged();
    00094     }
    00095 }
    00096
    00097 int QwtPlotItem::rtti() const
    00098 {
    00099     return Rtti_PlotItem;
    00100 }
    00101
    00103 QwtPlot *QwtPlotItem::plot() const
    00104 {
    00105     return d_data->plot;
    00106 }
    00107
    00113 double QwtPlotItem::z() const
    00114 {
    00115     return d_data->z;
    00116 }
    00117
    00126 void QwtPlotItem::setZ(double z)
    00127 {
    00128     if ( d_data->z != z )
    00129     {
    00130         d_data->z = z;
    00131         if ( d_data->plot )
    00132         {
    00133             // update the z order
    00134             d_data->plot->attachItem(this, false);
    00135             d_data->plot->attachItem(this, true);
    00136         }
    00137         itemChanged();
    00138     }
    00139 }
    00140
    00147 void QwtPlotItem::setTitle(const QString &title)
    00148 {
    00149     setTitle(QwtText(title));
    00150 }
    00151
    00158 void QwtPlotItem::setTitle(const QwtText &title)
    00159 {
    00160     if ( d_data->title != title )
    00161     {
    00162         d_data->title = title;
    00163         itemChanged();
    00164     }
    00165 }
    00166
    00171 const QwtText &QwtPlotItem::title() const
    00172 {
    00173     return d_data->title;
    00174 }
    00175
    00184 void QwtPlotItem::setItemAttribute(ItemAttribute attribute, bool on)
    00185 {
    00186     if ( bool(d_data->attributes & attribute) != on )
    00187     {
    00188         if ( on )
    00189             d_data->attributes |= attribute;
    00190         else
    00191             d_data->attributes &= ~attribute;
    00192
    00193         itemChanged();
    00194     }
    00195 }
    00196
    00204 bool QwtPlotItem::testItemAttribute(ItemAttribute attribute) const
    00205 {
    00206     return d_data->attributes & attribute;
    00207 }
    00208
    00209 #if QT_VERSION >= 0x040000
    00210
    00219 void QwtPlotItem::setRenderHint(RenderHint hint, bool on)
    00220 {
    00221     if ( ((d_data->renderHints & hint) != 0) != on )
    00222     {
    00223         if ( on )
    00224             d_data->renderHints |= hint;
    00225         else
    00226             d_data->renderHints &= ~hint;
    00227
    00228         itemChanged();
    00229     }
    00230 }
    00231
    00239 bool QwtPlotItem::testRenderHint(RenderHint hint) const
    00240 {
    00241     return (d_data->renderHints & hint);
    00242 }
    00243
    00244 #endif
    00245
    00246 void QwtPlotItem::show()
    00247 {
    00248     setVisible(true);
    00249 }
    00250
    00251 void QwtPlotItem::hide()
    00252 {
    00253     setVisible(false);
    00254 }
    00255
    00262 void QwtPlotItem::setVisible(bool on)
    00263 {
    00264     if ( on != d_data->isVisible )
    00265     {
    00266         d_data->isVisible = on;
    00267         itemChanged();
    00268     }
    00269 }
    00270
    00275 bool QwtPlotItem::isVisible() const
    00276 {
    00277     return d_data->isVisible;
    00278 }
    00279
    00286 void QwtPlotItem::itemChanged()
    00287 {
    00288     if ( d_data->plot )
    00289     {
    00290         if ( d_data->plot->legend() )
    00291             updateLegend(d_data->plot->legend());
    00292
    00293         d_data->plot->autoRefresh();
    00294     }
    00295 }
    00296
    00307 void QwtPlotItem::setAxis(int xAxis, int yAxis)
    00308 {
    00309     if (xAxis == QwtPlot::xBottom || xAxis == QwtPlot::xTop )
    00310        d_data->xAxis = xAxis;
    00311
    00312     if (yAxis == QwtPlot::yLeft || yAxis == QwtPlot::yRight )
    00313        d_data->yAxis = yAxis;
    00314
    00315     itemChanged();
    00316 }
    00317
    00326 void QwtPlotItem::setXAxis(int axis)
    00327 {
    00328     if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
    00329     {
    00330        d_data->xAxis = axis;
    00331        itemChanged();
    00332     }
    00333 }
    00334
    00343 void QwtPlotItem::setYAxis(int axis)
    00344 {
    00345     if (axis == QwtPlot::yLeft || axis == QwtPlot::yRight )
    00346     {
    00347        d_data->yAxis = axis;
    00348        itemChanged();
    00349     }
    00350 }
    00351
    00353 int QwtPlotItem::xAxis() const
    00354 {
    00355     return d_data->xAxis;
    00356 }
    00357
    00359 int QwtPlotItem::yAxis() const
    00360 {
    00361     return d_data->yAxis;
    00362 }
    00363
    00367 QwtDoubleRect QwtPlotItem::boundingRect() const
    00368 {
    00369     return QwtDoubleRect(1.0, 1.0, -2.0, -2.0); // invalid
    00370 }
    00371
    00382 QWidget *QwtPlotItem::legendItem() const
    00383 {
    00384     return new QwtLegendItem;
    00385 }
    00386
    00399 void QwtPlotItem::updateLegend(QwtLegend *legend) const
    00400 {
    00401     if ( !legend )
    00402         return;
    00403
    00404     QWidget *lgdItem = legend->find(this);
    00405     if ( testItemAttribute(QwtPlotItem::Legend) )
    00406     {
    00407         if ( lgdItem == NULL )
    00408         {
    00409             lgdItem = legendItem();
    00410             if ( lgdItem )
    00411             {
    00412                 if ( lgdItem->inherits("QwtLegendItem") )
    00413                 {
    00414                     QwtLegendItem *label = (QwtLegendItem *)lgdItem;
    00415                     label->setItemMode(legend->itemMode());
    00416
    00417                     if ( d_data->plot )
    00418                     {
    00419                         QObject::connect(label, SIGNAL(clicked()),
    00420                             d_data->plot, SLOT(legendItemClicked()));
    00421                         QObject::connect(label, SIGNAL(checked(bool)),
    00422                             d_data->plot, SLOT(legendItemChecked(bool)));
    00423                     }
    00424                 }
    00425                 legend->insert(this, lgdItem);
    00426             }
    00427         }
    00428         if ( lgdItem && lgdItem->inherits("QwtLegendItem") )
    00429         {
    00430             QwtLegendItem* label = (QwtLegendItem*)lgdItem;
    00431             if ( label )
    00432                 label->setText(d_data->title);
    00433         }
    00434     }
    00435     else
    00436     {
    00437         delete lgdItem;
    00438     }
    00439 }
    00440
    00454 void QwtPlotItem::updateScaleDiv(const QwtScaleDiv &,
    00455     const QwtScaleDiv &)
    00456 {
    00457 }
    00458
    00467 QwtDoubleRect QwtPlotItem::scaleRect(const QwtScaleMap &xMap,
    00468     const QwtScaleMap &yMap) const
    00469 {
    00470     return QwtDoubleRect(xMap.s1(), yMap.s1(),
    00471         xMap.sDist(), yMap.sDist() );
    00472 }
    00473
    00482 QRect QwtPlotItem::paintRect(const QwtScaleMap &xMap,
    00483     const QwtScaleMap &yMap) const
    00484 {
    00485     const QRect rect( qRound(xMap.p1()), qRound(yMap.p1()),
    00486         qRound(xMap.pDist()), qRound(yMap.pDist()) );
    00487
    00488     return rect;
    00489 }
    00490
    00501 QRect QwtPlotItem::transform(const QwtScaleMap &xMap,
    00502     const QwtScaleMap &yMap, const QwtDoubleRect& rect) const
    00503 {
    00504     int x1 = qRound(xMap.transform(rect.left()));
    00505     int x2 = qRound(xMap.transform(rect.right()));
    00506     int y1 = qRound(yMap.transform(rect.top()));
    00507     int y2 = qRound(yMap.transform(rect.bottom()));
    00508
    00509     if ( x2 < x1 )
    00510         qSwap(x1, x2);
    00511     if ( y2 < y1 )
    00512         qSwap(y1, y2);
    00513
    00514     return QRect(x1, y1, x2 - x1 - 1, y2 - y1 - 1);
    00515 }
    00516
    00526 QwtDoubleRect QwtPlotItem::invTransform(const QwtScaleMap &xMap,
    00527     const QwtScaleMap &yMap, const QRect& rect) const
    00528 {
    00529     const double x1 = xMap.invTransform(rect.x());
    00530     const double x2 = xMap.invTransform(rect.x() + rect.width() + 1);
    00531     const double y1 = yMap.invTransform(rect.y());
    00532     const double y2 = yMap.invTransform(rect.y() + rect.height() + 1);
    00533
    00534     const QwtDoubleRect r(x1, y1, x2 - x1, y2 - y1);
    00535
    00536     return r.normalized();
    00537 }