Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00169 void QwtPanner::setAbortKey(int key, int state)
00170 {
00171 d_data->abortKey = key;
00172 d_data->abortKeyState = state;
00173 }
00174
00176 void QwtPanner::getAbortKey(int &key, int &state) const
00177 {
00178 key = d_data->abortKey;
00179 state = d_data->abortKeyState;
00180 }
00181
00190 #ifndef QT_NO_CURSOR
00191 void QwtPanner::setCursor(const QCursor &cursor)
00192 {
00193 d_data->cursor = new QCursor(cursor);
00194 }
00195 #endif
00196
00201 #ifndef QT_NO_CURSOR
00202 const QCursor QwtPanner::cursor() const
00203 {
00204 if ( d_data->cursor )
00205 return *d_data->cursor;
00206
00207 if ( parentWidget() )
00208 return parentWidget()->cursor();
00209
00210 return QCursor();
00211 }
00212 #endif
00213
00223 void QwtPanner::setEnabled(bool on)
00224 {
00225 if ( d_data->isEnabled != on )
00226 {
00227 d_data->isEnabled = on;
00228
00229 QWidget *w = parentWidget();
00230 if ( w )
00231 {
00232 if ( d_data->isEnabled )
00233 {
00234 w->installEventFilter(this);
00235 }
00236 else
00237 {
00238 w->removeEventFilter(this);
00239 hide();
00240 }
00241 }
00242 }
00243 }
00244
00245 #if QT_VERSION >= 0x040000
00246
00252 void QwtPanner::setOrientations(Qt::Orientations o)
00253 {
00254 d_data->orientations = o;
00255 }
00256
00258 Qt::Orientations QwtPanner::orientations() const
00259 {
00260 return d_data->orientations;
00261 }
00262
00263 #else
00264 void QwtPanner::enableOrientation(Qt::Orientation o, bool enable)
00265 {
00266 if ( o == Qt::Vertical || o == Qt::Horizontal )
00267 d_data->orientations[o] = enable;
00268 }
00269 #endif
00270
00275 bool QwtPanner::isOrientationEnabled(Qt::Orientation o) const
00276 {
00277 #if QT_VERSION >= 0x040000
00278 return d_data->orientations & o;
00279 #else
00280 if ( o == Qt::Vertical || o == Qt::Horizontal )
00281 return d_data->orientations[o];
00282 return false;
00283 #endif
00284 }
00285
00290 bool QwtPanner::isEnabled() const
00291 {
00292 return d_data->isEnabled;
00293 }
00294
00303 void QwtPanner::paintEvent(QPaintEvent *pe)
00304 {
00305 QPixmap pm(size());
00306
00307 QPainter painter(&pm);
00308
00309 const QColor bg =
00310 #if QT_VERSION < 0x040000
00311 parentWidget()->palette().color(
00312 QPalette::Normal, QColorGroup::Background);
00313 #else
00314 parentWidget()->palette().color(
00315 QPalette::Normal, QPalette::Background);
00316 #endif
00317
00318 painter.setPen(Qt::NoPen);
00319 painter.setBrush(QBrush(bg));
00320 painter.drawRect(0, 0, pm.width(), pm.height());
00321
00322 int dx = d_data->pos.x() - d_data->initialPos.x();
00323 int dy = d_data->pos.y() - d_data->initialPos.y();
00324
00325 QRect r(0, 0, d_data->pixmap.width(), d_data->pixmap.height());
00326 r.moveCenter(QPoint(r.center().x() + dx, r.center().y() + dy));
00327
00328 painter.drawPixmap(r, d_data->pixmap);
00329 painter.end();
00330
00331 painter.begin(this);
00332 painter.setClipRegion(pe->region());
00333 painter.drawPixmap(0, 0, pm);
00334 }
00335
00344 bool QwtPanner::eventFilter(QObject *o, QEvent *e)
00345 {
00346 if ( o == NULL || o != parentWidget() )
00347 return false;
00348
00349 switch(e->type())
00350 {
00351 case QEvent::MouseButtonPress:
00352 {
00353 widgetMousePressEvent((QMouseEvent *)e);
00354 break;
00355 }
00356 case QEvent::MouseMove:
00357 {
00358 widgetMouseMoveEvent((QMouseEvent *)e);
00359 break;
00360 }
00361 case QEvent::MouseButtonRelease:
00362 {
00363 widgetMouseReleaseEvent((QMouseEvent *)e);
00364 break;
00365 }
00366 case QEvent::KeyPress:
00367 {
00368 widgetKeyPressEvent((QKeyEvent *)e);
00369 break;
00370 }
00371 case QEvent::KeyRelease:
00372 {
00373 widgetKeyReleaseEvent((QKeyEvent *)e);
00374 break;
00375 }
00376 case QEvent::Paint:
00377 {
00378 if ( isVisible() )
00379 return true;
00380 break;
00381 }
00382 default:;
00383 }
00384
00385 return false;
00386 }
00387
00395 void QwtPanner::widgetMousePressEvent(QMouseEvent *me)
00396 {
00397 if ( me->button() != d_data->button )
00398 return;
00399
00400 QWidget *w = parentWidget();
00401 if ( w == NULL )
00402 return;
00403
00404 #if QT_VERSION < 0x040000
00405 if ( (me->state() & Qt::KeyButtonMask) !=
00406 (d_data->buttonState & Qt::KeyButtonMask) )
00407 #else
00408 if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
00409 (int)(d_data->buttonState & Qt::KeyboardModifierMask) )
00410 #endif
00411 {
00412 return;
00413 }
00414
00415 #ifndef QT_NO_CURSOR
00416 showCursor(true);
00417 #endif
00418
00419 d_data->initialPos = d_data->pos = me->pos();
00420
00421 QRect cr = parentWidget()->rect();
00422 if ( parentWidget()->inherits("QFrame") )
00423 {
00424 const QFrame* frame = (QFrame*)parentWidget();
00425 cr = frame->contentsRect();
00426 }
00427 setGeometry(cr);
00428
00429
00430 QwtArray<QwtPicker *> pickers = activePickers(parentWidget());
00431 for ( int i = 0; i < (int)pickers.size(); i++ )
00432 pickers[i]->setEnabled(false);
00433
00434 d_data->pixmap = QPixmap::grabWidget(parentWidget(),
00435 cr.x(), cr.y(), cr.width(), cr.height());
00436
00437 for ( int i = 0; i < (int)pickers.size(); i++ )
00438 pickers[i]->setEnabled(true);
00439
00440 show();
00441 }
00442
00449 void QwtPanner::widgetMouseMoveEvent(QMouseEvent *me)
00450 {
00451 if ( !isVisible() )
00452 return;
00453
00454 QPoint pos = me->pos();
00455 if ( !isOrientationEnabled(Qt::Horizontal) )
00456 pos.setX(d_data->initialPos.x());
00457 if ( !isOrientationEnabled(Qt::Vertical) )
00458 pos.setY(d_data->initialPos.y());
00459
00460 if ( pos != d_data->pos && rect().contains(pos) )
00461 {
00462 d_data->pos = pos;
00463 update();
00464
00465 emit moved(d_data->pos.x() - d_data->initialPos.x(),
00466 d_data->pos.y() - d_data->initialPos.y());
00467 }
00468 }
00469
00477 void QwtPanner::widgetMouseReleaseEvent(QMouseEvent *me)
00478 {
00479 if ( isVisible() )
00480 {
00481 hide();
00482 #ifndef QT_NO_CURSOR
00483 showCursor(false);
00484 #endif
00485
00486 QPoint pos = me->pos();
00487 if ( !isOrientationEnabled(Qt::Horizontal) )
00488 pos.setX(d_data->initialPos.x());
00489 if ( !isOrientationEnabled(Qt::Vertical) )
00490 pos.setY(d_data->initialPos.y());
00491
00492 d_data->pixmap = QPixmap();
00493 d_data->pos = pos;
00494
00495 if ( d_data->pos != d_data->initialPos )
00496 {
00497 emit panned(d_data->pos.x() - d_data->initialPos.x(),
00498 d_data->pos.y() - d_data->initialPos.y());
00499 }
00500 }
00501 }
00502
00509 void QwtPanner::widgetKeyPressEvent(QKeyEvent *ke)
00510 {
00511 if ( ke->key() == d_data->abortKey )
00512 {
00513 const bool matched =
00514 #if QT_VERSION < 0x040000
00515 (ke->state() & Qt::KeyButtonMask) ==
00516 (d_data->abortKeyState & Qt::KeyButtonMask);
00517 #else
00518 (ke->modifiers() & Qt::KeyboardModifierMask) ==
00519 (int)(d_data->abortKeyState & Qt::KeyboardModifierMask);
00520 #endif
00521 if ( matched )
00522 {
00523 hide();
00524 #ifndef QT_NO_CURSOR
00525 showCursor(false);
00526 #endif
00527 d_data->pixmap = QPixmap();
00528 }
00529 }
00530 }
00531
00536 void QwtPanner::widgetKeyReleaseEvent(QKeyEvent *)
00537 {
00538 }
00539
00540 #ifndef QT_NO_CURSOR
00541 void QwtPanner::showCursor(bool on)
00542 {
00543 if ( on == d_data->hasCursor )
00544 return;
00545
00546 QWidget *w = parentWidget();
00547 if ( w == NULL || d_data->cursor == NULL )
00548 return;
00549
00550 d_data->hasCursor = on;
00551
00552 if ( on )
00553 {
00554 #if QT_VERSION < 0x040000
00555 if ( w->testWState(WState_OwnCursor) )
00556 #else
00557 if ( w->testAttribute(Qt::WA_SetCursor) )
00558 #endif
00559 {
00560 delete d_data->restoreCursor;
00561 d_data->restoreCursor = new QCursor(w->cursor());
00562 }
00563 w->setCursor(*d_data->cursor);
00564 }
00565 else
00566 {
00567 if ( d_data->restoreCursor )
00568 {
00569 w->setCursor(*d_data->restoreCursor);
00570 delete d_data->restoreCursor;
00571 d_data->restoreCursor = NULL;
00572 }
00573 else
00574 w->unsetCursor();
00575 }
00576 }
00577 #endif