qwt_plot_magnifier.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 <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            A positive delta indicates that the wheel was 
00336            rotated forwards away from the user; a negative 
00337            value indicates that the wheel was rotated 
00338            backwards toward the user.
00339            Most mouse types work in steps of 15 degrees, 
00340            in which case the delta value is a multiple 
00341            of 120 (== 15 * 8).
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 }

Generated on Mon Jun 11 07:41:38 2007 for Qwt User's Guide by  doxygen 1.4.6