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 #if QT_VERSION < 0x040000
00018 #include <qobjectlist.h>
00019 #endif
00020 #include "qwt_picker.h"
00021 #include "qwt_array.h"
00022 #include "qwt_panner.h"
00023 
00024 static QwtArray<QwtPicker *> activePickers(QWidget *w)
00025 {
00026     QwtArray<QwtPicker *> pickers;
00027 
00028 #if QT_VERSION >= 0x040000
00029     QObjectList children = w->children();
00030     for ( int i = 0; i < children.size(); i++ )
00031     {
00032         QObject *obj = children[i];
00033         if ( obj->inherits("QwtPicker") )
00034         {
00035             QwtPicker *picker = (QwtPicker *)obj;
00036             if ( picker->isEnabled() )
00037                 pickers += picker;
00038         }
00039     }
00040 #else
00041     QObjectList *children = (QObjectList *)w->children();
00042     if ( children )
00043     {
00044         for ( QObjectListIterator it(*children); it.current(); ++it )
00045         {
00046             QObject *obj = (QObject *)it.current();
00047             if ( obj->inherits("QwtPicker") )
00048             {
00049                 QwtPicker *picker = (QwtPicker *)obj;
00050                 if ( picker->isEnabled() )
00051                 {
00052                     pickers.resize(pickers.size() + 1);
00053                     pickers[pickers.size() - 1] = picker;
00054                 }
00055             }
00056         }
00057     }
00058 #endif
00059 
00060     return pickers;
00061 }
00062 
00063 class QwtPanner::PrivateData
00064 {
00065 public:
00066     PrivateData():
00067         button(Qt::LeftButton),
00068         buttonState(Qt::NoButton),
00069         abortKey(Qt::Key_Escape),
00070         abortKeyState(Qt::NoButton),
00071 #ifndef QT_NO_CURSOR
00072         cursor(NULL),
00073         restoreCursor(NULL),
00074 #endif
00075         isEnabled(false)
00076     {
00077     }
00078 
00079     ~PrivateData()
00080     {
00081 #ifndef QT_NO_CURSOR
00082         delete cursor;
00083         delete restoreCursor;
00084 #endif
00085     }
00086         
00087     int button;
00088     int buttonState;
00089     int abortKey;
00090     int abortKeyState;
00091 
00092     QPoint initialPos;
00093     QPoint pos;
00094 
00095     QPixmap pixmap;
00096 #ifndef QT_NO_CURSOR
00097     QCursor *cursor;
00098     QCursor *restoreCursor;
00099 #endif
00100     bool isEnabled;
00101 };
00102 
00108 QwtPanner::QwtPanner(QWidget *parent):
00109     QWidget(parent)
00110 {
00111     d_data = new PrivateData();
00112 
00113 #if QT_VERSION >= 0x040000
00114     setAttribute(Qt::WA_TransparentForMouseEvents);
00115     setAttribute(Qt::WA_NoSystemBackground);
00116     setFocusPolicy(Qt::NoFocus);
00117 #else
00118     setBackgroundMode(Qt::NoBackground);
00119     setFocusPolicy(QWidget::NoFocus);
00120 #endif
00121     hide();
00122 
00123     setEnabled(true);
00124 }
00125 
00127 QwtPanner::~QwtPanner()
00128 {
00129     delete d_data;
00130 }
00131 
00136 void QwtPanner::setMouseButton(int button, int buttonState)
00137 {
00138     d_data->button = button;
00139     d_data->buttonState = buttonState;
00140 }
00141 
00143 void QwtPanner::getMouseButton(int &button, int &buttonState) const
00144 {
00145     button = d_data->button;
00146     buttonState = d_data->buttonState;
00147 }
00148 
00153 void QwtPanner::setAbortKey(int key, int state)
00154 {
00155     d_data->abortKey = key;
00156     d_data->abortKeyState = state;
00157 }
00158 
00160 void QwtPanner::getAbortKey(int &key, int &state) const
00161 {
00162     key = d_data->abortKey;
00163     state = d_data->abortKeyState;
00164 }
00165 
00174 #ifndef QT_NO_CURSOR
00175 void QwtPanner::setCursor(const QCursor &cursor)
00176 {
00177     d_data->cursor = new QCursor(cursor);
00178 }
00179 #endif
00180 
00185 #ifndef QT_NO_CURSOR
00186 const QCursor QwtPanner::cursor() const
00187 {
00188     if ( d_data->cursor )
00189         return *d_data->cursor;
00190 
00191     if ( parentWidget() )
00192         return parentWidget()->cursor();
00193 
00194     return QCursor();
00195 }
00196 #endif
00197 
00207 void QwtPanner::setEnabled(bool on)
00208 {
00209     if ( d_data->isEnabled != on )
00210     {
00211         d_data->isEnabled = on;
00212 
00213         QWidget *w = parentWidget();
00214         if ( w )
00215         {
00216             if ( d_data->isEnabled )
00217             {
00218                 w->installEventFilter(this);
00219             }
00220             else
00221             {
00222                 w->removeEventFilter(this);
00223                 hide();
00224             }
00225         }
00226     }
00227 }
00228 
00233 bool QwtPanner::isEnabled() const
00234 {
00235     return d_data->isEnabled;
00236 }
00237 
00246 void QwtPanner::paintEvent(QPaintEvent *pe)
00247 {
00248     QPixmap pm(size());
00249 
00250     QPainter painter(&pm);
00251 
00252     const QColor bg =
00253 #if QT_VERSION < 0x040000
00254         parentWidget()->palette().color(
00255             QPalette::Normal, QColorGroup::Background);
00256 #else
00257         parentWidget()->palette().color(
00258             QPalette::Normal, QPalette::Background);
00259 #endif
00260 
00261     painter.setPen(Qt::NoPen);
00262     painter.setBrush(QBrush(bg));
00263     painter.drawRect(0, 0, pm.width(), pm.height());
00264 
00265     int dx = d_data->pos.x() - d_data->initialPos.x();
00266     int dy = d_data->pos.y() - d_data->initialPos.y();
00267 
00268     QRect r(0, 0, d_data->pixmap.width(), d_data->pixmap.height());
00269     r.moveCenter(QPoint(r.center().x() + dx, r.center().y() + dy));
00270 
00271     painter.drawPixmap(r, d_data->pixmap);
00272     painter.end();
00273 
00274     painter.begin(this);
00275     painter.setClipRegion(pe->region());
00276     painter.drawPixmap(0, 0, pm);
00277 }
00278 
00287 bool QwtPanner::eventFilter(QObject *o, QEvent *e)
00288 {
00289     if ( o == NULL || o != parentWidget() )
00290         return false;
00291 
00292     switch(e->type())
00293     {
00294         case QEvent::MouseButtonPress:
00295         {
00296             widgetMousePressEvent((QMouseEvent *)e);
00297             break;
00298         }
00299         case QEvent::MouseMove:
00300         {
00301             widgetMouseMoveEvent((QMouseEvent *)e);
00302             break;
00303         }
00304         case QEvent::MouseButtonRelease:
00305         {
00306             widgetMouseReleaseEvent((QMouseEvent *)e);
00307             break;
00308         }
00309         case QEvent::KeyPress:
00310         {
00311             widgetKeyPressEvent((QKeyEvent *)e);
00312             break;
00313         }
00314         case QEvent::KeyRelease:
00315         {
00316             widgetKeyReleaseEvent((QKeyEvent *)e);
00317             break;
00318         }
00319         default:;
00320     }
00321 
00322     return false;
00323 }
00324 
00332 void QwtPanner::widgetMousePressEvent(QMouseEvent *me)
00333 {
00334     if ( me->button() != d_data->button )
00335         return;
00336 
00337     QWidget *w = parentWidget();
00338     if ( w == NULL )
00339         return;
00340 
00341 #if QT_VERSION < 0x040000
00342     if ( (me->state() & Qt::KeyButtonMask) !=
00343         (d_data->buttonState & Qt::KeyButtonMask) )
00344 #else
00345     if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
00346         (int)(d_data->buttonState & Qt::KeyboardModifierMask) )
00347 #endif
00348     {
00349         return;
00350     }
00351 
00352 #ifndef QT_NO_CURSOR
00353     showCursor(true);
00354 #endif
00355 
00356     d_data->initialPos = d_data->pos = me->pos();
00357 
00358     QRect cr = parentWidget()->rect();
00359     if ( parentWidget()->inherits("QFrame") )
00360     {
00361         const QFrame* frame = (QFrame*)parentWidget();
00362         cr = frame->contentsRect();
00363     }
00364     setGeometry(cr);
00365 
00366     // We don't want to grab the picker !
00367     QwtArray<QwtPicker *> pickers = activePickers(parentWidget());
00368     for ( int i = 0; i < (int)pickers.size(); i++ )
00369         pickers[i]->setEnabled(false);
00370 
00371     d_data->pixmap = QPixmap::grabWidget(parentWidget(),
00372         cr.x(), cr.y(), cr.width(), cr.height());
00373 
00374     for ( int i = 0; i < (int)pickers.size(); i++ )
00375         pickers[i]->setEnabled(true);
00376 
00377     show();
00378 }
00379 
00387 void QwtPanner::widgetMouseMoveEvent(QMouseEvent *me)
00388 {
00389     if ( isVisible() && rect().contains(me->pos()) )
00390     {
00391         d_data->pos = me->pos();
00392         update();
00393 
00394         emit moved(d_data->pos.x() - d_data->initialPos.x(), 
00395             d_data->pos.y() - d_data->initialPos.y());
00396     }
00397 }
00398 
00404 void QwtPanner::widgetMouseReleaseEvent(QMouseEvent *me)
00405 {
00406     if ( isVisible() )
00407     {
00408         hide();
00409 #ifndef QT_NO_CURSOR
00410         showCursor(false);
00411 #endif
00412 
00413         d_data->pixmap = QPixmap();
00414         d_data->pos = me->pos();
00415 
00416         if ( d_data->pos != d_data->initialPos )
00417         {
00418             emit panned(d_data->pos.x() - d_data->initialPos.x(), 
00419                 d_data->pos.y() - d_data->initialPos.y());
00420         }
00421     }
00422 }
00423 
00430 void QwtPanner::widgetKeyPressEvent(QKeyEvent *ke)
00431 {
00432     if ( ke->key() == d_data->abortKey )
00433     {
00434         const bool matched =
00435 #if QT_VERSION < 0x040000
00436             (ke->state() & Qt::KeyButtonMask) ==
00437                 (d_data->abortKeyState & Qt::KeyButtonMask);
00438 #else
00439             (ke->modifiers() & Qt::KeyboardModifierMask) ==
00440                 (int)(d_data->abortKeyState & Qt::KeyboardModifierMask);
00441 #endif
00442         if ( matched )
00443         {
00444             hide();
00445 #ifndef QT_NO_CURSOR
00446             showCursor(false);
00447 #endif
00448             d_data->pixmap = QPixmap();
00449         }
00450     }
00451 }
00452 
00459 void QwtPanner::widgetKeyReleaseEvent(QKeyEvent *)
00460 {
00461 }
00462 
00463 #ifndef QT_NO_CURSOR
00464 void QwtPanner::showCursor(bool on)
00465 {
00466     QWidget *w = parentWidget();
00467     if ( w == NULL || d_data->cursor == NULL )
00468         return;
00469 
00470     if ( on )
00471     {
00472 #if QT_VERSION < 0x040000
00473         if ( w->testWState(WState_OwnCursor) )
00474 #else
00475         if ( w->testAttribute(Qt::WA_SetCursor) )
00476 #endif
00477         {
00478             delete d_data->restoreCursor;
00479             d_data->restoreCursor = new QCursor(w->cursor());
00480         }
00481         w->setCursor(*d_data->cursor);
00482     }
00483     else
00484     {
00485         if ( d_data->restoreCursor ) 
00486         {
00487             w->setCursor(*d_data->restoreCursor);
00488             delete d_data->restoreCursor;
00489             d_data->restoreCursor = NULL;
00490         }
00491         else
00492             w->unsetCursor();
00493     }
00494 }
00495 #endif

Generated on Mon Jun 11 07:41:38 2007 for Qwt User's Guide by  doxygen 1.4.6