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 #endif
00025
00026 class QwtPicker::PrivateData
00027 {
00028 public:
00029 class PickerWidget: public QWidget
00030 {
00031 public:
00032 enum Type
00033 {
00034 RubberBand,
00035 Text
00036 };
00037 PickerWidget(QwtPicker *, QWidget *, Type);
00038 virtual void updateMask();
00039
00040 protected:
00041 virtual void paintEvent(QPaintEvent *);
00042
00043 QwtPicker *d_picker;
00044 Type d_type;
00045 };
00046
00047 bool enabled;
00048
00049 QwtPickerMachine *stateMachine;
00050
00051 int selectionFlags;
00052 QwtPicker::ResizeMode resizeMode;
00053
00054 QwtPicker::RubberBand rubberBand;
00055 QPen rubberBandPen;
00056
00057 QwtPicker::DisplayMode trackerMode;
00058 QPen trackerPen;
00059 QFont trackerFont;
00060
00061 QwtPolygon selection;
00062 bool isActive;
00063 QPoint labelPosition;
00064
00065 bool mouseTracking;
00066
00067
00068
00069
00070
00071
00072
00073
00074 #if QT_VERSION < 0x040000
00075 QGuardedPtr<PickerWidget> rubberBandWidget;
00076 QGuardedPtr<PickerWidget> trackerWidget;
00077 #else
00078 QPointer<PickerWidget> rubberBandWidget;
00079 QPointer<PickerWidget> trackerWidget;
00080 #endif
00081 };
00082
00083 QwtPicker::PrivateData::PickerWidget::PickerWidget(
00084 QwtPicker *picker, QWidget *parent, Type type):
00085 QWidget(parent),
00086 d_picker(picker),
00087 d_type(type)
00088 {
00089 #if QT_VERSION >= 0x040000
00090 setAttribute(Qt::WA_TransparentForMouseEvents);
00091 setAttribute(Qt::WA_NoSystemBackground);
00092 #if 0
00093 setAttribute(Qt::WA_PaintOnScreen);
00094 #endif
00095 setFocusPolicy(Qt::NoFocus);
00096 #else
00097 setBackgroundMode(Qt::NoBackground);
00098 setFocusPolicy(QWidget::NoFocus);
00099 setMouseTracking(true);
00100 #endif
00101 hide();
00102 }
00103
00104 void QwtPicker::PrivateData::PickerWidget::updateMask()
00105 {
00106 QBitmap bm(width(), height());
00107 bm.fill(Qt::color0);
00108
00109 QPainter painter(&bm);
00110
00111 if ( d_type == RubberBand )
00112 {
00113 QPen pen = d_picker->rubberBandPen();
00114 pen.setColor(Qt::color1);
00115 painter.setPen(pen);
00116
00117 d_picker->drawRubberBand(&painter);
00118 }
00119 if ( d_type == Text )
00120 {
00121 QPen pen = d_picker->trackerPen();
00122 pen.setColor(Qt::color1);
00123 painter.setPen(pen);
00124
00125 d_picker->drawTracker(&painter);
00126 }
00127
00128 painter.end();
00129
00130
00131 #if QT_VERSION < 0x040000
00132 QWidget *w = parentWidget();
00133 const bool doUpdate = w->isUpdatesEnabled();
00134 const Qt::BackgroundMode bgMode = w->backgroundMode();
00135 w->setUpdatesEnabled(false);
00136 if ( bgMode != Qt::NoBackground )
00137 w->setBackgroundMode(Qt::NoBackground);
00138 #endif
00139
00140 const QRegion r(bm);
00141 setMask(r);
00142
00143 #if QT_VERSION < 0x040000
00144 if ( bgMode != Qt::NoBackground )
00145 w->setBackgroundMode(bgMode);
00146
00147 w->setUpdatesEnabled(doUpdate);
00148 #endif
00149
00150 setShown(!r.isEmpty());
00151 }
00152
00153 void QwtPicker::PrivateData::PickerWidget::paintEvent(QPaintEvent *e)
00154 {
00155 QPainter painter(this);
00156
00157 if ( d_type == RubberBand )
00158 {
00159 painter.setClipRegion(e->region());
00160 painter.setPen(d_picker->rubberBandPen());
00161 d_picker->drawRubberBand(&painter);
00162 }
00163
00164 if ( d_type == Text )
00165 {
00166 painter.setClipRegion(e->region());
00167 #if 0
00168 painter.setPen(d_picker->trackerPen());
00169 d_picker->drawTracker(&painter);
00170 #else
00171 painter.fillRect(e->rect(), QBrush(d_picker->trackerPen().color()));
00172 #endif
00173 }
00174 }
00175
00185 QwtPicker::QwtPicker(QWidget *parent):
00186 QObject(parent)
00187 {
00188 init(parent, NoSelection, NoRubberBand, AlwaysOff);
00189 }
00190
00200 QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
00201 DisplayMode trackerMode, QWidget *parent):
00202 QObject(parent)
00203 {
00204 init(parent, selectionFlags, rubberBand, trackerMode);
00205 }
00206
00208 QwtPicker::~QwtPicker()
00209 {
00210 setMouseTracking(false);
00211 delete d_data->stateMachine;
00212 delete d_data->rubberBandWidget;
00213 delete d_data->trackerWidget;
00214 delete d_data;
00215 }
00216
00218 void QwtPicker::init(QWidget *parent, int selectionFlags,
00219 RubberBand rubberBand, DisplayMode trackerMode)
00220 {
00221 d_data = new PrivateData;
00222
00223 d_data->rubberBandWidget = NULL;
00224 d_data->trackerWidget = NULL;
00225
00226 d_data->rubberBand = rubberBand;
00227 d_data->enabled = false;
00228 d_data->resizeMode = Stretch;
00229 d_data->trackerMode = AlwaysOff;
00230 d_data->isActive = false;
00231 d_data->labelPosition = QPoint(-1, -1);
00232 d_data->mouseTracking = false;
00233
00234 d_data->stateMachine = NULL;
00235 setSelectionFlags(selectionFlags);
00236
00237 if ( parent )
00238 {
00239 #if QT_VERSION >= 0x040000
00240 if ( parent->focusPolicy() == Qt::NoFocus )
00241 parent->setFocusPolicy(Qt::WheelFocus);
00242 #else
00243 if ( parent->focusPolicy() == QWidget::NoFocus )
00244 parent->setFocusPolicy(QWidget::WheelFocus);
00245 #endif
00246
00247 d_data->trackerFont = parent->font();
00248 d_data->mouseTracking = parent->hasMouseTracking();
00249 setEnabled(true);
00250 }
00251 setTrackerMode(trackerMode);
00252 }
00253
00257 void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
00258 {
00259 if ( d_data->stateMachine != stateMachine )
00260 {
00261 if ( isActive() )
00262 end(false);
00263
00264 delete d_data->stateMachine;
00265 d_data->stateMachine = stateMachine;
00266
00267 if ( d_data->stateMachine )
00268 d_data->stateMachine->reset();
00269 }
00270 }
00271
00288 QwtPickerMachine *QwtPicker::stateMachine(int flags) const
00289 {
00290 if ( flags & PointSelection )
00291 {
00292 if ( flags & ClickSelection )
00293 return new QwtPickerClickPointMachine;
00294 else
00295 return new QwtPickerDragPointMachine;
00296 }
00297 if ( flags & RectSelection )
00298 {
00299 if ( flags & ClickSelection )
00300 return new QwtPickerClickRectMachine;
00301 else
00302 return new QwtPickerDragRectMachine;
00303 }
00304 if ( flags & PolygonSelection )
00305 {
00306 return new QwtPickerPolygonMachine();
00307 }
00308 return NULL;
00309 }
00310
00312 QWidget *QwtPicker::parentWidget()
00313 {
00314 QObject *obj = parent();
00315 if ( obj && obj->isWidgetType() )
00316 return (QWidget *)obj;
00317
00318 return NULL;
00319 }
00320
00322 const QWidget *QwtPicker::parentWidget() const
00323 {
00324 QObject *obj = parent();
00325 if ( obj && obj->isWidgetType() )
00326 return (QWidget *)obj;
00327
00328 return NULL;
00329 }
00330
00340 void QwtPicker::setSelectionFlags(int flags)
00341 {
00342 d_data->selectionFlags = flags;
00343 setStateMachine(stateMachine(flags));
00344 }
00345
00351 int QwtPicker::selectionFlags() const
00352 {
00353 return d_data->selectionFlags;
00354 }
00355
00364 void QwtPicker::setRubberBand(RubberBand rubberBand)
00365 {
00366 d_data->rubberBand = rubberBand;
00367 }
00368
00373 QwtPicker::RubberBand QwtPicker::rubberBand() const
00374 {
00375 return d_data->rubberBand;
00376 }
00377
00394 void QwtPicker::setTrackerMode(DisplayMode mode)
00395 {
00396 if ( d_data->trackerMode != mode )
00397 {
00398 d_data->trackerMode = mode;
00399 setMouseTracking(d_data->trackerMode == AlwaysOn);
00400 }
00401 }
00402
00407 QwtPicker::DisplayMode QwtPicker::trackerMode() const
00408 {
00409 return d_data->trackerMode;
00410 }
00411
00426 void QwtPicker::setResizeMode(ResizeMode mode)
00427 {
00428 d_data->resizeMode = mode;
00429 }
00430
00436 QwtPicker::ResizeMode QwtPicker::resizeMode() const
00437 {
00438 return d_data->resizeMode;
00439 }
00440
00450 void QwtPicker::setEnabled(bool enabled)
00451 {
00452 if ( d_data->enabled != enabled )
00453 {
00454 d_data->enabled = enabled;
00455
00456 QWidget *w = parentWidget();
00457 if ( w )
00458 {
00459 if ( enabled )
00460 w->installEventFilter(this);
00461 else
00462 w->removeEventFilter(this);
00463 }
00464
00465 updateDisplay();
00466 }
00467 }
00468
00474 bool QwtPicker::isEnabled() const
00475 {
00476 return d_data->enabled;
00477 }
00478
00485 void QwtPicker::setTrackerFont(const QFont &font)
00486 {
00487 if ( font != d_data->trackerFont )
00488 {
00489 d_data->trackerFont = font;
00490 updateDisplay();
00491 }
00492 }
00493
00499 QFont QwtPicker::trackerFont() const
00500 {
00501 return d_data->trackerFont;
00502 }
00503
00510 void QwtPicker::setTrackerPen(const QPen &pen)
00511 {
00512 if ( pen != d_data->trackerPen )
00513 {
00514 d_data->trackerPen = pen;
00515 updateDisplay();
00516 }
00517 }
00518
00523 QPen QwtPicker::trackerPen() const
00524 {
00525 return d_data->trackerPen;
00526 }
00527
00534 void QwtPicker::setRubberBandPen(const QPen &pen)
00535 {
00536 if ( pen != d_data->rubberBandPen )
00537 {
00538 d_data->rubberBandPen = pen;
00539 updateDisplay();
00540 }
00541 }
00542
00547 QPen QwtPicker::rubberBandPen() const
00548 {
00549 return d_data->rubberBandPen;
00550 }
00551
00565 QwtText QwtPicker::trackerText(const QPoint &pos) const
00566 {
00567 QString label;
00568
00569 switch(rubberBand())
00570 {
00571 case HLineRubberBand:
00572 label.sprintf("%d", pos.y());
00573 break;
00574 case VLineRubberBand:
00575 label.sprintf("%d", pos.x());
00576 break;
00577 default:
00578 label.sprintf("%d, %d", pos.x(), pos.y());
00579 }
00580 return label;
00581 }
00582
00591 void QwtPicker::drawRubberBand(QPainter *painter) const
00592 {
00593 if ( !isActive() || rubberBand() == NoRubberBand ||
00594 rubberBandPen().style() == Qt::NoPen )
00595 {
00596 return;
00597 }
00598
00599 const QRect &pRect = pickRect();
00600 const QwtPolygon &pa = d_data->selection;
00601
00602 if ( selectionFlags() & PointSelection )
00603 {
00604 if ( pa.count() < 1 )
00605 return;
00606
00607 const QPoint pos = pa[0];
00608
00609 switch(rubberBand())
00610 {
00611 case VLineRubberBand:
00612 QwtPainter::drawLine(painter, pos.x(),
00613 pRect.top(), pos.x(), pRect.bottom());
00614 break;
00615
00616 case HLineRubberBand:
00617 QwtPainter::drawLine(painter, pRect.left(),
00618 pos.y(), pRect.right(), pos.y());
00619 break;
00620
00621 case CrossRubberBand:
00622 QwtPainter::drawLine(painter, pos.x(),
00623 pRect.top(), pos.x(), pRect.bottom());
00624 QwtPainter::drawLine(painter, pRect.left(),
00625 pos.y(), pRect.right(), pos.y());
00626 break;
00627 default:
00628 break;
00629 }
00630 }
00631
00632 else if ( selectionFlags() & RectSelection )
00633 {
00634 if ( pa.count() < 2 )
00635 return;
00636
00637 QPoint p1 = pa[0];
00638 QPoint p2 = pa[int(pa.count() - 1)];
00639
00640 if ( selectionFlags() & CenterToCorner )
00641 {
00642 p1.setX(p1.x() - (p2.x() - p1.x()));
00643 p1.setY(p1.y() - (p2.y() - p1.y()));
00644 }
00645 else if ( selectionFlags() & CenterToRadius )
00646 {
00647 const int radius = qwtMax(qwtAbs(p2.x() - p1.x()),
00648 qwtAbs(p2.y() - p1.y()));
00649 p2.setX(p1.x() + radius);
00650 p2.setY(p1.y() + radius);
00651 p1.setX(p1.x() - radius);
00652 p1.setY(p1.y() - radius);
00653 }
00654
00655 #if QT_VERSION < 0x040000
00656 const QRect rect = QRect(p1, p2).normalize();
00657 #else
00658 const QRect rect = QRect(p1, p2).normalized();
00659 #endif
00660 switch(rubberBand())
00661 {
00662 case EllipseRubberBand:
00663 QwtPainter::drawEllipse(painter, rect);
00664 break;
00665 case RectRubberBand:
00666 QwtPainter::drawRect(painter, rect);
00667 break;
00668 default:
00669 break;
00670 }
00671 }
00672 else if ( selectionFlags() & PolygonSelection )
00673 {
00674 if ( rubberBand() == PolygonRubberBand )
00675 painter->drawPolyline(pa);
00676 }
00677 }
00678
00686 void QwtPicker::drawTracker(QPainter *painter) const
00687 {
00688 const QRect textRect = trackerRect(painter);
00689 if ( !textRect.isEmpty() )
00690 {
00691 QwtText label = trackerText(d_data->labelPosition);
00692 if ( !label.isEmpty() )
00693 {
00694
00695 #if defined(Q_WS_MAC)
00696 #if QT_VERSION >= 0x040000
00697
00698 painter->save();
00699 painter->setRenderHint(QPainter::TextAntialiasing, false);
00700 #else
00701 QFont fnt = label.usedFont(painter->font());
00702 fnt.setStyleStrategy(QFont::NoAntialias);
00703 label.setFont(fnt);
00704 #endif
00705 #endif
00706 label.draw(painter, textRect);
00707
00708 #if defined(Q_WS_MAC)
00709 #if QT_VERSION >= 0x040000
00710 painter->restore();
00711 #endif
00712 #endif
00713 }
00714 }
00715 }
00716
00717 QRect QwtPicker::trackerRect(QPainter *painter) const
00718 {
00719 if ( trackerMode() == AlwaysOff ||
00720 (trackerMode() == ActiveOnly && !isActive() ) )
00721 {
00722 return QRect();
00723 }
00724
00725 if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 )
00726 return QRect();
00727
00728 QwtText text = trackerText(d_data->labelPosition);
00729 if ( text.isEmpty() )
00730 return QRect();
00731
00732 QRect textRect(QPoint(0, 0), text.textSize(painter->font()));
00733
00734 const QPoint &pos = d_data->labelPosition;
00735
00736 int alignment = 0;
00737 if ( isActive() && d_data->selection.count() > 1
00738 && rubberBand() != NoRubberBand )
00739 {
00740 const QPoint last =
00741 d_data->selection[int(d_data->selection.count()) - 2];
00742
00743 alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00744 alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00745 }
00746 else
00747 alignment = Qt::AlignTop | Qt::AlignRight;
00748
00749 const int margin = 5;
00750
00751 int x = pos.x();
00752 if ( alignment & Qt::AlignLeft )
00753 x -= textRect.width() + margin;
00754 else if ( alignment & Qt::AlignRight )
00755 x += margin;
00756
00757 int y = pos.y();
00758 if ( alignment & Qt::AlignBottom )
00759 y += margin;
00760 else if ( alignment & Qt::AlignTop )
00761 y -= textRect.height() + margin;
00762
00763 textRect.moveTopLeft(QPoint(x, y));
00764
00765 int right = qwtMin(textRect.right(), pickRect().right() - margin);
00766 int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00767 textRect.moveBottomRight(QPoint(right, bottom));
00768
00769 int left = qwtMax(textRect.left(), pickRect().left() + margin);
00770 int top = qwtMax(textRect.top(), pickRect().top() + margin);
00771 textRect.moveTopLeft(QPoint(left, top));
00772
00773 return textRect;
00774 }
00775
00788 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00789 {
00790 if ( o && o == parentWidget() )
00791 {
00792 switch(e->type())
00793 {
00794 case QEvent::Resize:
00795 {
00796 const QResizeEvent *re = (QResizeEvent *)e;
00797 if ( d_data->resizeMode == Stretch )
00798 stretchSelection(re->oldSize(), re->size());
00799
00800 if ( d_data->rubberBandWidget )
00801 d_data->rubberBandWidget->resize(re->size());
00802
00803 if ( d_data->trackerWidget )
00804 d_data->trackerWidget->resize(re->size());
00805 break;
00806 }
00807 case QEvent::Leave:
00808 widgetLeaveEvent(e);
00809 break;
00810 case QEvent::MouseButtonPress:
00811 widgetMousePressEvent((QMouseEvent *)e);
00812 break;
00813 case QEvent::MouseButtonRelease:
00814 widgetMouseReleaseEvent((QMouseEvent *)e);
00815 break;
00816 case QEvent::MouseButtonDblClick:
00817 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00818 break;
00819 case QEvent::MouseMove:
00820 widgetMouseMoveEvent((QMouseEvent *)e);
00821 break;
00822 case QEvent::KeyPress:
00823 widgetKeyPressEvent((QKeyEvent *)e);
00824 break;
00825 case QEvent::KeyRelease:
00826 widgetKeyReleaseEvent((QKeyEvent *)e);
00827 break;
00828 case QEvent::Wheel:
00829 widgetWheelEvent((QWheelEvent *)e);
00830 break;
00831 default:
00832 break;
00833 }
00834 }
00835 return false;
00836 }
00837
00848 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00849 {
00850 transition(e);
00851 }
00852
00862 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00863 {
00864 if ( pickRect().contains(e->pos()) )
00865 d_data->labelPosition = e->pos();
00866 else
00867 d_data->labelPosition = QPoint(-1, -1);
00868
00869 if ( !isActive() )
00870 updateDisplay();
00871
00872 transition(e);
00873 }
00874
00882 void QwtPicker::widgetLeaveEvent(QEvent *)
00883 {
00884 d_data->labelPosition = QPoint(-1, -1);
00885 if ( !isActive() )
00886 updateDisplay();
00887 }
00888
00899 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00900 {
00901 transition(e);
00902 }
00903
00913 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00914 {
00915 transition(me);
00916 }
00917
00918
00928 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
00929 {
00930 if ( pickRect().contains(e->pos()) )
00931 d_data->labelPosition = e->pos();
00932 else
00933 d_data->labelPosition = QPoint(-1, -1);
00934
00935 updateDisplay();
00936
00937 transition(e);
00938 }
00939
00953 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
00954 {
00955 int dx = 0;
00956 int dy = 0;
00957
00958 int offset = 1;
00959 if ( ke->isAutoRepeat() )
00960 offset = 5;
00961
00962 if ( keyMatch(KeyLeft, ke) )
00963 dx = -offset;
00964 else if ( keyMatch(KeyRight, ke) )
00965 dx = offset;
00966 else if ( keyMatch(KeyUp, ke) )
00967 dy = -offset;
00968 else if ( keyMatch(KeyDown, ke) )
00969 dy = offset;
00970 else if ( keyMatch(KeyAbort, ke) )
00971 {
00972 if ( d_data->stateMachine )
00973 d_data->stateMachine->reset();
00974
00975 if (isActive())
00976 end(false);
00977 }
00978 else
00979 transition(ke);
00980
00981 if ( dx != 0 || dy != 0 )
00982 {
00983 const QRect rect = pickRect();
00984 const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
00985
00986 int x = pos.x() + dx;
00987 x = qwtMax(rect.left(), x);
00988 x = qwtMin(rect.right(), x);
00989
00990 int y = pos.y() + dy;
00991 y = qwtMax(rect.top(), y);
00992 y = qwtMin(rect.bottom(), y);
00993
00994 QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
00995 }
00996 }
00997
01007 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
01008 {
01009 transition(ke);
01010 }
01011
01019 void QwtPicker::transition(const QEvent *e)
01020 {
01021 if ( !d_data->stateMachine )
01022 return;
01023
01024 QwtPickerMachine::CommandList commandList =
01025 d_data->stateMachine->transition(*this, e);
01026
01027 QPoint pos;
01028 switch(e->type())
01029 {
01030 case QEvent::MouseButtonDblClick:
01031 case QEvent::MouseButtonPress:
01032 case QEvent::MouseButtonRelease:
01033 case QEvent::MouseMove:
01034 {
01035 const QMouseEvent *me = (QMouseEvent *)e;
01036 pos = me->pos();
01037 break;
01038 }
01039 default:
01040 pos = parentWidget()->mapFromGlobal(QCursor::pos());
01041 }
01042
01043 for ( uint i = 0; i < (uint)commandList.count(); i++ )
01044 {
01045 switch(commandList[i])
01046 {
01047 case QwtPickerMachine::Begin:
01048 {
01049 begin();
01050 break;
01051 }
01052 case QwtPickerMachine::Append:
01053 {
01054 append(pos);
01055 break;
01056 }
01057 case QwtPickerMachine::Move:
01058 {
01059 move(pos);
01060 break;
01061 }
01062 case QwtPickerMachine::End:
01063 {
01064 end();
01065 break;
01066 }
01067 }
01068 }
01069 }
01070
01076 void QwtPicker::begin()
01077 {
01078 if ( d_data->isActive )
01079 return;
01080
01081 d_data->selection.resize(0);
01082 d_data->isActive = true;
01083
01084 if ( trackerMode() != AlwaysOff )
01085 {
01086 if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 )
01087 {
01088 QWidget *w = parentWidget();
01089 if ( w )
01090 d_data->labelPosition = w->mapFromGlobal(QCursor::pos());
01091 }
01092 }
01093
01094 updateDisplay();
01095 setMouseTracking(true);
01096 }
01097
01108 bool QwtPicker::end(bool ok)
01109 {
01110 if ( d_data->isActive )
01111 {
01112 setMouseTracking(false);
01113
01114 d_data->isActive = false;
01115
01116 if ( trackerMode() == ActiveOnly )
01117 d_data->labelPosition = QPoint(-1, -1);
01118
01119 if ( ok )
01120 ok = accept(d_data->selection);
01121
01122 if ( ok )
01123 emit selected(d_data->selection);
01124 else
01125 d_data->selection.resize(0);
01126
01127 updateDisplay();
01128 }
01129 else
01130 ok = false;
01131
01132 return ok;
01133 }
01134
01143 void QwtPicker::append(const QPoint &pos)
01144 {
01145 if ( d_data->isActive )
01146 {
01147 const int idx = d_data->selection.count();
01148 d_data->selection.resize(idx + 1);
01149 d_data->selection[idx] = pos;
01150
01151 updateDisplay();
01152
01153 emit appended(pos);
01154 }
01155 }
01156
01165 void QwtPicker::move(const QPoint &pos)
01166 {
01167 if ( d_data->isActive )
01168 {
01169 const int idx = d_data->selection.count() - 1;
01170 if ( idx >= 0 )
01171 {
01172 if ( d_data->selection[idx] != pos )
01173 {
01174 d_data->selection[idx] = pos;
01175
01176 updateDisplay();
01177
01178 emit moved(pos);
01179 }
01180 }
01181 }
01182 }
01183
01184 bool QwtPicker::accept(QwtPolygon &) const
01185 {
01186 return true;
01187 }
01188
01193 bool QwtPicker::isActive() const
01194 {
01195 return d_data->isActive;
01196 }
01197
01199 const QwtPolygon &QwtPicker::selection() const
01200 {
01201 return d_data->selection;
01202 }
01203
01213 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01214 {
01215 const double xRatio =
01216 double(newSize.width()) / double(oldSize.width());
01217 const double yRatio =
01218 double(newSize.height()) / double(oldSize.height());
01219
01220 for ( int i = 0; i < int(d_data->selection.count()); i++ )
01221 {
01222 QPoint &p = d_data->selection[i];
01223 p.setX(qRound(p.x() * xRatio));
01224 p.setY(qRound(p.y() * yRatio));
01225
01226 emit changed(d_data->selection);
01227 }
01228 }
01229
01243 void QwtPicker::setMouseTracking(bool enable)
01244 {
01245 QWidget *widget = parentWidget();
01246 if ( !widget )
01247 return;
01248
01249 if ( enable )
01250 {
01251 d_data->mouseTracking = widget->hasMouseTracking();
01252 widget->setMouseTracking(true);
01253 }
01254 else
01255 {
01256 widget->setMouseTracking(d_data->mouseTracking);
01257 }
01258 }
01259
01265 QRect QwtPicker::pickRect() const
01266 {
01267 QRect rect;
01268
01269 const QWidget *widget = parentWidget();
01270 if ( !widget )
01271 return rect;
01272
01273 if ( widget->inherits("QFrame") )
01274 rect = ((QFrame *)widget)->contentsRect();
01275 else
01276 rect = widget->rect();
01277
01278 return rect;
01279 }
01280
01281 void QwtPicker::updateDisplay()
01282 {
01283 QWidget *w = parentWidget();
01284
01285 bool showRubberband = false;
01286 bool showTracker = false;
01287 if ( w && w->isVisible() && d_data->enabled )
01288 {
01289 if ( rubberBand() != NoRubberBand && isActive() &&
01290 rubberBandPen().style() != Qt::NoPen )
01291 {
01292 showRubberband = true;
01293 }
01294
01295 if ( trackerMode() == AlwaysOn ||
01296 (trackerMode() == ActiveOnly && isActive() ) )
01297 {
01298 if ( trackerPen() != Qt::NoPen )
01299 showTracker = true;
01300 }
01301 }
01302
01303 #if QT_VERSION < 0x040000
01304 QGuardedPtr<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
01305 #else
01306 QPointer<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
01307 #endif
01308 if ( showRubberband )
01309 {
01310 if ( rw.isNull() )
01311 {
01312 rw = new PrivateData::PickerWidget(
01313 this, w, PrivateData::PickerWidget::RubberBand);
01314 rw->resize(w->size());
01315 }
01316 rw->updateMask();
01317 }
01318 else
01319 delete rw;
01320
01321 #if QT_VERSION < 0x040000
01322 QGuardedPtr<PrivateData::PickerWidget> &tw = d_data->trackerWidget;
01323 #else
01324 QPointer<PrivateData::PickerWidget> &tw = d_data->trackerWidget;
01325 #endif
01326 if ( showTracker )
01327 {
01328 if ( tw.isNull() )
01329 {
01330 tw = new PrivateData::PickerWidget(
01331 this, w, PrivateData::PickerWidget::Text);
01332 tw->resize(w->size());
01333 }
01334 tw->updateMask();
01335 }
01336 else
01337 delete tw;
01338 }
01339
01340 const QWidget *QwtPicker::rubberBandWidget() const
01341 {
01342 return d_data->rubberBandWidget;
01343 }
01344
01345 const QWidget *QwtPicker::trackerWidget() const
01346 {
01347 return d_data->trackerWidget;
01348 }
01349