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 {
00135 #if 0
00136 if ( parentWidget()->paintEngine()->type() != QPaintEngine::OpenGL )
00137 #endif
00138 {
00139
00140
00141
00142 d_hasTextMask = false;
00143 }
00144 }
00145 #endif
00146
00147 if ( d_hasTextMask )
00148 {
00149 const QwtText label = d_picker->trackerText(
00150 d_picker->trackerPosition());
00151 if ( label.testPaintAttribute(QwtText::PaintBackground)
00152 && label.backgroundBrush().style() != Qt::NoBrush )
00153 {
00154 #if QT_VERSION >= 0x040300
00155 if ( label.backgroundBrush().color().alpha() > 0 )
00156 #endif
00157
00158 d_hasTextMask = false;
00159 }
00160 }
00161
00162 if ( d_hasTextMask )
00163 {
00164 QBitmap bm(width(), height());
00165 bm.fill(Qt::color0);
00166
00167 QPainter painter(&bm);
00168 painter.setFont(font());
00169
00170 QPen pen = d_picker->trackerPen();
00171 pen.setColor(Qt::color1);
00172 painter.setPen(pen);
00173
00174 d_picker->drawTracker(&painter);
00175
00176 mask = QRegion(bm);
00177 }
00178 else
00179 {
00180 mask = d_picker->trackerRect(font());
00181 }
00182 }
00183
00184 #if QT_VERSION < 0x040000
00185 QWidget *w = parentWidget();
00186 const bool doUpdate = w->isUpdatesEnabled();
00187 const Qt::BackgroundMode bgMode = w->backgroundMode();
00188 w->setUpdatesEnabled(false);
00189 if ( bgMode != Qt::NoBackground )
00190 w->setBackgroundMode(Qt::NoBackground);
00191 #endif
00192
00193 setMask(mask);
00194
00195 #if QT_VERSION < 0x040000
00196 if ( bgMode != Qt::NoBackground )
00197 w->setBackgroundMode(bgMode);
00198
00199 w->setUpdatesEnabled(doUpdate);
00200 #endif
00201
00202 setShown(!mask.isEmpty());
00203 }
00204
00205 void QwtPicker::PickerWidget::paintEvent(QPaintEvent *e)
00206 {
00207 QPainter painter(this);
00208 painter.setClipRegion(e->region());
00209
00210 if ( d_type == RubberBand )
00211 {
00212 painter.setPen(d_picker->rubberBandPen());
00213 d_picker->drawRubberBand(&painter);
00214 }
00215
00216 if ( d_type == Text )
00217 {
00218
00219
00220
00221
00222 bool doDrawTracker = !d_hasTextMask;
00223 #if QT_VERSION < 0x040000
00224 if ( !doDrawTracker && QPainter::redirect(this) )
00225 {
00226
00227 doDrawTracker = true;
00228 }
00229 #endif
00230 if ( doDrawTracker )
00231 {
00232 painter.setPen(d_picker->trackerPen());
00233 d_picker->drawTracker(&painter);
00234 }
00235 else
00236 painter.fillRect(e->rect(), QBrush(d_picker->trackerPen().color()));
00237 }
00238 }
00239
00249 QwtPicker::QwtPicker(QWidget *parent):
00250 QObject(parent)
00251 {
00252 init(parent, NoSelection, NoRubberBand, AlwaysOff);
00253 }
00254
00264 QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
00265 DisplayMode trackerMode, QWidget *parent):
00266 QObject(parent)
00267 {
00268 init(parent, selectionFlags, rubberBand, trackerMode);
00269 }
00270
00272 QwtPicker::~QwtPicker()
00273 {
00274 setMouseTracking(false);
00275 delete d_data->stateMachine;
00276 delete d_data->rubberBandWidget;
00277 delete d_data->trackerWidget;
00278 delete d_data;
00279 }
00280
00282 void QwtPicker::init(QWidget *parent, int selectionFlags,
00283 RubberBand rubberBand, DisplayMode trackerMode)
00284 {
00285 d_data = new PrivateData;
00286
00287 d_data->rubberBandWidget = NULL;
00288 d_data->trackerWidget = NULL;
00289
00290 d_data->rubberBand = rubberBand;
00291 d_data->enabled = false;
00292 d_data->resizeMode = Stretch;
00293 d_data->trackerMode = AlwaysOff;
00294 d_data->isActive = false;
00295 d_data->trackerPosition = QPoint(-1, -1);
00296 d_data->mouseTracking = false;
00297
00298 d_data->stateMachine = NULL;
00299 setSelectionFlags(selectionFlags);
00300
00301 if ( parent )
00302 {
00303 #if QT_VERSION >= 0x040000
00304 if ( parent->focusPolicy() == Qt::NoFocus )
00305 parent->setFocusPolicy(Qt::WheelFocus);
00306 #else
00307 if ( parent->focusPolicy() == QWidget::NoFocus )
00308 parent->setFocusPolicy(QWidget::WheelFocus);
00309 #endif
00310
00311 d_data->trackerFont = parent->font();
00312 d_data->mouseTracking = parent->hasMouseTracking();
00313 setEnabled(true);
00314 }
00315 setTrackerMode(trackerMode);
00316 }
00317
00321 void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
00322 {
00323 if ( d_data->stateMachine != stateMachine )
00324 {
00325 reset();
00326
00327 delete d_data->stateMachine;
00328 d_data->stateMachine = stateMachine;
00329
00330 if ( d_data->stateMachine )
00331 d_data->stateMachine->reset();
00332 }
00333 }
00334
00351 QwtPickerMachine *QwtPicker::stateMachine(int flags) const
00352 {
00353 if ( flags & PointSelection )
00354 {
00355 if ( flags & ClickSelection )
00356 return new QwtPickerClickPointMachine;
00357 else
00358 return new QwtPickerDragPointMachine;
00359 }
00360 if ( flags & RectSelection )
00361 {
00362 if ( flags & ClickSelection )
00363 return new QwtPickerClickRectMachine;
00364 else
00365 return new QwtPickerDragRectMachine;
00366 }
00367 if ( flags & PolygonSelection )
00368 {
00369 return new QwtPickerPolygonMachine();
00370 }
00371 return NULL;
00372 }
00373
00375 QWidget *QwtPicker::parentWidget()
00376 {
00377 QObject *obj = parent();
00378 if ( obj && obj->isWidgetType() )
00379 return (QWidget *)obj;
00380
00381 return NULL;
00382 }
00383
00385 const QWidget *QwtPicker::parentWidget() const
00386 {
00387 QObject *obj = parent();
00388 if ( obj && obj->isWidgetType() )
00389 return (QWidget *)obj;
00390
00391 return NULL;
00392 }
00393
00403 void QwtPicker::setSelectionFlags(int flags)
00404 {
00405 d_data->selectionFlags = flags;
00406 setStateMachine(stateMachine(flags));
00407 }
00408
00414 int QwtPicker::selectionFlags() const
00415 {
00416 return d_data->selectionFlags;
00417 }
00418
00427 void QwtPicker::setRubberBand(RubberBand rubberBand)
00428 {
00429 d_data->rubberBand = rubberBand;
00430 }
00431
00436 QwtPicker::RubberBand QwtPicker::rubberBand() const
00437 {
00438 return d_data->rubberBand;
00439 }
00440
00457 void QwtPicker::setTrackerMode(DisplayMode mode)
00458 {
00459 if ( d_data->trackerMode != mode )
00460 {
00461 d_data->trackerMode = mode;
00462 setMouseTracking(d_data->trackerMode == AlwaysOn);
00463 }
00464 }
00465
00470 QwtPicker::DisplayMode QwtPicker::trackerMode() const
00471 {
00472 return d_data->trackerMode;
00473 }
00474
00489 void QwtPicker::setResizeMode(ResizeMode mode)
00490 {
00491 d_data->resizeMode = mode;
00492 }
00493
00499 QwtPicker::ResizeMode QwtPicker::resizeMode() const
00500 {
00501 return d_data->resizeMode;
00502 }
00503
00513 void QwtPicker::setEnabled(bool enabled)
00514 {
00515 if ( d_data->enabled != enabled )
00516 {
00517 d_data->enabled = enabled;
00518
00519 QWidget *w = parentWidget();
00520 if ( w )
00521 {
00522 if ( enabled )
00523 w->installEventFilter(this);
00524 else
00525 w->removeEventFilter(this);
00526 }
00527
00528 updateDisplay();
00529 }
00530 }
00531
00537 bool QwtPicker::isEnabled() const
00538 {
00539 return d_data->enabled;
00540 }
00541
00548 void QwtPicker::setTrackerFont(const QFont &font)
00549 {
00550 if ( font != d_data->trackerFont )
00551 {
00552 d_data->trackerFont = font;
00553 updateDisplay();
00554 }
00555 }
00556
00562 QFont QwtPicker::trackerFont() const
00563 {
00564 return d_data->trackerFont;
00565 }
00566
00573 void QwtPicker::setTrackerPen(const QPen &pen)
00574 {
00575 if ( pen != d_data->trackerPen )
00576 {
00577 d_data->trackerPen = pen;
00578 updateDisplay();
00579 }
00580 }
00581
00586 QPen QwtPicker::trackerPen() const
00587 {
00588 return d_data->trackerPen;
00589 }
00590
00597 void QwtPicker::setRubberBandPen(const QPen &pen)
00598 {
00599 if ( pen != d_data->rubberBandPen )
00600 {
00601 d_data->rubberBandPen = pen;
00602 updateDisplay();
00603 }
00604 }
00605
00610 QPen QwtPicker::rubberBandPen() const
00611 {
00612 return d_data->rubberBandPen;
00613 }
00614
00628 QwtText QwtPicker::trackerText(const QPoint &pos) const
00629 {
00630 QString label;
00631
00632 switch(rubberBand())
00633 {
00634 case HLineRubberBand:
00635 label.sprintf("%d", pos.y());
00636 break;
00637 case VLineRubberBand:
00638 label.sprintf("%d", pos.x());
00639 break;
00640 default:
00641 label.sprintf("%d, %d", pos.x(), pos.y());
00642 }
00643 return label;
00644 }
00645
00654 void QwtPicker::drawRubberBand(QPainter *painter) const
00655 {
00656 if ( !isActive() || rubberBand() == NoRubberBand ||
00657 rubberBandPen().style() == Qt::NoPen )
00658 {
00659 return;
00660 }
00661
00662 const QRect &pRect = pickRect();
00663 const QwtPolygon &pa = d_data->selection;
00664
00665 if ( selectionFlags() & PointSelection )
00666 {
00667 if ( pa.count() < 1 )
00668 return;
00669
00670 const QPoint pos = pa[0];
00671
00672 switch(rubberBand())
00673 {
00674 case VLineRubberBand:
00675 QwtPainter::drawLine(painter, pos.x(),
00676 pRect.top(), pos.x(), pRect.bottom());
00677 break;
00678
00679 case HLineRubberBand:
00680 QwtPainter::drawLine(painter, pRect.left(),
00681 pos.y(), pRect.right(), pos.y());
00682 break;
00683
00684 case CrossRubberBand:
00685 QwtPainter::drawLine(painter, pos.x(),
00686 pRect.top(), pos.x(), pRect.bottom());
00687 QwtPainter::drawLine(painter, pRect.left(),
00688 pos.y(), pRect.right(), pos.y());
00689 break;
00690 default:
00691 break;
00692 }
00693 }
00694
00695 else if ( selectionFlags() & RectSelection )
00696 {
00697 if ( pa.count() < 2 )
00698 return;
00699
00700 QPoint p1 = pa[0];
00701 QPoint p2 = pa[int(pa.count() - 1)];
00702
00703 if ( selectionFlags() & CenterToCorner )
00704 {
00705 p1.setX(p1.x() - (p2.x() - p1.x()));
00706 p1.setY(p1.y() - (p2.y() - p1.y()));
00707 }
00708 else if ( selectionFlags() & CenterToRadius )
00709 {
00710 const int radius = qwtMax(qwtAbs(p2.x() - p1.x()),
00711 qwtAbs(p2.y() - p1.y()));
00712 p2.setX(p1.x() + radius);
00713 p2.setY(p1.y() + radius);
00714 p1.setX(p1.x() - radius);
00715 p1.setY(p1.y() - radius);
00716 }
00717
00718 #if QT_VERSION < 0x040000
00719 const QRect rect = QRect(p1, p2).normalize();
00720 #else
00721 const QRect rect = QRect(p1, p2).normalized();
00722 #endif
00723 switch(rubberBand())
00724 {
00725 case EllipseRubberBand:
00726 QwtPainter::drawEllipse(painter, rect);
00727 break;
00728 case RectRubberBand:
00729 QwtPainter::drawRect(painter, rect);
00730 break;
00731 default:
00732 break;
00733 }
00734 }
00735 else if ( selectionFlags() & PolygonSelection )
00736 {
00737 if ( rubberBand() == PolygonRubberBand )
00738 painter->drawPolyline(pa);
00739 }
00740 }
00741
00749 void QwtPicker::drawTracker(QPainter *painter) const
00750 {
00751 const QRect textRect = trackerRect(painter->font());
00752 if ( !textRect.isEmpty() )
00753 {
00754 QwtText label = trackerText(d_data->trackerPosition);
00755 if ( !label.isEmpty() )
00756 {
00757 painter->save();
00758
00759 #if defined(Q_WS_MAC)
00760
00761 #if QT_VERSION >= 0x040000
00762 painter->setRenderHint(QPainter::TextAntialiasing, false);
00763 #else
00764 QFont fnt = label.usedFont(painter->font());
00765 fnt.setStyleStrategy(QFont::NoAntialias);
00766 label.setFont(fnt);
00767 #endif
00768 #endif
00769 label.draw(painter, textRect);
00770
00771 painter->restore();
00772 }
00773 }
00774 }
00775
00777 QPoint QwtPicker::trackerPosition() const
00778 {
00779 return d_data->trackerPosition;
00780 }
00781
00791 QRect QwtPicker::trackerRect(const QFont &font) const
00792 {
00793 if ( trackerMode() == AlwaysOff ||
00794 (trackerMode() == ActiveOnly && !isActive() ) )
00795 {
00796 return QRect();
00797 }
00798
00799 if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
00800 return QRect();
00801
00802 QwtText text = trackerText(d_data->trackerPosition);
00803 if ( text.isEmpty() )
00804 return QRect();
00805
00806 QRect textRect(QPoint(0, 0), text.textSize(font));
00807
00808 const QPoint &pos = d_data->trackerPosition;
00809
00810 int alignment = 0;
00811 if ( isActive() && d_data->selection.count() > 1
00812 && rubberBand() != NoRubberBand )
00813 {
00814 const QPoint last =
00815 d_data->selection[int(d_data->selection.count()) - 2];
00816
00817 alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00818 alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00819 }
00820 else
00821 alignment = Qt::AlignTop | Qt::AlignRight;
00822
00823 const int margin = 5;
00824
00825 int x = pos.x();
00826 if ( alignment & Qt::AlignLeft )
00827 x -= textRect.width() + margin;
00828 else if ( alignment & Qt::AlignRight )
00829 x += margin;
00830
00831 int y = pos.y();
00832 if ( alignment & Qt::AlignBottom )
00833 y += margin;
00834 else if ( alignment & Qt::AlignTop )
00835 y -= textRect.height() + margin;
00836
00837 textRect.moveTopLeft(QPoint(x, y));
00838
00839 int right = qwtMin(textRect.right(), pickRect().right() - margin);
00840 int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00841 textRect.moveBottomRight(QPoint(right, bottom));
00842
00843 int left = qwtMax(textRect.left(), pickRect().left() + margin);
00844 int top = qwtMax(textRect.top(), pickRect().top() + margin);
00845 textRect.moveTopLeft(QPoint(left, top));
00846
00847 return textRect;
00848 }
00849
00862 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00863 {
00864 if ( o && o == parentWidget() )
00865 {
00866 switch(e->type())
00867 {
00868 case QEvent::Resize:
00869 {
00870 const QResizeEvent *re = (QResizeEvent *)e;
00871 if ( d_data->resizeMode == Stretch )
00872 stretchSelection(re->oldSize(), re->size());
00873
00874 if ( d_data->rubberBandWidget )
00875 d_data->rubberBandWidget->resize(re->size());
00876
00877 if ( d_data->trackerWidget )
00878 d_data->trackerWidget->resize(re->size());
00879 break;
00880 }
00881 case QEvent::Leave:
00882 widgetLeaveEvent(e);
00883 break;
00884 case QEvent::MouseButtonPress:
00885 widgetMousePressEvent((QMouseEvent *)e);
00886 break;
00887 case QEvent::MouseButtonRelease:
00888 widgetMouseReleaseEvent((QMouseEvent *)e);
00889 break;
00890 case QEvent::MouseButtonDblClick:
00891 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00892 break;
00893 case QEvent::MouseMove:
00894 widgetMouseMoveEvent((QMouseEvent *)e);
00895 break;
00896 case QEvent::KeyPress:
00897 widgetKeyPressEvent((QKeyEvent *)e);
00898 break;
00899 case QEvent::KeyRelease:
00900 widgetKeyReleaseEvent((QKeyEvent *)e);
00901 break;
00902 case QEvent::Wheel:
00903 widgetWheelEvent((QWheelEvent *)e);
00904 break;
00905 default:
00906 break;
00907 }
00908 }
00909 return false;
00910 }
00911
00922 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00923 {
00924 transition(e);
00925 }
00926
00936 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00937 {
00938 if ( pickRect().contains(e->pos()) )
00939 d_data->trackerPosition = e->pos();
00940 else
00941 d_data->trackerPosition = QPoint(-1, -1);
00942
00943 if ( !isActive() )
00944 updateDisplay();
00945
00946 transition(e);
00947 }
00948
00956 void QwtPicker::widgetLeaveEvent(QEvent *)
00957 {
00958 d_data->trackerPosition = QPoint(-1, -1);
00959 if ( !isActive() )
00960 updateDisplay();
00961 }
00962
00973 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00974 {
00975 transition(e);
00976 }
00977
00987 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00988 {
00989 transition(me);
00990 }
00991
00992
01002 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
01003 {
01004 if ( pickRect().contains(e->pos()) )
01005 d_data->trackerPosition = e->pos();
01006 else
01007 d_data->trackerPosition = QPoint(-1, -1);
01008
01009 updateDisplay();
01010
01011 transition(e);
01012 }
01013
01027 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
01028 {
01029 int dx = 0;
01030 int dy = 0;
01031
01032 int offset = 1;
01033 if ( ke->isAutoRepeat() )
01034 offset = 5;
01035
01036 if ( keyMatch(KeyLeft, ke) )
01037 dx = -offset;
01038 else if ( keyMatch(KeyRight, ke) )
01039 dx = offset;
01040 else if ( keyMatch(KeyUp, ke) )
01041 dy = -offset;
01042 else if ( keyMatch(KeyDown, ke) )
01043 dy = offset;
01044 else if ( keyMatch(KeyAbort, ke) )
01045 {
01046 reset();
01047 }
01048 else
01049 transition(ke);
01050
01051 if ( dx != 0 || dy != 0 )
01052 {
01053 const QRect rect = pickRect();
01054 const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
01055
01056 int x = pos.x() + dx;
01057 x = qwtMax(rect.left(), x);
01058 x = qwtMin(rect.right(), x);
01059
01060 int y = pos.y() + dy;
01061 y = qwtMax(rect.top(), y);
01062 y = qwtMin(rect.bottom(), y);
01063
01064 QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
01065 }
01066 }
01067
01077 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
01078 {
01079 transition(ke);
01080 }
01081
01089 void QwtPicker::transition(const QEvent *e)
01090 {
01091 if ( !d_data->stateMachine )
01092 return;
01093
01094 QwtPickerMachine::CommandList commandList =
01095 d_data->stateMachine->transition(*this, e);
01096
01097 QPoint pos;
01098 switch(e->type())
01099 {
01100 case QEvent::MouseButtonDblClick:
01101 case QEvent::MouseButtonPress:
01102 case QEvent::MouseButtonRelease:
01103 case QEvent::MouseMove:
01104 {
01105 const QMouseEvent *me = (QMouseEvent *)e;
01106 pos = me->pos();
01107 break;
01108 }
01109 default:
01110 pos = parentWidget()->mapFromGlobal(QCursor::pos());
01111 }
01112
01113 for ( uint i = 0; i < (uint)commandList.count(); i++ )
01114 {
01115 switch(commandList[i])
01116 {
01117 case QwtPickerMachine::Begin:
01118 {
01119 begin();
01120 break;
01121 }
01122 case QwtPickerMachine::Append:
01123 {
01124 append(pos);
01125 break;
01126 }
01127 case QwtPickerMachine::Move:
01128 {
01129 move(pos);
01130 break;
01131 }
01132 case QwtPickerMachine::End:
01133 {
01134 end();
01135 break;
01136 }
01137 }
01138 }
01139 }
01140
01146 void QwtPicker::begin()
01147 {
01148 if ( d_data->isActive )
01149 return;
01150
01151 d_data->selection.resize(0);
01152 d_data->isActive = true;
01153
01154 if ( trackerMode() != AlwaysOff )
01155 {
01156 if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
01157 {
01158 QWidget *w = parentWidget();
01159 if ( w )
01160 d_data->trackerPosition = w->mapFromGlobal(QCursor::pos());
01161 }
01162 }
01163
01164 updateDisplay();
01165 setMouseTracking(true);
01166 }
01167
01178 bool QwtPicker::end(bool ok)
01179 {
01180 if ( d_data->isActive )
01181 {
01182 setMouseTracking(false);
01183
01184 d_data->isActive = false;
01185
01186 if ( trackerMode() == ActiveOnly )
01187 d_data->trackerPosition = QPoint(-1, -1);
01188
01189 if ( ok )
01190 ok = accept(d_data->selection);
01191
01192 if ( ok )
01193 emit selected(d_data->selection);
01194 else
01195 d_data->selection.resize(0);
01196
01197 updateDisplay();
01198 }
01199 else
01200 ok = false;
01201
01202 return ok;
01203 }
01204
01208 void QwtPicker::reset()
01209 {
01210 if ( d_data->stateMachine )
01211 d_data->stateMachine->reset();
01212
01213 if (isActive())
01214 end(false);
01215 }
01216
01225 void QwtPicker::append(const QPoint &pos)
01226 {
01227 if ( d_data->isActive )
01228 {
01229 const int idx = d_data->selection.count();
01230 d_data->selection.resize(idx + 1);
01231 d_data->selection[idx] = pos;
01232
01233 updateDisplay();
01234
01235 emit appended(pos);
01236 }
01237 }
01238
01247 void QwtPicker::move(const QPoint &pos)
01248 {
01249 if ( d_data->isActive )
01250 {
01251 const int idx = d_data->selection.count() - 1;
01252 if ( idx >= 0 )
01253 {
01254 if ( d_data->selection[idx] != pos )
01255 {
01256 d_data->selection[idx] = pos;
01257
01258 updateDisplay();
01259
01260 emit moved(pos);
01261 }
01262 }
01263 }
01264 }
01265
01266 bool QwtPicker::accept(QwtPolygon &) const
01267 {
01268 return true;
01269 }
01270
01275 bool QwtPicker::isActive() const
01276 {
01277 return d_data->isActive;
01278 }
01279
01281 const QwtPolygon &QwtPicker::selection() const
01282 {
01283 return d_data->selection;
01284 }
01285
01295 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01296 {
01297 if ( oldSize.isEmpty() )
01298 {
01299
01300
01301 return;
01302 }
01303
01304 const double xRatio =
01305 double(newSize.width()) / double(oldSize.width());
01306 const double yRatio =
01307 double(newSize.height()) / double(oldSize.height());
01308
01309 for ( int i = 0; i < int(d_data->selection.count()); i++ )
01310 {
01311 QPoint &p = d_data->selection[i];
01312 p.setX(qRound(p.x() * xRatio));
01313 p.setY(qRound(p.y() * yRatio));
01314
01315 emit changed(d_data->selection);
01316 }
01317 }
01318
01332 void QwtPicker::setMouseTracking(bool enable)
01333 {
01334 QWidget *widget = parentWidget();
01335 if ( !widget )
01336 return;
01337
01338 if ( enable )
01339 {
01340 d_data->mouseTracking = widget->hasMouseTracking();
01341 widget->setMouseTracking(true);
01342 }
01343 else
01344 {
01345 widget->setMouseTracking(d_data->mouseTracking);
01346 }
01347 }
01348
01354 QRect QwtPicker::pickRect() const
01355 {
01356 QRect rect;
01357
01358 const QWidget *widget = parentWidget();
01359 if ( !widget )
01360 return rect;
01361
01362 if ( widget->inherits("QFrame") )
01363 rect = ((QFrame *)widget)->contentsRect();
01364 else
01365 rect = widget->rect();
01366
01367 return rect;
01368 }
01369
01371 void QwtPicker::updateDisplay()
01372 {
01373 QWidget *w = parentWidget();
01374
01375 bool showRubberband = false;
01376 bool showTracker = false;
01377 if ( w && w->isVisible() && d_data->enabled )
01378 {
01379 if ( rubberBand() != NoRubberBand && isActive() &&
01380 rubberBandPen().style() != Qt::NoPen )
01381 {
01382 showRubberband = true;
01383 }
01384
01385 if ( trackerMode() == AlwaysOn ||
01386 (trackerMode() == ActiveOnly && isActive() ) )
01387 {
01388 if ( trackerPen() != Qt::NoPen )
01389 showTracker = true;
01390 }
01391 }
01392
01393 #if QT_VERSION < 0x040000
01394 QGuardedPtr<PickerWidget> &rw = d_data->rubberBandWidget;
01395 #else
01396 QPointer<PickerWidget> &rw = d_data->rubberBandWidget;
01397 #endif
01398 if ( showRubberband )
01399 {
01400 if ( rw.isNull() )
01401 {
01402 rw = new PickerWidget( this, w, PickerWidget::RubberBand);
01403 rw->resize(w->size());
01404 }
01405 rw->updateMask();
01406 rw->update();
01407 }
01408 else
01409 delete rw;
01410
01411 #if QT_VERSION < 0x040000
01412 QGuardedPtr<PickerWidget> &tw = d_data->trackerWidget;
01413 #else
01414 QPointer<PickerWidget> &tw = d_data->trackerWidget;
01415 #endif
01416 if ( showTracker )
01417 {
01418 if ( tw.isNull() )
01419 {
01420 tw = new PickerWidget( this, w, PickerWidget::Text);
01421 tw->resize(w->size());
01422 }
01423 tw->updateMask();
01424 tw->update();
01425 }
01426 else
01427 delete tw;
01428 }
01429
01431 const QWidget *QwtPicker::rubberBandWidget() const
01432 {
01433 return d_data->rubberBandWidget;
01434 }
01435
01437 const QWidget *QwtPicker::trackerWidget() const
01438 {
01439 return d_data->trackerWidget;
01440 }
01441