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     d_data->mousePressed = false;
00295     canvas()->setMouseTracking(d_data->hasMouseTracking);
00296 }
00297 
00298 void QwtPlotMagnifier::widgetMouseMoveEvent(QMouseEvent *me)
00299 {
00300     if ( !d_data->mousePressed )
00301         return;
00302 
00303     const int dy = me->pos().y() - d_data->mousePos.y();
00304     if ( dy != 0 )
00305     {
00306         double f = d_data->mouseFactor;
00307         if ( dy < 0 )
00308             f = 1 / f;
00309 
00310         rescale(f);
00311     }
00312 
00313     d_data->mousePos = me->pos();
00314 }
00315 
00316 void QwtPlotMagnifier::widgetWheelEvent(QWheelEvent *we)
00317 {
00318 #if QT_VERSION < 0x040000
00319     if ( (we->state() & Qt::KeyButtonMask) !=
00320         (d_data->wheelButtonState & Qt::KeyButtonMask) )
00321 #else
00322     if ( (we->modifiers() & Qt::KeyboardModifierMask) !=
00323         (int)(d_data->wheelButtonState & Qt::KeyboardModifierMask) )
00324 #endif
00325     {
00326         return;
00327     }
00328 
00329     if ( d_data->wheelFactor != 0.0 )
00330     {
00331        /*
00332            A positive delta indicates that the wheel was 
00333            rotated forwards away from the user; a negative 
00334            value indicates that the wheel was rotated 
00335            backwards toward the user.
00336            Most mouse types work in steps of 15 degrees, 
00337            in which case the delta value is a multiple 
00338            of 120 (== 15 * 8).
00339         */
00340         double f = ::pow(d_data->wheelFactor, 
00341             qwtAbs(we->delta() / 120));
00342         if ( we->delta() > 0 )
00343             f = 1 / f;
00344 
00345         rescale(f);
00346     }
00347 }
00348 
00349 void QwtPlotMagnifier::widgetKeyPressEvent(QKeyEvent *ke)
00350 {
00351     const int key = ke->key();
00352 #if QT_VERSION < 0x040000
00353     const int state = ke->state();
00354 #else
00355     const int state = ke->modifiers();
00356 #endif
00357 
00358     if ( key == d_data->zoomInKey && 
00359         state == d_data->zoomInKeyButtonState )
00360     {
00361         rescale(d_data->keyFactor);
00362     }
00363     else if ( key == d_data->zoomOutKey && 
00364         state == d_data->zoomOutKeyButtonState )
00365     {
00366         rescale(1.0 / d_data->keyFactor);
00367     }
00368 }
00369 
00370 void QwtPlotMagnifier::widgetKeyReleaseEvent(QKeyEvent *)
00371 {
00372 }
00373 
00374 void QwtPlotMagnifier::rescale(double factor)
00375 {
00376     if ( factor == 1.0 || factor == 0.0 )
00377         return;
00378 
00379     bool doReplot = false;
00380     QwtPlot* plt = plot();
00381 
00382     const bool autoReplot = plt->autoReplot();
00383     plt->setAutoReplot(false);
00384 
00385     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00386     {
00387         const QwtScaleDiv *scaleDiv = plt->axisScaleDiv(axisId);
00388         if ( isAxisEnabled(axisId) && scaleDiv->isValid() )
00389         {
00390             const double center =
00391                 scaleDiv->lBound() + scaleDiv->range() / 2;
00392             const double width_2 = scaleDiv->range() / 2 * factor;
00393 
00394             plt->setAxisScale(axisId, center - width_2, center + width_2);
00395             doReplot = true;
00396         }
00397     }
00398 
00399     plt->setAutoReplot(autoReplot);
00400 
00401     if ( doReplot )
00402         plt->replot();
00403 }

Generated on Mon Feb 26 21:22:37 2007 for Qwt User's Guide by  doxygen 1.4.6