qwt_panner.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
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     // We don't want to grab the picker !
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


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56