Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qpainter.h>
00013 #include "qwt_painter.h"
00014 #include "qwt_scale_map.h"
00015 #include "qwt_plot_marker.h"
00016 #include "qwt_symbol.h"
00017 #include "qwt_text.h"
00018 #include "qwt_math.h"
00019
00020 class QwtPlotMarker::PrivateData
00021 {
00022 public:
00023 PrivateData():
00024 labelAlignment(Qt::AlignCenter),
00025 labelOrientation(Qt::Horizontal),
00026 spacing(2),
00027 style(NoLine),
00028 xValue(0.0),
00029 yValue(0.0)
00030 {
00031 symbol = new QwtSymbol();
00032 }
00033
00034 ~PrivateData()
00035 {
00036 delete symbol;
00037 }
00038
00039 QwtText label;
00040 #if QT_VERSION < 0x040000
00041 int labelAlignment;
00042 #else
00043 Qt::Alignment labelAlignment;
00044 #endif
00045 Qt::Orientation labelOrientation;
00046 int spacing;
00047
00048 QPen pen;
00049 QwtSymbol *symbol;
00050 LineStyle style;
00051
00052 double xValue;
00053 double yValue;
00054 };
00055
00057 QwtPlotMarker::QwtPlotMarker():
00058 QwtPlotItem(QwtText("Marker"))
00059 {
00060 d_data = new PrivateData;
00061 setZ(30.0);
00062 }
00063
00065 QwtPlotMarker::~QwtPlotMarker()
00066 {
00067 delete d_data;
00068 }
00069
00071 int QwtPlotMarker::rtti() const
00072 {
00073 return QwtPlotItem::Rtti_PlotMarker;
00074 }
00075
00077 QwtDoublePoint QwtPlotMarker::value() const
00078 {
00079 return QwtDoublePoint(d_data->xValue, d_data->yValue);
00080 }
00081
00083 double QwtPlotMarker::xValue() const
00084 {
00085 return d_data->xValue;
00086 }
00087
00089 double QwtPlotMarker::yValue() const
00090 {
00091 return d_data->yValue;
00092 }
00093
00095 void QwtPlotMarker::setValue(const QwtDoublePoint& pos)
00096 {
00097 setValue(pos.x(), pos.y());
00098 }
00099
00101 void QwtPlotMarker::setValue(double x, double y)
00102 {
00103 if ( x != d_data->xValue || y != d_data->yValue )
00104 {
00105 d_data->xValue = x;
00106 d_data->yValue = y;
00107 itemChanged();
00108 }
00109 }
00110
00112 void QwtPlotMarker::setXValue(double x)
00113 {
00114 setValue(x, d_data->yValue);
00115 }
00116
00118 void QwtPlotMarker::setYValue(double y)
00119 {
00120 setValue(d_data->xValue, y);
00121 }
00122
00131 void QwtPlotMarker::draw(QPainter *painter,
00132 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00133 const QRect &canvasRect) const
00134 {
00135 const int x = xMap.transform(d_data->xValue);
00136 const int y = yMap.transform(d_data->yValue);
00137
00138 drawAt(painter, canvasRect, QPoint(x, y));
00139 }
00140
00148 void QwtPlotMarker::drawAt(QPainter *painter,
00149 const QRect &canvasRect, const QPoint &pos) const
00150 {
00151
00152 if (d_data->style != NoLine)
00153 {
00154 painter->setPen(QwtPainter::scaledPen(d_data->pen));
00155 if ( d_data->style == QwtPlotMarker::HLine ||
00156 d_data->style == QwtPlotMarker::Cross )
00157 {
00158 QwtPainter::drawLine(painter, canvasRect.left(),
00159 pos.y(), canvasRect.right(), pos.y() );
00160 }
00161 if (d_data->style == QwtPlotMarker::VLine ||
00162 d_data->style == QwtPlotMarker::Cross )
00163 {
00164 QwtPainter::drawLine(painter, pos.x(),
00165 canvasRect.top(), pos.x(), canvasRect.bottom());
00166 }
00167 }
00168
00169
00170 if (d_data->symbol->style() != QwtSymbol::NoSymbol)
00171 d_data->symbol->draw(painter, pos.x(), pos.y());
00172
00173 drawLabel(painter, canvasRect, pos);
00174 }
00175
00176 void QwtPlotMarker::drawLabel(QPainter *painter,
00177 const QRect &canvasRect, const QPoint &pos) const
00178 {
00179 if (d_data->label.isEmpty())
00180 return;
00181
00182 int align = d_data->labelAlignment;
00183 QPoint alignPos = pos;
00184
00185 QSize symbolOff(0, 0);
00186
00187 switch(d_data->style)
00188 {
00189 case QwtPlotMarker::VLine:
00190 {
00191
00192
00193
00194 if (d_data->labelAlignment & (int) Qt::AlignTop)
00195 {
00196 alignPos.setY(canvasRect.top());
00197 align &= ~Qt::AlignTop;
00198 align |= Qt::AlignBottom;
00199 }
00200 else if (d_data->labelAlignment & (int) Qt::AlignBottom)
00201 {
00202
00203
00204
00205 alignPos.setY(canvasRect.bottom() - 1);
00206 align &= ~Qt::AlignBottom;
00207 align |= Qt::AlignTop;
00208 }
00209 else
00210 {
00211 alignPos.setY(canvasRect.center().y());
00212 }
00213 break;
00214 }
00215 case QwtPlotMarker::HLine:
00216 {
00217 if (d_data->labelAlignment & (int) Qt::AlignLeft)
00218 {
00219 alignPos.setX(canvasRect.left());
00220 align &= ~Qt::AlignLeft;
00221 align |= Qt::AlignRight;
00222 }
00223 else if (d_data->labelAlignment & (int) Qt::AlignRight)
00224 {
00225 alignPos.setX(canvasRect.right() - 1);
00226 align &= ~Qt::AlignRight;
00227 align |= Qt::AlignLeft;
00228 }
00229 else
00230 {
00231 alignPos.setX(canvasRect.center().x());
00232 }
00233 break;
00234 }
00235 default:
00236 {
00237 if ( d_data->symbol->style() != QwtSymbol::NoSymbol )
00238 {
00239 symbolOff = d_data->symbol->size() + QSize(1, 1);
00240 symbolOff /= 2;
00241 }
00242 }
00243 }
00244
00245 int pw = d_data->pen.width();
00246 if ( pw == 0 )
00247 pw = 1;
00248
00249 const int xSpacing =
00250 QwtPainter::metricsMap().screenToLayoutX(d_data->spacing);
00251 const int ySpacing =
00252 QwtPainter::metricsMap().screenToLayoutY(d_data->spacing);
00253
00254
00255 int xOff = qwtMax( (pw + 1) / 2, symbolOff.width() );
00256 int yOff = qwtMax( (pw + 1) / 2, symbolOff.height() );
00257
00258 const QSize textSize = d_data->label.textSize(painter->font());
00259
00260 if ( align & Qt::AlignLeft )
00261 {
00262 alignPos.rx() -= xOff + xSpacing;
00263 if ( d_data->labelOrientation == Qt::Vertical )
00264 alignPos.rx() -= textSize.height();
00265 else
00266 alignPos.rx() -= textSize.width();
00267 }
00268 else if ( align & Qt::AlignRight )
00269 {
00270 alignPos.rx() += xOff + xSpacing;
00271 }
00272 else
00273 {
00274 if ( d_data->labelOrientation == Qt::Vertical )
00275 alignPos.rx() -= textSize.height() / 2;
00276 else
00277 alignPos.rx() -= textSize.width() / 2;
00278 }
00279
00280 if (align & (int) Qt::AlignTop)
00281 {
00282 alignPos.ry() -= yOff + ySpacing;
00283 if ( d_data->labelOrientation != Qt::Vertical )
00284 alignPos.ry() -= textSize.height();
00285 }
00286 else if (align & (int) Qt::AlignBottom)
00287 {
00288 alignPos.ry() += yOff + ySpacing;
00289 if ( d_data->labelOrientation == Qt::Vertical )
00290 alignPos.ry() += textSize.width();
00291 }
00292 else
00293 {
00294 if ( d_data->labelOrientation == Qt::Vertical )
00295 alignPos.ry() += textSize.width() / 2;
00296 else
00297 alignPos.ry() -= textSize.height() / 2;
00298 }
00299
00300 painter->translate(alignPos.x(), alignPos.y());
00301 if ( d_data->labelOrientation == Qt::Vertical )
00302 painter->rotate(-90.0);
00303
00304 const QRect textRect(0, 0, textSize.width(), textSize.height());
00305 d_data->label.draw(painter, textRect);
00306 }
00307
00314 void QwtPlotMarker::setLineStyle(QwtPlotMarker::LineStyle st)
00315 {
00316 if ( st != d_data->style )
00317 {
00318 d_data->style = st;
00319 itemChanged();
00320 }
00321 }
00322
00327 QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
00328 {
00329 return d_data->style;
00330 }
00331
00337 void QwtPlotMarker::setSymbol(const QwtSymbol &s)
00338 {
00339 delete d_data->symbol;
00340 d_data->symbol = s.clone();
00341 itemChanged();
00342 }
00343
00348 const QwtSymbol &QwtPlotMarker::symbol() const
00349 {
00350 return *d_data->symbol;
00351 }
00352
00358 void QwtPlotMarker::setLabel(const QwtText& label)
00359 {
00360 if ( label != d_data->label )
00361 {
00362 d_data->label = label;
00363 itemChanged();
00364 }
00365 }
00366
00371 QwtText QwtPlotMarker::label() const
00372 {
00373 return d_data->label;
00374 }
00375
00392 #if QT_VERSION < 0x040000
00393 void QwtPlotMarker::setLabelAlignment(int align)
00394 #else
00395 void QwtPlotMarker::setLabelAlignment(Qt::Alignment align)
00396 #endif
00397 {
00398 if ( align != d_data->labelAlignment )
00399 {
00400 d_data->labelAlignment = align;
00401 itemChanged();
00402 }
00403 }
00404
00409 #if QT_VERSION < 0x040000
00410 int QwtPlotMarker::labelAlignment() const
00411 #else
00412 Qt::Alignment QwtPlotMarker::labelAlignment() const
00413 #endif
00414 {
00415 return d_data->labelAlignment;
00416 }
00417
00428 void QwtPlotMarker::setLabelOrientation(Qt::Orientation orientation)
00429 {
00430 if ( orientation != d_data->labelOrientation )
00431 {
00432 d_data->labelOrientation = orientation;
00433 itemChanged();
00434 }
00435 }
00436
00441 Qt::Orientation QwtPlotMarker::labelOrientation() const
00442 {
00443 return d_data->labelOrientation;
00444 }
00445
00455 void QwtPlotMarker::setSpacing(int spacing)
00456 {
00457 if ( spacing < 0 )
00458 spacing = 0;
00459
00460 if ( spacing == d_data->spacing )
00461 return;
00462
00463 d_data->spacing = spacing;
00464 itemChanged();
00465 }
00466
00471 int QwtPlotMarker::spacing() const
00472 {
00473 return d_data->spacing;
00474 }
00475
00485 void QwtPlotMarker::setLinePen(const QPen &pen)
00486 {
00487 if ( pen != d_data->pen )
00488 {
00489 d_data->pen = pen;
00490 itemChanged();
00491 }
00492 }
00493
00498 const QPen &QwtPlotMarker::linePen() const
00499 {
00500 return d_data->pen;
00501 }
00502
00503 QwtDoubleRect QwtPlotMarker::boundingRect() const
00504 {
00505 return QwtDoubleRect(d_data->xValue, d_data->yValue, 0.0, 0.0);
00506 }