# qwt_plot_marker.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 "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 static const int LabelDist = 2;
    00021
    00022 class QwtPlotMarker::PrivateData
    00023 {
    00024 public:
    00025     PrivateData():
    00026         align(Qt::AlignCenter),
    00027         style(NoLine),
    00028         xValue(0.0),
    00029         yValue(0.0)
    00030     {
    00031     }
    00032
    00033     QwtText label;
    00034 #if QT_VERSION < 0x040000
    00035     int align;
    00036 #else
    00037     Qt::Alignment align;
    00038 #endif
    00039     QPen pen;
    00040     QwtSymbol sym;
    00041     LineStyle style;
    00042
    00043     double xValue;
    00044     double yValue;
    00045 };
    00046
    00048 QwtPlotMarker::QwtPlotMarker():
    00049     QwtPlotItem(QwtText("Marker"))
    00050 {
    00051     d_data = new PrivateData;
    00052     setZ(30.0);
    00053 }
    00054
    00056 QwtPlotMarker::~QwtPlotMarker()
    00057 {
    00058     delete d_data;
    00059 }
    00060
    00061 int QwtPlotMarker::rtti() const
    00062 {
    00063     return QwtPlotItem::Rtti_PlotMarker;
    00064 }
    00065
    00067 QwtDoublePoint QwtPlotMarker::value() const
    00068 {
    00069     return QwtDoublePoint(d_data->xValue, d_data->yValue);
    00070 }
    00071
    00073 double QwtPlotMarker::xValue() const
    00074 {
    00075     return d_data->xValue;
    00076 }
    00077
    00079 double QwtPlotMarker::yValue() const
    00080 {
    00081     return d_data->yValue;
    00082 }
    00083
    00085 void QwtPlotMarker::setValue(const QwtDoublePoint& pos)
    00086 {
    00087     setValue(pos.x(), pos.y());
    00088 }
    00089
    00091 void QwtPlotMarker::setValue(double x, double y)
    00092 {
    00093     if ( x != d_data->xValue || y != d_data->yValue )
    00094     {
    00095         d_data->xValue = x;
    00096         d_data->yValue = y;
    00097         itemChanged();
    00098     }
    00099 }
    00100
    00102 void QwtPlotMarker::setXValue(double x)
    00103 {
    00104     setValue(x, d_data->yValue);
    00105 }
    00106
    00108 void QwtPlotMarker::setYValue(double y)
    00109 {
    00110     setValue(d_data->xValue, y);
    00111 }
    00112
    00120 void QwtPlotMarker::draw(QPainter *p,
    00121     const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    00122     const QRect &r) const
    00123 {
    00124     const int x = xMap.transform(d_data->xValue);
    00125     const int y = yMap.transform(d_data->yValue);
    00126
    00127     // draw lines
    00128     if (d_data->style != NoLine)
    00129     {
    00130         p->setPen(d_data->pen);
    00131         if ((d_data->style == HLine) || (d_data->style == Cross))
    00132             QwtPainter::drawLine(p, r.left(), y, r.right(), y);
    00133         if ((d_data->style == VLine)||(d_data->style == Cross))
    00134             QwtPainter::drawLine(p, x, r.top(), x, r.bottom());
    00135     }
    00136
    00137     // draw symbol
    00138     QSize sSym(0, 0);
    00139     if (d_data->sym.style() != QwtSymbol::NoSymbol)
    00140     {
    00141         sSym = d_data->sym.size();
    00142         d_data->sym.draw(p, x, y);
    00143     }
    00144
    00145     // draw label
    00146     if (!d_data->label.isEmpty())
    00147     {
    00148         int xlw = qwtMax(int(d_data->pen.width()), 1);
    00149         int ylw = xlw;
    00150         int xlw1;
    00151         int ylw1;
    00152
    00153         const int xLabelDist =
    00154             QwtPainter::metricsMap().screenToLayoutX(LabelDist);
    00155         const int yLabelDist =
    00156             QwtPainter::metricsMap().screenToLayoutY(LabelDist);
    00157
    00158         if ((d_data->style == VLine) || (d_data->style == HLine))
    00159         {
    00160             xlw1 = (xlw + 1) / 2 + xLabelDist;
    00161             xlw = xlw / 2 + xLabelDist;
    00162             ylw1 = (ylw + 1) / 2 + yLabelDist;
    00163             ylw = ylw / 2 + yLabelDist;
    00164         }
    00165         else
    00166         {
    00167             xlw1 = qwtMax((xlw + 1) / 2, (sSym.width() + 1) / 2) + xLabelDist;
    00168             xlw = qwtMax(xlw / 2, (sSym.width() + 1) / 2) + xLabelDist;
    00169             ylw1 = qwtMax((ylw + 1) / 2, (sSym.height() + 1) / 2) + yLabelDist;
    00170             ylw = qwtMax(ylw / 2, (sSym. height() + 1) / 2) + yLabelDist;
    00171         }
    00172
    00173         QRect tr(QPoint(0, 0), d_data->label.textSize(p->font()));
    00174         tr.moveCenter(QPoint(0, 0));
    00175
    00176         int dx = x;
    00177         int dy = y;
    00178
    00179         if (d_data->style == VLine)
    00180         {
    00181             if (d_data->align & (int) Qt::AlignTop)
    00182                 dy = r.top() + yLabelDist - tr.y();
    00183             else if (d_data->align & (int) Qt::AlignBottom)
    00184                 dy = r.bottom() - yLabelDist + tr.y();
    00185             else
    00186                 dy = r.top() + r.height() / 2;
    00187         }
    00188         else
    00189         {
    00190             if (d_data->align & (int) Qt::AlignTop)
    00191                 dy += tr.y() - ylw1;
    00192             else if (d_data->align & (int) Qt::AlignBottom)
    00193                 dy -= tr.y() - ylw1;
    00194         }
    00195
    00196
    00197         if (d_data->style == HLine)
    00198         {
    00199             if (d_data->align & (int) Qt::AlignLeft)
    00200                 dx = r.left() + xLabelDist - tr.x();
    00201             else if (d_data->align & (int) Qt::AlignRight)
    00202                 dx = r.right() - xLabelDist + tr.x();
    00203             else
    00204                 dx = r.left() + r.width() / 2;
    00205         }
    00206         else
    00207         {
    00208             if (d_data->align & (int) Qt::AlignLeft)
    00209                 dx += tr.x() - xlw1;
    00210             else if (d_data->align & (int) Qt::AlignRight)
    00211                 dx -= tr.x() - xlw1;
    00212         }
    00213
    00214 #if QT_VERSION < 0x040000
    00215         tr.moveBy(dx, dy);
    00216 #else
    00217         tr.translate(dx, dy);
    00218 #endif
    00219         d_data->label.draw(p, tr);
    00220     }
    00221 }
    00222
    00229 void QwtPlotMarker::setLineStyle(QwtPlotMarker::LineStyle st)
    00230 {
    00231     if ( st != d_data->style )
    00232     {
    00233         d_data->style = st;
    00234         itemChanged();
    00235     }
    00236 }
    00237
    00242 QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
    00243 {
    00244     return d_data->style;
    00245 }
    00246
    00252 void QwtPlotMarker::setSymbol(const QwtSymbol &s)
    00253 {
    00254     d_data->sym = s;
    00255     itemChanged();
    00256 }
    00257
    00262 const QwtSymbol &QwtPlotMarker::symbol() const
    00263 {
    00264     return d_data->sym;
    00265 }
    00266
    00272 void QwtPlotMarker::setLabel(const QwtText& label)
    00273 {
    00274     if ( label != d_data->label )
    00275     {
    00276         d_data->label = label;
    00277         itemChanged();
    00278     }
    00279 }
    00280
    00285 QwtText QwtPlotMarker::label() const
    00286 {
    00287     return d_data->label;
    00288 }
    00289
    00301 #if QT_VERSION < 0x040000
    00302 void QwtPlotMarker::setLabelAlignment(int align)
    00303 #else
    00304 void QwtPlotMarker::setLabelAlignment(Qt::Alignment align)
    00305 #endif
    00306 {
    00307     if ( align == d_data->align )
    00308         return;
    00309
    00310     d_data->align = align;
    00311     itemChanged();
    00312 }
    00313
    00318 #if QT_VERSION < 0x040000
    00319 int QwtPlotMarker::labelAlignment() const
    00320 #else
    00321 Qt::Alignment QwtPlotMarker::labelAlignment() const
    00322 #endif
    00323 {
    00324     return d_data->align;
    00325 }
    00326
    00332 void QwtPlotMarker::setLinePen(const QPen &p)
    00333 {
    00334     if ( p != d_data->pen )
    00335     {
    00336         d_data->pen = p;
    00337         itemChanged();
    00338     }
    00339 }
    00340
    00345 const QPen &QwtPlotMarker::linePen() const
    00346 {
    00347     return d_data->pen;
    00348 }
    00349
    00350 QwtDoubleRect QwtPlotMarker::boundingRect() const
    00351 {
    00352     return QwtDoubleRect(d_data->xValue, d_data->yValue, 0.0, 0.0);
    00353 }