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[int(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         hasCursor(false),
00075 #endif
00076         isEnabled(false)
00077     {
00078 #if QT_VERSION >= 0x040000
00079         orientations = Qt::Vertical | Qt::Horizontal;
00080 #else
00081         orientations[Qt::Vertical] = true;
00082         orientations[Qt::Horizontal] = true;
00083 #endif
00084     }
00085 
00086     ~PrivateData()
00087     {
00088 #ifndef QT_NO_CURSOR
00089         delete cursor;
00090         delete restoreCursor;
00091 #endif
00092     }
00093         
00094     int button;
00095     int buttonState;
00096     int abortKey;
00097     int abortKeyState;
00098 
00099     QPoint initialPos;
00100     QPoint pos;
00101 
00102     QPixmap pixmap;
00103 #ifndef QT_NO_CURSOR
00104     QCursor *cursor;
00105     QCursor *restoreCursor;
00106     bool hasCursor;
00107 #endif
00108     bool isEnabled;
00109 #if QT_VERSION >= 0x040000
00110     Qt::Orientations orientations;
00111 #else
00112     bool orientations[2];
00113 #endif
00114 };
00115 
00121 QwtPanner::QwtPanner(QWidget *parent):
00122     QWidget(parent)
00123 {
00124     d_data = new PrivateData();
00125 
00126 #if QT_VERSION >= 0x040000
00127     setAttribute(Qt::WA_TransparentForMouseEvents);
00128     setAttribute(Qt::WA_NoSystemBackground);
00129     setFocusPolicy(Qt::NoFocus);
00130 #else
00131     setBackgroundMode(Qt::NoBackground);
00132     setFocusPolicy(QWidget::NoFocus);
00133 #endif
00134     hide();
00135 
00136     setEnabled(true);
00137 }
00138 
00140 QwtPanner::~QwtPanner()
00141 {
00142     delete d_data;
00143 }
00144 
00149 void QwtPanner::setMouseButton(int button, int buttonState)
00150 {
00151     d_data->button = button;
00152     d_data->buttonState = buttonState;
00153 }
00154 
00156 void QwtPanner::getMouseButton(int &button, int &buttonState) const
00157 {
00158     button = d_data->button;
00159     buttonState = d_data->buttonState;
00160 }
00161 
00166 void QwtPanner::setAbortKey(int key, int state)
00167 {
00168     d_data->abortKey = key;
00169     d_data->abortKeyState = state;
00170 }
00171 
00173 void QwtPanner::getAbortKey(int &key, int &state) const
00174 {
00175     key = d_data->abortKey;
00176     state = d_data->abortKeyState;
00177 }
00178 
00187 #ifndef QT_NO_CURSOR
00188 void QwtPanner::setCursor(const QCursor &cursor)
00189 {
00190     d_data->cursor = new QCursor(cursor);
00191 }
00192 #endif
00193 
00198 #ifndef QT_NO_CURSOR
00199 const QCursor QwtPanner::cursor() const
00200 {
00201     if ( d_data->cursor )
00202         return *d_data->cursor;
00203 
00204     if ( parentWidget() )
00205         return parentWidget()->cursor();
00206 
00207     return QCursor();
00208 }
00209 #endif
00210 
00220 void QwtPanner::setEnabled(bool on)
00221 {
00222     if ( d_data->isEnabled != on )
00223     {
00224         d_data->isEnabled = on;
00225 
00226         QWidget *w = parentWidget();
00227         if ( w )
00228         {
00229             if ( d_data->isEnabled )
00230             {
00231                 w->installEventFilter(this);
00232             }
00233             else
00234             {
00235                 w->removeEventFilter(this);
00236                 hide();
00237             }
00238         }
00239     }
00240 }
00241 
00242 #if QT_VERSION >= 0x040000
00243 
00249 void QwtPanner::setOrientations(Qt::Orientations o)
00250 {
00251     d_data->orientations = o;
00252 }
00253 
00255 Qt::Orientations QwtPanner::orientations() const
00256 {
00257     return d_data->orientations;
00258 }
00259 
00260 #else
00261 void QwtPanner::enableOrientation(Qt::Orientation o, bool enable)
00262 {
00263     if ( o == Qt::Vertical || o == Qt::Horizontal )
00264         d_data->orientations[o] = enable;
00265 }
00266 #endif
00267 
00272 bool QwtPanner::isOrientationEnabled(Qt::Orientation o) const
00273 {
00274 #if QT_VERSION >= 0x040000
00275     return d_data->orientations & o;
00276 #else
00277     if ( o == Qt::Vertical || o == Qt::Horizontal )
00278         return d_data->orientations[o];
00279     return false;
00280 #endif
00281 }
00282 
00287 bool QwtPanner::isEnabled() const
00288 {
00289     return d_data->isEnabled;
00290 }
00291 
00300 void QwtPanner::paintEvent(QPaintEvent *pe)
00301 {
00302     QPixmap pm(size());
00303 
00304     QPainter painter(&pm);
00305 
00306     const QColor bg =
00307 #if QT_VERSION < 0x040000
00308         parentWidget()->palette().color(
00309             QPalette::Normal, QColorGroup::Background);
00310 #else
00311         parentWidget()->palette().color(
00312             QPalette::Normal, QPalette::Background);
00313 #endif
00314 
00315     painter.setPen(Qt::NoPen);
00316     painter.setBrush(QBrush(bg));
00317     painter.drawRect(0, 0, pm.width(), pm.height());
00318 
00319     int dx = d_data->pos.x() - d_data->initialPos.x();
00320     int dy = d_data->pos.y() - d_data->initialPos.y();
00321 
00322     QRect r(0, 0, d_data->pixmap.width(), d_data->pixmap.height());
00323     r.moveCenter(QPoint(r.center().x() + dx, r.center().y() + dy));
00324 
00325     painter.drawPixmap(r, d_data->pixmap);
00326     painter.end();
00327 
00328     painter.begin(this);
00329     painter.setClipRegion(pe->region());
00330     painter.drawPixmap(0, 0, pm);
00331 }
00332 
00341 bool QwtPanner::eventFilter(QObject *o, QEvent *e)
00342 {
00343     if ( o == NULL || o != parentWidget() )
00344         return false;
00345 
00346     switch(e->type())
00347     {
00348         case QEvent::MouseButtonPress:
00349         {
00350             widgetMousePressEvent((QMouseEvent *)e);
00351             break;
00352         }
00353         case QEvent::MouseMove:
00354         {
00355             widgetMouseMoveEvent((QMouseEvent *)e);
00356             break;
00357         }
00358         case QEvent::MouseButtonRelease:
00359         {
00360             widgetMouseReleaseEvent((QMouseEvent *)e);
00361             break;
00362         }
00363         case QEvent::KeyPress:
00364         {
00365             widgetKeyPressEvent((QKeyEvent *)e);
00366             break;
00367         }
00368         case QEvent::KeyRelease:
00369         {
00370             widgetKeyReleaseEvent((QKeyEvent *)e);
00371             break;
00372         }
00373         case QEvent::Paint:
00374         {
00375             if ( isVisible() )
00376                 return true;
00377             break;
00378         }
00379         default:;
00380     }
00381 
00382     return false;
00383 }
00384 
00392 void QwtPanner::widgetMousePressEvent(QMouseEvent *me)
00393 {
00394     if ( me->button() != d_data->button )
00395         return;
00396 
00397     QWidget *w = parentWidget();
00398     if ( w == NULL )
00399         return;
00400 
00401 #if QT_VERSION < 0x040000
00402     if ( (me->state() & Qt::KeyButtonMask) !=
00403         (d_data->buttonState & Qt::KeyButtonMask) )
00404 #else
00405     if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
00406         (int)(d_data->buttonState & Qt::KeyboardModifierMask) )
00407 #endif
00408     {
00409         return;
00410     }
00411 
00412 #ifndef QT_NO_CURSOR
00413     showCursor(true);
00414 #endif
00415 
00416     d_data->initialPos = d_data->pos = me->pos();
00417 
00418     QRect cr = parentWidget()->rect();
00419     if ( parentWidget()->inherits("QFrame") )
00420     {
00421         const QFrame* frame = (QFrame*)parentWidget();
00422         cr = frame->contentsRect();
00423     }
00424     setGeometry(cr);
00425 
00426     // We don't want to grab the picker !
00427     QwtArray<QwtPicker *> pickers = activePickers(parentWidget());
00428     for ( int i = 0; i < (int)pickers.size(); i++ )
00429         pickers[i]->setEnabled(false);
00430 
00431     d_data->pixmap = QPixmap::grabWidget(parentWidget(),
00432         cr.x(), cr.y(), cr.width(), cr.height());
00433 
00434     for ( int i = 0; i < (int)pickers.size(); i++ )
00435         pickers[i]->setEnabled(true);
00436 
00437     show();
00438 }
00439 
00446 void QwtPanner::widgetMouseMoveEvent(QMouseEvent *me)
00447 {
00448     if ( !isVisible() )
00449         return;
00450 
00451     QPoint pos = me->pos();
00452     if ( !isOrientationEnabled(Qt::Horizontal) )
00453         pos.setX(d_data->initialPos.x());
00454     if ( !isOrientationEnabled(Qt::Vertical) )
00455         pos.setY(d_data->initialPos.y());
00456 
00457     if ( pos != d_data->pos && rect().contains(pos) )
00458     {
00459         d_data->pos = pos;
00460         update();
00461 
00462         emit moved(d_data->pos.x() - d_data->initialPos.x(), 
00463             d_data->pos.y() - d_data->initialPos.y());
00464     }
00465 }
00466 
00474 void QwtPanner::widgetMouseReleaseEvent(QMouseEvent *me)
00475 {
00476     if ( isVisible() )
00477     {
00478         hide();
00479 #ifndef QT_NO_CURSOR
00480         showCursor(false);
00481 #endif
00482 
00483         QPoint pos = me->pos();
00484         if ( !isOrientationEnabled(Qt::Horizontal) )
00485             pos.setX(d_data->initialPos.x());
00486         if ( !isOrientationEnabled(Qt::Vertical) )
00487             pos.setY(d_data->initialPos.y());
00488 
00489         d_data->pixmap = QPixmap();
00490         d_data->pos = pos;
00491 
00492         if ( d_data->pos != d_data->initialPos )
00493         {
00494             emit panned(d_data->pos.x() - d_data->initialPos.x(), 
00495                 d_data->pos.y() - d_data->initialPos.y());
00496         }
00497     }
00498 }
00499 
00506 void QwtPanner::widgetKeyPressEvent(QKeyEvent *ke)
00507 {
00508     if ( ke->key() == d_data->abortKey )
00509     {
00510         const bool matched =
00511 #if QT_VERSION < 0x040000
00512             (ke->state() & Qt::KeyButtonMask) ==
00513                 (d_data->abortKeyState & Qt::KeyButtonMask);
00514 #else
00515             (ke->modifiers() & Qt::KeyboardModifierMask) ==
00516                 (int)(d_data->abortKeyState & Qt::KeyboardModifierMask);
00517 #endif
00518         if ( matched )
00519         {
00520             hide();
00521 #ifndef QT_NO_CURSOR
00522             showCursor(false);
00523 #endif
00524             d_data->pixmap = QPixmap();
00525         }
00526     }
00527 }
00528 
00535 void QwtPanner::widgetKeyReleaseEvent(QKeyEvent *)
00536 {
00537 }
00538 
00539 #ifndef QT_NO_CURSOR
00540 void QwtPanner::showCursor(bool on)
00541 {
00542     if ( on == d_data->hasCursor )
00543         return;
00544 
00545     QWidget *w = parentWidget();
00546     if ( w == NULL || d_data->cursor == NULL )
00547         return;
00548 
00549     d_data->hasCursor = on;
00550 
00551     if ( on )
00552     {
00553 #if QT_VERSION < 0x040000
00554         if ( w->testWState(WState_OwnCursor) )
00555 #else
00556         if ( w->testAttribute(Qt::WA_SetCursor) )
00557 #endif
00558         {
00559             delete d_data->restoreCursor;
00560             d_data->restoreCursor = new QCursor(w->cursor());
00561         }
00562         w->setCursor(*d_data->cursor);
00563     }
00564     else
00565     {
00566         if ( d_data->restoreCursor ) 
00567         {
00568             w->setCursor(*d_data->restoreCursor);
00569             delete d_data->restoreCursor;
00570             d_data->restoreCursor = NULL;
00571         }
00572         else
00573             w->unsetCursor();
00574     }
00575 }
00576 #endif

Generated on Sun Mar 22 16:54:07 2009 for Qwt User's Guide by  doxygen 1.5.0