00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 #include <math.h>
00013 #include <qevent.h>
00014 #include "qwt_plot.h"
00015 #include "qwt_plot_canvas.h"
00016 #include "qwt_scale_div.h"
00017 #include "qwt_plot_magnifier.h"
00018 
00019 class QwtPlotMagnifier::PrivateData
00020 {
00021 public:
00022     PrivateData():
00023         isEnabled(false),
00024         wheelFactor(0.9),
00025         wheelButtonState(Qt::NoButton),
00026         mouseFactor(0.95),
00027         mouseButton(Qt::RightButton),
00028         mouseButtonState(Qt::NoButton),
00029         keyFactor(0.9),
00030         zoomInKey(Qt::Key_Plus),
00031         zoomOutKey(Qt::Key_Minus),
00032 #if QT_VERSION < 0x040000
00033         zoomInKeyButtonState(Qt::NoButton),
00034         zoomOutKeyButtonState(Qt::NoButton),
00035 #else
00036         zoomInKeyButtonState(Qt::NoModifier),
00037         zoomOutKeyButtonState(Qt::NoModifier),
00038 #endif
00039         mousePressed(false)
00040     {
00041         for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00042             isAxisEnabled[axis] = true;
00043     }
00044 
00045     bool isEnabled;
00046 
00047     double wheelFactor;
00048     int wheelButtonState;
00049 
00050     double mouseFactor;
00051     int mouseButton;
00052     int mouseButtonState;
00053 
00054     double keyFactor;
00055     int zoomInKey;
00056     int zoomOutKey;
00057     int zoomInKeyButtonState;
00058     int zoomOutKeyButtonState;
00059 
00060     bool isAxisEnabled[QwtPlot::axisCnt];
00061 
00062     bool mousePressed;
00063     bool hasMouseTracking;
00064     QPoint mousePos;
00065 };
00066 
00067 QwtPlotMagnifier::QwtPlotMagnifier(QwtPlotCanvas *canvas):
00068     QObject(canvas)
00069 {
00070     d_data = new PrivateData();
00071     setEnabled(true);
00072 }
00073 
00074 QwtPlotMagnifier::~QwtPlotMagnifier()
00075 {
00076     delete d_data;
00077 }
00078 
00079 void QwtPlotMagnifier::setEnabled(bool on)
00080 {
00081     if ( d_data->isEnabled != on )
00082     {
00083         d_data->isEnabled = on;
00084 
00085         QObject *o = parent();
00086         if ( o )
00087         {
00088             if ( d_data->isEnabled )
00089                 o->installEventFilter(this);
00090             else
00091                 o->removeEventFilter(this);
00092         }
00093     }
00094 }
00095 
00096 bool QwtPlotMagnifier::isEnabled() const
00097 {
00098     return d_data->isEnabled;
00099 }
00100 
00101 void QwtPlotMagnifier::setWheelFactor(double factor)
00102 {
00103     d_data->wheelFactor = factor;
00104 }
00105 
00106 double QwtPlotMagnifier::wheelFactor() const
00107 {
00108     return d_data->wheelFactor;
00109 }
00110 
00111 void QwtPlotMagnifier::setWheelButtonState(int buttonState)
00112 {
00113     d_data->wheelButtonState = buttonState;
00114 }
00115 
00116 int QwtPlotMagnifier::wheelButtonState() const
00117 {
00118     return d_data->wheelButtonState;
00119 }
00120 
00121 void QwtPlotMagnifier::setMouseFactor(double factor)
00122 {
00123     d_data->mouseFactor = factor;
00124 }
00125 
00126 double QwtPlotMagnifier::mouseFactor() const
00127 {
00128     return d_data->mouseFactor;
00129 }
00130 
00131 void QwtPlotMagnifier::setMouseButton(int button, int buttonState)
00132 {
00133     d_data->mouseButton = button;
00134     d_data->mouseButtonState = buttonState;
00135 }
00136 
00137 void QwtPlotMagnifier::getMouseButton(
00138     int &button, int &buttonState) const
00139 {
00140     button = d_data->mouseButton;
00141     buttonState = d_data->mouseButtonState;
00142 }
00143 
00144 void QwtPlotMagnifier::setKeyFactor(double factor)
00145 {
00146     d_data->keyFactor = factor;
00147 }
00148 
00149 double QwtPlotMagnifier::keyFactor() const
00150 {
00151     return d_data->keyFactor;
00152 }
00153 
00154 void QwtPlotMagnifier::setZoomInKey(int key, int buttonState)
00155 {
00156     d_data->zoomInKey = key;
00157     d_data->zoomInKeyButtonState = buttonState;
00158 }
00159 
00160 void QwtPlotMagnifier::getZoomInKey(int &key, int &buttonState)
00161 {
00162     key = d_data->zoomInKey;
00163     buttonState = d_data->zoomInKeyButtonState;
00164 }
00165 
00166 void QwtPlotMagnifier::setZoomOutKey(int key, int buttonState)
00167 {
00168     d_data->zoomOutKey = key;
00169     d_data->zoomOutKeyButtonState = buttonState;
00170 }
00171 
00172 void QwtPlotMagnifier::getZoomOutKey(int &key, int &buttonState)
00173 {
00174     key = d_data->zoomOutKey;
00175     buttonState = d_data->zoomOutKeyButtonState;
00176 }
00177 
00178 void QwtPlotMagnifier::setAxisEnabled(int axis, bool on)
00179 {
00180     if ( axis >= 0 && axis < QwtPlot::axisCnt )
00181         d_data->isAxisEnabled[axis] = on;
00182 }
00183 
00184 bool QwtPlotMagnifier::isAxisEnabled(int axis) const
00185 {
00186     if ( axis >= 0 && axis < QwtPlot::axisCnt )
00187         return d_data->isAxisEnabled[axis];
00188 
00189     return true;
00190 }
00191 
00193 QwtPlotCanvas *QwtPlotMagnifier::canvas()
00194 {
00195     QObject *w = parent();
00196     if ( w && w->inherits("QwtPlotCanvas") )
00197         return (QwtPlotCanvas *)w;
00198 
00199     return NULL;
00200 }
00201 
00203 const QwtPlotCanvas *QwtPlotMagnifier::canvas() const
00204 {
00205     return ((QwtPlotMagnifier *)this)->canvas();
00206 }
00207 
00209 QwtPlot *QwtPlotMagnifier::plot()
00210 {
00211     QObject *w = canvas();
00212     if ( w )
00213     {
00214         w = w->parent();
00215         if ( w && w->inherits("QwtPlot") )
00216             return (QwtPlot *)w;
00217     }
00218 
00219     return NULL;
00220 }
00221 
00223 const QwtPlot *QwtPlotMagnifier::plot() const
00224 {
00225     return ((QwtPlotMagnifier *)this)->plot();
00226 }
00227 
00228 bool QwtPlotMagnifier::eventFilter(QObject *o, QEvent *e)
00229 {
00230     if ( o && o == parent() )
00231     {
00232         switch(e->type() )
00233         {
00234             case QEvent::MouseButtonPress:
00235             {
00236                 widgetMousePressEvent((QMouseEvent *)e);
00237                 break;
00238             }
00239             case QEvent::MouseMove:
00240             {
00241                 widgetMouseMoveEvent((QMouseEvent *)e);
00242                 break;
00243             }
00244             case QEvent::MouseButtonRelease:
00245             {
00246                 widgetMouseReleaseEvent((QMouseEvent *)e);
00247                 break;
00248             }
00249             case QEvent::Wheel:
00250             {
00251                 widgetWheelEvent((QWheelEvent *)e);
00252                 break;
00253             }
00254             case QEvent::KeyPress:
00255             {
00256                 widgetKeyPressEvent((QKeyEvent *)e);
00257                 break;
00258             }
00259             case QEvent::KeyRelease:
00260             {
00261                 widgetKeyReleaseEvent((QKeyEvent *)e);
00262                 break;
00263             }
00264             default:;
00265         }
00266     }
00267     return QObject::eventFilter(o, e);
00268 }
00269 
00270 void QwtPlotMagnifier::widgetMousePressEvent(QMouseEvent *me)
00271 {
00272     if ( me->button() != d_data->mouseButton )
00273         return;
00274 
00275 #if QT_VERSION < 0x040000
00276     if ( (me->state() & Qt::KeyButtonMask) !=
00277         (d_data->mouseButtonState & Qt::KeyButtonMask) )
00278 #else
00279     if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
00280         (int)(d_data->mouseButtonState & Qt::KeyboardModifierMask) )
00281 #endif
00282     {
00283         return;
00284     }
00285 
00286     d_data->hasMouseTracking = canvas()->hasMouseTracking();
00287     canvas()->setMouseTracking(true);
00288     d_data->mousePos = me->pos();
00289     d_data->mousePressed = true;
00290 }
00291 
00292 void QwtPlotMagnifier::widgetMouseReleaseEvent(QMouseEvent *)
00293 {
00294     if ( d_data->mousePressed )
00295     {
00296         d_data->mousePressed = false;
00297         canvas()->setMouseTracking(d_data->hasMouseTracking);
00298     }
00299 }
00300 
00301 void QwtPlotMagnifier::widgetMouseMoveEvent(QMouseEvent *me)
00302 {
00303     if ( !d_data->mousePressed )
00304         return;
00305 
00306     const int dy = me->pos().y() - d_data->mousePos.y();
00307     if ( dy != 0 )
00308     {
00309         double f = d_data->mouseFactor;
00310         if ( dy < 0 )
00311             f = 1 / f;
00312 
00313         rescale(f);
00314     }
00315 
00316     d_data->mousePos = me->pos();
00317 }
00318 
00319 void QwtPlotMagnifier::widgetWheelEvent(QWheelEvent *we)
00320 {
00321 #if QT_VERSION < 0x040000
00322     if ( (we->state() & Qt::KeyButtonMask) !=
00323         (d_data->wheelButtonState & Qt::KeyButtonMask) )
00324 #else
00325     if ( (we->modifiers() & Qt::KeyboardModifierMask) !=
00326         (int)(d_data->wheelButtonState & Qt::KeyboardModifierMask) )
00327 #endif
00328     {
00329         return;
00330     }
00331 
00332     if ( d_data->wheelFactor != 0.0 )
00333     {
00334        
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343         double f = ::pow(d_data->wheelFactor, 
00344             qwtAbs(we->delta() / 120));
00345         if ( we->delta() > 0 )
00346             f = 1 / f;
00347 
00348         rescale(f);
00349     }
00350 }
00351 
00352 void QwtPlotMagnifier::widgetKeyPressEvent(QKeyEvent *ke)
00353 {
00354     const int key = ke->key();
00355 #if QT_VERSION < 0x040000
00356     const int state = ke->state();
00357 #else
00358     const int state = ke->modifiers();
00359 #endif
00360 
00361     if ( key == d_data->zoomInKey && 
00362         state == d_data->zoomInKeyButtonState )
00363     {
00364         rescale(d_data->keyFactor);
00365     }
00366     else if ( key == d_data->zoomOutKey && 
00367         state == d_data->zoomOutKeyButtonState )
00368     {
00369         rescale(1.0 / d_data->keyFactor);
00370     }
00371 }
00372 
00373 void QwtPlotMagnifier::widgetKeyReleaseEvent(QKeyEvent *)
00374 {
00375 }
00376 
00377 void QwtPlotMagnifier::rescale(double factor)
00378 {
00379     if ( factor == 1.0 || factor == 0.0 )
00380         return;
00381 
00382     bool doReplot = false;
00383     QwtPlot* plt = plot();
00384 
00385     const bool autoReplot = plt->autoReplot();
00386     plt->setAutoReplot(false);
00387 
00388     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00389     {
00390         const QwtScaleDiv *scaleDiv = plt->axisScaleDiv(axisId);
00391         if ( isAxisEnabled(axisId) && scaleDiv->isValid() )
00392         {
00393             const double center =
00394                 scaleDiv->lBound() + scaleDiv->range() / 2;
00395             const double width_2 = scaleDiv->range() / 2 * factor;
00396 
00397             plt->setAxisScale(axisId, center - width_2, center + width_2);
00398             doReplot = true;
00399         }
00400     }
00401 
00402     plt->setAutoReplot(autoReplot);
00403 
00404     if ( doReplot )
00405         plt->replot();
00406 }