Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
qwt_panner.cpp
1/******************************************************************************
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#include "qwt_panner.h"
11#include "qwt_picker.h"
12#include "qwt_painter.h"
13
14#include <qpainter.h>
15#include <qpixmap.h>
16#include <qevent.h>
17#include <qcursor.h>
18#include <qbitmap.h>
19
20static QVector< QwtPicker* > qwtActivePickers( QWidget* w )
21{
23
24 QObjectList children = w->children();
25 for ( int i = 0; i < children.size(); i++ )
26 {
27 QwtPicker* picker = qobject_cast< QwtPicker* >( children[i] );
28 if ( picker && picker->isEnabled() )
29 pickers += picker;
30 }
31
32 return pickers;
33}
34
35class QwtPanner::PrivateData
36{
37 public:
38 PrivateData()
39 : button( Qt::LeftButton )
40 , buttonModifiers( Qt::NoModifier )
41 , abortKey( Qt::Key_Escape )
42 , abortKeyModifiers( Qt::NoModifier )
43#ifndef QT_NO_CURSOR
44 , cursor( NULL )
45 , restoreCursor( NULL )
46 , hasCursor( false )
47#endif
48 , isEnabled( false )
49 , orientations( Qt::Vertical | Qt::Horizontal )
50 {
51 }
52
53 ~PrivateData()
54 {
55#ifndef QT_NO_CURSOR
56 delete cursor;
57 delete restoreCursor;
58#endif
59 }
60
61 Qt::MouseButton button;
62 Qt::KeyboardModifiers buttonModifiers;
63
64 int abortKey;
65 Qt::KeyboardModifiers abortKeyModifiers;
66
67 QPoint initialPos;
68 QPoint pos;
69
70 QPixmap pixmap;
71 QBitmap contentsMask;
72
73#ifndef QT_NO_CURSOR
74 QCursor* cursor;
75 QCursor* restoreCursor;
76 bool hasCursor;
77#endif
78 bool isEnabled;
79 Qt::Orientations orientations;
80};
81
87QwtPanner::QwtPanner( QWidget* parent )
88 : QWidget( parent )
89{
90 m_data = new PrivateData();
91
92 setAttribute( Qt::WA_TransparentForMouseEvents );
93 setAttribute( Qt::WA_NoSystemBackground );
94 setFocusPolicy( Qt::NoFocus );
95 hide();
96
97 setEnabled( true );
98}
99
102{
103 delete m_data;
104}
105
110void QwtPanner::setMouseButton( Qt::MouseButton button,
111 Qt::KeyboardModifiers modifiers )
112{
113 m_data->button = button;
114 m_data->buttonModifiers = modifiers;
115}
116
118void QwtPanner::getMouseButton( Qt::MouseButton& button,
119 Qt::KeyboardModifiers& modifiers ) const
120{
121 button = m_data->button;
122 modifiers = m_data->buttonModifiers;
123}
124
133 Qt::KeyboardModifiers modifiers )
134{
135 m_data->abortKey = key;
136 m_data->abortKeyModifiers = modifiers;
137}
138
141 Qt::KeyboardModifiers& modifiers ) const
142{
143 key = m_data->abortKey;
144 modifiers = m_data->abortKeyModifiers;
145}
146
155#ifndef QT_NO_CURSOR
156void QwtPanner::setCursor( const QCursor& cursor )
157{
158 m_data->cursor = new QCursor( cursor );
159}
160#endif
161
166#ifndef QT_NO_CURSOR
167const QCursor QwtPanner::cursor() const
168{
169 if ( m_data->cursor )
170 return *m_data->cursor;
171
172 if ( parentWidget() )
173 return parentWidget()->cursor();
174
175 return QCursor();
176}
177#endif
178
189{
190 if ( m_data->isEnabled != on )
191 {
192 m_data->isEnabled = on;
193
194 QWidget* w = parentWidget();
195 if ( w )
196 {
197 if ( m_data->isEnabled )
198 {
199 w->installEventFilter( this );
200 }
201 else
202 {
203 w->removeEventFilter( this );
204 hide();
205 }
206 }
207 }
208}
209
216void QwtPanner::setOrientations( Qt::Orientations o )
217{
218 m_data->orientations = o;
219}
220
222Qt::Orientations QwtPanner::orientations() const
223{
224 return m_data->orientations;
225}
226
231bool QwtPanner::isOrientationEnabled( Qt::Orientation o ) const
232{
233 return m_data->orientations & o;
234}
235
241{
242 return m_data->isEnabled;
243}
244
253void QwtPanner::paintEvent( QPaintEvent* event )
254{
255 int dx = m_data->pos.x() - m_data->initialPos.x();
256 int dy = m_data->pos.y() - m_data->initialPos.y();
257
258 QRectF r;
259 r.setSize( m_data->pixmap.size() / QwtPainter::devicePixelRatio( &m_data->pixmap ) );
260 r.moveCenter( QPointF( r.center().x() + dx, r.center().y() + dy ) );
261
262 QPixmap pm = QwtPainter::backingStore( this, size() );
263 QwtPainter::fillPixmap( parentWidget(), pm );
264
265 QPainter painter( &pm );
266
267 if ( !m_data->contentsMask.isNull() )
268 {
269 QPixmap masked = m_data->pixmap;
270 masked.setMask( m_data->contentsMask );
271 painter.drawPixmap( r.toRect(), masked );
272 }
273 else
274 {
275 painter.drawPixmap( r.toRect(), m_data->pixmap );
276 }
277
278 painter.end();
279
280 if ( !m_data->contentsMask.isNull() )
281 pm.setMask( m_data->contentsMask );
282
283 painter.begin( this );
284 painter.setClipRegion( event->region() );
285 painter.drawPixmap( 0, 0, pm );
286}
287
298{
299 return QBitmap();
300}
301
306QPixmap QwtPanner::grab() const
307{
308#if QT_VERSION >= 0x050000
309 return parentWidget()->grab( parentWidget()->rect() );
310#else
311 return QPixmap::grabWidget( parentWidget() );
312#endif
313}
314
330bool QwtPanner::eventFilter( QObject* object, QEvent* event )
331{
332 if ( object == NULL || object != parentWidget() )
333 return false;
334
335 switch ( event->type() )
336 {
337 case QEvent::MouseButtonPress:
338 {
339 widgetMousePressEvent( static_cast< QMouseEvent* >( event ) );
340 break;
341 }
342 case QEvent::MouseMove:
343 {
344 widgetMouseMoveEvent( static_cast< QMouseEvent* >( event ) );
345 break;
346 }
347 case QEvent::MouseButtonRelease:
348 {
349 widgetMouseReleaseEvent( static_cast< QMouseEvent* >( event ) );
350 break;
351 }
352 case QEvent::KeyPress:
353 {
354 widgetKeyPressEvent( static_cast< QKeyEvent* >( event ) );
355 break;
356 }
357 case QEvent::KeyRelease:
358 {
359 widgetKeyReleaseEvent( static_cast< QKeyEvent* >( event ) );
360 break;
361 }
362 case QEvent::Paint:
363 {
364 if ( isVisible() )
365 return true;
366 break;
367 }
368 default:;
369 }
370
371 return false;
372}
373
381void QwtPanner::widgetMousePressEvent( QMouseEvent* mouseEvent )
382{
383 if ( ( mouseEvent->button() != m_data->button )
384 || ( mouseEvent->modifiers() != m_data->buttonModifiers ) )
385 {
386 return;
387 }
388
389 QWidget* w = parentWidget();
390 if ( w == NULL )
391 return;
392
393#ifndef QT_NO_CURSOR
394 showCursor( true );
395#endif
396
397 m_data->initialPos = m_data->pos = mouseEvent->pos();
398
399 setGeometry( parentWidget()->rect() );
400
401 // We don't want to grab the picker !
402 QVector< QwtPicker* > pickers = qwtActivePickers( parentWidget() );
403 for ( int i = 0; i < pickers.size(); i++ )
404 pickers[i]->setEnabled( false );
405
406 m_data->pixmap = grab();
407 m_data->contentsMask = contentsMask();
408
409 for ( int i = 0; i < pickers.size(); i++ )
410 pickers[i]->setEnabled( true );
411
412 show();
413}
414
421void QwtPanner::widgetMouseMoveEvent( QMouseEvent* mouseEvent )
422{
423 if ( !isVisible() )
424 return;
425
426 QPoint pos = mouseEvent->pos();
427 if ( !isOrientationEnabled( Qt::Horizontal ) )
428 pos.setX( m_data->initialPos.x() );
429 if ( !isOrientationEnabled( Qt::Vertical ) )
430 pos.setY( m_data->initialPos.y() );
431
432 if ( pos != m_data->pos && rect().contains( pos ) )
433 {
434 m_data->pos = pos;
435 update();
436
437 Q_EMIT moved( m_data->pos.x() - m_data->initialPos.x(),
438 m_data->pos.y() - m_data->initialPos.y() );
439 }
440}
441
449void QwtPanner::widgetMouseReleaseEvent( QMouseEvent* mouseEvent )
450{
451 if ( isVisible() )
452 {
453 hide();
454#ifndef QT_NO_CURSOR
455 showCursor( false );
456#endif
457
458 QPoint pos = mouseEvent->pos();
459 if ( !isOrientationEnabled( Qt::Horizontal ) )
460 pos.setX( m_data->initialPos.x() );
461 if ( !isOrientationEnabled( Qt::Vertical ) )
462 pos.setY( m_data->initialPos.y() );
463
464 m_data->pixmap = QPixmap();
465 m_data->contentsMask = QBitmap();
466 m_data->pos = pos;
467
468 if ( m_data->pos != m_data->initialPos )
469 {
470 Q_EMIT panned( m_data->pos.x() - m_data->initialPos.x(),
471 m_data->pos.y() - m_data->initialPos.y() );
472 }
473 }
474}
475
482void QwtPanner::widgetKeyPressEvent( QKeyEvent* keyEvent )
483{
484 if ( ( keyEvent->key() == m_data->abortKey )
485 && ( keyEvent->modifiers() == m_data->abortKeyModifiers ) )
486 {
487 hide();
488
489#ifndef QT_NO_CURSOR
490 showCursor( false );
491#endif
492 m_data->pixmap = QPixmap();
493 }
494}
495
502void QwtPanner::widgetKeyReleaseEvent( QKeyEvent* keyEvent )
503{
504 Q_UNUSED( keyEvent );
505}
506
507#ifndef QT_NO_CURSOR
508void QwtPanner::showCursor( bool on )
509{
510 if ( on == m_data->hasCursor )
511 return;
512
513 QWidget* w = parentWidget();
514 if ( w == NULL || m_data->cursor == NULL )
515 return;
516
517 m_data->hasCursor = on;
518
519 if ( on )
520 {
521 if ( w->testAttribute( Qt::WA_SetCursor ) )
522 {
523 delete m_data->restoreCursor;
524 m_data->restoreCursor = new QCursor( w->cursor() );
525 }
526 w->setCursor( *m_data->cursor );
527 }
528 else
529 {
530 if ( m_data->restoreCursor )
531 {
532 w->setCursor( *m_data->restoreCursor );
533 delete m_data->restoreCursor;
534 m_data->restoreCursor = NULL;
535 }
536 else
537 w->unsetCursor();
538 }
539}
540#endif
541
542#include "moc_qwt_panner.cpp"
static void fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())
static qreal devicePixelRatio(const QPaintDevice *)
static QPixmap backingStore(QWidget *, const QSize &)
Qt::Orientations orientations() const
Return the orientation, where panning is enabled.
bool isEnabled() const
virtual ~QwtPanner()
Destructor.
const QCursor cursor() const
virtual bool eventFilter(QObject *, QEvent *) override
Event filter.
void setEnabled(bool)
En/disable the panner.
virtual void widgetMouseMoveEvent(QMouseEvent *)
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
virtual void widgetKeyPressEvent(QKeyEvent *)
void getMouseButton(Qt::MouseButton &button, Qt::KeyboardModifiers &) const
Get mouse button and modifiers used for panning.
virtual void widgetKeyReleaseEvent(QKeyEvent *)
void moved(int dx, int dy)
bool isOrientationEnabled(Qt::Orientation) const
virtual void paintEvent(QPaintEvent *) override
Paint event.
void setOrientations(Qt::Orientations)
virtual QBitmap contentsMask() const
Calculate a mask for the contents of the panned widget.
virtual void widgetMouseReleaseEvent(QMouseEvent *)
void getAbortKey(int &key, Qt::KeyboardModifiers &) const
Get the abort key and modifiers.
virtual QPixmap grab() const
void setCursor(const QCursor &)
void setAbortKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
virtual void widgetMousePressEvent(QMouseEvent *)
void panned(int dx, int dy)
QwtPanner(QWidget *parent)
QwtPicker provides selections on a widget.
Definition qwt_picker.h:104
bool isEnabled() const