Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_panner.h"
00011 #include "qwt_picker.h"
00012 #include "qwt_painter.h"
00013 #include <qpainter.h>
00014 #include <qpixmap.h>
00015 #include <qevent.h>
00016 #include <qcursor.h>
00017 #include <qbitmap.h>
00018
00019 static QVector<QwtPicker *> qwtActivePickers( QWidget *w )
00020 {
00021 QVector<QwtPicker *> pickers;
00022
00023 QObjectList children = w->children();
00024 for ( int i = 0; i < children.size(); i++ )
00025 {
00026 QwtPicker *picker = qobject_cast<QwtPicker *>( children[i] );
00027 if ( picker && picker->isEnabled() )
00028 pickers += picker;
00029 }
00030
00031 return pickers;
00032 }
00033
00034 class QwtPanner::PrivateData
00035 {
00036 public:
00037 PrivateData():
00038 button( Qt::LeftButton ),
00039 buttonModifiers( Qt::NoModifier ),
00040 abortKey( Qt::Key_Escape ),
00041 abortKeyModifiers( Qt::NoModifier ),
00042 #ifndef QT_NO_CURSOR
00043 cursor( NULL ),
00044 restoreCursor( NULL ),
00045 hasCursor( false ),
00046 #endif
00047 isEnabled( false )
00048 {
00049 orientations = Qt::Vertical | Qt::Horizontal;
00050 }
00051
00052 ~PrivateData()
00053 {
00054 #ifndef QT_NO_CURSOR
00055 delete cursor;
00056 delete restoreCursor;
00057 #endif
00058 }
00059
00060 Qt::MouseButton button;
00061 Qt::KeyboardModifiers buttonModifiers;
00062
00063 int abortKey;
00064 Qt::KeyboardModifiers abortKeyModifiers;
00065
00066 QPoint initialPos;
00067 QPoint pos;
00068
00069 QPixmap pixmap;
00070 QBitmap contentsMask;
00071
00072 #ifndef QT_NO_CURSOR
00073 QCursor *cursor;
00074 QCursor *restoreCursor;
00075 bool hasCursor;
00076 #endif
00077 bool isEnabled;
00078 Qt::Orientations orientations;
00079 };
00080
00086 QwtPanner::QwtPanner( QWidget *parent ):
00087 QWidget( parent )
00088 {
00089 d_data = new PrivateData();
00090
00091 setAttribute( Qt::WA_TransparentForMouseEvents );
00092 setAttribute( Qt::WA_NoSystemBackground );
00093 setFocusPolicy( Qt::NoFocus );
00094 hide();
00095
00096 setEnabled( true );
00097 }
00098
00100 QwtPanner::~QwtPanner()
00101 {
00102 delete d_data;
00103 }
00104
00109 void QwtPanner::setMouseButton( Qt::MouseButton button,
00110 Qt::KeyboardModifiers modifiers )
00111 {
00112 d_data->button = button;
00113 d_data->buttonModifiers = modifiers;
00114 }
00115
00117 void QwtPanner::getMouseButton( Qt::MouseButton &button,
00118 Qt::KeyboardModifiers &modifiers ) const
00119 {
00120 button = d_data->button;
00121 modifiers = d_data->buttonModifiers;
00122 }
00123
00131 void QwtPanner::setAbortKey( int key,
00132 Qt::KeyboardModifiers modifiers )
00133 {
00134 d_data->abortKey = key;
00135 d_data->abortKeyModifiers = modifiers;
00136 }
00137
00139 void QwtPanner::getAbortKey( int &key,
00140 Qt::KeyboardModifiers &modifiers ) const
00141 {
00142 key = d_data->abortKey;
00143 modifiers = d_data->abortKeyModifiers;
00144 }
00145
00154 #ifndef QT_NO_CURSOR
00155 void QwtPanner::setCursor( const QCursor &cursor )
00156 {
00157 d_data->cursor = new QCursor( cursor );
00158 }
00159 #endif
00160
00165 #ifndef QT_NO_CURSOR
00166 const QCursor QwtPanner::cursor() const
00167 {
00168 if ( d_data->cursor )
00169 return *d_data->cursor;
00170
00171 if ( parentWidget() )
00172 return parentWidget()->cursor();
00173
00174 return QCursor();
00175 }
00176 #endif
00177
00187 void QwtPanner::setEnabled( bool on )
00188 {
00189 if ( d_data->isEnabled != on )
00190 {
00191 d_data->isEnabled = on;
00192
00193 QWidget *w = parentWidget();
00194 if ( w )
00195 {
00196 if ( d_data->isEnabled )
00197 {
00198 w->installEventFilter( this );
00199 }
00200 else
00201 {
00202 w->removeEventFilter( this );
00203 hide();
00204 }
00205 }
00206 }
00207 }
00208
00215 void QwtPanner::setOrientations( Qt::Orientations o )
00216 {
00217 d_data->orientations = o;
00218 }
00219
00221 Qt::Orientations QwtPanner::orientations() const
00222 {
00223 return d_data->orientations;
00224 }
00225
00230 bool QwtPanner::isOrientationEnabled( Qt::Orientation o ) const
00231 {
00232 return d_data->orientations & o;
00233 }
00234
00239 bool QwtPanner::isEnabled() const
00240 {
00241 return d_data->isEnabled;
00242 }
00243
00252 void QwtPanner::paintEvent( QPaintEvent *pe )
00253 {
00254 int dx = d_data->pos.x() - d_data->initialPos.x();
00255 int dy = d_data->pos.y() - d_data->initialPos.y();
00256
00257 QRect r( 0, 0, d_data->pixmap.width(), d_data->pixmap.height() );
00258 r.moveCenter( QPoint( r.center().x() + dx, r.center().y() + dy ) );
00259
00260 QPixmap pm( size() );
00261 QwtPainter::fillPixmap( parentWidget(), pm );
00262
00263 QPainter painter( &pm );
00264
00265 if ( !d_data->contentsMask.isNull() )
00266 {
00267 QPixmap masked = d_data->pixmap;
00268 masked.setMask( d_data->contentsMask );
00269 painter.drawPixmap( r, masked );
00270 }
00271 else
00272 {
00273 painter.drawPixmap( r, d_data->pixmap );
00274 }
00275
00276 painter.end();
00277
00278 if ( !d_data->contentsMask.isNull() )
00279 pm.setMask( d_data->contentsMask );
00280
00281 painter.begin( this );
00282 painter.setClipRegion( pe->region() );
00283 painter.drawPixmap( 0, 0, pm );
00284 }
00285
00295 QBitmap QwtPanner::contentsMask() const
00296 {
00297 return QBitmap();
00298 }
00299
00304 QPixmap QwtPanner::grab() const
00305 {
00306 #if QT_VERSION >= 0x050000
00307 return parentWidget()->grab( parentWidget()->rect() );
00308 #else
00309 return QPixmap::grabWidget( parentWidget() );
00310 #endif
00311 }
00312
00328 bool QwtPanner::eventFilter( QObject *object, QEvent *event )
00329 {
00330 if ( object == NULL || object != parentWidget() )
00331 return false;
00332
00333 switch ( event->type() )
00334 {
00335 case QEvent::MouseButtonPress:
00336 {
00337 widgetMousePressEvent( static_cast<QMouseEvent *>( event ) );
00338 break;
00339 }
00340 case QEvent::MouseMove:
00341 {
00342 widgetMouseMoveEvent( static_cast<QMouseEvent *>( event ) );
00343 break;
00344 }
00345 case QEvent::MouseButtonRelease:
00346 {
00347 widgetMouseReleaseEvent( static_cast<QMouseEvent *>( event ) );
00348 break;
00349 }
00350 case QEvent::KeyPress:
00351 {
00352 widgetKeyPressEvent( static_cast<QKeyEvent *>( event ) );
00353 break;
00354 }
00355 case QEvent::KeyRelease:
00356 {
00357 widgetKeyReleaseEvent( static_cast<QKeyEvent *>( event ) );
00358 break;
00359 }
00360 case QEvent::Paint:
00361 {
00362 if ( isVisible() )
00363 return true;
00364 break;
00365 }
00366 default:;
00367 }
00368
00369 return false;
00370 }
00371
00379 void QwtPanner::widgetMousePressEvent( QMouseEvent *mouseEvent )
00380 {
00381 if ( ( mouseEvent->button() != d_data->button )
00382 || ( mouseEvent->modifiers() != d_data->buttonModifiers ) )
00383 {
00384 return;
00385 }
00386
00387 QWidget *w = parentWidget();
00388 if ( w == NULL )
00389 return;
00390
00391 #ifndef QT_NO_CURSOR
00392 showCursor( true );
00393 #endif
00394
00395 d_data->initialPos = d_data->pos = mouseEvent->pos();
00396
00397 setGeometry( parentWidget()->rect() );
00398
00399
00400 QVector<QwtPicker *> pickers = qwtActivePickers( parentWidget() );
00401 for ( int i = 0; i < pickers.size(); i++ )
00402 pickers[i]->setEnabled( false );
00403
00404 d_data->pixmap = grab();
00405 d_data->contentsMask = contentsMask();
00406
00407 for ( int i = 0; i < pickers.size(); i++ )
00408 pickers[i]->setEnabled( true );
00409
00410 show();
00411 }
00412
00419 void QwtPanner::widgetMouseMoveEvent( QMouseEvent *mouseEvent )
00420 {
00421 if ( !isVisible() )
00422 return;
00423
00424 QPoint pos = mouseEvent->pos();
00425 if ( !isOrientationEnabled( Qt::Horizontal ) )
00426 pos.setX( d_data->initialPos.x() );
00427 if ( !isOrientationEnabled( Qt::Vertical ) )
00428 pos.setY( d_data->initialPos.y() );
00429
00430 if ( pos != d_data->pos && rect().contains( pos ) )
00431 {
00432 d_data->pos = pos;
00433 update();
00434
00435 Q_EMIT moved( d_data->pos.x() - d_data->initialPos.x(),
00436 d_data->pos.y() - d_data->initialPos.y() );
00437 }
00438 }
00439
00447 void QwtPanner::widgetMouseReleaseEvent( QMouseEvent *mouseEvent )
00448 {
00449 if ( isVisible() )
00450 {
00451 hide();
00452 #ifndef QT_NO_CURSOR
00453 showCursor( false );
00454 #endif
00455
00456 QPoint pos = mouseEvent->pos();
00457 if ( !isOrientationEnabled( Qt::Horizontal ) )
00458 pos.setX( d_data->initialPos.x() );
00459 if ( !isOrientationEnabled( Qt::Vertical ) )
00460 pos.setY( d_data->initialPos.y() );
00461
00462 d_data->pixmap = QPixmap();
00463 d_data->contentsMask = QBitmap();
00464 d_data->pos = pos;
00465
00466 if ( d_data->pos != d_data->initialPos )
00467 {
00468 Q_EMIT panned( d_data->pos.x() - d_data->initialPos.x(),
00469 d_data->pos.y() - d_data->initialPos.y() );
00470 }
00471 }
00472 }
00473
00480 void QwtPanner::widgetKeyPressEvent( QKeyEvent *keyEvent )
00481 {
00482 if ( ( keyEvent->key() == d_data->abortKey )
00483 && ( keyEvent->modifiers() == d_data->abortKeyModifiers ) )
00484 {
00485 hide();
00486
00487 #ifndef QT_NO_CURSOR
00488 showCursor( false );
00489 #endif
00490 d_data->pixmap = QPixmap();
00491 }
00492 }
00493
00500 void QwtPanner::widgetKeyReleaseEvent( QKeyEvent *keyEvent )
00501 {
00502 Q_UNUSED( keyEvent );
00503 }
00504
00505 #ifndef QT_NO_CURSOR
00506 void QwtPanner::showCursor( bool on )
00507 {
00508 if ( on == d_data->hasCursor )
00509 return;
00510
00511 QWidget *w = parentWidget();
00512 if ( w == NULL || d_data->cursor == NULL )
00513 return;
00514
00515 d_data->hasCursor = on;
00516
00517 if ( on )
00518 {
00519 if ( w->testAttribute( Qt::WA_SetCursor ) )
00520 {
00521 delete d_data->restoreCursor;
00522 d_data->restoreCursor = new QCursor( w->cursor() );
00523 }
00524 w->setCursor( *d_data->cursor );
00525 }
00526 else
00527 {
00528 if ( d_data->restoreCursor )
00529 {
00530 w->setCursor( *d_data->restoreCursor );
00531 delete d_data->restoreCursor;
00532 d_data->restoreCursor = NULL;
00533 }
00534 else
00535 w->unsetCursor();
00536 }
00537 }
00538 #endif