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_text.h"
00018 #include "qwt_painter.h"
00019 #include "qwt_picker_machine.h"
00020 #include "qwt_picker.h"
00021 #if QT_VERSION < 0x040000
00022 #include <qguardedptr.h>
00023 #else
00024 #include <qpointer.h>
00025 #endif
00026 
00027 class QwtPicker::PrivateData
00028 {
00029 public:
00030     class PickerWidget: public QWidget
00031     {
00032     public:
00033         enum Type
00034         {
00035             RubberBand,
00036             Text
00037         };
00038         PickerWidget(QwtPicker *, QWidget *, Type);
00039         virtual void updateMask();
00040 
00041     protected:
00042         virtual void paintEvent(QPaintEvent *);
00043 
00044         QwtPicker *d_picker;
00045         Type d_type;
00046     };
00047 
00048     bool enabled;
00049 
00050     QwtPickerMachine *stateMachine;
00051 
00052     int selectionFlags;
00053     QwtPicker::ResizeMode resizeMode;
00054 
00055     QwtPicker::RubberBand rubberBand;
00056     QPen rubberBandPen;
00057 
00058     QwtPicker::DisplayMode trackerMode;
00059     QPen trackerPen;
00060     QFont trackerFont;
00061 
00062     QwtPicker::SelectedPoints selection;
00063     bool isActive;
00064     QPoint labelPosition;
00065 
00066     bool mouseTracking; // used to save previous value
00067 
00068     /*
00069       On X11 the widget below the picker widgets gets paint events
00070       with a region that is the bounding rect of the mask, if it is complex.
00071       In case of (f.e) a CrossRubberBand and a text this creates complete
00072       repaints of the widget. So we better use two different widgets.
00073      */
00074      
00075 #if QT_VERSION < 0x040000
00076     QGuardedPtr<PickerWidget> rubberBandWidget;
00077     QGuardedPtr<PickerWidget> textLabelWidget;
00078 #else
00079     QPointer<PickerWidget> rubberBandWidget;
00080     QPointer<PickerWidget> textLabelWidget;
00081 #endif
00082 };
00083 
00084 QwtPicker::PrivateData::PickerWidget::PickerWidget(
00085         QwtPicker *picker, QWidget *parent, Type type):
00086     QWidget(parent),
00087     d_picker(picker),
00088     d_type(type)
00089 {
00090 #if QT_VERSION >= 0x040000
00091     setAttribute(Qt::WA_TransparentForMouseEvents);
00092     setAttribute(Qt::WA_NoSystemBackground);
00093     setAttribute(Qt::WA_PaintOnScreen);
00094     setFocusPolicy(Qt::NoFocus);
00095 #else
00096     setBackgroundMode(Qt::NoBackground);
00097     setFocusPolicy(QWidget::NoFocus);
00098 #endif
00099     setMask(QRegion());
00100 }
00101 
00102 void QwtPicker::PrivateData::PickerWidget::updateMask()
00103 {
00104     QBitmap bm(width(), height());
00105     bm.fill(Qt::color0);
00106 
00107     QPainter painter(&bm);
00108 
00109     if ( d_type == RubberBand )
00110     {
00111         QPen pen = d_picker->rubberBandPen();
00112         pen.setColor(Qt::color1);
00113         painter.setPen(pen);
00114 
00115         d_picker->drawRubberBand(&painter);
00116     }
00117     if ( d_type == Text )
00118     {
00119         QPen pen = d_picker->trackerPen();
00120         pen.setColor(Qt::color1);
00121         painter.setPen(pen);
00122 
00123         d_picker->drawTracker(&painter);
00124     }
00125 
00126     painter.end();
00127 
00128     setMask(bm);
00129 }
00130 
00131 void QwtPicker::PrivateData::PickerWidget::paintEvent(QPaintEvent *e)
00132 {
00133     QPainter painter(this);
00134 
00135     if ( d_type == RubberBand )
00136     {
00137 #if QT_VERSION < 0x040000
00138         painter.setClipRegion(e->region());
00139 #else
00140 #ifdef __GNUC__
00141 #warning bad update regions
00142 #endif
00143 #endif
00144         painter.setPen(d_picker->rubberBandPen());
00145         d_picker->drawRubberBand(&painter);
00146     }
00147 
00148     if ( d_type == Text )
00149     {
00150         painter.setClipRegion(e->region());
00151         painter.setPen(d_picker->trackerPen());
00152         d_picker->drawTracker(&painter);
00153     }
00154 }
00155 
00165 QwtPicker::QwtPicker(QWidget *parent):
00166     QObject(parent)
00167 {
00168     init(parent, NoSelection, NoRubberBand, AlwaysOff);
00169 }
00170 
00180 QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
00181         DisplayMode trackerMode, QWidget *parent):
00182     QObject(parent)
00183 {
00184     init(parent, selectionFlags, rubberBand, trackerMode);
00185 }
00186 
00188 QwtPicker::~QwtPicker()
00189 {
00190     setMouseTracking(false);
00191     delete d_data->stateMachine;
00192     delete d_data->rubberBandWidget;
00193     delete d_data->textLabelWidget;
00194     delete d_data;
00195 }
00196 
00198 void QwtPicker::init(QWidget *parent, int selectionFlags, 
00199     RubberBand rubberBand, DisplayMode trackerMode)
00200 {
00201     d_data = new PrivateData;
00202 
00203     d_data->rubberBandWidget = NULL;
00204     d_data->textLabelWidget = NULL;
00205 
00206     d_data->rubberBand = rubberBand;
00207     d_data->enabled = false;
00208     d_data->resizeMode = Stretch;
00209     d_data->trackerMode = AlwaysOff;
00210     d_data->isActive = false;
00211     d_data->labelPosition = QPoint(-1, -1);
00212     d_data->mouseTracking = false;
00213 
00214     d_data->stateMachine = NULL;
00215     setSelectionFlags(selectionFlags);
00216 
00217     if ( parent )
00218     {
00219 #if QT_VERSION >= 0x040000
00220         if ( parent->focusPolicy() == Qt::NoFocus )
00221             parent->setFocusPolicy(Qt::WheelFocus);
00222 #else
00223         if ( parent->focusPolicy() == QWidget::NoFocus )
00224             parent->setFocusPolicy(QWidget::WheelFocus);
00225 #endif
00226 
00227         d_data->trackerFont = parent->font();
00228         d_data->mouseTracking = parent->hasMouseTracking();
00229         setEnabled(true);
00230     }
00231     setTrackerMode(trackerMode);
00232 }
00233 
00237 void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
00238 {
00239     if ( d_data->stateMachine != stateMachine )
00240     {
00241         if ( isActive() )
00242             end(false);
00243 
00244         delete d_data->stateMachine;
00245         d_data->stateMachine = stateMachine;
00246 
00247         if ( d_data->stateMachine )
00248             d_data->stateMachine->reset();
00249     }
00250 }
00251 
00268 QwtPickerMachine *QwtPicker::stateMachine(int flags) const
00269 {
00270     if ( flags & PointSelection )
00271     {
00272         if ( flags & ClickSelection )
00273             return new QwtPickerClickPointMachine;
00274         else
00275             return new QwtPickerDragPointMachine;
00276     }
00277     if ( flags & RectSelection )
00278     {
00279         if ( flags & ClickSelection )
00280             return new QwtPickerClickRectMachine;
00281         else
00282             return new QwtPickerDragRectMachine;
00283     }
00284     if ( flags & PolygonSelection )
00285     {
00286         return new QwtPickerPolygonMachine();
00287     }
00288     return NULL;
00289 }
00290 
00292 QWidget *QwtPicker::parentWidget()
00293 {
00294     QObject *obj = parent();
00295     if ( obj && obj->isWidgetType() )
00296         return (QWidget *)obj;
00297 
00298     return NULL;
00299 }
00300 
00302 const QWidget *QwtPicker::parentWidget() const
00303 {
00304     QObject *obj = parent();
00305     if ( obj && obj->isWidgetType() )
00306         return (QWidget *)obj;
00307 
00308     return NULL;
00309 }
00310 
00320 void QwtPicker::setSelectionFlags(int flags)
00321 {
00322     d_data->selectionFlags = flags;
00323     setStateMachine(stateMachine(flags));
00324 }
00325 
00331 int QwtPicker::selectionFlags() const
00332 {
00333     return d_data->selectionFlags;
00334 }
00335 
00344 void QwtPicker::setRubberBand(RubberBand rubberBand)
00345 {
00346     d_data->rubberBand = rubberBand;
00347 }
00348 
00353 QwtPicker::RubberBand QwtPicker::rubberBand() const
00354 {
00355     return d_data->rubberBand;
00356 }
00357 
00374 void QwtPicker::setTrackerMode(DisplayMode mode)
00375 {   
00376     if ( d_data->trackerMode != mode )
00377     {
00378         d_data->trackerMode = mode;
00379         setMouseTracking(d_data->trackerMode == AlwaysOn);
00380     }
00381 }   
00382 
00387 QwtPicker::DisplayMode QwtPicker::trackerMode() const
00388 {   
00389     return d_data->trackerMode;
00390 }   
00391 
00406 void QwtPicker::setResizeMode(ResizeMode mode)
00407 {
00408     d_data->resizeMode = mode;
00409 }   
00410 
00416 QwtPicker::ResizeMode QwtPicker::resizeMode() const
00417 {   
00418     return d_data->resizeMode;
00419 }
00420 
00430 void QwtPicker::setEnabled(bool enabled)
00431 {
00432     if ( d_data->enabled != enabled )
00433     {
00434         d_data->enabled = enabled;
00435 
00436         QWidget *w = parentWidget();
00437         if ( w )
00438         {
00439             if ( enabled )
00440                 w->installEventFilter(this);
00441             else
00442                 w->removeEventFilter(this);
00443         }
00444 
00445         updateDisplay();
00446     }
00447 }
00448 
00454 bool QwtPicker::isEnabled() const
00455 {
00456     return d_data->enabled;
00457 }
00458 
00465 void QwtPicker::setTrackerFont(const QFont &font)
00466 {
00467     if ( font != d_data->trackerFont )
00468     {
00469         d_data->trackerFont = font;
00470         updateDisplay();
00471     }
00472 }
00473 
00479 QFont QwtPicker::trackerFont() const
00480 {
00481     return d_data->trackerFont;
00482 }
00483 
00490 void QwtPicker::setTrackerPen(const QPen &pen)
00491 {
00492     if ( pen != d_data->trackerPen )
00493     {
00494         d_data->trackerPen = pen;
00495         updateDisplay();
00496     }
00497 }
00498 
00503 QPen QwtPicker::trackerPen() const
00504 {
00505     return d_data->trackerPen;
00506 }
00507 
00514 void QwtPicker::setRubberBandPen(const QPen &pen)
00515 {
00516     if ( pen != d_data->rubberBandPen )
00517     {
00518         d_data->rubberBandPen = pen;
00519         updateDisplay();
00520     }
00521 }
00522 
00527 QPen QwtPicker::rubberBandPen() const
00528 {
00529     return d_data->rubberBandPen;
00530 }
00531 
00545 QString QwtPicker::trackerText(const QPoint &pos) const
00546 {
00547     QString label;
00548 
00549     switch(rubberBand())
00550     {
00551         case HLineRubberBand:
00552             label.sprintf("%d", pos.y());
00553             break;
00554         case VLineRubberBand:
00555             label.sprintf("%d", pos.x());
00556             break;
00557         default:
00558             label.sprintf("%d, %d", pos.x(), pos.y());
00559     }
00560     return label;
00561 }
00562 
00573 void QwtPicker::drawRubberBand(QPainter *painter) const
00574 {
00575     if ( !isActive() || rubberBand() == NoRubberBand || 
00576         rubberBandPen().style() == Qt::NoPen )
00577     {
00578         return;
00579     }
00580 
00581     const QRect &pRect = pickRect();
00582     const SelectedPoints &pa = d_data->selection;
00583 
00584     if ( selectionFlags() & PointSelection )
00585     {
00586         if ( pa.count() < 1 )
00587             return;
00588 
00589         const QPoint pos = pa[0];
00590 
00591         switch(rubberBand())
00592         {
00593             case VLineRubberBand:
00594                 QwtPainter::drawLine(painter, pos.x(),
00595                     pRect.top(), pos.x(), pRect.bottom());
00596                 break;
00597 
00598             case HLineRubberBand:
00599                 QwtPainter::drawLine(painter, pRect.left(), 
00600                     pos.y(), pRect.right(), pos.y());
00601                 break;
00602 
00603             case CrossRubberBand:
00604                 QwtPainter::drawLine(painter, pos.x(),
00605                     pRect.top(), pos.x(), pRect.bottom());
00606                 QwtPainter::drawLine(painter, pRect.left(), 
00607                     pos.y(), pRect.right(), pos.y());
00608                 break;
00609             default:
00610                 break;
00611         }
00612     }
00613 
00614     else if ( selectionFlags() & RectSelection )
00615     {
00616         if ( pa.count() < 2 )
00617             return;
00618 
00619         QPoint p1 = pa[0];
00620         QPoint p2 = pa[int(pa.count() - 1)];
00621 
00622         if ( selectionFlags() & CenterToCorner )
00623         {
00624             p1.setX(p1.x() - (p2.x() - p1.x()));
00625             p1.setY(p1.y() - (p2.y() - p1.y()));
00626         }
00627         else if ( selectionFlags() & CenterToRadius )
00628         {
00629             const int radius = qwtMax(qwtAbs(p2.x() - p1.x()), 
00630                 qwtAbs(p2.y() - p1.y()));
00631             p2.setX(p1.x() + radius);
00632             p2.setY(p1.y() + radius);
00633             p1.setX(p1.x() - radius);
00634             p1.setY(p1.y() - radius);
00635         }
00636 
00637 #if QT_VERSION < 0x040000
00638         const QRect rect = QRect(p1, p2).normalize();
00639 #else
00640         const QRect rect = QRect(p1, p2).normalized();
00641 #endif
00642         switch(rubberBand())
00643         {
00644             case EllipseRubberBand:
00645                 QwtPainter::drawEllipse(painter, rect);
00646                 break;
00647             case RectRubberBand:
00648                 QwtPainter::drawRect(painter, rect);
00649                 break;
00650             default:
00651                 break;
00652         }
00653     }
00654     else if ( selectionFlags() & PolygonSelection )
00655     {
00656         if ( rubberBand() == PolygonRubberBand )
00657             painter->drawPolyline(pa);
00658     }
00659 }
00660 
00670 void QwtPicker::drawTracker(QPainter *painter) const
00671 {
00672     const QRect textRect = trackerRect(painter);
00673     if ( !textRect.isEmpty() )
00674     {
00675         painter->setFont(d_data->trackerFont);
00676 
00677         QString label = trackerText(d_data->labelPosition);
00678 
00679         QwtText *text = QwtText::makeText(label, 0, d_data->trackerFont,
00680             painter->pen().color());
00681         text->draw(painter, textRect);
00682         delete text;
00683     }
00684 }
00685 
00686 QRect QwtPicker::trackerRect(QPainter *painter) const
00687 {
00688     if ( trackerMode() == AlwaysOff || 
00689         (trackerMode() == ActiveOnly && !isActive() ) )
00690     {
00691         return QRect();
00692     }
00693 
00694     if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 )
00695         return QRect();
00696 
00697     const QString label = trackerText(d_data->labelPosition);
00698     if ( label.isEmpty() )
00699         return QRect();
00700 
00701     QwtText *text = QwtText::makeText(label, 0, d_data->trackerFont,
00702         painter->pen().color());
00703     QRect textRect = text->boundingRect(painter);
00704     delete text;
00705 
00706     const QPoint &pos = d_data->labelPosition;
00707 
00708     int alignment = 0;
00709     if ( isActive() && d_data->selection.count() > 1 
00710         && rubberBand() != NoRubberBand )
00711     {
00712         const QPoint last = 
00713             d_data->selection[int(d_data->selection.count()) - 2];
00714 
00715         alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00716         alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00717     }
00718     else
00719         alignment = Qt::AlignTop | Qt::AlignRight;
00720 
00721     const int margin = 5;
00722 
00723     int x = pos.x();
00724     if ( alignment & Qt::AlignLeft )
00725         x -= textRect.width() + margin;
00726     else if ( alignment & Qt::AlignRight )
00727         x += margin;
00728 
00729     int y = pos.y();
00730     if ( alignment & Qt::AlignBottom )
00731         y += margin;
00732     else if ( alignment & Qt::AlignTop )
00733         y -= textRect.height() + margin;
00734     
00735     textRect.moveTopLeft(QPoint(x, y));
00736 
00737     int right = qwtMin(textRect.right(), pickRect().right() - margin);
00738     int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00739     textRect.moveBottomRight(QPoint(right, bottom));
00740 
00741     int left = qwtMax(textRect.left(), pickRect().left() + margin);
00742     int top = qwtMax(textRect.top(), pickRect().top() + margin);
00743     textRect.moveTopLeft(QPoint(left, top));
00744 
00745     return textRect;
00746 }
00747 
00760 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00761 {
00762     if ( o && o == parentWidget() )
00763     {
00764         switch(e->type())
00765         {
00766             case QEvent::Resize:
00767             {
00768                 const QResizeEvent *re = (QResizeEvent *)e;
00769                 if ( d_data->resizeMode == Stretch )
00770                     stretchSelection(re->oldSize(), re->size());
00771 
00772                 if ( d_data->rubberBandWidget )
00773                     d_data->rubberBandWidget->resize(re->size());
00774                 if ( d_data->textLabelWidget )
00775                     d_data->textLabelWidget->resize(re->size());
00776                 break;
00777             }
00778             case QEvent::MouseButtonPress:
00779 #ifdef __GNUC__
00780 #warning QCursor::pos differs drom e->pos
00781 #endif
00782                 widgetMousePressEvent((QMouseEvent *)e);
00783                 break;
00784             case QEvent::MouseButtonRelease:
00785                 widgetMouseReleaseEvent((QMouseEvent *)e);
00786                 break;
00787             case QEvent::MouseButtonDblClick:
00788                 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00789                 break;
00790             case QEvent::MouseMove:
00791                 widgetMouseMoveEvent((QMouseEvent *)e);
00792                 break;
00793             case QEvent::KeyPress:
00794                 widgetKeyPressEvent((QKeyEvent *)e);
00795                 break;
00796             case QEvent::KeyRelease:
00797                 widgetKeyReleaseEvent((QKeyEvent *)e);
00798                 break;
00799             case QEvent::Wheel:
00800                 widgetWheelEvent((QWheelEvent *)e);
00801                 break;
00802             default:
00803                 break;
00804         }
00805     }
00806     return false;
00807 }
00808 
00819 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00820 {
00821     transition(e);
00822 }
00823 
00833 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00834 {
00835     if ( pickRect().contains(e->pos()) )
00836         d_data->labelPosition = e->pos();
00837     else
00838         d_data->labelPosition = QPoint(-1, -1);
00839 
00840     if ( !isActive() )
00841         updateDisplay();
00842 
00843     transition(e);
00844 }
00845 
00856 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00857 {
00858     transition(e);
00859 }
00860 
00870 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00871 {
00872     transition(me);
00873 }
00874     
00875 
00885 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
00886 {
00887     if ( pickRect().contains(e->pos()) )
00888         d_data->labelPosition = e->pos();
00889     else
00890         d_data->labelPosition = QPoint(-1, -1);
00891 
00892     updateDisplay();
00893 
00894     transition(e);
00895 }
00896 
00910 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
00911 {
00912     int dx = 0;
00913     int dy = 0;
00914 
00915     int offset = 1;
00916     if ( ke->isAutoRepeat() )
00917         offset = 5;
00918 
00919     if ( keyMatch(KeyLeft, ke) )
00920         dx = -offset;
00921     else if ( keyMatch(KeyRight, ke) )
00922         dx = offset;
00923     else if ( keyMatch(KeyUp, ke) )
00924         dy = -offset;
00925     else if ( keyMatch(KeyDown, ke) )
00926         dy = offset;
00927     else if ( keyMatch(KeyAbort, ke) )
00928     {
00929         if ( d_data->stateMachine )
00930             d_data->stateMachine->reset();
00931 
00932         if (isActive())
00933             end(false);
00934     }
00935     else
00936         transition(ke);
00937 
00938     if ( dx != 0 || dy != 0 )
00939     {
00940         const QRect rect = pickRect();
00941         const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
00942 
00943         int x = pos.x() + dx;
00944         x = qwtMax(rect.left(), x);
00945         x = qwtMin(rect.right(), x);
00946 
00947         int y = pos.y() + dy;
00948         y = qwtMax(rect.top(), y);
00949         y = qwtMin(rect.bottom(), y);
00950 
00951 #ifdef __GNUC__
00952 #warning QCursor::setPos triggers not always mouse move events
00953 #endif
00954         QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
00955     }
00956 }
00957  
00967 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
00968 {
00969     transition(ke);
00970 }
00971 
00979 void QwtPicker::transition(const QEvent *e)
00980 {
00981     if ( !d_data->stateMachine )
00982         return;
00983 
00984     QwtPickerMachine::CommandList commandList =
00985         d_data->stateMachine->transition(*this, e);
00986 
00987     QPoint pos;
00988     switch(e->type())
00989     {
00990         case QEvent::MouseButtonDblClick:
00991         case QEvent::MouseButtonPress:
00992         case QEvent::MouseButtonRelease:
00993         case QEvent::MouseMove:
00994         {
00995             const QMouseEvent *me = (QMouseEvent *)e;
00996             pos = me->pos();
00997             break;
00998         }
00999         default:
01000             pos = parentWidget()->mapFromGlobal(QCursor::pos());
01001     }
01002 
01003     for ( uint i = 0; i < (uint)commandList.count(); i++ )
01004     {
01005         switch(commandList[i])
01006         {
01007             case QwtPickerMachine::Begin:
01008             {
01009                 begin();
01010                 break;
01011             }
01012             case QwtPickerMachine::Append:
01013             {
01014                 append(pos);
01015                 break;
01016             }
01017             case QwtPickerMachine::Move:
01018             {
01019                 move(pos);
01020                 break;
01021             }
01022             case QwtPickerMachine::End:
01023             {
01024                 end();
01025                 break;
01026             }
01027         }
01028     }
01029 }
01030 
01036 void QwtPicker::begin()
01037 {
01038     if ( d_data->isActive )
01039         return;
01040 
01041     d_data->selection.resize(0);
01042     d_data->isActive = true;
01043 
01044     if ( trackerMode() != AlwaysOff )
01045     {
01046         if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 ) 
01047         {
01048             QWidget *w = parentWidget();
01049             if ( w )
01050                 d_data->labelPosition = w->mapFromGlobal(QCursor::pos());
01051         }
01052     }
01053 
01054     updateDisplay();
01055     setMouseTracking(true);
01056 }
01057 
01068 bool QwtPicker::end(bool ok)
01069 {
01070     if ( d_data->isActive )
01071     {
01072         setMouseTracking(false);
01073 
01074         d_data->isActive = false;
01075 
01076         if ( trackerMode() == ActiveOnly )
01077             d_data->labelPosition = QPoint(-1, -1);
01078 
01079         if ( ok )
01080             ok = accept(d_data->selection);
01081 
01082         if ( ok )
01083             emit selected(d_data->selection);
01084         else
01085             d_data->selection.resize(0);
01086 
01087         updateDisplay();
01088     }
01089     else
01090         ok = false;
01091 
01092     return ok;
01093 }
01094 
01103 void QwtPicker::append(const QPoint &pos)
01104 {
01105     if ( d_data->isActive )
01106     {
01107         const int idx = d_data->selection.count();
01108         d_data->selection.resize(idx + 1);
01109         d_data->selection[idx] = pos;
01110 
01111         updateDisplay();
01112 
01113         emit appended(pos);
01114     }
01115 }
01116 
01125 void QwtPicker::move(const QPoint &pos)
01126 {
01127     if ( d_data->isActive )
01128     {
01129         const int idx = d_data->selection.count() - 1;
01130         if ( idx >= 0 )
01131         {
01132             if ( d_data->selection[idx] != pos )
01133             {
01134                 d_data->selection[idx] = pos;
01135 
01136                 updateDisplay();
01137 
01138                 emit moved(pos);
01139             }
01140         }
01141     }
01142 }
01143 
01144 bool QwtPicker::accept(SelectedPoints &) const
01145 {
01146     return true;
01147 }
01148 
01153 bool QwtPicker::isActive() const 
01154 {
01155     return d_data->isActive;
01156 }
01157 
01159 const QwtPicker::SelectedPoints &QwtPicker::selection() const
01160 {
01161     return d_data->selection;
01162 }
01163 
01173 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01174 {
01175     const double xRatio =
01176         double(newSize.width()) / double(oldSize.width());
01177     const double yRatio =
01178         double(newSize.height()) / double(oldSize.height());
01179 
01180     for ( int i = 0; i < int(d_data->selection.count()); i++ )
01181     {
01182         QPoint &p = d_data->selection[i];
01183         p.setX(qRound(p.x() * xRatio));
01184         p.setY(qRound(p.y() * yRatio));
01185 
01186         emit changed(d_data->selection);
01187     }
01188 }
01189 
01203 void QwtPicker::setMouseTracking(bool enable)
01204 {
01205     QWidget *widget = parentWidget();
01206     if ( !widget )
01207         return;
01208 
01209     if ( enable )
01210     {
01211         d_data->mouseTracking = widget->hasMouseTracking();
01212         widget->setMouseTracking(true);
01213     }
01214     else
01215     {
01216         widget->setMouseTracking(d_data->mouseTracking);
01217     }
01218 }
01219 
01225 QRect QwtPicker::pickRect() const
01226 {
01227     QRect rect;
01228 
01229     const QWidget *widget = parentWidget();
01230     if ( !widget )
01231         return rect;
01232 
01233     if ( widget->inherits("QFrame") )
01234         rect = ((QFrame *)widget)->contentsRect();
01235     else
01236         rect = widget->rect();
01237 
01238     return rect;
01239 }
01240 
01241 void QwtPicker::updateDisplay()
01242 {
01243     QWidget *w = parentWidget();
01244 
01245     bool isVisible = false;
01246     if ( w && d_data->enabled )
01247     {
01248         if ( rubberBand() != NoRubberBand && isActive() &&
01249             rubberBandPen().style() != Qt::NoPen )
01250         {
01251             isVisible = true;
01252         }
01253 
01254         if ( trackerMode() == AlwaysOn ||
01255             (trackerMode() == ActiveOnly && isActive() ) )
01256         {
01257             if ( trackerPen() != Qt::NoPen )
01258                 isVisible = true;
01259         }
01260     }
01261 
01262     if ( isVisible )
01263     {
01264         if ( d_data->rubberBandWidget.isNull() )
01265         {
01266             d_data->rubberBandWidget = new PrivateData::PickerWidget(
01267                 this, w, PrivateData::PickerWidget::RubberBand);
01268             d_data->rubberBandWidget->resize(w->size());
01269             if ( w->isVisible() )
01270                 d_data->rubberBandWidget->show();
01271         }
01272         if ( d_data->textLabelWidget.isNull() )
01273         {
01274             d_data->textLabelWidget = new PrivateData::PickerWidget(
01275                 this, w, PrivateData::PickerWidget::Text);
01276             d_data->textLabelWidget->resize(w->size());
01277             if ( w->isVisible() )
01278                 d_data->textLabelWidget->show();
01279         }
01280 
01281         if ( d_data->rubberBandWidget->isVisible() 
01282             || d_data->textLabelWidget->isVisible()  )
01283         {
01284 #if QT_VERSION < 0x040000
01285             const bool doUpdate = w->isUpdatesEnabled();
01286             const Qt::BackgroundMode bgMode = w->backgroundMode();
01287 
01288             w->setUpdatesEnabled(false);
01289             if ( bgMode != Qt::NoBackground )
01290                 w->setBackgroundMode(Qt::NoBackground);
01291 
01292             d_data->rubberBandWidget->updateMask();
01293             d_data->textLabelWidget->updateMask();
01294 
01295             if ( bgMode != Qt::NoBackground )
01296                 w->setBackgroundMode(bgMode);
01297 
01298             w->setUpdatesEnabled(doUpdate);
01299 #else
01300             d_data->rubberBandWidget->updateMask();
01301             d_data->textLabelWidget->updateMask();
01302 #endif
01303         }
01304     }
01305     else
01306     {
01307         delete d_data->rubberBandWidget;
01308         d_data->rubberBandWidget = NULL;
01309         delete d_data->textLabelWidget;
01310         d_data->textLabelWidget = NULL;
01311     }
01312 }

Generated on Wed Aug 31 23:02:29 2005 for Qwt User's Guide by  doxygen 1.4.1