# 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