qwt_panner.cpp

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 // vim: expandtab
00011 
00012 #include <qpainter.h>
00013 #include <qpixmap.h>
00014 #include <qevent.h>
00015 #include <qframe.h>
00016 #include <qcursor.h>
00017 #include "qwt_panner.h"
00018 
00019 class QwtPanner::PrivateData
00020 {
00021 public:
00022     PrivateData():
00023         button(Qt::LeftButton),
00024         buttonState(Qt::NoButton),
00025         abortKey(Qt::Key_Escape),
00026         abortKeyState(Qt::NoButton),
00027 #ifndef QT_NO_CURSOR
00028         cursor(NULL),
00029         restoreCursor(NULL),
00030 #endif
00031         isEnabled(false)
00032     {
00033     }
00034 
00035     ~PrivateData()
00036     {
00037 #ifndef QT_NO_CURSOR
00038         delete cursor;
00039         delete restoreCursor;
00040 #endif
00041     }
00042         
00043     int button;
00044     int buttonState;
00045     int abortKey;
00046     int abortKeyState;
00047 
00048     QPoint initialPos;
00049     QPoint pos;
00050 
00051     QPixmap pixmap;
00052 #ifndef QT_NO_CURSOR
00053     QCursor *cursor;
00054     QCursor *restoreCursor;
00055 #endif
00056     bool isEnabled;
00057 };
00058 
00064 QwtPanner::QwtPanner(QWidget *parent):
00065     QWidget(parent)
00066 {
00067     d_data = new PrivateData();
00068 
00069 #if QT_VERSION >= 0x040000
00070     setAttribute(Qt::WA_TransparentForMouseEvents);
00071     setAttribute(Qt::WA_NoSystemBackground);
00072 #if 0
00073     setAttribute(Qt::WA_PaintOnScreen);
00074 #endif
00075     setFocusPolicy(Qt::NoFocus);
00076 #else
00077     setBackgroundMode(Qt::NoBackground);
00078     setFocusPolicy(QWidget::NoFocus);
00079 #endif
00080     hide();
00081 
00082     setEnabled(true);
00083 }
00084 
00086 QwtPanner::~QwtPanner()
00087 {
00088     delete d_data;
00089 }
00090 
00095 void QwtPanner::setMouseButton(int button, int buttonState)
00096 {
00097     d_data->button = button;
00098     d_data->buttonState = buttonState;
00099 }
00100 
00102 void QwtPanner::getMouseButton(int &button, int &buttonState) const
00103 {
00104     button = d_data->button;
00105     buttonState = d_data->buttonState;
00106 }
00107 
00112 void QwtPanner::setAbortKey(int key, int state)
00113 {
00114     d_data->abortKey = key;
00115     d_data->abortKeyState = state;
00116 }
00117 
00119 void QwtPanner::getAbortKey(int &key, int &state) const
00120 {
00121     key = d_data->abortKey;
00122     state = d_data->abortKeyState;
00123 }
00124 
00133 #ifndef QT_NO_CURSOR
00134 void QwtPanner::setCursor(const QCursor &cursor)
00135 {
00136     d_data->cursor = new QCursor(cursor);
00137 }
00138 #endif
00139 
00144 #ifndef QT_NO_CURSOR
00145 const QCursor QwtPanner::cursor() const
00146 {
00147     if ( d_data->cursor )
00148         return *d_data->cursor;
00149 
00150     if ( parentWidget() )
00151         return parentWidget()->cursor();
00152 
00153     return QCursor();
00154 }
00155 #endif
00156 
00166 void QwtPanner::setEnabled(bool on)
00167 {
00168     if ( d_data->isEnabled != on )
00169     {
00170         d_data->isEnabled = on;
00171 
00172         QWidget *w = parentWidget();
00173         if ( w )
00174         {
00175             if ( d_data->isEnabled )
00176             {
00177                 w->installEventFilter(this);
00178             }
00179             else
00180             {
00181                 w->removeEventFilter(this);
00182                 hide();
00183             }
00184         }
00185     }
00186 }
00187 
00192 bool QwtPanner::isEnabled() const
00193 {
00194     return d_data->isEnabled;
00195 }
00196 
00205 void QwtPanner::paintEvent(QPaintEvent *pe)
00206 {
00207     QPixmap pm(size());
00208 
00209     QPainter painter(&pm);
00210 
00211     const QColor bg =
00212 #if QT_VERSION < 0x040000
00213         parentWidget()->palette().color(
00214             QPalette::Normal, QColorGroup::Background);
00215 #else
00216         parentWidget()->palette().color(
00217             QPalette::Normal, QPalette::Background);
00218 #endif
00219 
00220     painter.setPen(Qt::NoPen);
00221     painter.setBrush(QBrush(bg));
00222     painter.drawRect(0, 0, pm.width(), pm.height());
00223 
00224     int dx = d_data->pos.x() - d_data->initialPos.x();
00225     int dy = d_data->pos.y() - d_data->initialPos.y();
00226 
00227     QRect r(0, 0, d_data->pixmap.width(), d_data->pixmap.height());
00228     r.moveCenter(QPoint(r.center().x() + dx, r.center().y() + dy));
00229 
00230     painter.drawPixmap(r, d_data->pixmap);
00231     painter.end();
00232 
00233     painter.begin(this);
00234     painter.setClipRegion(pe->region());
00235     painter.drawPixmap(0, 0, pm);
00236 }
00237 
00246 bool QwtPanner::eventFilter(QObject *o, QEvent *e)
00247 {
00248     if ( o == NULL || o != parentWidget() )
00249         return false;
00250 
00251     switch(e->type())
00252     {
00253         case QEvent::MouseButtonPress:
00254         {
00255             widgetMousePressEvent((QMouseEvent *)e);
00256             break;
00257         }
00258         case QEvent::MouseMove:
00259         {
00260             widgetMouseMoveEvent((QMouseEvent *)e);
00261             break;
00262         }
00263         case QEvent::MouseButtonRelease:
00264         {
00265             widgetMouseReleaseEvent((QMouseEvent *)e);
00266             break;
00267         }
00268         case QEvent::KeyPress:
00269         {
00270             widgetKeyPressEvent((QKeyEvent *)e);
00271             break;
00272         }
00273         case QEvent::KeyRelease:
00274         {
00275             widgetKeyReleaseEvent((QKeyEvent *)e);
00276             break;
00277         }
00278         default:;
00279     }
00280 
00281     return false;
00282 }
00283 
00291 void QwtPanner::widgetMousePressEvent(QMouseEvent *me)
00292 {
00293     if ( me->button() != d_data->button )
00294         return;
00295 
00296     QWidget *w = parentWidget();
00297     if ( w == NULL )
00298         return;
00299 
00300 #if QT_VERSION < 0x040000
00301     if ( (me->state() & Qt::KeyButtonMask) !=
00302         (d_data->buttonState & Qt::KeyButtonMask) )
00303 #else
00304     if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
00305         (int)(d_data->buttonState & Qt::KeyboardModifierMask) )
00306 #endif
00307     {
00308         return;
00309     }
00310 
00311 #ifndef QT_NO_CURSOR
00312     showCursor(true);
00313 #endif
00314 
00315     d_data->initialPos = d_data->pos = me->pos();
00316 
00317     QRect cr = parentWidget()->rect();
00318     if ( parentWidget()->inherits("QFrame") )
00319     {
00320         const QFrame* frame = (QFrame*)parentWidget();
00321         cr = frame->contentsRect();
00322     }
00323     setGeometry(cr);
00324     d_data->pixmap = QPixmap::grabWidget(parentWidget(),
00325         cr.x(), cr.y(), cr.width(), cr.height());
00326     show();
00327 }
00328 
00336 void QwtPanner::widgetMouseMoveEvent(QMouseEvent *me)
00337 {
00338     if ( isVisible() && rect().contains(me->pos()) )
00339     {
00340         d_data->pos = me->pos();
00341         update();
00342 
00343         emit moved(d_data->pos.x() - d_data->initialPos.x(), 
00344             d_data->pos.y() - d_data->initialPos.y());
00345     }
00346 }
00347 
00353 void QwtPanner::widgetMouseReleaseEvent(QMouseEvent *me)
00354 {
00355     if ( isVisible() )
00356     {
00357         hide();
00358 #ifndef QT_NO_CURSOR
00359         showCursor(false);
00360 #endif
00361 
00362         d_data->pixmap = QPixmap();
00363         d_data->pos = me->pos();
00364 
00365         if ( d_data->pos != d_data->initialPos )
00366         {
00367             emit panned(d_data->pos.x() - d_data->initialPos.x(), 
00368                 d_data->pos.y() - d_data->initialPos.y());
00369         }
00370     }
00371 }
00372 
00379 void QwtPanner::widgetKeyPressEvent(QKeyEvent *ke)
00380 {
00381     if ( ke->key() == d_data->abortKey )
00382     {
00383         const bool matched =
00384 #if QT_VERSION < 0x040000
00385             (ke->state() & Qt::KeyButtonMask) ==
00386                 (d_data->abortKeyState & Qt::KeyButtonMask);
00387 #else
00388             (ke->modifiers() & Qt::KeyboardModifierMask) ==
00389                 (int)(d_data->abortKeyState & Qt::KeyboardModifierMask);
00390 #endif
00391         if ( matched )
00392         {
00393             hide();
00394 #ifndef QT_NO_CURSOR
00395             showCursor(false);
00396 #endif
00397             d_data->pixmap = QPixmap();
00398         }
00399     }
00400 }
00401 
00408 void QwtPanner::widgetKeyReleaseEvent(QKeyEvent *)
00409 {
00410 }
00411 
00412 #ifndef QT_NO_CURSOR
00413 void QwtPanner::showCursor(bool on)
00414 {
00415     QWidget *w = parentWidget();
00416     if ( w == NULL || d_data->cursor == NULL )
00417         return;
00418 
00419     if ( on )
00420     {
00421 #if QT_VERSION < 0x040000
00422         if ( w->testWState(WState_OwnCursor) )
00423 #else
00424         if ( w->testAttribute(Qt::WA_SetCursor) )
00425 #endif
00426         {
00427             delete d_data->restoreCursor;
00428             d_data->restoreCursor = new QCursor(w->cursor());
00429         }
00430         w->setCursor(*d_data->cursor);
00431     }
00432     else
00433     {
00434         if ( d_data->restoreCursor ) 
00435         {
00436             w->setCursor(*d_data->restoreCursor);
00437             delete d_data->restoreCursor;
00438             d_data->restoreCursor = NULL;
00439         }
00440         else
00441             w->unsetCursor();
00442     }
00443 }
00444 #endif

Generated on Mon Feb 26 21:22:37 2007 for Qwt User's Guide by  doxygen 1.4.6