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
00776 QPoint QwtPicker::trackerPosition() const
00777 {
00778 return d_data->trackerPosition;
00779 }
00780
00781 QRect QwtPicker::trackerRect(const QFont &font) const
00782 {
00783 if ( trackerMode() == AlwaysOff ||
00784 (trackerMode() == ActiveOnly && !isActive() ) )
00785 {
00786 return QRect();
00787 }
00788
00789 if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
00790 return QRect();
00791
00792 QwtText text = trackerText(d_data->trackerPosition);
00793 if ( text.isEmpty() )
00794 return QRect();
00795
00796 QRect textRect(QPoint(0, 0), text.textSize(font));
00797
00798 const QPoint &pos = d_data->trackerPosition;
00799
00800 int alignment = 0;
00801 if ( isActive() && d_data->selection.count() > 1
00802 && rubberBand() != NoRubberBand )
00803 {
00804 const QPoint last =
00805 d_data->selection[int(d_data->selection.count()) - 2];
00806
00807 alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00808 alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00809 }
00810 else
00811 alignment = Qt::AlignTop | Qt::AlignRight;
00812
00813 const int margin = 5;
00814
00815 int x = pos.x();
00816 if ( alignment & Qt::AlignLeft )
00817 x -= textRect.width() + margin;
00818 else if ( alignment & Qt::AlignRight )
00819 x += margin;
00820
00821 int y = pos.y();
00822 if ( alignment & Qt::AlignBottom )
00823 y += margin;
00824 else if ( alignment & Qt::AlignTop )
00825 y -= textRect.height() + margin;
00826
00827 textRect.moveTopLeft(QPoint(x, y));
00828
00829 int right = qwtMin(textRect.right(), pickRect().right() - margin);
00830 int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00831 textRect.moveBottomRight(QPoint(right, bottom));
00832
00833 int left = qwtMax(textRect.left(), pickRect().left() + margin);
00834 int top = qwtMax(textRect.top(), pickRect().top() + margin);
00835 textRect.moveTopLeft(QPoint(left, top));
00836
00837 return textRect;
00838 }
00839
00852 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00853 {
00854 if ( o && o == parentWidget() )
00855 {
00856 switch(e->type())
00857 {
00858 case QEvent::Resize:
00859 {
00860 const QResizeEvent *re = (QResizeEvent *)e;
00861 if ( d_data->resizeMode == Stretch )
00862 stretchSelection(re->oldSize(), re->size());
00863
00864 if ( d_data->rubberBandWidget )
00865 d_data->rubberBandWidget->resize(re->size());
00866
00867 if ( d_data->trackerWidget )
00868 d_data->trackerWidget->resize(re->size());
00869 break;
00870 }
00871 case QEvent::Leave:
00872 widgetLeaveEvent(e);
00873 break;
00874 case QEvent::MouseButtonPress:
00875 widgetMousePressEvent((QMouseEvent *)e);
00876 break;
00877 case QEvent::MouseButtonRelease:
00878 widgetMouseReleaseEvent((QMouseEvent *)e);
00879 break;
00880 case QEvent::MouseButtonDblClick:
00881 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00882 break;
00883 case QEvent::MouseMove:
00884 widgetMouseMoveEvent((QMouseEvent *)e);
00885 break;
00886 case QEvent::KeyPress:
00887 widgetKeyPressEvent((QKeyEvent *)e);
00888 break;
00889 case QEvent::KeyRelease:
00890 widgetKeyReleaseEvent((QKeyEvent *)e);
00891 break;
00892 case QEvent::Wheel:
00893 widgetWheelEvent((QWheelEvent *)e);
00894 break;
00895 default:
00896 break;
00897 }
00898 }
00899 return false;
00900 }
00901
00912 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00913 {
00914 transition(e);
00915 }
00916
00926 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00927 {
00928 if ( pickRect().contains(e->pos()) )
00929 d_data->trackerPosition = e->pos();
00930 else
00931 d_data->trackerPosition = QPoint(-1, -1);
00932
00933 if ( !isActive() )
00934 updateDisplay();
00935
00936 transition(e);
00937 }
00938
00946 void QwtPicker::widgetLeaveEvent(QEvent *)
00947 {
00948 d_data->trackerPosition = QPoint(-1, -1);
00949 if ( !isActive() )
00950 updateDisplay();
00951 }
00952
00963 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00964 {
00965 transition(e);
00966 }
00967
00977 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00978 {
00979 transition(me);
00980 }
00981
00982
00992 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
00993 {
00994 if ( pickRect().contains(e->pos()) )
00995 d_data->trackerPosition = e->pos();
00996 else
00997 d_data->trackerPosition = QPoint(-1, -1);
00998
00999 updateDisplay();
01000
01001 transition(e);
01002 }
01003
01017 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
01018 {
01019 int dx = 0;
01020 int dy = 0;
01021
01022 int offset = 1;
01023 if ( ke->isAutoRepeat() )
01024 offset = 5;
01025
01026 if ( keyMatch(KeyLeft, ke) )
01027 dx = -offset;
01028 else if ( keyMatch(KeyRight, ke) )
01029 dx = offset;
01030 else if ( keyMatch(KeyUp, ke) )
01031 dy = -offset;
01032 else if ( keyMatch(KeyDown, ke) )
01033 dy = offset;
01034 else if ( keyMatch(KeyAbort, ke) )
01035 {
01036 reset();
01037 }
01038 else
01039 transition(ke);
01040
01041 if ( dx != 0 || dy != 0 )
01042 {
01043 const QRect rect = pickRect();
01044 const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
01045
01046 int x = pos.x() + dx;
01047 x = qwtMax(rect.left(), x);
01048 x = qwtMin(rect.right(), x);
01049
01050 int y = pos.y() + dy;
01051 y = qwtMax(rect.top(), y);
01052 y = qwtMin(rect.bottom(), y);
01053
01054 QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
01055 }
01056 }
01057
01067 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
01068 {
01069 transition(ke);
01070 }
01071
01079 void QwtPicker::transition(const QEvent *e)
01080 {
01081 if ( !d_data->stateMachine )
01082 return;
01083
01084 QwtPickerMachine::CommandList commandList =
01085 d_data->stateMachine->transition(*this, e);
01086
01087 QPoint pos;
01088 switch(e->type())
01089 {
01090 case QEvent::MouseButtonDblClick:
01091 case QEvent::MouseButtonPress:
01092 case QEvent::MouseButtonRelease:
01093 case QEvent::MouseMove:
01094 {
01095 const QMouseEvent *me = (QMouseEvent *)e;
01096 pos = me->pos();
01097 break;
01098 }
01099 default:
01100 pos = parentWidget()->mapFromGlobal(QCursor::pos());
01101 }
01102
01103 for ( uint i = 0; i < (uint)commandList.count(); i++ )
01104 {
01105 switch(commandList[i])
01106 {
01107 case QwtPickerMachine::Begin:
01108 {
01109 begin();
01110 break;
01111 }
01112 case QwtPickerMachine::Append:
01113 {
01114 append(pos);
01115 break;
01116 }
01117 case QwtPickerMachine::Move:
01118 {
01119 move(pos);
01120 break;
01121 }
01122 case QwtPickerMachine::End:
01123 {
01124 end();
01125 break;
01126 }
01127 }
01128 }
01129 }
01130
01136 void QwtPicker::begin()
01137 {
01138 if ( d_data->isActive )
01139 return;
01140
01141 d_data->selection.resize(0);
01142 d_data->isActive = true;
01143
01144 if ( trackerMode() != AlwaysOff )
01145 {
01146 if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
01147 {
01148 QWidget *w = parentWidget();
01149 if ( w )
01150 d_data->trackerPosition = w->mapFromGlobal(QCursor::pos());
01151 }
01152 }
01153
01154 updateDisplay();
01155 setMouseTracking(true);
01156 }
01157
01168 bool QwtPicker::end(bool ok)
01169 {
01170 if ( d_data->isActive )
01171 {
01172 setMouseTracking(false);
01173
01174 d_data->isActive = false;
01175
01176 if ( trackerMode() == ActiveOnly )
01177 d_data->trackerPosition = QPoint(-1, -1);
01178
01179 if ( ok )
01180 ok = accept(d_data->selection);
01181
01182 if ( ok )
01183 emit selected(d_data->selection);
01184 else
01185 d_data->selection.resize(0);
01186
01187 updateDisplay();
01188 }
01189 else
01190 ok = false;
01191
01192 return ok;
01193 }
01194
01198 void QwtPicker::reset()
01199 {
01200 if ( d_data->stateMachine )
01201 d_data->stateMachine->reset();
01202
01203 if (isActive())
01204 end(false);
01205 }
01206
01215 void QwtPicker::append(const QPoint &pos)
01216 {
01217 if ( d_data->isActive )
01218 {
01219 const int idx = d_data->selection.count();
01220 d_data->selection.resize(idx + 1);
01221 d_data->selection[idx] = pos;
01222
01223 updateDisplay();
01224
01225 emit appended(pos);
01226 }
01227 }
01228
01237 void QwtPicker::move(const QPoint &pos)
01238 {
01239 if ( d_data->isActive )
01240 {
01241 const int idx = d_data->selection.count() - 1;
01242 if ( idx >= 0 )
01243 {
01244 if ( d_data->selection[idx] != pos )
01245 {
01246 d_data->selection[idx] = pos;
01247
01248 updateDisplay();
01249
01250 emit moved(pos);
01251 }
01252 }
01253 }
01254 }
01255
01256 bool QwtPicker::accept(QwtPolygon &) const
01257 {
01258 return true;
01259 }
01260
01265 bool QwtPicker::isActive() const
01266 {
01267 return d_data->isActive;
01268 }
01269
01271 const QwtPolygon &QwtPicker::selection() const
01272 {
01273 return d_data->selection;
01274 }
01275
01285 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01286 {
01287 if ( oldSize.isEmpty() )
01288 {
01289
01290
01291 return;
01292 }
01293
01294 const double xRatio =
01295 double(newSize.width()) / double(oldSize.width());
01296 const double yRatio =
01297 double(newSize.height()) / double(oldSize.height());
01298
01299 for ( int i = 0; i < int(d_data->selection.count()); i++ )
01300 {
01301 QPoint &p = d_data->selection[i];
01302 p.setX(qRound(p.x() * xRatio));
01303 p.setY(qRound(p.y() * yRatio));
01304
01305 emit changed(d_data->selection);
01306 }
01307 }
01308
01322 void QwtPicker::setMouseTracking(bool enable)
01323 {
01324 QWidget *widget = parentWidget();
01325 if ( !widget )
01326 return;
01327
01328 if ( enable )
01329 {
01330 d_data->mouseTracking = widget->hasMouseTracking();
01331 widget->setMouseTracking(true);
01332 }
01333 else
01334 {
01335 widget->setMouseTracking(d_data->mouseTracking);
01336 }
01337 }
01338
01344 QRect QwtPicker::pickRect() const
01345 {
01346 QRect rect;
01347
01348 const QWidget *widget = parentWidget();
01349 if ( !widget )
01350 return rect;
01351
01352 if ( widget->inherits("QFrame") )
01353 rect = ((QFrame *)widget)->contentsRect();
01354 else
01355 rect = widget->rect();
01356
01357 return rect;
01358 }
01359
01360 void QwtPicker::updateDisplay()
01361 {
01362 QWidget *w = parentWidget();
01363
01364 bool showRubberband = false;
01365 bool showTracker = false;
01366 if ( w && w->isVisible() && d_data->enabled )
01367 {
01368 if ( rubberBand() != NoRubberBand && isActive() &&
01369 rubberBandPen().style() != Qt::NoPen )
01370 {
01371 showRubberband = true;
01372 }
01373
01374 if ( trackerMode() == AlwaysOn ||
01375 (trackerMode() == ActiveOnly && isActive() ) )
01376 {
01377 if ( trackerPen() != Qt::NoPen )
01378 showTracker = true;
01379 }
01380 }
01381
01382 #if QT_VERSION < 0x040000
01383 QGuardedPtr<PickerWidget> &rw = d_data->rubberBandWidget;
01384 #else
01385 QPointer<PickerWidget> &rw = d_data->rubberBandWidget;
01386 #endif
01387 if ( showRubberband )
01388 {
01389 if ( rw.isNull() )
01390 {
01391 rw = new PickerWidget( this, w, PickerWidget::RubberBand);
01392 rw->resize(w->size());
01393 }
01394 rw->updateMask();
01395 rw->update();
01396 }
01397 else
01398 delete rw;
01399
01400 #if QT_VERSION < 0x040000
01401 QGuardedPtr<PickerWidget> &tw = d_data->trackerWidget;
01402 #else
01403 QPointer<PickerWidget> &tw = d_data->trackerWidget;
01404 #endif
01405 if ( showTracker )
01406 {
01407 if ( tw.isNull() )
01408 {
01409 tw = new PickerWidget( this, w, PickerWidget::Text);
01410 tw->resize(w->size());
01411 }
01412 tw->updateMask();
01413 tw->update();
01414 }
01415 else
01416 delete tw;
01417 }
01418
01419 const QWidget *QwtPicker::rubberBandWidget() const
01420 {
01421 return d_data->rubberBandWidget;
01422 }
01423
01424 const QWidget *QwtPicker::trackerWidget() const
01425 {
01426 return d_data->trackerWidget;
01427 }
01428