# qwt_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 <qwidget.h>
    00015 #include "qwt_math.h"
    00016 #include "qwt_magnifier.h"
    00017
    00018 class QwtMagnifier::PrivateData
    00019 {
    00020 public:
    00021     PrivateData():
    00022         isEnabled(false),
    00023         wheelFactor(0.9),
    00024         wheelButtonState(Qt::NoButton),
    00025         mouseFactor(0.95),
    00026         mouseButton(Qt::RightButton),
    00027         mouseButtonState(Qt::NoButton),
    00028         keyFactor(0.9),
    00029         zoomInKey(Qt::Key_Plus),
    00030         zoomOutKey(Qt::Key_Minus),
    00031 #if QT_VERSION < 0x040000
    00032         zoomInKeyModifiers(Qt::NoButton),
    00033         zoomOutKeyModifiers(Qt::NoButton),
    00034 #else
    00035         zoomInKeyModifiers(Qt::NoModifier),
    00036         zoomOutKeyModifiers(Qt::NoModifier),
    00037 #endif
    00038         mousePressed(false)
    00039     {
    00040     }
    00041
    00042     bool isEnabled;
    00043
    00044     double wheelFactor;
    00045     int wheelButtonState;
    00046
    00047     double mouseFactor;
    00048     int mouseButton;
    00049     int mouseButtonState;
    00050
    00051     double keyFactor;
    00052     int zoomInKey;
    00053     int zoomOutKey;
    00054     int zoomInKeyModifiers;
    00055     int zoomOutKeyModifiers;
    00056
    00057     bool mousePressed;
    00058     bool hasMouseTracking;
    00059     QPoint mousePos;
    00060 };
    00061
    00066 QwtMagnifier::QwtMagnifier(QWidget *parent):
    00067     QObject(parent)
    00068 {
    00069     d_data = new PrivateData();
    00070     setEnabled(true);
    00071 }
    00072
    00074 QwtMagnifier::~QwtMagnifier()
    00075 {
    00076     delete d_data;
    00077 }
    00078
    00088 void QwtMagnifier::setEnabled(bool on)
    00089 {
    00090     if ( d_data->isEnabled != on )
    00091     {
    00092         d_data->isEnabled = on;
    00093
    00094         QObject *o = parent();
    00095         if ( o )
    00096         {
    00097             if ( d_data->isEnabled )
    00098                 o->installEventFilter(this);
    00099             else
    00100                 o->removeEventFilter(this);
    00101         }
    00102     }
    00103 }
    00104
    00109 bool QwtMagnifier::isEnabled() const
    00110 {
    00111     return d_data->isEnabled;
    00112 }
    00113
    00125 void QwtMagnifier::setWheelFactor(double factor)
    00126 {
    00127     d_data->wheelFactor = factor;
    00128 }
    00129
    00134 double QwtMagnifier::wheelFactor() const
    00135 {
    00136     return d_data->wheelFactor;
    00137 }
    00138
    00146 void QwtMagnifier::setWheelButtonState(int buttonState)
    00147 {
    00148     d_data->wheelButtonState = buttonState;
    00149 }
    00150
    00155 int QwtMagnifier::wheelButtonState() const
    00156 {
    00157     return d_data->wheelButtonState;
    00158 }
    00159
    00170 void QwtMagnifier::setMouseFactor(double factor)
    00171 {
    00172     d_data->mouseFactor = factor;
    00173 }
    00174
    00179 double QwtMagnifier::mouseFactor() const
    00180 {
    00181     return d_data->mouseFactor;
    00182 }
    00183
    00192 void QwtMagnifier::setMouseButton(int button, int buttonState)
    00193 {
    00194     d_data->mouseButton = button;
    00195     d_data->mouseButtonState = buttonState;
    00196 }
    00197
    00199 void QwtMagnifier::getMouseButton(
    00200     int &button, int &buttonState) const
    00201 {
    00202     button = d_data->mouseButton;
    00203     buttonState = d_data->mouseButtonState;
    00204 }
    00205
    00217 void QwtMagnifier::setKeyFactor(double factor)
    00218 {
    00219     d_data->keyFactor = factor;
    00220 }
    00221
    00226 double QwtMagnifier::keyFactor() const
    00227 {
    00228     return d_data->keyFactor;
    00229 }
    00230
    00239 void QwtMagnifier::setZoomInKey(int key, int modifiers)
    00240 {
    00241     d_data->zoomInKey = key;
    00242     d_data->zoomInKeyModifiers = modifiers;
    00243 }
    00244
    00246 void QwtMagnifier::getZoomInKey(int &key, int &modifiers) const
    00247 {
    00248     key = d_data->zoomInKey;
    00249     modifiers = d_data->zoomInKeyModifiers;
    00250 }
    00251
    00260 void QwtMagnifier::setZoomOutKey(int key, int modifiers)
    00261 {
    00262     d_data->zoomOutKey = key;
    00263     d_data->zoomOutKeyModifiers = modifiers;
    00264 }
    00265
    00267 void QwtMagnifier::getZoomOutKey(int &key, int &modifiers) const
    00268 {
    00269     key = d_data->zoomOutKey;
    00270     modifiers = d_data->zoomOutKeyModifiers;
    00271 }
    00272
    00282 bool QwtMagnifier::eventFilter(QObject *o, QEvent *e)
    00283 {
    00284     if ( o && o == parent() )
    00285     {
    00286         switch(e->type() )
    00287         {
    00288             case QEvent::MouseButtonPress:
    00289             {
    00290                 widgetMousePressEvent((QMouseEvent *)e);
    00291                 break;
    00292             }
    00293             case QEvent::MouseMove:
    00294             {
    00295                 widgetMouseMoveEvent((QMouseEvent *)e);
    00296                 break;
    00297             }
    00298             case QEvent::MouseButtonRelease:
    00299             {
    00300                 widgetMouseReleaseEvent((QMouseEvent *)e);
    00301                 break;
    00302             }
    00303             case QEvent::Wheel:
    00304             {
    00305                 widgetWheelEvent((QWheelEvent *)e);
    00306                 break;
    00307             }
    00308             case QEvent::KeyPress:
    00309             {
    00310                 widgetKeyPressEvent((QKeyEvent *)e);
    00311                 break;
    00312             }
    00313             case QEvent::KeyRelease:
    00314             {
    00315                 widgetKeyReleaseEvent((QKeyEvent *)e);
    00316                 break;
    00317             }
    00318             default:;
    00319         }
    00320     }
    00321     return QObject::eventFilter(o, e);
    00322 }
    00323
    00330 void QwtMagnifier::widgetMousePressEvent(QMouseEvent *me)
    00331 {
    00332     if ( me->button() != d_data->mouseButton || parentWidget() == NULL )
    00333         return;
    00334
    00335 #if QT_VERSION < 0x040000
    00336     if ( (me->state() & Qt::KeyButtonMask) !=
    00337         (d_data->mouseButtonState & Qt::KeyButtonMask) )
    00338 #else
    00339     if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
    00340         (int)(d_data->mouseButtonState & Qt::KeyboardModifierMask) )
    00341 #endif
    00342     {
    00343         return;
    00344     }
    00345
    00346     d_data->hasMouseTracking = parentWidget()->hasMouseTracking();
    00347     parentWidget()->setMouseTracking(true);
    00348     d_data->mousePos = me->pos();
    00349     d_data->mousePressed = true;
    00350 }
    00351
    00356 void QwtMagnifier::widgetMouseReleaseEvent(QMouseEvent *)
    00357 {
    00358     if ( d_data->mousePressed && parentWidget() )
    00359     {
    00360         d_data->mousePressed = false;
    00361         parentWidget()->setMouseTracking(d_data->hasMouseTracking);
    00362     }
    00363 }
    00364
    00371 void QwtMagnifier::widgetMouseMoveEvent(QMouseEvent *me)
    00372 {
    00373     if ( !d_data->mousePressed )
    00374         return;
    00375
    00376     const int dy = me->pos().y() - d_data->mousePos.y();
    00377     if ( dy != 0 )
    00378     {
    00379         double f = d_data->mouseFactor;
    00380         if ( dy < 0 )
    00381             f = 1 / f;
    00382
    00383         rescale(f);
    00384     }
    00385
    00386     d_data->mousePos = me->pos();
    00387 }
    00388
    00395 void QwtMagnifier::widgetWheelEvent(QWheelEvent *we)
    00396 {
    00397 #if QT_VERSION < 0x040000
    00398     if ( (we->state() & Qt::KeyButtonMask) !=
    00399         (d_data->wheelButtonState & Qt::KeyButtonMask) )
    00400 #else
    00401     if ( (we->modifiers() & Qt::KeyboardModifierMask) !=
    00402         (int)(d_data->wheelButtonState & Qt::KeyboardModifierMask) )
    00403 #endif
    00404     {
    00405         return;
    00406     }
    00407
    00408     if ( d_data->wheelFactor != 0.0 )
    00409     {
    00410        /*
    00411            A positive delta indicates that the wheel was
    00412            rotated forwards away from the user; a negative
    00413            value indicates that the wheel was rotated
    00414            backwards toward the user.
    00415            Most mouse types work in steps of 15 degrees,
    00416            in which case the delta value is a multiple
    00417            of 120 (== 15 * 8).
    00418         */
    00419         double f = ::pow(d_data->wheelFactor,
    00420             qwtAbs(we->delta() / 120));
    00421         if ( we->delta() > 0 )
    00422             f = 1 / f;
    00423
    00424         rescale(f);
    00425     }
    00426 }
    00427
    00434 void QwtMagnifier::widgetKeyPressEvent(QKeyEvent *ke)
    00435 {
    00436     const int key = ke->key();
    00437 #if QT_VERSION < 0x040000
    00438     const int state = ke->state();
    00439 #else
    00440     const int state = ke->modifiers();
    00441 #endif
    00442
    00443     if ( key == d_data->zoomInKey &&
    00444         state == d_data->zoomInKeyModifiers )
    00445     {
    00446         rescale(d_data->keyFactor);
    00447     }
    00448     else if ( key == d_data->zoomOutKey &&
    00449         state == d_data->zoomOutKeyModifiers )
    00450     {
    00451         rescale(1.0 / d_data->keyFactor);
    00452     }
    00453 }
    00454
    00461 void QwtMagnifier::widgetKeyReleaseEvent(QKeyEvent *)
    00462 {
    00463 }
    00464
    00465 QWidget *QwtMagnifier::parentWidget()
    00466 {
    00467     if ( parent()->inherits("QWidget") )
    00468         return (QWidget *)parent();
    00469
    00470     return NULL;
    00471 }
    00472
    00473 const QWidget *QwtMagnifier::parentWidget() const
    00474 {
    00475     if ( parent()->inherits("QWidget") )
    00476         return (const QWidget *)parent();
    00477
    00478     return NULL;
    00479 }
    00480