~ubuntu-branches/ubuntu/oneiric/qwt/oneiric-proposed

« back to all changes in this revision

Viewing changes to qwt-5.0.1/src/qwt_plot_magnifier.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2007-10-05 15:20:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071005152041-qmybqh4fj9jejyo2
Tags: 5.0.2-2
* Handle nostrip build option. (Closes: #437877)
* Build libqwt5-doc package in binary-indep target. (Closes: #443110)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2
 
 * Qwt Widget Library
3
 
 * Copyright (C) 1997   Josef Wilgen
4
 
 * Copyright (C) 2002   Uwe Rathmann
5
 
 *
6
 
 * This library is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the Qwt License, Version 1.0
8
 
 *****************************************************************************/
9
 
 
10
 
// vim: expandtab
11
 
 
12
 
#include <math.h>
13
 
#include <qevent.h>
14
 
#include "qwt_plot.h"
15
 
#include "qwt_plot_canvas.h"
16
 
#include "qwt_scale_div.h"
17
 
#include "qwt_plot_magnifier.h"
18
 
 
19
 
class QwtPlotMagnifier::PrivateData
20
 
{
21
 
public:
22
 
    PrivateData():
23
 
        isEnabled(false),
24
 
        wheelFactor(0.9),
25
 
        wheelButtonState(Qt::NoButton),
26
 
        mouseFactor(0.95),
27
 
        mouseButton(Qt::RightButton),
28
 
        mouseButtonState(Qt::NoButton),
29
 
        keyFactor(0.9),
30
 
        zoomInKey(Qt::Key_Plus),
31
 
        zoomOutKey(Qt::Key_Minus),
32
 
#if QT_VERSION < 0x040000
33
 
        zoomInKeyButtonState(Qt::NoButton),
34
 
        zoomOutKeyButtonState(Qt::NoButton),
35
 
#else
36
 
        zoomInKeyButtonState(Qt::NoModifier),
37
 
        zoomOutKeyButtonState(Qt::NoModifier),
38
 
#endif
39
 
        mousePressed(false)
40
 
    {
41
 
        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
42
 
            isAxisEnabled[axis] = true;
43
 
    }
44
 
 
45
 
    bool isEnabled;
46
 
 
47
 
    double wheelFactor;
48
 
    int wheelButtonState;
49
 
 
50
 
    double mouseFactor;
51
 
    int mouseButton;
52
 
    int mouseButtonState;
53
 
 
54
 
    double keyFactor;
55
 
    int zoomInKey;
56
 
    int zoomOutKey;
57
 
    int zoomInKeyButtonState;
58
 
    int zoomOutKeyButtonState;
59
 
 
60
 
    bool isAxisEnabled[QwtPlot::axisCnt];
61
 
 
62
 
    bool mousePressed;
63
 
    bool hasMouseTracking;
64
 
    QPoint mousePos;
65
 
};
66
 
 
67
 
QwtPlotMagnifier::QwtPlotMagnifier(QwtPlotCanvas *canvas):
68
 
    QObject(canvas)
69
 
{
70
 
    d_data = new PrivateData();
71
 
    setEnabled(true);
72
 
}
73
 
 
74
 
QwtPlotMagnifier::~QwtPlotMagnifier()
75
 
{
76
 
    delete d_data;
77
 
}
78
 
 
79
 
void QwtPlotMagnifier::setEnabled(bool on)
80
 
{
81
 
    if ( d_data->isEnabled != on )
82
 
    {
83
 
        d_data->isEnabled = on;
84
 
 
85
 
        QObject *o = parent();
86
 
        if ( o )
87
 
        {
88
 
            if ( d_data->isEnabled )
89
 
                o->installEventFilter(this);
90
 
            else
91
 
                o->removeEventFilter(this);
92
 
        }
93
 
    }
94
 
}
95
 
 
96
 
bool QwtPlotMagnifier::isEnabled() const
97
 
{
98
 
    return d_data->isEnabled;
99
 
}
100
 
 
101
 
void QwtPlotMagnifier::setWheelFactor(double factor)
102
 
{
103
 
    d_data->wheelFactor = factor;
104
 
}
105
 
 
106
 
double QwtPlotMagnifier::wheelFactor() const
107
 
{
108
 
    return d_data->wheelFactor;
109
 
}
110
 
 
111
 
void QwtPlotMagnifier::setWheelButtonState(int buttonState)
112
 
{
113
 
    d_data->wheelButtonState = buttonState;
114
 
}
115
 
 
116
 
int QwtPlotMagnifier::wheelButtonState() const
117
 
{
118
 
    return d_data->wheelButtonState;
119
 
}
120
 
 
121
 
void QwtPlotMagnifier::setMouseFactor(double factor)
122
 
{
123
 
    d_data->mouseFactor = factor;
124
 
}
125
 
 
126
 
double QwtPlotMagnifier::mouseFactor() const
127
 
{
128
 
    return d_data->mouseFactor;
129
 
}
130
 
 
131
 
void QwtPlotMagnifier::setMouseButton(int button, int buttonState)
132
 
{
133
 
    d_data->mouseButton = button;
134
 
    d_data->mouseButtonState = buttonState;
135
 
}
136
 
 
137
 
void QwtPlotMagnifier::getMouseButton(
138
 
    int &button, int &buttonState) const
139
 
{
140
 
    button = d_data->mouseButton;
141
 
    buttonState = d_data->mouseButtonState;
142
 
}
143
 
 
144
 
void QwtPlotMagnifier::setKeyFactor(double factor)
145
 
{
146
 
    d_data->keyFactor = factor;
147
 
}
148
 
 
149
 
double QwtPlotMagnifier::keyFactor() const
150
 
{
151
 
    return d_data->keyFactor;
152
 
}
153
 
 
154
 
void QwtPlotMagnifier::setZoomInKey(int key, int buttonState)
155
 
{
156
 
    d_data->zoomInKey = key;
157
 
    d_data->zoomInKeyButtonState = buttonState;
158
 
}
159
 
 
160
 
void QwtPlotMagnifier::getZoomInKey(int &key, int &buttonState)
161
 
{
162
 
    key = d_data->zoomInKey;
163
 
    buttonState = d_data->zoomInKeyButtonState;
164
 
}
165
 
 
166
 
void QwtPlotMagnifier::setZoomOutKey(int key, int buttonState)
167
 
{
168
 
    d_data->zoomOutKey = key;
169
 
    d_data->zoomOutKeyButtonState = buttonState;
170
 
}
171
 
 
172
 
void QwtPlotMagnifier::getZoomOutKey(int &key, int &buttonState)
173
 
{
174
 
    key = d_data->zoomOutKey;
175
 
    buttonState = d_data->zoomOutKeyButtonState;
176
 
}
177
 
 
178
 
void QwtPlotMagnifier::setAxisEnabled(int axis, bool on)
179
 
{
180
 
    if ( axis >= 0 && axis <= QwtPlot::axisCnt )
181
 
        d_data->isAxisEnabled[axis] = on;
182
 
}
183
 
 
184
 
bool QwtPlotMagnifier::isAxisEnabled(int axis) const
185
 
{
186
 
    if ( axis >= 0 && axis <= QwtPlot::axisCnt )
187
 
        return d_data->isAxisEnabled[axis];
188
 
 
189
 
    return true;
190
 
}
191
 
 
192
 
//! Return observed plot canvas
193
 
QwtPlotCanvas *QwtPlotMagnifier::canvas()
194
 
{
195
 
    QObject *w = parent();
196
 
    if ( w && w->inherits("QwtPlotCanvas") )
197
 
        return (QwtPlotCanvas *)w;
198
 
 
199
 
    return NULL;
200
 
}
201
 
 
202
 
//! Return Observed plot canvas
203
 
const QwtPlotCanvas *QwtPlotMagnifier::canvas() const
204
 
{
205
 
    return ((QwtPlotMagnifier *)this)->canvas();
206
 
}
207
 
 
208
 
//! Return plot widget, containing the observed plot canvas
209
 
QwtPlot *QwtPlotMagnifier::plot()
210
 
{
211
 
    QObject *w = canvas();
212
 
    if ( w )
213
 
    {
214
 
        w = w->parent();
215
 
        if ( w && w->inherits("QwtPlot") )
216
 
            return (QwtPlot *)w;
217
 
    }
218
 
 
219
 
    return NULL;
220
 
}
221
 
 
222
 
//! Return plot widget, containing the observed plot canvas
223
 
const QwtPlot *QwtPlotMagnifier::plot() const
224
 
{
225
 
    return ((QwtPlotMagnifier *)this)->plot();
226
 
}
227
 
 
228
 
bool QwtPlotMagnifier::eventFilter(QObject *o, QEvent *e)
229
 
{
230
 
    if ( o && o == parent() )
231
 
    {
232
 
        switch(e->type() )
233
 
        {
234
 
            case QEvent::MouseButtonPress:
235
 
            {
236
 
                widgetMousePressEvent((QMouseEvent *)e);
237
 
                break;
238
 
            }
239
 
            case QEvent::MouseMove:
240
 
            {
241
 
                widgetMouseMoveEvent((QMouseEvent *)e);
242
 
                break;
243
 
            }
244
 
            case QEvent::MouseButtonRelease:
245
 
            {
246
 
                widgetMouseReleaseEvent((QMouseEvent *)e);
247
 
                break;
248
 
            }
249
 
            case QEvent::Wheel:
250
 
            {
251
 
                widgetWheelEvent((QWheelEvent *)e);
252
 
                break;
253
 
            }
254
 
            case QEvent::KeyPress:
255
 
            {
256
 
                widgetKeyPressEvent((QKeyEvent *)e);
257
 
                break;
258
 
            }
259
 
            case QEvent::KeyRelease:
260
 
            {
261
 
                widgetKeyReleaseEvent((QKeyEvent *)e);
262
 
                break;
263
 
            }
264
 
            default:;
265
 
        }
266
 
    }
267
 
    return QObject::eventFilter(o, e);
268
 
}
269
 
 
270
 
void QwtPlotMagnifier::widgetMousePressEvent(QMouseEvent *me)
271
 
{
272
 
    if ( me->button() != d_data->mouseButton )
273
 
        return;
274
 
 
275
 
#if QT_VERSION < 0x040000
276
 
    if ( (me->state() & Qt::KeyButtonMask) !=
277
 
        (d_data->mouseButtonState & Qt::KeyButtonMask) )
278
 
#else
279
 
    if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
280
 
        (int)(d_data->mouseButtonState & Qt::KeyboardModifierMask) )
281
 
#endif
282
 
    {
283
 
        return;
284
 
    }
285
 
 
286
 
    d_data->hasMouseTracking = canvas()->hasMouseTracking();
287
 
    canvas()->setMouseTracking(true);
288
 
    d_data->mousePos = me->pos();
289
 
    d_data->mousePressed = true;
290
 
}
291
 
 
292
 
void QwtPlotMagnifier::widgetMouseReleaseEvent(QMouseEvent *)
293
 
{
294
 
    d_data->mousePressed = false;
295
 
    canvas()->setMouseTracking(d_data->hasMouseTracking);
296
 
}
297
 
 
298
 
void QwtPlotMagnifier::widgetMouseMoveEvent(QMouseEvent *me)
299
 
{
300
 
    if ( !d_data->mousePressed )
301
 
        return;
302
 
 
303
 
    const int dy = me->pos().y() - d_data->mousePos.y();
304
 
    if ( dy != 0 )
305
 
    {
306
 
        double f = d_data->mouseFactor;
307
 
        if ( dy < 0 )
308
 
            f = 1 / f;
309
 
 
310
 
        rescale(f);
311
 
    }
312
 
 
313
 
    d_data->mousePos = me->pos();
314
 
}
315
 
 
316
 
void QwtPlotMagnifier::widgetWheelEvent(QWheelEvent *we)
317
 
{
318
 
#if QT_VERSION < 0x040000
319
 
    if ( (we->state() & Qt::KeyButtonMask) !=
320
 
        (d_data->wheelButtonState & Qt::KeyButtonMask) )
321
 
#else
322
 
    if ( (we->modifiers() & Qt::KeyboardModifierMask) !=
323
 
        (int)(d_data->wheelButtonState & Qt::KeyboardModifierMask) )
324
 
#endif
325
 
    {
326
 
        return;
327
 
    }
328
 
 
329
 
    if ( d_data->wheelFactor != 0.0 )
330
 
    {
331
 
       /*
332
 
           A positive delta indicates that the wheel was 
333
 
           rotated forwards away from the user; a negative 
334
 
           value indicates that the wheel was rotated 
335
 
           backwards toward the user.
336
 
           Most mouse types work in steps of 15 degrees, 
337
 
           in which case the delta value is a multiple 
338
 
           of 120 (== 15 * 8).
339
 
        */
340
 
        double f = ::pow(d_data->wheelFactor, 
341
 
            qwtAbs(we->delta() / 120));
342
 
        if ( we->delta() > 0 )
343
 
            f = 1 / f;
344
 
 
345
 
        rescale(f);
346
 
    }
347
 
}
348
 
 
349
 
void QwtPlotMagnifier::widgetKeyPressEvent(QKeyEvent *ke)
350
 
{
351
 
    const int key = ke->key();
352
 
#if QT_VERSION < 0x040000
353
 
    const int state = ke->state();
354
 
#else
355
 
    const int state = ke->modifiers();
356
 
#endif
357
 
 
358
 
    if ( key == d_data->zoomInKey && 
359
 
        state == d_data->zoomInKeyButtonState )
360
 
    {
361
 
        rescale(d_data->keyFactor);
362
 
    }
363
 
    else if ( key == d_data->zoomOutKey && 
364
 
        state == d_data->zoomOutKeyButtonState )
365
 
    {
366
 
        rescale(1.0 / d_data->keyFactor);
367
 
    }
368
 
}
369
 
 
370
 
void QwtPlotMagnifier::widgetKeyReleaseEvent(QKeyEvent *)
371
 
{
372
 
}
373
 
 
374
 
void QwtPlotMagnifier::rescale(double factor)
375
 
{
376
 
    if ( factor == 1.0 || factor == 0.0 )
377
 
        return;
378
 
 
379
 
    bool doReplot = false;
380
 
    QwtPlot* plt = plot();
381
 
 
382
 
    const bool autoReplot = plt->autoReplot();
383
 
    plt->setAutoReplot(false);
384
 
 
385
 
    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
386
 
    {
387
 
        const QwtScaleDiv *scaleDiv = plt->axisScaleDiv(axisId);
388
 
        if ( isAxisEnabled(axisId) && scaleDiv->isValid() )
389
 
        {
390
 
            const double center =
391
 
                scaleDiv->lBound() + scaleDiv->range() / 2;
392
 
            const double width_2 = scaleDiv->range() / 2 * factor;
393
 
 
394
 
            plt->setAxisScale(axisId, center - width_2, center + width_2);
395
 
            doReplot = true;
396
 
        }
397
 
    }
398
 
 
399
 
    plt->setAutoReplot(autoReplot);
400
 
 
401
 
    if ( doReplot )
402
 
        plt->replot();
403
 
}