~l3on/ubuntu/oneiric/qwt/fix-921430

« back to all changes in this revision

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