Qwt User's Guide: qwt_panner.cpp Source File

Qwt User's Guide 6.2.0

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
20 static QVector< QwtPicker* > qwtActivePickers( QWidget* w )
21 {
22 QVector< QwtPicker* > pickers;
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
35 class 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
87 QwtPanner::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
101 QwtPanner::~QwtPanner()
102 {
103 delete m_data;
104 }
105
110 void QwtPanner::setMouseButton( Qt::MouseButton button,
111 Qt::KeyboardModifiers modifiers )
112 {
113 m_data->button = button;
114 m_data->buttonModifiers = modifiers;
115 }
116
118 void QwtPanner::getMouseButton( Qt::MouseButton& button,
119 Qt::KeyboardModifiers& modifiers ) const
120 {
121 button = m_data->button;
122 modifiers = m_data->buttonModifiers;
123 }
124
132 void QwtPanner::setAbortKey( int key,
133 Qt::KeyboardModifiers modifiers )
134 {
135 m_data->abortKey = key;
136 m_data->abortKeyModifiers = modifiers;
137 }
138
140 void QwtPanner::getAbortKey( int& key,
141 Qt::KeyboardModifiers& modifiers ) const
142 {
143 key = m_data->abortKey;
144 modifiers = m_data->abortKeyModifiers;
145 }
146
155 #ifndef QT_NO_CURSOR
156 void QwtPanner::setCursor( const QCursor& cursor )
157 {
158 m_data->cursor = new QCursor( cursor );
159 }
160 #endif
161
166 #ifndef QT_NO_CURSOR
167 const 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
188 void QwtPanner::setEnabled( bool on )
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
216 void QwtPanner::setOrientations( Qt::Orientations o )
217 {
218 m_data->orientations = o;
219 }
220
222 Qt::Orientations QwtPanner::orientations() const
223 {
224 return m_data->orientations;
225 }
226
231 bool QwtPanner::isOrientationEnabled( Qt::Orientation o ) const
232 {
233 return m_data->orientations & o;
234 }
235
240 bool QwtPanner::isEnabled() const
241 {
242 return m_data->isEnabled;
243 }
244
253 void 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
297 QBitmap QwtPanner::contentsMask() const
298 {
299 return QBitmap();
300 }
301
306 QPixmap 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
330 bool 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
381 void 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
421 void 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
449 void 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
482 void 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
502 void QwtPanner::widgetKeyReleaseEvent( QKeyEvent* keyEvent )
503 {
504 Q_UNUSED( keyEvent );
505 }
506
507 #ifndef QT_NO_CURSOR
508 void 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 #if QWT_MOC_INCLUDE
543 #include "moc_qwt_panner.cpp"
544 #endif
QVector
Definition: qwt_clipper.h:23
QwtPainter::fillPixmap
static void fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())
Definition: qwt_painter.cpp:1311
QwtPainter::devicePixelRatio
static qreal devicePixelRatio(const QPaintDevice *)
Definition: qwt_painter.cpp:1491
QwtPainter::backingStore
static QPixmap backingStore(QWidget *, const QSize &)
Definition: qwt_painter.cpp:1525
QwtPanner::orientations
Qt::Orientations orientations() const
Return the orientation, where panning is enabled.
Definition: qwt_panner.cpp:222
QwtPanner::isEnabled
bool isEnabled() const
Definition: qwt_panner.cpp:240
QwtPanner::~QwtPanner
virtual ~QwtPanner()
Destructor.
Definition: qwt_panner.cpp:101
QwtPanner::cursor
const QCursor cursor() const
Definition: qwt_panner.cpp:167
QwtPanner::eventFilter
virtual bool eventFilter(QObject *, QEvent *) override
Event filter.
Definition: qwt_panner.cpp:330
QwtPanner::setEnabled
void setEnabled(bool)
En/disable the panner.
Definition: qwt_panner.cpp:188
QwtPanner::widgetMouseMoveEvent
virtual void widgetMouseMoveEvent(QMouseEvent *)
Definition: qwt_panner.cpp:421
QwtPanner::setMouseButton
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
Definition: qwt_panner.cpp:110
QwtPanner::widgetKeyPressEvent
virtual void widgetKeyPressEvent(QKeyEvent *)
Definition: qwt_panner.cpp:482
QwtPanner::getMouseButton
void getMouseButton(Qt::MouseButton &button, Qt::KeyboardModifiers &) const
Get mouse button and modifiers used for panning.
Definition: qwt_panner.cpp:118
QwtPanner::widgetKeyReleaseEvent
virtual void widgetKeyReleaseEvent(QKeyEvent *)
Definition: qwt_panner.cpp:502
QwtPanner::moved
void moved(int dx, int dy)
QwtPanner::isOrientationEnabled
bool isOrientationEnabled(Qt::Orientation) const
Definition: qwt_panner.cpp:231
QwtPanner::paintEvent
virtual void paintEvent(QPaintEvent *) override
Paint event.
Definition: qwt_panner.cpp:253
QwtPanner::setOrientations
void setOrientations(Qt::Orientations)
Definition: qwt_panner.cpp:216
QwtPanner::contentsMask
virtual QBitmap contentsMask() const
Calculate a mask for the contents of the panned widget.
Definition: qwt_panner.cpp:297
QwtPanner::widgetMouseReleaseEvent
virtual void widgetMouseReleaseEvent(QMouseEvent *)
Definition: qwt_panner.cpp:449
QwtPanner::getAbortKey
void getAbortKey(int &key, Qt::KeyboardModifiers &) const
Get the abort key and modifiers.
Definition: qwt_panner.cpp:140
QwtPanner::grab
virtual QPixmap grab() const
Definition: qwt_panner.cpp:306
QwtPanner::setCursor
void setCursor(const QCursor &)
Definition: qwt_panner.cpp:156
QwtPanner::setAbortKey
void setAbortKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
Definition: qwt_panner.cpp:132
QwtPanner::widgetMousePressEvent
virtual void widgetMousePressEvent(QMouseEvent *)
Definition: qwt_panner.cpp:381
QwtPanner::panned
void panned(int dx, int dy)
QwtPanner::QwtPanner
QwtPanner(QWidget *parent)
Definition: qwt_panner.cpp:87
QwtPicker
QwtPicker provides selections on a widget.
Definition: qwt_picker.h:104
QwtPicker::isEnabled
bool isEnabled() const
Definition: qwt_picker.cpp:399