00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <qapplication.h>
00011 #include <qevent.h>
00012 #include <qpainter.h>
00013 #include <qframe.h>
00014 #include <qcursor.h>
00015 #include <qbitmap.h>
00016 #include "qwt_math.h"
00017 #include "qwt_painter.h"
00018 #include "qwt_picker_machine.h"
00019 #include "qwt_picker.h"
00020 #if QT_VERSION < 0x040000
00021 #include <qguardedptr.h>
00022 #else
00023 #include <qpointer.h>
00024 #include <qpaintengine.h>
00025 #endif
00026
00027 class QwtPicker::PickerWidget: public QWidget
00028 {
00029 public:
00030 enum Type
00031 {
00032 RubberBand,
00033 Text
00034 };
00035
00036 PickerWidget(QwtPicker *, QWidget *, Type);
00037 virtual void updateMask();
00038
00039
00040
00041
00042
00043
00044 bool d_hasTextMask;
00045
00046 protected:
00047 virtual void paintEvent(QPaintEvent *);
00048
00049 QwtPicker *d_picker;
00050 Type d_type;
00051 };
00052
00053 class QwtPicker::PrivateData
00054 {
00055 public:
00056 bool enabled;
00057
00058 QwtPickerMachine *stateMachine;
00059
00060 int selectionFlags;
00061 QwtPicker::ResizeMode resizeMode;
00062
00063 QwtPicker::RubberBand rubberBand;
00064 QPen rubberBandPen;
00065
00066 QwtPicker::DisplayMode trackerMode;
00067 QPen trackerPen;
00068 QFont trackerFont;
00069
00070 QwtPolygon selection;
00071 bool isActive;
00072 QPoint trackerPosition;
00073
00074 bool mouseTracking;
00075
00076
00077
00078
00079
00080
00081
00082
00083 #if QT_VERSION < 0x040000
00084 QGuardedPtr<PickerWidget> rubberBandWidget;
00085 QGuardedPtr<PickerWidget> trackerWidget;
00086 #else
00087 QPointer<PickerWidget> rubberBandWidget;
00088 QPointer<PickerWidget> trackerWidget;
00089 #endif
00090 };
00091
00092 QwtPicker::PickerWidget::PickerWidget(
00093 QwtPicker *picker, QWidget *parent, Type type):
00094 QWidget(parent),
00095 d_hasTextMask(false),
00096 d_picker(picker),
00097 d_type(type)
00098 {
00099 #if QT_VERSION >= 0x040000
00100 setAttribute(Qt::WA_TransparentForMouseEvents);
00101 setAttribute(Qt::WA_NoSystemBackground);
00102 setFocusPolicy(Qt::NoFocus);
00103 #else
00104 setBackgroundMode(Qt::NoBackground);
00105 setFocusPolicy(QWidget::NoFocus);
00106 setMouseTracking(true);
00107 #endif
00108 hide();
00109 }
00110
00111 void QwtPicker::PickerWidget::updateMask()
00112 {
00113 QRegion mask;
00114
00115 if ( d_type == RubberBand )
00116 {
00117 QBitmap bm(width(), height());
00118 bm.fill(Qt::color0);
00119
00120 QPainter painter(&bm);
00121 QPen pen = d_picker->rubberBandPen();
00122 pen.setColor(Qt::color1);
00123 painter.setPen(pen);
00124
00125 d_picker->drawRubberBand(&painter);
00126
00127 mask = QRegion(bm);
00128 }
00129 if ( d_type == Text )
00130 {
00131 d_hasTextMask = true;
00132 #if QT_VERSION >= 0x040300
00133 if ( !parentWidget()->testAttribute(Qt::WA_PaintOnScreen) &&
00134 parentWidget()->paintEngine()->type() != QPaintEngine::OpenGL )
00135 {
00136
00137
00138
00139
00140
00141 d_hasTextMask = false;
00142 }
00143 #endif
00144
00145 if ( d_hasTextMask )
00146 {
00147 const QwtText label = d_picker->trackerText(
00148 d_picker->trackerPosition());
00149 if ( label.testPaintAttribute(QwtText::PaintBackground)
00150 && label.backgroundBrush().style() != Qt::NoBrush )
00151 {
00152 #if QT_VERSION >= 0x040300
00153 if ( label.backgroundBrush().color().alpha() > 0 )
00154 #endif
00155
00156 d_hasTextMask = false;
00157 }
00158 }
00159
00160 if ( d_hasTextMask )
00161 {
00162 QBitmap bm(width(), height());
00163 bm.fill(Qt::color0);
00164
00165 QPainter painter(&bm);
00166 painter.setFont(font());
00167
00168 QPen pen = d_picker->trackerPen();
00169 pen.setColor(Qt::color1);
00170 painter.setPen(pen);
00171
00172 d_picker->drawTracker(&painter);
00173
00174 mask = QRegion(bm);
00175 }
00176 else
00177 {
00178 mask = d_picker->trackerRect(font());
00179 }
00180 }
00181
00182 #if QT_VERSION < 0x040000
00183 QWidget *w = parentWidget();
00184 const bool doUpdate = w->isUpdatesEnabled();
00185 const Qt::BackgroundMode bgMode = w->backgroundMode();
00186 w->setUpdatesEnabled(false);
00187 if ( bgMode != Qt::NoBackground )
00188 w->setBackgroundMode(Qt::NoBackground);
00189 #endif
00190
00191 setMask(mask);
00192
00193 #if QT_VERSION < 0x040000
00194 if ( bgMode != Qt::NoBackground )
00195 w->setBackgroundMode(bgMode);
00196
00197 w->setUpdatesEnabled(doUpdate);
00198 #endif
00199
00200 setShown(!mask.isEmpty());
00201 }
00202
00203 void QwtPicker::PickerWidget::paintEvent(QPaintEvent *e)
00204 {
00205 QPainter painter(this);
00206 painter.setClipRegion(e->region());
00207
00208 if ( d_type == RubberBand )
00209 {
00210 painter.setPen(d_picker->rubberBandPen());
00211 d_picker->drawRubberBand(&painter);
00212 }
00213
00214 if ( d_type == Text )
00215 {
00216
00217
00218
00219
00220 bool doDrawTracker = !d_hasTextMask;
00221 #if QT_VERSION < 0x040000
00222 if ( !doDrawTracker && QPainter::redirect(this) )
00223 {
00224
00225 doDrawTracker = true;
00226 }
00227 #endif
00228 if ( doDrawTracker )
00229 {
00230 painter.setPen(d_picker->trackerPen());
00231 d_picker->drawTracker(&painter);
00232 }
00233 else
00234 painter.fillRect(e->rect(), QBrush(d_picker->trackerPen().color()));
00235 }
00236 }
00237
00247 QwtPicker::QwtPicker(QWidget *parent):
00248 QObject(parent)
00249 {
00250 init(parent, NoSelection, NoRubberBand, AlwaysOff);
00251 }
00252
00262 QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
00263 DisplayMode trackerMode, QWidget *parent):
00264 QObject(parent)
00265 {
00266 init(parent, selectionFlags, rubberBand, trackerMode);
00267 }
00268
00270 QwtPicker::~QwtPicker()
00271 {
00272 setMouseTracking(false);
00273 delete d_data->stateMachine;
00274 delete d_data->rubberBandWidget;
00275 delete d_data->trackerWidget;
00276 delete d_data;
00277 }
00278
00280 void QwtPicker::init(QWidget *parent, int selectionFlags,
00281 RubberBand rubberBand, DisplayMode trackerMode)
00282 {
00283 d_data = new PrivateData;
00284
00285 d_data->rubberBandWidget = NULL;
00286 d_data->trackerWidget = NULL;
00287
00288 d_data->rubberBand = rubberBand;
00289 d_data->enabled = false;
00290 d_data->resizeMode = Stretch;
00291 d_data->trackerMode = AlwaysOff;
00292 d_data->isActive = false;
00293 d_data->trackerPosition = QPoint(-1, -1);
00294 d_data->mouseTracking = false;
00295
00296 d_data->stateMachine = NULL;
00297 setSelectionFlags(selectionFlags);
00298
00299 if ( parent )
00300 {
00301 #if QT_VERSION >= 0x040000
00302 if ( parent->focusPolicy() == Qt::NoFocus )
00303 parent->setFocusPolicy(Qt::WheelFocus);
00304 #else
00305 if ( parent->focusPolicy() == QWidget::NoFocus )
00306 parent->setFocusPolicy(QWidget::WheelFocus);
00307 #endif
00308
00309 d_data->trackerFont = parent->font();
00310 d_data->mouseTracking = parent->hasMouseTracking();
00311 setEnabled(true);
00312 }
00313 setTrackerMode(trackerMode);
00314 }
00315
00319 void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
00320 {
00321 if ( d_data->stateMachine != stateMachine )
00322 {
00323 reset();
00324
00325 delete d_data->stateMachine;
00326 d_data->stateMachine = stateMachine;
00327
00328 if ( d_data->stateMachine )
00329 d_data->stateMachine->reset();
00330 }
00331 }
00332
00349 QwtPickerMachine *QwtPicker::stateMachine(int flags) const
00350 {
00351 if ( flags & PointSelection )
00352 {
00353 if ( flags & ClickSelection )
00354 return new QwtPickerClickPointMachine;
00355 else
00356 return new QwtPickerDragPointMachine;
00357 }
00358 if ( flags & RectSelection )
00359 {
00360 if ( flags & ClickSelection )
00361 return new QwtPickerClickRectMachine;
00362 else
00363 return new QwtPickerDragRectMachine;
00364 }
00365 if ( flags & PolygonSelection )
00366 {
00367 return new QwtPickerPolygonMachine();
00368 }
00369 return NULL;
00370 }
00371
00373 QWidget *QwtPicker::parentWidget()
00374 {
00375 QObject *obj = parent();
00376 if ( obj && obj->isWidgetType() )
00377 return (QWidget *)obj;
00378
00379 return NULL;
00380 }
00381
00383 const QWidget *QwtPicker::parentWidget() const
00384 {
00385 QObject *obj = parent();
00386 if ( obj && obj->isWidgetType() )
00387 return (QWidget *)obj;
00388
00389 return NULL;
00390 }
00391
00401 void QwtPicker::setSelectionFlags(int flags)
00402 {
00403 d_data->selectionFlags = flags;
00404 setStateMachine(stateMachine(flags));
00405 }
00406
00412 int QwtPicker::selectionFlags() const
00413 {
00414 return d_data->selectionFlags;
00415 }
00416
00425 void QwtPicker::setRubberBand(RubberBand rubberBand)
00426 {
00427 d_data->rubberBand = rubberBand;
00428 }
00429
00434 QwtPicker::RubberBand QwtPicker::rubberBand() const
00435 {
00436 return d_data->rubberBand;
00437 }
00438
00455 void QwtPicker::setTrackerMode(DisplayMode mode)
00456 {
00457 if ( d_data->trackerMode != mode )
00458 {
00459 d_data->trackerMode = mode;
00460 setMouseTracking(d_data->trackerMode == AlwaysOn);
00461 }
00462 }
00463
00468 QwtPicker::DisplayMode QwtPicker::trackerMode() const
00469 {
00470 return d_data->trackerMode;
00471 }
00472
00487 void QwtPicker::setResizeMode(ResizeMode mode)
00488 {
00489 d_data->resizeMode = mode;
00490 }
00491
00497 QwtPicker::ResizeMode QwtPicker::resizeMode() const
00498 {
00499 return d_data->resizeMode;
00500 }
00501
00511 void QwtPicker::setEnabled(bool enabled)
00512 {
00513 if ( d_data->enabled != enabled )
00514 {
00515 d_data->enabled = enabled;
00516
00517 QWidget *w = parentWidget();
00518 if ( w )
00519 {
00520 if ( enabled )
00521 w->installEventFilter(this);
00522 else
00523 w->removeEventFilter(this);
00524 }
00525
00526 updateDisplay();
00527 }
00528 }
00529
00535 bool QwtPicker::isEnabled() const
00536 {
00537 return d_data->enabled;
00538 }
00539
00546 void QwtPicker::setTrackerFont(const QFont &font)
00547 {
00548 if ( font != d_data->trackerFont )
00549 {
00550 d_data->trackerFont = font;
00551 updateDisplay();
00552 }
00553 }
00554
00560 QFont QwtPicker::trackerFont() const
00561 {
00562 return d_data->trackerFont;
00563 }
00564
00571 void QwtPicker::setTrackerPen(const QPen &pen)
00572 {
00573 if ( pen != d_data->trackerPen )
00574 {
00575 d_data->trackerPen = pen;
00576 updateDisplay();
00577 }
00578 }
00579
00584 QPen QwtPicker::trackerPen() const
00585 {
00586 return d_data->trackerPen;
00587 }
00588
00595 void QwtPicker::setRubberBandPen(const QPen &pen)
00596 {
00597 if ( pen != d_data->rubberBandPen )
00598 {
00599 d_data->rubberBandPen = pen;
00600 updateDisplay();
00601 }
00602 }
00603
00608 QPen QwtPicker::rubberBandPen() const
00609 {
00610 return d_data->rubberBandPen;
00611 }
00612
00626 QwtText QwtPicker::trackerText(const QPoint &pos) const
00627 {
00628 QString label;
00629
00630 switch(rubberBand())
00631 {
00632 case HLineRubberBand:
00633 label.sprintf("%d", pos.y());
00634 break;
00635 case VLineRubberBand:
00636 label.sprintf("%d", pos.x());
00637 break;
00638 default:
00639 label.sprintf("%d, %d", pos.x(), pos.y());
00640 }
00641 return label;
00642 }
00643
00652 void QwtPicker::drawRubberBand(QPainter *painter) const
00653 {
00654 if ( !isActive() || rubberBand() == NoRubberBand ||
00655 rubberBandPen().style() == Qt::NoPen )
00656 {
00657 return;
00658 }
00659
00660 const QRect &pRect = pickRect();
00661 const QwtPolygon &pa = d_data->selection;
00662
00663 if ( selectionFlags() & PointSelection )
00664 {
00665 if ( pa.count() < 1 )
00666 return;
00667
00668 const QPoint pos = pa[0];
00669
00670 switch(rubberBand())
00671 {
00672 case VLineRubberBand:
00673 QwtPainter::drawLine(painter, pos.x(),
00674 pRect.top(), pos.x(), pRect.bottom());
00675 break;
00676
00677 case HLineRubberBand:
00678 QwtPainter::drawLine(painter, pRect.left(),
00679 pos.y(), pRect.right(), pos.y());
00680 break;
00681
00682 case CrossRubberBand:
00683 QwtPainter::drawLine(painter, pos.x(),
00684 pRect.top(), pos.x(), pRect.bottom());
00685 QwtPainter::drawLine(painter, pRect.left(),
00686 pos.y(), pRect.right(), pos.y());
00687 break;
00688 default:
00689 break;
00690 }
00691 }
00692
00693 else if ( selectionFlags() & RectSelection )
00694 {
00695 if ( pa.count() < 2 )
00696 return;
00697
00698 QPoint p1 = pa[0];
00699 QPoint p2 = pa[int(pa.count() - 1)];
00700
00701 if ( selectionFlags() & CenterToCorner )
00702 {
00703 p1.setX(p1.x() - (p2.x() - p1.x()));
00704 p1.setY(p1.y() - (p2.y() - p1.y()));
00705 }
00706 else if ( selectionFlags() & CenterToRadius )
00707 {
00708 const int radius = qwtMax(qwtAbs(p2.x() - p1.x()),
00709 qwtAbs(p2.y() - p1.y()));
00710 p2.setX(p1.x() + radius);
00711 p2.setY(p1.y() + radius);
00712 p1.setX(p1.x() - radius);
00713 p1.setY(p1.y() - radius);
00714 }
00715
00716 #if QT_VERSION < 0x040000
00717 const QRect rect = QRect(p1, p2).normalize();
00718 #else
00719 const QRect rect = QRect(p1, p2).normalized();
00720 #endif
00721 switch(rubberBand())
00722 {
00723 case EllipseRubberBand:
00724 QwtPainter::drawEllipse(painter, rect);
00725 break;
00726 case RectRubberBand:
00727 QwtPainter::drawRect(painter, rect);
00728 break;
00729 default:
00730 break;
00731 }
00732 }
00733 else if ( selectionFlags() & PolygonSelection )
00734 {
00735 if ( rubberBand() == PolygonRubberBand )
00736 painter->drawPolyline(pa);
00737 }
00738 }
00739
00747 void QwtPicker::drawTracker(QPainter *painter) const
00748 {
00749 const QRect textRect = trackerRect(painter->font());
00750 if ( !textRect.isEmpty() )
00751 {
00752 QwtText label = trackerText(d_data->trackerPosition);
00753 if ( !label.isEmpty() )
00754 {
00755 painter->save();
00756
00757 #if defined(Q_WS_MAC)
00758
00759 #if QT_VERSION >= 0x040000
00760 painter->setRenderHint(QPainter::TextAntialiasing, false);
00761 #else
00762 QFont fnt = label.usedFont(painter->font());
00763 fnt.setStyleStrategy(QFont::NoAntialias);
00764 label.setFont(fnt);
00765 #endif
00766 #endif
00767 label.draw(painter, textRect);
00768
00769 painter->restore();
00770 }
00771 }
00772 }
00773
00774 QPoint QwtPicker::trackerPosition() const
00775 {
00776 return d_data->trackerPosition;
00777 }
00778
00779 QRect QwtPicker::trackerRect(const QFont &font) const
00780 {
00781 if ( trackerMode() == AlwaysOff ||
00782 (trackerMode() == ActiveOnly && !isActive() ) )
00783 {
00784 return QRect();
00785 }
00786
00787 if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
00788 return QRect();
00789
00790 QwtText text = trackerText(d_data->trackerPosition);
00791 if ( text.isEmpty() )
00792 return QRect();
00793
00794 QRect textRect(QPoint(0, 0), text.textSize(font));
00795
00796 const QPoint &pos = d_data->trackerPosition;
00797
00798 int alignment = 0;
00799 if ( isActive() && d_data->selection.count() > 1
00800 && rubberBand() != NoRubberBand )
00801 {
00802 const QPoint last =
00803 d_data->selection[int(d_data->selection.count()) - 2];
00804
00805 alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00806 alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00807 }
00808 else
00809 alignment = Qt::AlignTop | Qt::AlignRight;
00810
00811 const int margin = 5;
00812
00813 int x = pos.x();
00814 if ( alignment & Qt::AlignLeft )
00815 x -= textRect.width() + margin;
00816 else if ( alignment & Qt::AlignRight )
00817 x += margin;
00818
00819 int y = pos.y();
00820 if ( alignment & Qt::AlignBottom )
00821 y += margin;
00822 else if ( alignment & Qt::AlignTop )
00823 y -= textRect.height() + margin;
00824
00825 textRect.moveTopLeft(QPoint(x, y));
00826
00827 int right = qwtMin(textRect.right(), pickRect().right() - margin);
00828 int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00829 textRect.moveBottomRight(QPoint(right, bottom));
00830
00831 int left = qwtMax(textRect.left(), pickRect().left() + margin);
00832 int top = qwtMax(textRect.top(), pickRect().top() + margin);
00833 textRect.moveTopLeft(QPoint(left, top));
00834
00835 return textRect;
00836 }
00837
00850 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00851 {
00852 if ( o && o == parentWidget() )
00853 {
00854 switch(e->type())
00855 {
00856 case QEvent::Resize:
00857 {
00858 const QResizeEvent *re = (QResizeEvent *)e;
00859 if ( d_data->resizeMode == Stretch )
00860 stretchSelection(re->oldSize(), re->size());
00861
00862 if ( d_data->rubberBandWidget )
00863 d_data->rubberBandWidget->resize(re->size());
00864
00865 if ( d_data->trackerWidget )
00866 d_data->trackerWidget->resize(re->size());
00867 break;
00868 }
00869 case QEvent::Leave:
00870 widgetLeaveEvent(e);
00871 break;
00872 case QEvent::MouseButtonPress:
00873 widgetMousePressEvent((QMouseEvent *)e);
00874 break;
00875 case QEvent::MouseButtonRelease:
00876 widgetMouseReleaseEvent((QMouseEvent *)e);
00877 break;
00878 case QEvent::MouseButtonDblClick:
00879 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00880 break;
00881 case QEvent::MouseMove:
00882 widgetMouseMoveEvent((QMouseEvent *)e);
00883 break;
00884 case QEvent::KeyPress:
00885 widgetKeyPressEvent((QKeyEvent *)e);
00886 break;
00887 case QEvent::KeyRelease:
00888 widgetKeyReleaseEvent((QKeyEvent *)e);
00889 break;
00890 case QEvent::Wheel:
00891 widgetWheelEvent((QWheelEvent *)e);
00892 break;
00893 default:
00894 break;
00895 }
00896 }
00897 return false;
00898 }
00899
00910 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00911 {
00912 transition(e);
00913 }
00914
00924 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00925 {
00926 if ( pickRect().contains(e->pos()) )
00927 d_data->trackerPosition = e->pos();
00928 else
00929 d_data->trackerPosition = QPoint(-1, -1);
00930
00931 if ( !isActive() )
00932 updateDisplay();
00933
00934 transition(e);
00935 }
00936
00944 void QwtPicker::widgetLeaveEvent(QEvent *)
00945 {
00946 d_data->trackerPosition = QPoint(-1, -1);
00947 if ( !isActive() )
00948 updateDisplay();
00949 }
00950
00961 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00962 {
00963 transition(e);
00964 }
00965
00975 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00976 {
00977 transition(me);
00978 }
00979
00980
00990 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
00991 {
00992 if ( pickRect().contains(e->pos()) )
00993 d_data->trackerPosition = e->pos();
00994 else
00995 d_data->trackerPosition = QPoint(-1, -1);
00996
00997 updateDisplay();
00998
00999 transition(e);
01000 }
01001
01015 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
01016 {
01017 int dx = 0;
01018 int dy = 0;
01019
01020 int offset = 1;
01021 if ( ke->isAutoRepeat() )
01022 offset = 5;
01023
01024 if ( keyMatch(KeyLeft, ke) )
01025 dx = -offset;
01026 else if ( keyMatch(KeyRight, ke) )
01027 dx = offset;
01028 else if ( keyMatch(KeyUp, ke) )
01029 dy = -offset;
01030 else if ( keyMatch(KeyDown, ke) )
01031 dy = offset;
01032 else if ( keyMatch(KeyAbort, ke) )
01033 {
01034 reset();
01035 }
01036 else
01037 transition(ke);
01038
01039 if ( dx != 0 || dy != 0 )
01040 {
01041 const QRect rect = pickRect();
01042 const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
01043
01044 int x = pos.x() + dx;
01045 x = qwtMax(rect.left(), x);
01046 x = qwtMin(rect.right(), x);
01047
01048 int y = pos.y() + dy;
01049 y = qwtMax(rect.top(), y);
01050 y = qwtMin(rect.bottom(), y);
01051
01052 QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
01053 }
01054 }
01055
01065 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
01066 {
01067 transition(ke);
01068 }
01069
01077 void QwtPicker::transition(const QEvent *e)
01078 {
01079 if ( !d_data->stateMachine )
01080 return;
01081
01082 QwtPickerMachine::CommandList commandList =
01083 d_data->stateMachine->transition(*this, e);
01084
01085 QPoint pos;
01086 switch(e->type())
01087 {
01088 case QEvent::MouseButtonDblClick:
01089 case QEvent::MouseButtonPress:
01090 case QEvent::MouseButtonRelease:
01091 case QEvent::MouseMove:
01092 {
01093 const QMouseEvent *me = (QMouseEvent *)e;
01094 pos = me->pos();
01095 break;
01096 }
01097 default:
01098 pos = parentWidget()->mapFromGlobal(QCursor::pos());
01099 }
01100
01101 for ( uint i = 0; i < (uint)commandList.count(); i++ )
01102 {
01103 switch(commandList[i])
01104 {
01105 case QwtPickerMachine::Begin:
01106 {
01107 begin();
01108 break;
01109 }
01110 case QwtPickerMachine::Append:
01111 {
01112 append(pos);
01113 break;
01114 }
01115 case QwtPickerMachine::Move:
01116 {
01117 move(pos);
01118 break;
01119 }
01120 case QwtPickerMachine::End:
01121 {
01122 end();
01123 break;
01124 }
01125 }
01126 }
01127 }
01128
01134 void QwtPicker::begin()
01135 {
01136 if ( d_data->isActive )
01137 return;
01138
01139 d_data->selection.resize(0);
01140 d_data->isActive = true;
01141
01142 if ( trackerMode() != AlwaysOff )
01143 {
01144 if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
01145 {
01146 QWidget *w = parentWidget();
01147 if ( w )
01148 d_data->trackerPosition = w->mapFromGlobal(QCursor::pos());
01149 }
01150 }
01151
01152 updateDisplay();
01153 setMouseTracking(true);
01154 }
01155
01166 bool QwtPicker::end(bool ok)
01167 {
01168 if ( d_data->isActive )
01169 {
01170 setMouseTracking(false);
01171
01172 d_data->isActive = false;
01173
01174 if ( trackerMode() == ActiveOnly )
01175 d_data->trackerPosition = QPoint(-1, -1);
01176
01177 if ( ok )
01178 ok = accept(d_data->selection);
01179
01180 if ( ok )
01181 emit selected(d_data->selection);
01182 else
01183 d_data->selection.resize(0);
01184
01185 updateDisplay();
01186 }
01187 else
01188 ok = false;
01189
01190 return ok;
01191 }
01192
01196 void QwtPicker::reset()
01197 {
01198 if ( d_data->stateMachine )
01199 d_data->stateMachine->reset();
01200
01201 if (isActive())
01202 end(false);
01203 }
01204
01213 void QwtPicker::append(const QPoint &pos)
01214 {
01215 if ( d_data->isActive )
01216 {
01217 const int idx = d_data->selection.count();
01218 d_data->selection.resize(idx + 1);
01219 d_data->selection[idx] = pos;
01220
01221 updateDisplay();
01222
01223 emit appended(pos);
01224 }
01225 }
01226
01235 void QwtPicker::move(const QPoint &pos)
01236 {
01237 if ( d_data->isActive )
01238 {
01239 const int idx = d_data->selection.count() - 1;
01240 if ( idx >= 0 )
01241 {
01242 if ( d_data->selection[idx] != pos )
01243 {
01244 d_data->selection[idx] = pos;
01245
01246 updateDisplay();
01247
01248 emit moved(pos);
01249 }
01250 }
01251 }
01252 }
01253
01254 bool QwtPicker::accept(QwtPolygon &) const
01255 {
01256 return true;
01257 }
01258
01263 bool QwtPicker::isActive() const
01264 {
01265 return d_data->isActive;
01266 }
01267
01269 const QwtPolygon &QwtPicker::selection() const
01270 {
01271 return d_data->selection;
01272 }
01273
01283 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01284 {
01285 if ( oldSize.isEmpty() )
01286 {
01287
01288
01289 return;
01290 }
01291
01292 const double xRatio =
01293 double(newSize.width()) / double(oldSize.width());
01294 const double yRatio =
01295 double(newSize.height()) / double(oldSize.height());
01296
01297 for ( int i = 0; i < int(d_data->selection.count()); i++ )
01298 {
01299 QPoint &p = d_data->selection[i];
01300 p.setX(qRound(p.x() * xRatio));
01301 p.setY(qRound(p.y() * yRatio));
01302
01303 emit changed(d_data->selection);
01304 }
01305 }
01306
01320 void QwtPicker::setMouseTracking(bool enable)
01321 {
01322 QWidget *widget = parentWidget();
01323 if ( !widget )
01324 return;
01325
01326 if ( enable )
01327 {
01328 d_data->mouseTracking = widget->hasMouseTracking();
01329 widget->setMouseTracking(true);
01330 }
01331 else
01332 {
01333 widget->setMouseTracking(d_data->mouseTracking);
01334 }
01335 }
01336
01342 QRect QwtPicker::pickRect() const
01343 {
01344 QRect rect;
01345
01346 const QWidget *widget = parentWidget();
01347 if ( !widget )
01348 return rect;
01349
01350 if ( widget->inherits("QFrame") )
01351 rect = ((QFrame *)widget)->contentsRect();
01352 else
01353 rect = widget->rect();
01354
01355 return rect;
01356 }
01357
01358 void QwtPicker::updateDisplay()
01359 {
01360 QWidget *w = parentWidget();
01361
01362 bool showRubberband = false;
01363 bool showTracker = false;
01364 if ( w && w->isVisible() && d_data->enabled )
01365 {
01366 if ( rubberBand() != NoRubberBand && isActive() &&
01367 rubberBandPen().style() != Qt::NoPen )
01368 {
01369 showRubberband = true;
01370 }
01371
01372 if ( trackerMode() == AlwaysOn ||
01373 (trackerMode() == ActiveOnly && isActive() ) )
01374 {
01375 if ( trackerPen() != Qt::NoPen )
01376 showTracker = true;
01377 }
01378 }
01379
01380 #if QT_VERSION < 0x040000
01381 QGuardedPtr<PickerWidget> &rw = d_data->rubberBandWidget;
01382 #else
01383 QPointer<PickerWidget> &rw = d_data->rubberBandWidget;
01384 #endif
01385 if ( showRubberband )
01386 {
01387 if ( rw.isNull() )
01388 {
01389 rw = new PickerWidget( this, w, PickerWidget::RubberBand);
01390 rw->resize(w->size());
01391 }
01392 rw->updateMask();
01393 rw->update();
01394 }
01395 else
01396 delete rw;
01397
01398 #if QT_VERSION < 0x040000
01399 QGuardedPtr<PickerWidget> &tw = d_data->trackerWidget;
01400 #else
01401 QPointer<PickerWidget> &tw = d_data->trackerWidget;
01402 #endif
01403 if ( showTracker )
01404 {
01405 if ( tw.isNull() )
01406 {
01407 tw = new PickerWidget( this, w, PickerWidget::Text);
01408 tw->resize(w->size());
01409 }
01410 tw->updateMask();
01411 tw->update();
01412 }
01413 else
01414 delete tw;
01415 }
01416
01417 const QWidget *QwtPicker::rubberBandWidget() const
01418 {
01419 return d_data->rubberBandWidget;
01420 }
01421
01422 const QWidget *QwtPicker::trackerWidget() const
01423 {
01424 return d_data->trackerWidget;
01425 }
01426