Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

qwt_picker.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
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     QwtPicker::SelectedPoints selection;
00062     bool isActive;
00063     QPoint labelPosition;
00064 
00065     bool mouseTracking; // used to save previous value
00066 
00067     /*
00068       On X11 the widget below the picker widgets gets paint events
00069       with a region that is the bounding rect of the mask, if it is complex.
00070       In case of (f.e) a CrossRubberBand and a text this creates complete
00071       repaints of the widget. So we better use two different widgets.
00072      */
00073      
00074 #if QT_VERSION < 0x040000
00075     QGuardedPtr<PickerWidget> rubberBandWidget;
00076     QGuardedPtr<PickerWidget> textLabelWidget;
00077 #else
00078     QPointer<PickerWidget> rubberBandWidget;
00079     QPointer<PickerWidget> textLabelWidget;
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     setAttribute(Qt::WA_PaintOnScreen);
00093     setFocusPolicy(Qt::NoFocus);
00094 #else
00095     setBackgroundMode(Qt::NoBackground);
00096     setFocusPolicy(QWidget::NoFocus);
00097 #endif
00098     hide();
00099 }
00100 
00101 void QwtPicker::PrivateData::PickerWidget::updateMask()
00102 {
00103     QBitmap bm(width(), height());
00104     bm.fill(Qt::color0);
00105 
00106     QPainter painter(&bm);
00107 
00108     if ( d_type == RubberBand )
00109     {
00110         QPen pen = d_picker->rubberBandPen();
00111         pen.setColor(Qt::color1);
00112         painter.setPen(pen);
00113 
00114         d_picker->drawRubberBand(&painter);
00115     }
00116     if ( d_type == Text )
00117     {
00118         QPen pen = d_picker->trackerPen();
00119         pen.setColor(Qt::color1);
00120         painter.setPen(pen);
00121 
00122         d_picker->drawTracker(&painter);
00123     }
00124 
00125     painter.end();
00126 
00127 
00128 #if QT_VERSION < 0x040000
00129     QWidget *w = parentWidget();
00130     const bool doUpdate = w->isUpdatesEnabled();
00131     const Qt::BackgroundMode bgMode = w->backgroundMode();
00132     w->setUpdatesEnabled(false);
00133     if ( bgMode != Qt::NoBackground )
00134         w->setBackgroundMode(Qt::NoBackground);
00135 #endif
00136 
00137     const QRegion r(bm);
00138     setMask(r);
00139 
00140 #if QT_VERSION < 0x040000
00141     if ( bgMode != Qt::NoBackground )
00142         w->setBackgroundMode(bgMode);
00143 
00144     w->setUpdatesEnabled(doUpdate);
00145 #endif
00146 
00147     setShown(!r.isEmpty());
00148 }
00149 
00150 void QwtPicker::PrivateData::PickerWidget::paintEvent(QPaintEvent *e)
00151 {
00152     QPainter painter(this);
00153 
00154     if ( d_type == RubberBand )
00155     {
00156         painter.setClipRegion(e->region());
00157         painter.setPen(d_picker->rubberBandPen());
00158         d_picker->drawRubberBand(&painter);
00159     }
00160 
00161     if ( d_type == Text )
00162     {
00163         painter.setClipRegion(e->region());
00164         painter.setPen(d_picker->trackerPen());
00165         d_picker->drawTracker(&painter);
00166     }
00167 }
00168 
00178 QwtPicker::QwtPicker(QWidget *parent):
00179     QObject(parent)
00180 {
00181     init(parent, NoSelection, NoRubberBand, AlwaysOff);
00182 }
00183 
00193 QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
00194         DisplayMode trackerMode, QWidget *parent):
00195     QObject(parent)
00196 {
00197     init(parent, selectionFlags, rubberBand, trackerMode);
00198 }
00199 
00201 QwtPicker::~QwtPicker()
00202 {
00203     setMouseTracking(false);
00204     delete d_data->stateMachine;
00205     delete d_data->rubberBandWidget;
00206     delete d_data->textLabelWidget;
00207     delete d_data;
00208 }
00209 
00211 void QwtPicker::init(QWidget *parent, int selectionFlags, 
00212     RubberBand rubberBand, DisplayMode trackerMode)
00213 {
00214     d_data = new PrivateData;
00215 
00216     d_data->rubberBandWidget = NULL;
00217     d_data->textLabelWidget = NULL;
00218 
00219     d_data->rubberBand = rubberBand;
00220     d_data->enabled = false;
00221     d_data->resizeMode = Stretch;
00222     d_data->trackerMode = AlwaysOff;
00223     d_data->isActive = false;
00224     d_data->labelPosition = QPoint(-1, -1);
00225     d_data->mouseTracking = false;
00226 
00227     d_data->stateMachine = NULL;
00228     setSelectionFlags(selectionFlags);
00229 
00230     if ( parent )
00231     {
00232 #if QT_VERSION >= 0x040000
00233         if ( parent->focusPolicy() == Qt::NoFocus )
00234             parent->setFocusPolicy(Qt::WheelFocus);
00235 #else
00236         if ( parent->focusPolicy() == QWidget::NoFocus )
00237             parent->setFocusPolicy(QWidget::WheelFocus);
00238 #endif
00239 
00240         d_data->trackerFont = parent->font();
00241         d_data->mouseTracking = parent->hasMouseTracking();
00242         setEnabled(true);
00243     }
00244     setTrackerMode(trackerMode);
00245 }
00246 
00250 void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
00251 {
00252     if ( d_data->stateMachine != stateMachine )
00253     {
00254         if ( isActive() )
00255             end(false);
00256 
00257         delete d_data->stateMachine;
00258         d_data->stateMachine = stateMachine;
00259 
00260         if ( d_data->stateMachine )
00261             d_data->stateMachine->reset();
00262     }
00263 }
00264 
00281 QwtPickerMachine *QwtPicker::stateMachine(int flags) const
00282 {
00283     if ( flags & PointSelection )
00284     {
00285         if ( flags & ClickSelection )
00286             return new QwtPickerClickPointMachine;
00287         else
00288             return new QwtPickerDragPointMachine;
00289     }
00290     if ( flags & RectSelection )
00291     {
00292         if ( flags & ClickSelection )
00293             return new QwtPickerClickRectMachine;
00294         else
00295             return new QwtPickerDragRectMachine;
00296     }
00297     if ( flags & PolygonSelection )
00298     {
00299         return new QwtPickerPolygonMachine();
00300     }
00301     return NULL;
00302 }
00303 
00305 QWidget *QwtPicker::parentWidget()
00306 {
00307     QObject *obj = parent();
00308     if ( obj && obj->isWidgetType() )
00309         return (QWidget *)obj;
00310 
00311     return NULL;
00312 }
00313 
00315 const QWidget *QwtPicker::parentWidget() const
00316 {
00317     QObject *obj = parent();
00318     if ( obj && obj->isWidgetType() )
00319         return (QWidget *)obj;
00320 
00321     return NULL;
00322 }
00323 
00333 void QwtPicker::setSelectionFlags(int flags)
00334 {
00335     d_data->selectionFlags = flags;
00336     setStateMachine(stateMachine(flags));
00337 }
00338 
00344 int QwtPicker::selectionFlags() const
00345 {
00346     return d_data->selectionFlags;
00347 }
00348 
00357 void QwtPicker::setRubberBand(RubberBand rubberBand)
00358 {
00359     d_data->rubberBand = rubberBand;
00360 }
00361 
00366 QwtPicker::RubberBand QwtPicker::rubberBand() const
00367 {
00368     return d_data->rubberBand;
00369 }
00370 
00387 void QwtPicker::setTrackerMode(DisplayMode mode)
00388 {   
00389     if ( d_data->trackerMode != mode )
00390     {
00391         d_data->trackerMode = mode;
00392         setMouseTracking(d_data->trackerMode == AlwaysOn);
00393     }
00394 }   
00395 
00400 QwtPicker::DisplayMode QwtPicker::trackerMode() const
00401 {   
00402     return d_data->trackerMode;
00403 }   
00404 
00419 void QwtPicker::setResizeMode(ResizeMode mode)
00420 {
00421     d_data->resizeMode = mode;
00422 }   
00423 
00429 QwtPicker::ResizeMode QwtPicker::resizeMode() const
00430 {   
00431     return d_data->resizeMode;
00432 }
00433 
00443 void QwtPicker::setEnabled(bool enabled)
00444 {
00445     if ( d_data->enabled != enabled )
00446     {
00447         d_data->enabled = enabled;
00448 
00449         QWidget *w = parentWidget();
00450         if ( w )
00451         {
00452             if ( enabled )
00453                 w->installEventFilter(this);
00454             else
00455                 w->removeEventFilter(this);
00456         }
00457 
00458         updateDisplay();
00459     }
00460 }
00461 
00467 bool QwtPicker::isEnabled() const
00468 {
00469     return d_data->enabled;
00470 }
00471 
00478 void QwtPicker::setTrackerFont(const QFont &font)
00479 {
00480     if ( font != d_data->trackerFont )
00481     {
00482         d_data->trackerFont = font;
00483         updateDisplay();
00484     }
00485 }
00486 
00492 QFont QwtPicker::trackerFont() const
00493 {
00494     return d_data->trackerFont;
00495 }
00496 
00503 void QwtPicker::setTrackerPen(const QPen &pen)
00504 {
00505     if ( pen != d_data->trackerPen )
00506     {
00507         d_data->trackerPen = pen;
00508         updateDisplay();
00509     }
00510 }
00511 
00516 QPen QwtPicker::trackerPen() const
00517 {
00518     return d_data->trackerPen;
00519 }
00520 
00527 void QwtPicker::setRubberBandPen(const QPen &pen)
00528 {
00529     if ( pen != d_data->rubberBandPen )
00530     {
00531         d_data->rubberBandPen = pen;
00532         updateDisplay();
00533     }
00534 }
00535 
00540 QPen QwtPicker::rubberBandPen() const
00541 {
00542     return d_data->rubberBandPen;
00543 }
00544 
00558 QwtText QwtPicker::trackerText(const QPoint &pos) const
00559 {
00560     QString label;
00561 
00562     switch(rubberBand())
00563     {
00564         case HLineRubberBand:
00565             label.sprintf("%d", pos.y());
00566             break;
00567         case VLineRubberBand:
00568             label.sprintf("%d", pos.x());
00569             break;
00570         default:
00571             label.sprintf("%d, %d", pos.x(), pos.y());
00572     }
00573     return label;
00574 }
00575 
00584 void QwtPicker::drawRubberBand(QPainter *painter) const
00585 {
00586     if ( !isActive() || rubberBand() == NoRubberBand || 
00587         rubberBandPen().style() == Qt::NoPen )
00588     {
00589         return;
00590     }
00591 
00592     const QRect &pRect = pickRect();
00593     const SelectedPoints &pa = d_data->selection;
00594 
00595     if ( selectionFlags() & PointSelection )
00596     {
00597         if ( pa.count() < 1 )
00598             return;
00599 
00600         const QPoint pos = pa[0];
00601 
00602         switch(rubberBand())
00603         {
00604             case VLineRubberBand:
00605                 QwtPainter::drawLine(painter, pos.x(),
00606                     pRect.top(), pos.x(), pRect.bottom());
00607                 break;
00608 
00609             case HLineRubberBand:
00610                 QwtPainter::drawLine(painter, pRect.left(), 
00611                     pos.y(), pRect.right(), pos.y());
00612                 break;
00613 
00614             case CrossRubberBand:
00615                 QwtPainter::drawLine(painter, pos.x(),
00616                     pRect.top(), pos.x(), pRect.bottom());
00617                 QwtPainter::drawLine(painter, pRect.left(), 
00618                     pos.y(), pRect.right(), pos.y());
00619                 break;
00620             default:
00621                 break;
00622         }
00623     }
00624 
00625     else if ( selectionFlags() & RectSelection )
00626     {
00627         if ( pa.count() < 2 )
00628             return;
00629 
00630         QPoint p1 = pa[0];
00631         QPoint p2 = pa[int(pa.count() - 1)];
00632 
00633         if ( selectionFlags() & CenterToCorner )
00634         {
00635             p1.setX(p1.x() - (p2.x() - p1.x()));
00636             p1.setY(p1.y() - (p2.y() - p1.y()));
00637         }
00638         else if ( selectionFlags() & CenterToRadius )
00639         {
00640             const int radius = qwtMax(qwtAbs(p2.x() - p1.x()), 
00641                 qwtAbs(p2.y() - p1.y()));
00642             p2.setX(p1.x() + radius);
00643             p2.setY(p1.y() + radius);
00644             p1.setX(p1.x() - radius);
00645             p1.setY(p1.y() - radius);
00646         }
00647 
00648 #if QT_VERSION < 0x040000
00649         const QRect rect = QRect(p1, p2).normalize();
00650 #else
00651         const QRect rect = QRect(p1, p2).normalized();
00652 #endif
00653         switch(rubberBand())
00654         {
00655             case EllipseRubberBand:
00656                 QwtPainter::drawEllipse(painter, rect);
00657                 break;
00658             case RectRubberBand:
00659                 QwtPainter::drawRect(painter, rect);
00660                 break;
00661             default:
00662                 break;
00663         }
00664     }
00665     else if ( selectionFlags() & PolygonSelection )
00666     {
00667         if ( rubberBand() == PolygonRubberBand )
00668             painter->drawPolyline(pa);
00669     }
00670 }
00671 
00679 void QwtPicker::drawTracker(QPainter *painter) const
00680 {
00681     const QRect textRect = trackerRect(painter);
00682     if ( !textRect.isEmpty() )
00683     {
00684         QwtText label = trackerText(d_data->labelPosition);
00685         if ( !label.isEmpty() )
00686             label.draw(painter, textRect);
00687     }
00688 }
00689 
00690 QRect QwtPicker::trackerRect(QPainter *painter) const
00691 {
00692     if ( trackerMode() == AlwaysOff || 
00693         (trackerMode() == ActiveOnly && !isActive() ) )
00694     {
00695         return QRect();
00696     }
00697 
00698     if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 )
00699         return QRect();
00700 
00701     QwtText text = trackerText(d_data->labelPosition);
00702     if ( text.isEmpty() )
00703         return QRect();
00704 
00705     QRect textRect(QPoint(0, 0), text.textSize(painter->font()));
00706 
00707     const QPoint &pos = d_data->labelPosition;
00708 
00709     int alignment = 0;
00710     if ( isActive() && d_data->selection.count() > 1 
00711         && rubberBand() != NoRubberBand )
00712     {
00713         const QPoint last = 
00714             d_data->selection[int(d_data->selection.count()) - 2];
00715 
00716         alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00717         alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00718     }
00719     else
00720         alignment = Qt::AlignTop | Qt::AlignRight;
00721 
00722     const int margin = 5;
00723 
00724     int x = pos.x();
00725     if ( alignment & Qt::AlignLeft )
00726         x -= textRect.width() + margin;
00727     else if ( alignment & Qt::AlignRight )
00728         x += margin;
00729 
00730     int y = pos.y();
00731     if ( alignment & Qt::AlignBottom )
00732         y += margin;
00733     else if ( alignment & Qt::AlignTop )
00734         y -= textRect.height() + margin;
00735     
00736     textRect.moveTopLeft(QPoint(x, y));
00737 
00738     int right = qwtMin(textRect.right(), pickRect().right() - margin);
00739     int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00740     textRect.moveBottomRight(QPoint(right, bottom));
00741 
00742     int left = qwtMax(textRect.left(), pickRect().left() + margin);
00743     int top = qwtMax(textRect.top(), pickRect().top() + margin);
00744     textRect.moveTopLeft(QPoint(left, top));
00745 
00746     return textRect;
00747 }
00748 
00761 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00762 {
00763     if ( o && o == parentWidget() )
00764     {
00765         switch(e->type())
00766         {
00767             case QEvent::Resize:
00768             {
00769                 const QResizeEvent *re = (QResizeEvent *)e;
00770                 if ( d_data->resizeMode == Stretch )
00771                     stretchSelection(re->oldSize(), re->size());
00772 
00773                 if ( d_data->rubberBandWidget )
00774                     d_data->rubberBandWidget->resize(re->size());
00775              
00776                 if ( d_data->textLabelWidget )
00777                     d_data->textLabelWidget->resize(re->size());
00778                 break;
00779             }
00780             case QEvent::MouseButtonPress:
00781                 widgetMousePressEvent((QMouseEvent *)e);
00782                 break;
00783             case QEvent::MouseButtonRelease:
00784                 widgetMouseReleaseEvent((QMouseEvent *)e);
00785                 break;
00786             case QEvent::MouseButtonDblClick:
00787                 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00788                 break;
00789             case QEvent::MouseMove:
00790                 widgetMouseMoveEvent((QMouseEvent *)e);
00791                 break;
00792             case QEvent::KeyPress:
00793                 widgetKeyPressEvent((QKeyEvent *)e);
00794                 break;
00795             case QEvent::KeyRelease:
00796                 widgetKeyReleaseEvent((QKeyEvent *)e);
00797                 break;
00798             case QEvent::Wheel:
00799                 widgetWheelEvent((QWheelEvent *)e);
00800                 break;
00801             default:
00802                 break;
00803         }
00804     }
00805     return false;
00806 }
00807 
00818 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00819 {
00820     transition(e);
00821 }
00822 
00832 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00833 {
00834     if ( pickRect().contains(e->pos()) )
00835         d_data->labelPosition = e->pos();
00836     else
00837         d_data->labelPosition = QPoint(-1, -1);
00838 
00839     if ( !isActive() )
00840         updateDisplay();
00841 
00842     transition(e);
00843 }
00844 
00855 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00856 {
00857     transition(e);
00858 }
00859 
00869 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00870 {
00871     transition(me);
00872 }
00873     
00874 
00884 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
00885 {
00886     if ( pickRect().contains(e->pos()) )
00887         d_data->labelPosition = e->pos();
00888     else
00889         d_data->labelPosition = QPoint(-1, -1);
00890 
00891     updateDisplay();
00892 
00893     transition(e);
00894 }
00895 
00909 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
00910 {
00911     int dx = 0;
00912     int dy = 0;
00913 
00914     int offset = 1;
00915     if ( ke->isAutoRepeat() )
00916         offset = 5;
00917 
00918     if ( keyMatch(KeyLeft, ke) )
00919         dx = -offset;
00920     else if ( keyMatch(KeyRight, ke) )
00921         dx = offset;
00922     else if ( keyMatch(KeyUp, ke) )
00923         dy = -offset;
00924     else if ( keyMatch(KeyDown, ke) )
00925         dy = offset;
00926     else if ( keyMatch(KeyAbort, ke) )
00927     {
00928         if ( d_data->stateMachine )
00929             d_data->stateMachine->reset();
00930 
00931         if (isActive())
00932             end(false);
00933     }
00934     else
00935         transition(ke);
00936 
00937     if ( dx != 0 || dy != 0 )
00938     {
00939         const QRect rect = pickRect();
00940         const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
00941 
00942         int x = pos.x() + dx;
00943         x = qwtMax(rect.left(), x);
00944         x = qwtMin(rect.right(), x);
00945 
00946         int y = pos.y() + dy;
00947         y = qwtMax(rect.top(), y);
00948         y = qwtMin(rect.bottom(), y);
00949 
00950         QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
00951     }
00952 }
00953  
00963 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
00964 {
00965     transition(ke);
00966 }
00967 
00975 void QwtPicker::transition(const QEvent *e)
00976 {
00977     if ( !d_data->stateMachine )
00978         return;
00979 
00980     QwtPickerMachine::CommandList commandList =
00981         d_data->stateMachine->transition(*this, e);
00982 
00983     QPoint pos;
00984     switch(e->type())
00985     {
00986         case QEvent::MouseButtonDblClick:
00987         case QEvent::MouseButtonPress:
00988         case QEvent::MouseButtonRelease:
00989         case QEvent::MouseMove:
00990         {
00991             const QMouseEvent *me = (QMouseEvent *)e;
00992             pos = me->pos();
00993             break;
00994         }
00995         default:
00996             pos = parentWidget()->mapFromGlobal(QCursor::pos());
00997     }
00998 
00999     for ( uint i = 0; i < (uint)commandList.count(); i++ )
01000     {
01001         switch(commandList[i])
01002         {
01003             case QwtPickerMachine::Begin:
01004             {
01005                 begin();
01006                 break;
01007             }
01008             case QwtPickerMachine::Append:
01009             {
01010                 append(pos);
01011                 break;
01012             }
01013             case QwtPickerMachine::Move:
01014             {
01015                 move(pos);
01016                 break;
01017             }
01018             case QwtPickerMachine::End:
01019             {
01020                 end();
01021                 break;
01022             }
01023         }
01024     }
01025 }
01026 
01032 void QwtPicker::begin()
01033 {
01034     if ( d_data->isActive )
01035         return;
01036 
01037     d_data->selection.resize(0);
01038     d_data->isActive = true;
01039 
01040     if ( trackerMode() != AlwaysOff )
01041     {
01042         if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 ) 
01043         {
01044             QWidget *w = parentWidget();
01045             if ( w )
01046                 d_data->labelPosition = w->mapFromGlobal(QCursor::pos());
01047         }
01048     }
01049 
01050     updateDisplay();
01051     setMouseTracking(true);
01052 }
01053 
01064 bool QwtPicker::end(bool ok)
01065 {
01066     if ( d_data->isActive )
01067     {
01068         setMouseTracking(false);
01069 
01070         d_data->isActive = false;
01071 
01072         if ( trackerMode() == ActiveOnly )
01073             d_data->labelPosition = QPoint(-1, -1);
01074 
01075         if ( ok )
01076             ok = accept(d_data->selection);
01077 
01078         if ( ok )
01079             emit selected(d_data->selection);
01080         else
01081             d_data->selection.resize(0);
01082 
01083         updateDisplay();
01084     }
01085     else
01086         ok = false;
01087 
01088     return ok;
01089 }
01090 
01099 void QwtPicker::append(const QPoint &pos)
01100 {
01101     if ( d_data->isActive )
01102     {
01103         const int idx = d_data->selection.count();
01104         d_data->selection.resize(idx + 1);
01105         d_data->selection[idx] = pos;
01106 
01107         updateDisplay();
01108 
01109         emit appended(pos);
01110     }
01111 }
01112 
01121 void QwtPicker::move(const QPoint &pos)
01122 {
01123     if ( d_data->isActive )
01124     {
01125         const int idx = d_data->selection.count() - 1;
01126         if ( idx >= 0 )
01127         {
01128             if ( d_data->selection[idx] != pos )
01129             {
01130                 d_data->selection[idx] = pos;
01131 
01132                 updateDisplay();
01133 
01134                 emit moved(pos);
01135             }
01136         }
01137     }
01138 }
01139 
01140 bool QwtPicker::accept(SelectedPoints &) const
01141 {
01142     return true;
01143 }
01144 
01149 bool QwtPicker::isActive() const 
01150 {
01151     return d_data->isActive;
01152 }
01153 
01155 const QwtPicker::SelectedPoints &QwtPicker::selection() const
01156 {
01157     return d_data->selection;
01158 }
01159 
01169 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01170 {
01171     const double xRatio =
01172         double(newSize.width()) / double(oldSize.width());
01173     const double yRatio =
01174         double(newSize.height()) / double(oldSize.height());
01175 
01176     for ( int i = 0; i < int(d_data->selection.count()); i++ )
01177     {
01178         QPoint &p = d_data->selection[i];
01179         p.setX(qRound(p.x() * xRatio));
01180         p.setY(qRound(p.y() * yRatio));
01181 
01182         emit changed(d_data->selection);
01183     }
01184 }
01185 
01199 void QwtPicker::setMouseTracking(bool enable)
01200 {
01201     QWidget *widget = parentWidget();
01202     if ( !widget )
01203         return;
01204 
01205     if ( enable )
01206     {
01207         d_data->mouseTracking = widget->hasMouseTracking();
01208         widget->setMouseTracking(true);
01209     }
01210     else
01211     {
01212         widget->setMouseTracking(d_data->mouseTracking);
01213     }
01214 }
01215 
01221 QRect QwtPicker::pickRect() const
01222 {
01223     QRect rect;
01224 
01225     const QWidget *widget = parentWidget();
01226     if ( !widget )
01227         return rect;
01228 
01229     if ( widget->inherits("QFrame") )
01230         rect = ((QFrame *)widget)->contentsRect();
01231     else
01232         rect = widget->rect();
01233 
01234     return rect;
01235 }
01236 
01237 void QwtPicker::updateDisplay()
01238 {
01239     QWidget *w = parentWidget();
01240 
01241     bool showRubberband = false;
01242     bool showTracker = false;
01243     if ( w && w->isVisible() && d_data->enabled )
01244     {
01245         if ( rubberBand() != NoRubberBand && isActive() &&
01246             rubberBandPen().style() != Qt::NoPen )
01247         {
01248             showRubberband = true;
01249         }
01250 
01251         if ( trackerMode() == AlwaysOn ||
01252             (trackerMode() == ActiveOnly && isActive() ) )
01253         {
01254             if ( trackerPen() != Qt::NoPen )
01255                 showTracker = true;
01256         }
01257     }
01258 
01259 #if QT_VERSION < 0x040000
01260     QGuardedPtr<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
01261 #else
01262     QPointer<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
01263 #endif
01264     if ( showRubberband )
01265     {
01266         if ( rw.isNull() )
01267         {
01268             rw = new PrivateData::PickerWidget(
01269                 this, w, PrivateData::PickerWidget::RubberBand);
01270             rw->resize(w->size());
01271         }
01272         rw->updateMask();
01273     }
01274     else
01275         delete rw;
01276 
01277 #if QT_VERSION < 0x040000
01278     QGuardedPtr<PrivateData::PickerWidget> &tw = d_data->textLabelWidget;
01279 #else
01280     QPointer<PrivateData::PickerWidget> &tw = d_data->textLabelWidget;
01281 #endif
01282     if ( showTracker )
01283     {
01284         if ( tw.isNull() )
01285         {
01286             tw = new PrivateData::PickerWidget(
01287                 this, w, PrivateData::PickerWidget::Text);
01288             tw->resize(w->size());
01289         }
01290         tw->updateMask();
01291     }
01292     else
01293         delete tw;
01294 }

Generated on Mon Jan 30 22:16:25 2006 for Qwt User's Guide by  doxygen 1.4.4