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
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
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