You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
538 lines
0 B
538 lines
0 B
15 years ago
|
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
||
|
* Qwt Widget Library
|
||
|
* Copyright (C) 1997 Josef Wilgen
|
||
|
* Copyright (C) 2002 Uwe Rathmann
|
||
14 years ago
|
*
|
||
15 years ago
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the Qwt License, Version 1.0
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "qwt_text.h"
|
||
|
#include "qwt_plot.h"
|
||
|
#include "qwt_legend.h"
|
||
|
#include "qwt_legend_item.h"
|
||
|
#include "qwt_plot_item.h"
|
||
|
|
||
|
class QwtPlotItem::PrivateData
|
||
|
{
|
||
|
public:
|
||
|
PrivateData():
|
||
|
plot(NULL),
|
||
|
isVisible(true),
|
||
|
attributes(0),
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
renderHints(0),
|
||
|
#endif
|
||
|
z(0.0),
|
||
|
xAxis(QwtPlot::xBottom),
|
||
14 years ago
|
yAxis(QwtPlot::yLeft) {
|
||
15 years ago
|
}
|
||
|
|
||
|
mutable QwtPlot *plot;
|
||
|
|
||
|
bool isVisible;
|
||
|
int attributes;
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
int renderHints;
|
||
|
#endif
|
||
|
double z;
|
||
|
|
||
|
int xAxis;
|
||
|
int yAxis;
|
||
|
|
||
|
QwtText title;
|
||
|
};
|
||
|
|
||
|
//! Constructor
|
||
|
QwtPlotItem::QwtPlotItem(const QwtText &title)
|
||
|
{
|
||
|
d_data = new PrivateData;
|
||
|
d_data->title = title;
|
||
|
}
|
||
|
|
||
|
//! Destroy the QwtPlotItem
|
||
|
QwtPlotItem::~QwtPlotItem()
|
||
|
{
|
||
|
attach(NULL);
|
||
|
delete d_data;
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
\brief Attach the item to a plot.
|
||
|
|
||
|
This method will attach a QwtPlotItem to the QwtPlot argument. It will first
|
||
|
detach the QwtPlotItem from any plot from a previous call to attach (if
|
||
|
necessary). If a NULL argument is passed, it will detach from any QwtPlot it
|
||
|
was attached to.
|
||
|
|
||
|
\sa QwtPlotItem::detach()
|
||
|
*/
|
||
|
void QwtPlotItem::attach(QwtPlot *plot)
|
||
|
{
|
||
|
if ( plot == d_data->plot )
|
||
|
return;
|
||
|
|
||
|
// remove the item from the previous plot
|
||
|
|
||
14 years ago
|
if ( d_data->plot ) {
|
||
|
if ( d_data->plot->legend() ) {
|
||
15 years ago
|
QWidget *legendItem = d_data->plot->legend()->find(this);
|
||
|
if ( legendItem )
|
||
14 years ago
|
delete legendItem;
|
||
15 years ago
|
}
|
||
|
|
||
|
d_data->plot->attachItem(this, false);
|
||
|
|
||
|
if ( d_data->plot->autoReplot() )
|
||
|
d_data->plot->update();
|
||
|
}
|
||
|
|
||
|
d_data->plot = plot;
|
||
|
|
||
14 years ago
|
if ( d_data->plot ) {
|
||
15 years ago
|
// insert the item into the current plot
|
||
|
|
||
|
d_data->plot->attachItem(this, true);
|
||
|
itemChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Return rtti for the specific class represented. QwtPlotItem is simply
|
||
|
a virtual interface class, and base classes will implement this method
|
||
|
with specific rtti values so a user can differentiate them.
|
||
|
|
||
14 years ago
|
The rtti value is useful for environments, where the
|
||
15 years ago
|
runtime type information is disabled and it is not possible
|
||
|
to do a dynamic_cast<...>.
|
||
14 years ago
|
|
||
15 years ago
|
\return rtti value
|
||
|
\sa RttiValues
|
||
|
*/
|
||
|
int QwtPlotItem::rtti() const
|
||
|
{
|
||
|
return Rtti_PlotItem;
|
||
|
}
|
||
|
|
||
|
//! Return attached plot
|
||
14 years ago
|
QwtPlot *QwtPlotItem::plot() const
|
||
|
{
|
||
|
return d_data->plot;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
Plot items are painted in increasing z-order.
|
||
|
|
||
|
\return setZ(), QwtPlotDict::itemList()
|
||
|
*/
|
||
14 years ago
|
double QwtPlotItem::z() const
|
||
|
{
|
||
|
return d_data->z;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Set the z value
|
||
|
|
||
|
Plot items are painted in increasing z-order.
|
||
|
|
||
|
\param z Z-value
|
||
|
\sa z(), QwtPlotDict::itemList()
|
||
|
*/
|
||
14 years ago
|
void QwtPlotItem::setZ(double z)
|
||
|
{
|
||
|
if ( d_data->z != z ) {
|
||
|
d_data->z = z;
|
||
|
if ( d_data->plot ) {
|
||
15 years ago
|
// update the z order
|
||
|
d_data->plot->attachItem(this, false);
|
||
|
d_data->plot->attachItem(this, true);
|
||
|
}
|
||
|
itemChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Set a new title
|
||
|
|
||
|
\param title Title
|
||
14 years ago
|
\sa title()
|
||
|
*/
|
||
15 years ago
|
void QwtPlotItem::setTitle(const QString &title)
|
||
|
{
|
||
|
setTitle(QwtText(title));
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Set a new title
|
||
|
|
||
|
\param title Title
|
||
14 years ago
|
\sa title()
|
||
|
*/
|
||
15 years ago
|
void QwtPlotItem::setTitle(const QwtText &title)
|
||
|
{
|
||
14 years ago
|
if ( d_data->title != title ) {
|
||
|
d_data->title = title;
|
||
15 years ago
|
itemChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return Title of the item
|
||
|
\sa setTitle()
|
||
|
*/
|
||
|
const QwtText &QwtPlotItem::title() const
|
||
|
{
|
||
|
return d_data->title;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Toggle an item attribute
|
||
14 years ago
|
|
||
15 years ago
|
\param attribute Attribute type
|
||
|
\param on true/false
|
||
|
|
||
|
\sa testItemAttribute(), ItemAttribute
|
||
|
*/
|
||
|
void QwtPlotItem::setItemAttribute(ItemAttribute attribute, bool on)
|
||
|
{
|
||
14 years ago
|
if ( bool(d_data->attributes & attribute) != on ) {
|
||
15 years ago
|
if ( on )
|
||
|
d_data->attributes |= attribute;
|
||
|
else
|
||
|
d_data->attributes &= ~attribute;
|
||
|
|
||
|
itemChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Test an item attribute
|
||
|
|
||
|
\param ItemAttribute Attribute type
|
||
|
\return true/false
|
||
|
\sa setItemAttribute(), ItemAttribute
|
||
|
*/
|
||
|
bool QwtPlotItem::testItemAttribute(ItemAttribute attribute) const
|
||
|
{
|
||
|
return d_data->attributes & attribute;
|
||
|
}
|
||
|
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
|
||
|
/*!
|
||
|
Toggle an render hint
|
||
14 years ago
|
|
||
15 years ago
|
\param hint Render hint
|
||
|
\param on true/false
|
||
|
|
||
|
\sa testRenderHint(), RenderHint
|
||
|
*/
|
||
|
void QwtPlotItem::setRenderHint(RenderHint hint, bool on)
|
||
|
{
|
||
14 years ago
|
if ( ((d_data->renderHints & hint) != 0) != on ) {
|
||
15 years ago
|
if ( on )
|
||
|
d_data->renderHints |= hint;
|
||
|
else
|
||
|
d_data->renderHints &= ~hint;
|
||
|
|
||
|
itemChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Test a render hint
|
||
|
|
||
|
\param hint Render hint
|
||
|
\return true/false
|
||
|
\sa setRenderHint(), RenderHint
|
||
|
*/
|
||
|
bool QwtPlotItem::testRenderHint(RenderHint hint) const
|
||
|
{
|
||
|
return (d_data->renderHints & hint);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
//! Show the item
|
||
|
void QwtPlotItem::show()
|
||
|
{
|
||
|
setVisible(true);
|
||
|
}
|
||
|
|
||
|
//! Hide the item
|
||
|
void QwtPlotItem::hide()
|
||
|
{
|
||
|
setVisible(false);
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Show/Hide the item
|
||
|
|
||
|
\param on Show if true, otherwise hide
|
||
|
\sa isVisible(), show(), hide()
|
||
|
*/
|
||
14 years ago
|
void QwtPlotItem::setVisible(bool on)
|
||
|
{
|
||
|
if ( on != d_data->isVisible ) {
|
||
|
d_data->isVisible = on;
|
||
|
itemChanged();
|
||
15 years ago
|
}
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
\return true if visible
|
||
|
\sa setVisible(), show(), hide()
|
||
|
*/
|
||
|
bool QwtPlotItem::isVisible() const
|
||
14 years ago
|
{
|
||
|
return d_data->isVisible;
|
||
15 years ago
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
|
Update the legend and call QwtPlot::autoRefresh for the
|
||
15 years ago
|
parent plot.
|
||
|
|
||
|
\sa updateLegend()
|
||
|
*/
|
||
|
void QwtPlotItem::itemChanged()
|
||
|
{
|
||
14 years ago
|
if ( d_data->plot ) {
|
||
15 years ago
|
if ( d_data->plot->legend() )
|
||
|
updateLegend(d_data->plot->legend());
|
||
|
|
||
|
d_data->plot->autoRefresh();
|
||
|
}
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Set X and Y axis
|
||
|
|
||
|
The item will painted according to the coordinates its Axes.
|
||
|
|
||
|
\param xAxis X Axis
|
||
|
\param yAxis Y Axis
|
||
|
|
||
|
\sa setXAxis(), setYAxis(), xAxis(), yAxis()
|
||
|
*/
|
||
|
void QwtPlotItem::setAxis(int xAxis, int yAxis)
|
||
|
{
|
||
|
if (xAxis == QwtPlot::xBottom || xAxis == QwtPlot::xTop )
|
||
14 years ago
|
d_data->xAxis = xAxis;
|
||
15 years ago
|
|
||
|
if (yAxis == QwtPlot::yLeft || yAxis == QwtPlot::yRight )
|
||
14 years ago
|
d_data->yAxis = yAxis;
|
||
15 years ago
|
|
||
14 years ago
|
itemChanged();
|
||
15 years ago
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Set the X axis
|
||
|
|
||
|
The item will painted according to the coordinates its Axes.
|
||
|
|
||
|
\param axis X Axis
|
||
|
\sa setAxis(), setYAxis(), xAxis()
|
||
|
*/
|
||
|
void QwtPlotItem::setXAxis(int axis)
|
||
|
{
|
||
14 years ago
|
if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) {
|
||
|
d_data->xAxis = axis;
|
||
|
itemChanged();
|
||
15 years ago
|
}
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Set the Y axis
|
||
|
|
||
|
The item will painted according to the coordinates its Axes.
|
||
|
|
||
|
\param axis Y Axis
|
||
|
\sa setAxis(), setXAxis(), yAxis()
|
||
|
*/
|
||
|
void QwtPlotItem::setYAxis(int axis)
|
||
|
{
|
||
14 years ago
|
if (axis == QwtPlot::yLeft || axis == QwtPlot::yRight ) {
|
||
|
d_data->yAxis = axis;
|
||
|
itemChanged();
|
||
15 years ago
|
}
|
||
|
}
|
||
|
|
||
|
//! Return xAxis
|
||
14 years ago
|
int QwtPlotItem::xAxis() const
|
||
|
{
|
||
|
return d_data->xAxis;
|
||
15 years ago
|
}
|
||
|
|
||
|
//! Return yAxis
|
||
14 years ago
|
int QwtPlotItem::yAxis() const
|
||
|
{
|
||
|
return d_data->yAxis;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
\return An invalid bounding rect: QwtDoubleRect(1.0, 1.0, -2.0, -2.0)
|
||
|
*/
|
||
|
QwtDoubleRect QwtPlotItem::boundingRect() const
|
||
|
{
|
||
|
return QwtDoubleRect(1.0, 1.0, -2.0, -2.0); // invalid
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Allocate the widget that represents the item on the legend
|
||
|
|
||
14 years ago
|
The default implementation is made for QwtPlotCurve and returns a
|
||
15 years ago
|
QwtLegendItem(), but an item could be represented by any type of widget,
|
||
|
by overloading legendItem() and updateLegend().
|
||
|
|
||
|
\return QwtLegendItem()
|
||
|
\sa updateLegend() QwtLegend()
|
||
|
*/
|
||
|
QWidget *QwtPlotItem::legendItem() const
|
||
|
{
|
||
|
return new QwtLegendItem;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Update the widget that represents the item on the legend
|
||
|
|
||
|
updateLegend() is called from itemChanged() to adopt the widget
|
||
|
representing the item on the legend to its new configuration.
|
||
14 years ago
|
|
||
|
The default implementation is made for QwtPlotCurve and updates a
|
||
15 years ago
|
QwtLegendItem(), but an item could be represented by any type of widget,
|
||
|
by overloading legendItem() and updateLegend().
|
||
|
|
||
|
\sa legendItem(), itemChanged(), QwtLegend()
|
||
|
*/
|
||
|
void QwtPlotItem::updateLegend(QwtLegend *legend) const
|
||
|
{
|
||
|
if ( !legend )
|
||
|
return;
|
||
|
|
||
|
QWidget *lgdItem = legend->find(this);
|
||
14 years ago
|
if ( testItemAttribute(QwtPlotItem::Legend) ) {
|
||
|
if ( lgdItem == NULL ) {
|
||
15 years ago
|
lgdItem = legendItem();
|
||
14 years ago
|
if ( lgdItem ) {
|
||
|
if ( lgdItem->inherits("QwtLegendItem") ) {
|
||
15 years ago
|
QwtLegendItem *label = (QwtLegendItem *)lgdItem;
|
||
|
label->setItemMode(legend->itemMode());
|
||
|
|
||
14 years ago
|
if ( d_data->plot ) {
|
||
|
QObject::connect(label, SIGNAL(clicked()),
|
||
|
d_data->plot, SLOT(legendItemClicked()));
|
||
|
QObject::connect(label, SIGNAL(checked(bool)),
|
||
|
d_data->plot, SLOT(legendItemChecked(bool)));
|
||
15 years ago
|
}
|
||
|
}
|
||
|
legend->insert(this, lgdItem);
|
||
|
}
|
||
|
}
|
||
14 years ago
|
if ( lgdItem && lgdItem->inherits("QwtLegendItem") ) {
|
||
15 years ago
|
QwtLegendItem* label = (QwtLegendItem*)lgdItem;
|
||
|
if ( label )
|
||
|
label->setText(d_data->title);
|
||
|
}
|
||
14 years ago
|
} else {
|
||
15 years ago
|
delete lgdItem;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Update the item to changes of the axes scale division
|
||
|
|
||
|
Update the item, when the axes of plot have changed.
|
||
|
The default implementation does nothing, but items that depend
|
||
|
on the scale division (like QwtPlotGrid()) have to reimplement
|
||
|
updateScaleDiv()
|
||
|
|
||
|
\param xScaleDiv Scale division of the x-axis
|
||
|
\param yScaleDiv Scale division of the y-axis
|
||
|
|
||
|
\sa QwtPlot::updateAxes()
|
||
|
*/
|
||
|
void QwtPlotItem::updateScaleDiv(const QwtScaleDiv &,
|
||
14 years ago
|
const QwtScaleDiv &)
|
||
|
{
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Calculate the bounding scale rect of 2 maps
|
||
|
|
||
|
\param xMap X map
|
||
|
\param yMap X map
|
||
|
|
||
|
\return Bounding rect of the scale maps
|
||
|
*/
|
||
14 years ago
|
QwtDoubleRect QwtPlotItem::scaleRect(const QwtScaleMap &xMap,
|
||
|
const QwtScaleMap &yMap) const
|
||
15 years ago
|
{
|
||
14 years ago
|
return QwtDoubleRect(xMap.s1(), yMap.s1(),
|
||
|
xMap.sDist(), yMap.sDist() );
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Calculate the bounding paint rect of 2 maps
|
||
|
|
||
|
\param xMap X map
|
||
|
\param yMap X map
|
||
|
|
||
|
\return Bounding rect of the scale maps
|
||
|
*/
|
||
14 years ago
|
QRect QwtPlotItem::paintRect(const QwtScaleMap &xMap,
|
||
|
const QwtScaleMap &yMap) const
|
||
15 years ago
|
{
|
||
|
const QRect rect( qRound(xMap.p1()), qRound(yMap.p1()),
|
||
14 years ago
|
qRound(xMap.pDist()), qRound(yMap.pDist()) );
|
||
15 years ago
|
|
||
|
return rect;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Transform a rectangle
|
||
|
|
||
|
\param xMap X map
|
||
|
\param yMap Y map
|
||
|
\param rect Rectangle in scale coordinates
|
||
|
\return Rectangle in paint coordinates
|
||
14 years ago
|
|
||
15 years ago
|
\sa invTransform()
|
||
|
*/
|
||
14 years ago
|
QRect QwtPlotItem::transform(const QwtScaleMap &xMap,
|
||
|
const QwtScaleMap &yMap, const QwtDoubleRect& rect) const
|
||
15 years ago
|
{
|
||
|
int x1 = qRound(xMap.transform(rect.left()));
|
||
|
int x2 = qRound(xMap.transform(rect.right()));
|
||
|
int y1 = qRound(yMap.transform(rect.top()));
|
||
|
int y2 = qRound(yMap.transform(rect.bottom()));
|
||
|
|
||
|
if ( x2 < x1 )
|
||
|
qSwap(x1, x2);
|
||
|
if ( y2 < y1 )
|
||
|
qSwap(y1, y2);
|
||
|
|
||
|
return QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Transform a rectangle from paint to scale coordinates
|
||
|
|
||
|
\param xMap X map
|
||
|
\param yMap Y map
|
||
|
\param rect Rectangle in paint coordinates
|
||
|
\return Rectangle in scale coordinates
|
||
|
\sa transform()
|
||
|
*/
|
||
14 years ago
|
QwtDoubleRect QwtPlotItem::invTransform(const QwtScaleMap &xMap,
|
||
|
const QwtScaleMap &yMap, const QRect& rect) const
|
||
15 years ago
|
{
|
||
|
const double x1 = xMap.invTransform(rect.left());
|
||
|
const double x2 = xMap.invTransform(rect.right());
|
||
|
const double y1 = yMap.invTransform(rect.top());
|
||
|
const double y2 = yMap.invTransform(rect.bottom());
|
||
14 years ago
|
|
||
15 years ago
|
const QwtDoubleRect r(x1, y1, x2 - x1, y2 - y1);
|
||
|
|
||
|
return r.normalized();
|
||
|
}
|