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

« back to all changes in this revision

Viewing changes to qwt-5.1.2/examples/realtime_plot/scrollzoomer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2009-04-12 23:25:58 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090412232558-3bl06x785yr8xm8u
Tags: 5.1.2-1
* New upstream release.
* Bump compat/debhelper to 7.
* Bump Standards-Version to 3.8.1. No changes needed.
* Invert Maintainers and Uploaders field.
* Fix lintian warnings:
  - dh_clean _k deprecated.
  - missing dependency on libc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <qevent.h>
 
2
#include <qwt_plot_canvas.h>
 
3
#include <qwt_plot_layout.h>
 
4
#include <qwt_scale_engine.h>
 
5
#include <qwt_scale_widget.h>
 
6
#include "scrollbar.h"
 
7
#include "scrollzoomer.h"
 
8
 
 
9
class ScrollData
 
10
{
 
11
public:
 
12
    ScrollData():
 
13
        scrollBar(NULL),
 
14
        position(ScrollZoomer::OppositeToScale),
 
15
#if QT_VERSION < 0x040000
 
16
        mode(QScrollView::Auto)
 
17
#else
 
18
        mode(Qt::ScrollBarAsNeeded)
 
19
#endif
 
20
    {
 
21
    }
 
22
 
 
23
    ~ScrollData()
 
24
    {
 
25
        delete scrollBar;
 
26
    }
 
27
 
 
28
    ScrollBar *scrollBar;
 
29
    ScrollZoomer::ScrollBarPosition position;
 
30
#if QT_VERSION < 0x040000
 
31
    QScrollView::ScrollBarMode mode;
 
32
#else
 
33
    Qt::ScrollBarPolicy mode;
 
34
#endif
 
35
};
 
36
 
 
37
ScrollZoomer::ScrollZoomer(QwtPlotCanvas *canvas):
 
38
    QwtPlotZoomer(canvas),
 
39
    d_cornerWidget(NULL),
 
40
    d_hScrollData(NULL),
 
41
    d_vScrollData(NULL),
 
42
    d_inZoom(false),
 
43
    d_alignCanvasToScales(false)
 
44
{
 
45
    if ( !canvas )
 
46
        return;
 
47
 
 
48
    d_hScrollData = new ScrollData;
 
49
    d_vScrollData = new ScrollData;
 
50
}
 
51
 
 
52
ScrollZoomer::~ScrollZoomer()
 
53
{
 
54
    delete d_cornerWidget;
 
55
    delete d_vScrollData;
 
56
    delete d_hScrollData;
 
57
}
 
58
 
 
59
void ScrollZoomer::rescale()
 
60
{
 
61
    QwtScaleWidget *xScale = plot()->axisWidget(xAxis());
 
62
    QwtScaleWidget *yScale = plot()->axisWidget(yAxis());
 
63
 
 
64
    if ( zoomRectIndex() <= 0 )
 
65
    {
 
66
        if ( d_inZoom )
 
67
        {
 
68
            xScale->setMinBorderDist(0, 0);
 
69
            yScale->setMinBorderDist(0, 0);
 
70
 
 
71
            QwtPlotLayout *layout = plot()->plotLayout();
 
72
            layout->setAlignCanvasToScales(d_alignCanvasToScales);
 
73
 
 
74
            d_inZoom = false;
 
75
        }
 
76
    }
 
77
    else
 
78
    {
 
79
        if ( !d_inZoom )
 
80
        {
 
81
            /*
 
82
             We set a minimum border distance. 
 
83
             Otherwise the canvas size changes when scrolling, 
 
84
             between situations where the major ticks are at
 
85
             the canvas borders (requiring extra space for the label)
 
86
             and situations where all labels can be painted below/top
 
87
             or left/right of the canvas.
 
88
             */
 
89
            int start, end;
 
90
 
 
91
            xScale->getBorderDistHint(start, end);
 
92
            xScale->setMinBorderDist(start, end);
 
93
 
 
94
            yScale->getBorderDistHint(start, end);
 
95
            yScale->setMinBorderDist(start, end);
 
96
 
 
97
            QwtPlotLayout *layout = plot()->plotLayout();
 
98
            d_alignCanvasToScales = layout->alignCanvasToScales();
 
99
            layout->setAlignCanvasToScales(false);
 
100
 
 
101
            d_inZoom = true;
 
102
        }
 
103
    }
 
104
 
 
105
    QwtPlotZoomer::rescale();
 
106
    updateScrollBars();
 
107
}
 
108
 
 
109
ScrollBar *ScrollZoomer::scrollBar(Qt::Orientation o)
 
110
{
 
111
    ScrollBar *&sb = (o == Qt::Vertical) 
 
112
        ? d_vScrollData->scrollBar : d_hScrollData->scrollBar;
 
113
 
 
114
    if ( sb == NULL )
 
115
    {
 
116
        sb = new ScrollBar(o, canvas());
 
117
        sb->hide();
 
118
        connect(sb,
 
119
            SIGNAL(valueChanged(Qt::Orientation, double, double)),
 
120
            SLOT(scrollBarMoved(Qt::Orientation, double, double)));
 
121
    }
 
122
    return sb;
 
123
}
 
124
 
 
125
ScrollBar *ScrollZoomer::horizontalScrollBar() const
 
126
{
 
127
    return d_hScrollData->scrollBar;
 
128
}
 
129
 
 
130
ScrollBar *ScrollZoomer::verticalScrollBar() const
 
131
{
 
132
    return d_vScrollData->scrollBar;
 
133
}
 
134
    
 
135
#if QT_VERSION < 0x040000
 
136
void ScrollZoomer::setHScrollBarMode(QScrollView::ScrollBarMode mode)
 
137
#else
 
138
void ScrollZoomer::setHScrollBarMode(Qt::ScrollBarPolicy mode)
 
139
#endif
 
140
{
 
141
    if ( hScrollBarMode() != mode )
 
142
    {
 
143
        d_hScrollData->mode = mode;
 
144
        updateScrollBars();
 
145
    }
 
146
}
 
147
 
 
148
#if QT_VERSION < 0x040000
 
149
void ScrollZoomer::setVScrollBarMode(QScrollView::ScrollBarMode mode)
 
150
#else
 
151
void ScrollZoomer::setVScrollBarMode(Qt::ScrollBarPolicy mode)
 
152
#endif
 
153
{
 
154
    if ( vScrollBarMode() != mode )
 
155
    {
 
156
        d_vScrollData->mode = mode;
 
157
        updateScrollBars();
 
158
    }
 
159
}
 
160
 
 
161
#if QT_VERSION < 0x040000
 
162
QScrollView::ScrollBarMode ScrollZoomer::hScrollBarMode() const
 
163
#else
 
164
Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const
 
165
#endif
 
166
{
 
167
    return d_hScrollData->mode;
 
168
}
 
169
 
 
170
#if QT_VERSION < 0x040000
 
171
QScrollView::ScrollBarMode ScrollZoomer::vScrollBarMode() const
 
172
#else
 
173
Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const
 
174
#endif
 
175
{
 
176
    return d_vScrollData->mode;
 
177
}
 
178
 
 
179
void ScrollZoomer::setHScrollBarPosition(ScrollBarPosition pos)
 
180
{
 
181
    if ( d_hScrollData->position != pos )
 
182
    {
 
183
        d_hScrollData->position = pos;
 
184
        updateScrollBars();
 
185
    }
 
186
}
 
187
 
 
188
void ScrollZoomer::setVScrollBarPosition(ScrollBarPosition pos)
 
189
{
 
190
    if ( d_vScrollData->position != pos )
 
191
    {
 
192
        d_vScrollData->position = pos;
 
193
        updateScrollBars();
 
194
    }
 
195
}
 
196
 
 
197
ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const
 
198
{
 
199
    return d_hScrollData->position;
 
200
}
 
201
 
 
202
ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const
 
203
{
 
204
    return d_vScrollData->position;
 
205
}
 
206
 
 
207
void ScrollZoomer::setCornerWidget(QWidget *w)
 
208
{
 
209
    if ( w != d_cornerWidget )
 
210
    {
 
211
        if ( canvas() )
 
212
        {
 
213
            delete d_cornerWidget;
 
214
            d_cornerWidget = w;
 
215
            if ( d_cornerWidget->parent() != canvas() )
 
216
            {
 
217
#if QT_VERSION < 0x040000
 
218
                d_cornerWidget->reparent(canvas(), QPoint(0, 0));
 
219
#else
 
220
                d_cornerWidget->setParent(canvas());
 
221
#endif
 
222
            }
 
223
 
 
224
            updateScrollBars();
 
225
        }
 
226
    }
 
227
}
 
228
 
 
229
QWidget *ScrollZoomer::cornerWidget() const
 
230
{
 
231
    return d_cornerWidget;
 
232
}
 
233
 
 
234
bool ScrollZoomer::eventFilter(QObject *o, QEvent *e)
 
235
{
 
236
    if (  o == canvas() )
 
237
    {
 
238
        switch(e->type())
 
239
        {
 
240
            case QEvent::Resize:
 
241
            {
 
242
                const int fw = ((QwtPlotCanvas *)canvas())->frameWidth();
 
243
 
 
244
                QRect rect;
 
245
                rect.setSize(((QResizeEvent *)e)->size());
 
246
                rect.setRect(rect.x() + fw, rect.y() + fw,
 
247
                    rect.width() - 2 * fw, rect.height() - 2 * fw);
 
248
 
 
249
                layoutScrollBars(rect);
 
250
                break;
 
251
            }
 
252
            case QEvent::ChildRemoved:
 
253
            {
 
254
                const QObject *child = ((QChildEvent *)e)->child();
 
255
                if ( child == d_cornerWidget )
 
256
                    d_cornerWidget = NULL;
 
257
                else if ( child == d_hScrollData->scrollBar )
 
258
                    d_hScrollData->scrollBar = NULL;
 
259
                else if ( child == d_vScrollData->scrollBar )
 
260
                    d_vScrollData->scrollBar = NULL;
 
261
                break;
 
262
            }
 
263
            default:
 
264
                break;
 
265
        }
 
266
    }
 
267
    return QwtPlotZoomer::eventFilter(o, e);
 
268
}
 
269
 
 
270
bool ScrollZoomer::needScrollBar(Qt::Orientation o) const
 
271
{
 
272
#if QT_VERSION < 0x040000
 
273
    QScrollView::ScrollBarMode mode;
 
274
#else
 
275
    Qt::ScrollBarPolicy mode;
 
276
#endif
 
277
    double zoomMin, zoomMax, baseMin, baseMax;
 
278
 
 
279
    if ( o == Qt::Horizontal )
 
280
    {
 
281
        mode = d_hScrollData->mode;
 
282
        baseMin = zoomBase().left();
 
283
        baseMax = zoomBase().right();
 
284
        zoomMin = zoomRect().left();
 
285
        zoomMax = zoomRect().right();
 
286
    }
 
287
    else
 
288
    {
 
289
        mode = d_vScrollData->mode;
 
290
        baseMin = zoomBase().top();
 
291
        baseMax = zoomBase().bottom();
 
292
        zoomMin = zoomRect().top();
 
293
        zoomMax = zoomRect().bottom();
 
294
    }
 
295
 
 
296
    bool needed = false;
 
297
    switch(mode)
 
298
    {
 
299
#if QT_VERSION < 0x040000
 
300
        case QScrollView::AlwaysOn:
 
301
#else
 
302
        case Qt::ScrollBarAlwaysOn:
 
303
#endif
 
304
            needed = true;
 
305
            break;
 
306
#if QT_VERSION < 0x040000
 
307
        case QScrollView::AlwaysOff:    
 
308
#else
 
309
        case Qt::ScrollBarAlwaysOff:
 
310
#endif
 
311
            needed = false;
 
312
            break;
 
313
        default:
 
314
        {
 
315
            if ( baseMin < zoomMin || baseMax > zoomMax )
 
316
                needed = true;
 
317
            break;
 
318
        }
 
319
    }
 
320
    return needed;
 
321
}
 
322
 
 
323
void ScrollZoomer::updateScrollBars()
 
324
{
 
325
    if ( !canvas() )
 
326
        return;
 
327
 
 
328
    const int xAxis = QwtPlotZoomer::xAxis();
 
329
    const int yAxis = QwtPlotZoomer::yAxis();
 
330
 
 
331
    int xScrollBarAxis = xAxis;
 
332
    if ( hScrollBarPosition() == OppositeToScale )
 
333
        xScrollBarAxis = oppositeAxis(xScrollBarAxis);
 
334
 
 
335
    int yScrollBarAxis = yAxis;
 
336
    if ( vScrollBarPosition() == OppositeToScale ) 
 
337
        yScrollBarAxis = oppositeAxis(yScrollBarAxis); 
 
338
 
 
339
 
 
340
    QwtPlotLayout *layout = plot()->plotLayout();
 
341
 
 
342
    bool showHScrollBar = needScrollBar(Qt::Horizontal);
 
343
    if ( showHScrollBar )
 
344
    {
 
345
        ScrollBar *sb = scrollBar(Qt::Horizontal);
 
346
 
 
347
        sb->setPalette(plot()->palette());
 
348
 
 
349
        const QwtScaleDiv *sd = plot()->axisScaleDiv(xAxis);
 
350
        sb->setInverted(sd->lBound() > sd->hBound() );
 
351
 
 
352
        sb->setBase(zoomBase().left(), zoomBase().right());
 
353
        sb->moveSlider(zoomRect().left(), zoomRect().right());
 
354
 
 
355
        if ( !sb->isVisibleTo(canvas()) )
 
356
        {
 
357
            sb->show();
 
358
            layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis) 
 
359
                + sb->extent(), xScrollBarAxis);
 
360
        }
 
361
    }
 
362
    else
 
363
    {
 
364
        if ( horizontalScrollBar() )
 
365
        {
 
366
            horizontalScrollBar()->hide();
 
367
            layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis) 
 
368
                - horizontalScrollBar()->extent(), xScrollBarAxis);
 
369
        }
 
370
    }
 
371
 
 
372
    bool showVScrollBar = needScrollBar(Qt::Vertical);
 
373
    if ( showVScrollBar )
 
374
    {
 
375
        ScrollBar *sb = scrollBar(Qt::Vertical);
 
376
 
 
377
        sb->setPalette(plot()->palette());
 
378
 
 
379
        const QwtScaleDiv *sd = plot()->axisScaleDiv(yAxis);
 
380
        sb->setInverted(sd->lBound() > sd->hBound() );
 
381
 
 
382
        sb->setBase(zoomBase().top(), zoomBase().bottom());
 
383
        sb->moveSlider(zoomRect().top(), zoomRect().bottom());
 
384
 
 
385
        if ( !sb->isVisibleTo(canvas()) )
 
386
        {
 
387
            sb->show();
 
388
            layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis) 
 
389
                + sb->extent(), yScrollBarAxis);
 
390
        }
 
391
    }
 
392
    else
 
393
    {
 
394
        if ( verticalScrollBar() )
 
395
        {
 
396
            verticalScrollBar()->hide();
 
397
            layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis) 
 
398
                - verticalScrollBar()->extent(), yScrollBarAxis);
 
399
        }
 
400
    }
 
401
 
 
402
    if ( showHScrollBar && showVScrollBar )
 
403
    {
 
404
        if ( d_cornerWidget == NULL )
 
405
        {
 
406
            d_cornerWidget = new QWidget(canvas());
 
407
#if QT_VERSION >= 0x040100
 
408
            d_cornerWidget->setAutoFillBackground(true);
 
409
#endif
 
410
            d_cornerWidget->setPalette(plot()->palette());
 
411
        }
 
412
        d_cornerWidget->show();
 
413
    }
 
414
    else
 
415
    {
 
416
        if ( d_cornerWidget )
 
417
            d_cornerWidget->hide();
 
418
    }
 
419
 
 
420
    layoutScrollBars(((QwtPlotCanvas *)canvas())->contentsRect());
 
421
    plot()->updateLayout();
 
422
}
 
423
 
 
424
void ScrollZoomer::layoutScrollBars(const QRect &rect)
 
425
{
 
426
    int hPos = xAxis();
 
427
    if ( hScrollBarPosition() == OppositeToScale )
 
428
        hPos = oppositeAxis(hPos);
 
429
 
 
430
    int vPos = yAxis();
 
431
    if ( vScrollBarPosition() == OppositeToScale )
 
432
        vPos = oppositeAxis(vPos);
 
433
 
 
434
    ScrollBar *hScrollBar = horizontalScrollBar();
 
435
    ScrollBar *vScrollBar = verticalScrollBar();
 
436
 
 
437
    const int hdim = hScrollBar ? hScrollBar->extent() : 0;
 
438
    const int vdim = vScrollBar ? vScrollBar->extent() : 0;
 
439
    
 
440
    if ( hScrollBar && hScrollBar->isVisible() )
 
441
    {
 
442
        int x = rect.x();
 
443
        int y = (hPos == QwtPlot::xTop) 
 
444
            ? rect.top() : rect.bottom() - hdim + 1;
 
445
        int w = rect.width();
 
446
 
 
447
        if ( vScrollBar && vScrollBar->isVisible() )
 
448
        {
 
449
            if ( vPos == QwtPlot::yLeft )
 
450
                x += vdim;
 
451
            w -= vdim;
 
452
        }
 
453
 
 
454
        hScrollBar->setGeometry(x, y, w, hdim);
 
455
    }
 
456
    if ( vScrollBar && vScrollBar->isVisible() )
 
457
    {
 
458
        int pos = yAxis();
 
459
        if ( vScrollBarPosition() == OppositeToScale )
 
460
            pos = oppositeAxis(pos);
 
461
 
 
462
        int x = (vPos == QwtPlot::yLeft)
 
463
            ? rect.left() : rect.right() - vdim + 1;
 
464
        int y = rect.y();
 
465
 
 
466
        int h = rect.height();
 
467
 
 
468
        if ( hScrollBar && hScrollBar->isVisible() )
 
469
        {
 
470
            if ( hPos == QwtPlot::xTop )
 
471
                y += hdim;
 
472
                
 
473
            h -= hdim;
 
474
        }
 
475
 
 
476
        vScrollBar->setGeometry(x, y, vdim, h);
 
477
    }
 
478
    if ( hScrollBar && hScrollBar->isVisible() &&
 
479
        vScrollBar && vScrollBar->isVisible() )
 
480
    {
 
481
        if ( d_cornerWidget )
 
482
        {
 
483
            QRect cornerRect(
 
484
                vScrollBar->pos().x(), hScrollBar->pos().y(),
 
485
                vdim, hdim);
 
486
            d_cornerWidget->setGeometry(cornerRect);
 
487
        }
 
488
    }
 
489
}
 
490
 
 
491
void ScrollZoomer::scrollBarMoved(Qt::Orientation o, double min, double)
 
492
{
 
493
    if ( o == Qt::Horizontal )
 
494
        move(min, zoomRect().top());
 
495
    else
 
496
        move(zoomRect().left(), min);
 
497
 
 
498
    emit zoomed(zoomRect());
 
499
}
 
500
 
 
501
int ScrollZoomer::oppositeAxis(int axis) const
 
502
{
 
503
    switch(axis)
 
504
    {
 
505
        case QwtPlot::xBottom:
 
506
            return QwtPlot::xTop;
 
507
        case QwtPlot::xTop:
 
508
            return QwtPlot::xBottom;
 
509
        case QwtPlot::yLeft:
 
510
            return QwtPlot::yRight;
 
511
        case QwtPlot::yRight:
 
512
            return QwtPlot::yLeft;
 
513
        default:
 
514
            break;
 
515
    }
 
516
 
 
517
    return axis;
 
518
}