# 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         symbol = new QwtSymbol();
    00032     }
    00033
    00034     ~PrivateData()
    00035     {
    00036         delete symbol;
    00037     }
    00038
    00039     QwtText label;
    00040 #if QT_VERSION < 0x040000
    00041     int align;
    00042 #else
    00043     Qt::Alignment align;
    00044 #endif
    00045     QPen pen;
    00046     QwtSymbol *symbol;
    00047     LineStyle style;
    00048
    00049     double xValue;
    00050     double yValue;
    00051 };
    00052
    00054 QwtPlotMarker::QwtPlotMarker():
    00055     QwtPlotItem(QwtText("Marker"))
    00056 {
    00057     d_data = new PrivateData;
    00058     setZ(30.0);
    00059 }
    00060
    00062 QwtPlotMarker::~QwtPlotMarker()
    00063 {
    00064     delete d_data;
    00065 }
    00066
    00068 int QwtPlotMarker::rtti() const
    00069 {
    00070     return QwtPlotItem::Rtti_PlotMarker;
    00071 }
    00072
    00074 QwtDoublePoint QwtPlotMarker::value() const
    00075 {
    00076     return QwtDoublePoint(d_data->xValue, d_data->yValue);
    00077 }
    00078
    00080 double QwtPlotMarker::xValue() const
    00081 {
    00082     return d_data->xValue;
    00083 }
    00084
    00086 double QwtPlotMarker::yValue() const
    00087 {
    00088     return d_data->yValue;
    00089 }
    00090
    00092 void QwtPlotMarker::setValue(const QwtDoublePoint& pos)
    00093 {
    00094     setValue(pos.x(), pos.y());
    00095 }
    00096
    00098 void QwtPlotMarker::setValue(double x, double y)
    00099 {
    00100     if ( x != d_data->xValue || y != d_data->yValue )
    00101     {
    00102         d_data->xValue = x;
    00103         d_data->yValue = y;
    00104         itemChanged();
    00105     }
    00106 }
    00107
    00109 void QwtPlotMarker::setXValue(double x)
    00110 {
    00111     setValue(x, d_data->yValue);
    00112 }
    00113
    00115 void QwtPlotMarker::setYValue(double y)
    00116 {
    00117     setValue(d_data->xValue, y);
    00118 }
    00119
    00127 void QwtPlotMarker::draw(QPainter *p,
    00128     const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    00129     const QRect &r) const
    00130 {
    00131     const int x = xMap.transform(d_data->xValue);
    00132     const int y = yMap.transform(d_data->yValue);
    00133
    00134     // draw lines
    00135     if (d_data->style != NoLine)
    00136     {
    00137         p->setPen(d_data->pen);
    00138         if ((d_data->style == HLine) || (d_data->style == Cross))
    00139             QwtPainter::drawLine(p, r.left(), y, r.right(), y);
    00140         if ((d_data->style == VLine)||(d_data->style == Cross))
    00141             QwtPainter::drawLine(p, x, r.top(), x, r.bottom());
    00142     }
    00143
    00144     // draw symbol
    00145     QSize sSym(0, 0);
    00146     if (d_data->symbol->style() != QwtSymbol::NoSymbol)
    00147     {
    00148         sSym = d_data->symbol->size();
    00149         d_data->symbol->draw(p, x, y);
    00150     }
    00151
    00152     // draw label
    00153     if (!d_data->label.isEmpty())
    00154     {
    00155         int xlw = qwtMax(int(d_data->pen.width()), 1);
    00156         int ylw = xlw;
    00157         int xlw1;
    00158         int ylw1;
    00159
    00160         const int xLabelDist =
    00161             QwtPainter::metricsMap().screenToLayoutX(LabelDist);
    00162         const int yLabelDist =
    00163             QwtPainter::metricsMap().screenToLayoutY(LabelDist);
    00164
    00165         if ((d_data->style == VLine) || (d_data->style == HLine))
    00166         {
    00167             xlw1 = (xlw + 1) / 2 + xLabelDist;
    00168             xlw = xlw / 2 + xLabelDist;
    00169             ylw1 = (ylw + 1) / 2 + yLabelDist;
    00170             ylw = ylw / 2 + yLabelDist;
    00171         }
    00172         else
    00173         {
    00174             xlw1 = qwtMax((xlw + 1) / 2, (sSym.width() + 1) / 2) + xLabelDist;
    00175             xlw = qwtMax(xlw / 2, (sSym.width() + 1) / 2) + xLabelDist;
    00176             ylw1 = qwtMax((ylw + 1) / 2, (sSym.height() + 1) / 2) + yLabelDist;
    00177             ylw = qwtMax(ylw / 2, (sSym. height() + 1) / 2) + yLabelDist;
    00178         }
    00179
    00180         QRect tr(QPoint(0, 0), d_data->label.textSize(p->font()));
    00181         tr.moveCenter(QPoint(0, 0));
    00182
    00183         int dx = x;
    00184         int dy = y;
    00185
    00186         if (d_data->style == VLine)
    00187         {
    00188             if (d_data->align & (int) Qt::AlignTop)
    00189                 dy = r.top() + yLabelDist - tr.y();
    00190             else if (d_data->align & (int) Qt::AlignBottom)
    00191                 dy = r.bottom() - yLabelDist + tr.y();
    00192             else
    00193                 dy = r.top() + r.height() / 2;
    00194         }
    00195         else
    00196         {
    00197             if (d_data->align & (int) Qt::AlignTop)
    00198                 dy += tr.y() - ylw1;
    00199             else if (d_data->align & (int) Qt::AlignBottom)
    00200                 dy -= tr.y() - ylw1;
    00201         }
    00202
    00203
    00204         if (d_data->style == HLine)
    00205         {
    00206             if (d_data->align & (int) Qt::AlignLeft)
    00207                 dx = r.left() + xLabelDist - tr.x();
    00208             else if (d_data->align & (int) Qt::AlignRight)
    00209                 dx = r.right() - xLabelDist + tr.x();
    00210             else
    00211                 dx = r.left() + r.width() / 2;
    00212         }
    00213         else
    00214         {
    00215             if (d_data->align & (int) Qt::AlignLeft)
    00216                 dx += tr.x() - xlw1;
    00217             else if (d_data->align & (int) Qt::AlignRight)
    00218                 dx -= tr.x() - xlw1;
    00219         }
    00220
    00221 #if QT_VERSION < 0x040000
    00222         tr.moveBy(dx, dy);
    00223 #else
    00224         tr.translate(dx, dy);
    00225 #endif
    00226         d_data->label.draw(p, tr);
    00227     }
    00228 }
    00229
    00236 void QwtPlotMarker::setLineStyle(QwtPlotMarker::LineStyle st)
    00237 {
    00238     if ( st != d_data->style )
    00239     {
    00240         d_data->style = st;
    00241         itemChanged();
    00242     }
    00243 }
    00244
    00249 QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
    00250 {
    00251     return d_data->style;
    00252 }
    00253
    00259 void QwtPlotMarker::setSymbol(const QwtSymbol &s)
    00260 {
    00261     delete d_data->symbol;
    00262     d_data->symbol = s.clone();
    00263     itemChanged();
    00264 }
    00265
    00270 const QwtSymbol &QwtPlotMarker::symbol() const
    00271 {
    00272     return *d_data->symbol;
    00273 }
    00274
    00280 void QwtPlotMarker::setLabel(const QwtText& label)
    00281 {
    00282     if ( label != d_data->label )
    00283     {
    00284         d_data->label = label;
    00285         itemChanged();
    00286     }
    00287 }
    00288
    00293 QwtText QwtPlotMarker::label() const
    00294 {
    00295     return d_data->label;
    00296 }
    00297
    00309 #if QT_VERSION < 0x040000
    00310 void QwtPlotMarker::setLabelAlignment(int align)
    00311 #else
    00312 void QwtPlotMarker::setLabelAlignment(Qt::Alignment align)
    00313 #endif
    00314 {
    00315     if ( align == d_data->align )
    00316         return;
    00317
    00318     d_data->align = align;
    00319     itemChanged();
    00320 }
    00321
    00326 #if QT_VERSION < 0x040000
    00327 int QwtPlotMarker::labelAlignment() const
    00328 #else
    00329 Qt::Alignment QwtPlotMarker::labelAlignment() const
    00330 #endif
    00331 {
    00332     return d_data->align;
    00333 }
    00334
    00340 void QwtPlotMarker::setLinePen(const QPen &p)
    00341 {
    00342     if ( p != d_data->pen )
    00343     {
    00344         d_data->pen = p;
    00345         itemChanged();
    00346     }
    00347 }
    00348
    00353 const QPen &QwtPlotMarker::linePen() const
    00354 {
    00355     return d_data->pen;
    00356 }
    00357
    00358 QwtDoubleRect QwtPlotMarker::boundingRect() const
    00359 {
    00360     return QwtDoubleRect(d_data->xValue, d_data->yValue, 0.0, 0.0);
    00361 }