# qwt_plot_picker.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 "qwt_plot.h"
    00013 #include "qwt_double_rect.h"
    00014 #include "qwt_scale_div.h"
    00015 #include "qwt_painter.h"
    00016 #include "qwt_scale_map.h"
    00017 #include "qwt_plot_picker.h"
    00018
    00032 QwtPlotPicker::QwtPlotPicker(QwtPlotCanvas *canvas):
    00033     QwtPicker(canvas),
    00034     d_xAxis(-1),
    00035     d_yAxis(-1)
    00036 {
    00037     if ( !canvas )
    00038         return;
    00039
    00040     // attach axes
    00041
    00042     int xAxis = QwtPlot::xBottom;
    00043
    00044     const QwtPlot *plot = QwtPlotPicker::plot();
    00045     if ( !plot->axisEnabled(QwtPlot::xBottom) &&
    00046         plot->axisEnabled(QwtPlot::xTop) )
    00047     {
    00048         xAxis = QwtPlot::xTop;
    00049     }
    00050
    00051     int yAxis = QwtPlot::yLeft;
    00052     if ( !plot->axisEnabled(QwtPlot::yLeft) &&
    00053         plot->axisEnabled(QwtPlot::yRight) )
    00054     {
    00055         yAxis = QwtPlot::yRight;
    00056     }
    00057
    00058     setAxis(xAxis, yAxis);
    00059 }
    00060
    00070 QwtPlotPicker::QwtPlotPicker(int xAxis, int yAxis, QwtPlotCanvas *canvas):
    00071     QwtPicker(canvas),
    00072     d_xAxis(xAxis),
    00073     d_yAxis(yAxis)
    00074 {
    00075 }
    00076
    00093 QwtPlotPicker::QwtPlotPicker(int xAxis, int yAxis, int selectionFlags,
    00094         RubberBand rubberBand, DisplayMode trackerMode,
    00095         QwtPlotCanvas *canvas):
    00096     QwtPicker(selectionFlags, rubberBand, trackerMode, canvas),
    00097     d_xAxis(xAxis),
    00098     d_yAxis(yAxis)
    00099 {
    00100 }
    00101
    00103 QwtPlotCanvas *QwtPlotPicker::canvas()
    00104 {
    00105     QWidget *w = parentWidget();
    00106     if ( w && w->inherits("QwtPlotCanvas") )
    00107         return (QwtPlotCanvas *)w;
    00108
    00109     return NULL;
    00110 }
    00111
    00113 const QwtPlotCanvas *QwtPlotPicker::canvas() const
    00114 {
    00115     return ((QwtPlotPicker *)this)->canvas();
    00116 }
    00117
    00119 QwtPlot *QwtPlotPicker::plot()
    00120 {
    00121     QObject *w = canvas();
    00122     if ( w )
    00123     {
    00124         w = w->parent();
    00125         if ( w && w->inherits("QwtPlot") )
    00126             return (QwtPlot *)w;
    00127     }
    00128
    00129     return NULL;
    00130 }
    00131
    00133 const QwtPlot *QwtPlotPicker::plot() const
    00134 {
    00135     return ((QwtPlotPicker *)this)->plot();
    00136 }
    00137
    00143 QwtDoubleRect QwtPlotPicker::scaleRect() const
    00144 {
    00145     QwtDoubleRect rect;
    00146
    00147     if ( plot() )
    00148     {
    00149         const QwtScaleDiv *xs = plot()->axisScaleDiv(xAxis());
    00150         const QwtScaleDiv *ys = plot()->axisScaleDiv(yAxis());
    00151
    00152         if ( xs && ys )
    00153         {
    00154             rect = QwtDoubleRect( xs->lBound(), ys->lBound(),
    00155                 xs->range(), ys->range() );
    00156             rect = rect.normalized();
    00157         }
    00158     }
    00159
    00160     return rect;
    00161 }
    00162
    00169 void QwtPlotPicker::setAxis(int xAxis, int yAxis)
    00170 {
    00171     const QwtPlot *plt = plot();
    00172     if ( !plt )
    00173         return;
    00174
    00175     if ( xAxis != d_xAxis || yAxis != d_yAxis )
    00176     {
    00177         d_xAxis = xAxis;
    00178         d_yAxis = yAxis;
    00179     }
    00180 }
    00181
    00183 int QwtPlotPicker::xAxis() const
    00184 {
    00185     return d_xAxis;
    00186 }
    00187
    00189 int QwtPlotPicker::yAxis() const
    00190 {
    00191     return d_yAxis;
    00192 }
    00193
    00200 QwtText QwtPlotPicker::trackerText(const QPoint &pos) const
    00201 {
    00202     return trackerText(invTransform(pos));
    00203 }
    00204
    00217 QwtText QwtPlotPicker::trackerText(const QwtDoublePoint &pos) const
    00218 {
    00219     QString text;
    00220
    00221     switch(rubberBand())
    00222     {
    00223         case HLineRubberBand:
    00224             text.sprintf("%.4f", pos.y());
    00225             break;
    00226         case VLineRubberBand:
    00227             text.sprintf("%.4f", pos.x());
    00228             break;
    00229         default:
    00230             text.sprintf("%.4f, %.4f", pos.x(), pos.y());
    00231     }
    00232     return QwtText(text);
    00233 }
    00234
    00244 void QwtPlotPicker::append(const QPoint &pos)
    00245 {
    00246     QwtPicker::append(pos);
    00247     emit appended(invTransform(pos));
    00248 }
    00249
    00259 void QwtPlotPicker::move(const QPoint &pos)
    00260 {
    00261     QwtPicker::move(pos);
    00262     emit moved(invTransform(pos));
    00263 }
    00264
    00273 bool QwtPlotPicker::end(bool ok)
    00274 {
    00275     ok = QwtPicker::end(ok);
    00276     if ( !ok )
    00277         return false;
    00278
    00279     QwtPlot *plot = QwtPlotPicker::plot();
    00280     if ( !plot )
    00281         return false;
    00282
    00283     const QwtPolygon &pa = selection();
    00284     if ( pa.count() == 0 )
    00285         return false;
    00286
    00287     if ( selectionFlags() & PointSelection )
    00288     {
    00289         const QwtDoublePoint pos = invTransform(pa[0]);
    00290         emit selected(pos);
    00291     }
    00292     else if ( (selectionFlags() & RectSelection) && pa.count() >= 2 )
    00293     {
    00294         QPoint p1 = pa[0];
    00295         QPoint p2 = pa[int(pa.count() - 1)];
    00296
    00297         if ( selectionFlags() & CenterToCorner )
    00298         {
    00299             p1.setX(p1.x() - (p2.x() - p1.x()));
    00300             p1.setY(p1.y() - (p2.y() - p1.y()));
    00301         }
    00302         else if ( selectionFlags() & CenterToRadius )
    00303         {
    00304             const int radius = qwtMax(qwtAbs(p2.x() - p1.x()),
    00305                 qwtAbs(p2.y() - p1.y()));
    00306             p2.setX(p1.x() + radius);
    00307             p2.setY(p1.y() + radius);
    00308             p1.setX(p1.x() - radius);
    00309             p1.setY(p1.y() - radius);
    00310         }
    00311
    00312         emit selected(invTransform(QRect(p1, p2)).normalized());
    00313     }
    00314     else
    00315     {
    00316         QwtArray<QwtDoublePoint> dpa(pa.count());
    00317         for ( int i = 0; i < int(pa.count()); i++ )
    00318             dpa[i] = invTransform(pa[i]);
    00319
    00320         emit selected(dpa);
    00321     }
    00322
    00323     return true;
    00324 }
    00325
    00332 QwtDoubleRect QwtPlotPicker::invTransform(const QRect &rect) const
    00333 {
    00334     QwtScaleMap xMap = plot()->canvasMap(d_xAxis);
    00335     QwtScaleMap yMap = plot()->canvasMap(d_yAxis);
    00336
    00337     const double left = xMap.invTransform(rect.left());
    00338     const double right = xMap.invTransform(rect.right());
    00339     const double top = yMap.invTransform(rect.top());
    00340     const double bottom = yMap.invTransform(rect.bottom());
    00341
    00342     return QwtDoubleRect(left, top,
    00343         right - left, bottom - top);
    00344 }
    00345
    00351 QRect QwtPlotPicker::transform(const QwtDoubleRect &rect) const
    00352 {
    00353     QwtScaleMap xMap = plot()->canvasMap(d_xAxis);
    00354     QwtScaleMap yMap = plot()->canvasMap(d_yAxis);
    00355
    00356     const int left = xMap.transform(rect.left());
    00357     const int right = xMap.transform(rect.right());
    00358     const int top = yMap.transform(rect.top());
    00359     const int bottom = yMap.transform(rect.bottom());
    00360
    00361     return QRect(left, top, right - left, bottom - top);
    00362 }
    00363
    00369 QwtDoublePoint QwtPlotPicker::invTransform(const QPoint &pos) const
    00370 {
    00371     QwtScaleMap xMap = plot()->canvasMap(d_xAxis);
    00372     QwtScaleMap yMap = plot()->canvasMap(d_yAxis);
    00373
    00374     return QwtDoublePoint(
    00375         xMap.invTransform(pos.x()),
    00376         yMap.invTransform(pos.y())
    00377     );
    00378 }
    00379
    00385 QPoint QwtPlotPicker::transform(const QwtDoublePoint &pos) const
    00386 {
    00387     QwtScaleMap xMap = plot()->canvasMap(d_xAxis);
    00388     QwtScaleMap yMap = plot()->canvasMap(d_yAxis);
    00389
    00390     return QPoint(
    00391         xMap.transform(pos.x()),
    00392         yMap.transform(pos.y())
    00393     );
    00394 }