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     QwtPolygon 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> 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     setAttribute(Qt::WA_PaintOnScreen);
00093     setFocusPolicy(Qt::NoFocus);
00094 #else
00095     setBackgroundMode(Qt::NoBackground);
00096     setFocusPolicy(QWidget::NoFocus);
00097     setMouseTracking(true);
00098 #endif
00099     hide();
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 
00129 #if QT_VERSION < 0x040000
00130     QWidget *w = parentWidget();
00131     const bool doUpdate = w->isUpdatesEnabled();
00132     const Qt::BackgroundMode bgMode = w->backgroundMode();
00133     w->setUpdatesEnabled(false);
00134     if ( bgMode != Qt::NoBackground )
00135         w->setBackgroundMode(Qt::NoBackground);
00136 #endif
00137 
00138     const QRegion r(bm);
00139     setMask(r);
00140 
00141 #if QT_VERSION < 0x040000
00142     if ( bgMode != Qt::NoBackground )
00143         w->setBackgroundMode(bgMode);
00144 
00145     w->setUpdatesEnabled(doUpdate);
00146 #endif
00147 
00148     setShown(!r.isEmpty());
00149 }
00150 
00151 void QwtPicker::PrivateData::PickerWidget::paintEvent(QPaintEvent *e)
00152 {
00153     QPainter painter(this);
00154 
00155     if ( d_type == RubberBand )
00156     {
00157         painter.setClipRegion(e->region());
00158         painter.setPen(d_picker->rubberBandPen());
00159         d_picker->drawRubberBand(&painter);
00160     }
00161 
00162     if ( d_type == Text )
00163     {
00164         painter.setClipRegion(e->region());
00165 #if 0
00166         painter.setPen(d_picker->trackerPen());
00167         d_picker->drawTracker(&painter);
00168 #else
00169         painter.fillRect(e->rect(), QBrush(d_picker->trackerPen().color()));
00170 #endif
00171     }
00172 }
00173 
00183 QwtPicker::QwtPicker(QWidget *parent):
00184     QObject(parent)
00185 {
00186     init(parent, NoSelection, NoRubberBand, AlwaysOff);
00187 }
00188 
00198 QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
00199         DisplayMode trackerMode, QWidget *parent):
00200     QObject(parent)
00201 {
00202     init(parent, selectionFlags, rubberBand, trackerMode);
00203 }
00204 
00206 QwtPicker::~QwtPicker()
00207 {
00208     setMouseTracking(false);
00209     delete d_data->stateMachine;
00210     delete d_data->rubberBandWidget;
00211     delete d_data->trackerWidget;
00212     delete d_data;
00213 }
00214 
00216 void QwtPicker::init(QWidget *parent, int selectionFlags, 
00217     RubberBand rubberBand, DisplayMode trackerMode)
00218 {
00219     d_data = new PrivateData;
00220 
00221     d_data->rubberBandWidget = NULL;
00222     d_data->trackerWidget = NULL;
00223 
00224     d_data->rubberBand = rubberBand;
00225     d_data->enabled = false;
00226     d_data->resizeMode = Stretch;
00227     d_data->trackerMode = AlwaysOff;
00228     d_data->isActive = false;
00229     d_data->labelPosition = QPoint(-1, -1);
00230     d_data->mouseTracking = false;
00231 
00232     d_data->stateMachine = NULL;
00233     setSelectionFlags(selectionFlags);
00234 
00235     if ( parent )
00236     {
00237 #if QT_VERSION >= 0x040000
00238         if ( parent->focusPolicy() == Qt::NoFocus )
00239             parent->setFocusPolicy(Qt::WheelFocus);
00240 #else
00241         if ( parent->focusPolicy() == QWidget::NoFocus )
00242             parent->setFocusPolicy(QWidget::WheelFocus);
00243 #endif
00244 
00245         d_data->trackerFont = parent->font();
00246         d_data->mouseTracking = parent->hasMouseTracking();
00247         setEnabled(true);
00248     }
00249     setTrackerMode(trackerMode);
00250 }
00251 
00255 void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
00256 {
00257     if ( d_data->stateMachine != stateMachine )
00258     {
00259         if ( isActive() )
00260             end(false);
00261 
00262         delete d_data->stateMachine;
00263         d_data->stateMachine = stateMachine;
00264 
00265         if ( d_data->stateMachine )
00266             d_data->stateMachine->reset();
00267     }
00268 }
00269 
00286 QwtPickerMachine *QwtPicker::stateMachine(int flags) const
00287 {
00288     if ( flags & PointSelection )
00289     {
00290         if ( flags & ClickSelection )
00291             return new QwtPickerClickPointMachine;
00292         else
00293             return new QwtPickerDragPointMachine;
00294     }
00295     if ( flags & RectSelection )
00296     {
00297         if ( flags & ClickSelection )
00298             return new QwtPickerClickRectMachine;
00299         else
00300             return new QwtPickerDragRectMachine;
00301     }
00302     if ( flags & PolygonSelection )
00303     {
00304         return new QwtPickerPolygonMachine();
00305     }
00306     return NULL;
00307 }
00308 
00310 QWidget *QwtPicker::parentWidget()
00311 {
00312     QObject *obj = parent();
00313     if ( obj && obj->isWidgetType() )
00314         return (QWidget *)obj;
00315 
00316     return NULL;
00317 }
00318 
00320 const QWidget *QwtPicker::parentWidget() const
00321 {
00322     QObject *obj = parent();
00323     if ( obj && obj->isWidgetType() )
00324         return (QWidget *)obj;
00325 
00326     return NULL;
00327 }
00328 
00338 void QwtPicker::setSelectionFlags(int flags)
00339 {
00340     d_data->selectionFlags = flags;
00341     setStateMachine(stateMachine(flags));
00342 }
00343 
00349 int QwtPicker::selectionFlags() const
00350 {
00351     return d_data->selectionFlags;
00352 }
00353 
00362 void QwtPicker::setRubberBand(RubberBand rubberBand)
00363 {
00364     d_data->rubberBand = rubberBand;
00365 }
00366 
00371 QwtPicker::RubberBand QwtPicker::rubberBand() const
00372 {
00373     return d_data->rubberBand;
00374 }
00375 
00392 void QwtPicker::setTrackerMode(DisplayMode mode)
00393 {   
00394     if ( d_data->trackerMode != mode )
00395     {
00396         d_data->trackerMode = mode;
00397         setMouseTracking(d_data->trackerMode == AlwaysOn);
00398     }
00399 }   
00400 
00405 QwtPicker::DisplayMode QwtPicker::trackerMode() const
00406 {   
00407     return d_data->trackerMode;
00408 }   
00409 
00424 void QwtPicker::setResizeMode(ResizeMode mode)
00425 {
00426     d_data->resizeMode = mode;
00427 }   
00428 
00434 QwtPicker::ResizeMode QwtPicker::resizeMode() const
00435 {   
00436     return d_data->resizeMode;
00437 }
00438 
00448 void QwtPicker::setEnabled(bool enabled)
00449 {
00450     if ( d_data->enabled != enabled )
00451     {
00452         d_data->enabled = enabled;
00453 
00454         QWidget *w = parentWidget();
00455         if ( w )
00456         {
00457             if ( enabled )
00458                 w->installEventFilter(this);
00459             else
00460                 w->removeEventFilter(this);
00461         }
00462 
00463         updateDisplay();
00464     }
00465 }
00466 
00472 bool QwtPicker::isEnabled() const
00473 {
00474     return d_data->enabled;
00475 }
00476 
00483 void QwtPicker::setTrackerFont(const QFont &font)
00484 {
00485     if ( font != d_data->trackerFont )
00486     {
00487         d_data->trackerFont = font;
00488         updateDisplay();
00489     }
00490 }
00491 
00497 QFont QwtPicker::trackerFont() const
00498 {
00499     return d_data->trackerFont;
00500 }
00501 
00508 void QwtPicker::setTrackerPen(const QPen &pen)
00509 {
00510     if ( pen != d_data->trackerPen )
00511     {
00512         d_data->trackerPen = pen;
00513         updateDisplay();
00514     }
00515 }
00516 
00521 QPen QwtPicker::trackerPen() const
00522 {
00523     return d_data->trackerPen;
00524 }
00525 
00532 void QwtPicker::setRubberBandPen(const QPen &pen)
00533 {
00534     if ( pen != d_data->rubberBandPen )
00535     {
00536         d_data->rubberBandPen = pen;
00537         updateDisplay();
00538     }
00539 }
00540 
00545 QPen QwtPicker::rubberBandPen() const
00546 {
00547     return d_data->rubberBandPen;
00548 }
00549 
00563 QwtText QwtPicker::trackerText(const QPoint &pos) const
00564 {
00565     QString label;
00566 
00567     switch(rubberBand())
00568     {
00569         case HLineRubberBand:
00570             label.sprintf("%d", pos.y());
00571             break;
00572         case VLineRubberBand:
00573             label.sprintf("%d", pos.x());
00574             break;
00575         default:
00576             label.sprintf("%d, %d", pos.x(), pos.y());
00577     }
00578     return label;
00579 }
00580 
00589 void QwtPicker::drawRubberBand(QPainter *painter) const
00590 {
00591     if ( !isActive() || rubberBand() == NoRubberBand || 
00592         rubberBandPen().style() == Qt::NoPen )
00593     {
00594         return;
00595     }
00596 
00597     const QRect &pRect = pickRect();
00598     const QwtPolygon &pa = d_data->selection;
00599 
00600     if ( selectionFlags() & PointSelection )
00601     {
00602         if ( pa.count() < 1 )
00603             return;
00604 
00605         const QPoint pos = pa[0];
00606 
00607         switch(rubberBand())
00608         {
00609             case VLineRubberBand:
00610                 QwtPainter::drawLine(painter, pos.x(),
00611                     pRect.top(), pos.x(), pRect.bottom());
00612                 break;
00613 
00614             case HLineRubberBand:
00615                 QwtPainter::drawLine(painter, pRect.left(), 
00616                     pos.y(), pRect.right(), pos.y());
00617                 break;
00618 
00619             case CrossRubberBand:
00620                 QwtPainter::drawLine(painter, pos.x(),
00621                     pRect.top(), pos.x(), pRect.bottom());
00622                 QwtPainter::drawLine(painter, pRect.left(), 
00623                     pos.y(), pRect.right(), pos.y());
00624                 break;
00625             default:
00626                 break;
00627         }
00628     }
00629 
00630     else if ( selectionFlags() & RectSelection )
00631     {
00632         if ( pa.count() < 2 )
00633             return;
00634 
00635         QPoint p1 = pa[0];
00636         QPoint p2 = pa[int(pa.count() - 1)];
00637 
00638         if ( selectionFlags() & CenterToCorner )
00639         {
00640             p1.setX(p1.x() - (p2.x() - p1.x()));
00641             p1.setY(p1.y() - (p2.y() - p1.y()));
00642         }
00643         else if ( selectionFlags() & CenterToRadius )
00644         {
00645             const int radius = qwtMax(qwtAbs(p2.x() - p1.x()), 
00646                 qwtAbs(p2.y() - p1.y()));
00647             p2.setX(p1.x() + radius);
00648             p2.setY(p1.y() + radius);
00649             p1.setX(p1.x() - radius);
00650             p1.setY(p1.y() - radius);
00651         }
00652 
00653 #if QT_VERSION < 0x040000
00654         const QRect rect = QRect(p1, p2).normalize();
00655 #else
00656         const QRect rect = QRect(p1, p2).normalized();
00657 #endif
00658         switch(rubberBand())
00659         {
00660             case EllipseRubberBand:
00661                 QwtPainter::drawEllipse(painter, rect);
00662                 break;
00663             case RectRubberBand:
00664                 QwtPainter::drawRect(painter, rect);
00665                 break;
00666             default:
00667                 break;
00668         }
00669     }
00670     else if ( selectionFlags() & PolygonSelection )
00671     {
00672         if ( rubberBand() == PolygonRubberBand )
00673             painter->drawPolyline(pa);
00674     }
00675 }
00676 
00684 void QwtPicker::drawTracker(QPainter *painter) const
00685 {
00686     const QRect textRect = trackerRect(painter);
00687     if ( !textRect.isEmpty() )
00688     {
00689         QwtText label = trackerText(d_data->labelPosition);
00690         if ( !label.isEmpty() )
00691             label.draw(painter, textRect);
00692     }
00693 }
00694 
00695 QRect QwtPicker::trackerRect(QPainter *painter) const
00696 {
00697     if ( trackerMode() == AlwaysOff || 
00698         (trackerMode() == ActiveOnly && !isActive() ) )
00699     {
00700         return QRect();
00701     }
00702 
00703     if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 )
00704         return QRect();
00705 
00706     QwtText text = trackerText(d_data->labelPosition);
00707     if ( text.isEmpty() )
00708         return QRect();
00709 
00710     QRect textRect(QPoint(0, 0), text.textSize(painter->font()));
00711 
00712     const QPoint &pos = d_data->labelPosition;
00713 
00714     int alignment = 0;
00715     if ( isActive() && d_data->selection.count() > 1 
00716         && rubberBand() != NoRubberBand )
00717     {
00718         const QPoint last = 
00719             d_data->selection[int(d_data->selection.count()) - 2];
00720 
00721         alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
00722         alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
00723     }
00724     else
00725         alignment = Qt::AlignTop | Qt::AlignRight;
00726 
00727     const int margin = 5;
00728 
00729     int x = pos.x();
00730     if ( alignment & Qt::AlignLeft )
00731         x -= textRect.width() + margin;
00732     else if ( alignment & Qt::AlignRight )
00733         x += margin;
00734 
00735     int y = pos.y();
00736     if ( alignment & Qt::AlignBottom )
00737         y += margin;
00738     else if ( alignment & Qt::AlignTop )
00739         y -= textRect.height() + margin;
00740     
00741     textRect.moveTopLeft(QPoint(x, y));
00742 
00743     int right = qwtMin(textRect.right(), pickRect().right() - margin);
00744     int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
00745     textRect.moveBottomRight(QPoint(right, bottom));
00746 
00747     int left = qwtMax(textRect.left(), pickRect().left() + margin);
00748     int top = qwtMax(textRect.top(), pickRect().top() + margin);
00749     textRect.moveTopLeft(QPoint(left, top));
00750 
00751     return textRect;
00752 }
00753 
00766 bool QwtPicker::eventFilter(QObject *o, QEvent *e)
00767 {
00768     if ( o && o == parentWidget() )
00769     {
00770         switch(e->type())
00771         {
00772             case QEvent::Resize:
00773             {
00774                 const QResizeEvent *re = (QResizeEvent *)e;
00775                 if ( d_data->resizeMode == Stretch )
00776                     stretchSelection(re->oldSize(), re->size());
00777 
00778                 if ( d_data->rubberBandWidget )
00779                     d_data->rubberBandWidget->resize(re->size());
00780              
00781                 if ( d_data->trackerWidget )
00782                     d_data->trackerWidget->resize(re->size());
00783                 break;
00784             }
00785             case QEvent::MouseButtonPress:
00786                 widgetMousePressEvent((QMouseEvent *)e);
00787                 break;
00788             case QEvent::MouseButtonRelease:
00789                 widgetMouseReleaseEvent((QMouseEvent *)e);
00790                 break;
00791             case QEvent::MouseButtonDblClick:
00792                 widgetMouseDoubleClickEvent((QMouseEvent *)e);
00793                 break;
00794             case QEvent::MouseMove:
00795                 widgetMouseMoveEvent((QMouseEvent *)e);
00796                 break;
00797             case QEvent::KeyPress:
00798                 widgetKeyPressEvent((QKeyEvent *)e);
00799                 break;
00800             case QEvent::KeyRelease:
00801                 widgetKeyReleaseEvent((QKeyEvent *)e);
00802                 break;
00803             case QEvent::Wheel:
00804                 widgetWheelEvent((QWheelEvent *)e);
00805                 break;
00806             default:
00807                 break;
00808         }
00809     }
00810     return false;
00811 }
00812 
00823 void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
00824 {
00825     transition(e);
00826 }
00827 
00837 void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
00838 {
00839     if ( pickRect().contains(e->pos()) )
00840         d_data->labelPosition = e->pos();
00841     else
00842         d_data->labelPosition = QPoint(-1, -1);
00843 
00844     if ( !isActive() )
00845         updateDisplay();
00846 
00847     transition(e);
00848 }
00849 
00860 void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
00861 {
00862     transition(e);
00863 }
00864 
00874 void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
00875 {
00876     transition(me);
00877 }
00878     
00879 
00889 void QwtPicker::widgetWheelEvent(QWheelEvent *e)
00890 {
00891     if ( pickRect().contains(e->pos()) )
00892         d_data->labelPosition = e->pos();
00893     else
00894         d_data->labelPosition = QPoint(-1, -1);
00895 
00896     updateDisplay();
00897 
00898     transition(e);
00899 }
00900 
00914 void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
00915 {
00916     int dx = 0;
00917     int dy = 0;
00918 
00919     int offset = 1;
00920     if ( ke->isAutoRepeat() )
00921         offset = 5;
00922 
00923     if ( keyMatch(KeyLeft, ke) )
00924         dx = -offset;
00925     else if ( keyMatch(KeyRight, ke) )
00926         dx = offset;
00927     else if ( keyMatch(KeyUp, ke) )
00928         dy = -offset;
00929     else if ( keyMatch(KeyDown, ke) )
00930         dy = offset;
00931     else if ( keyMatch(KeyAbort, ke) )
00932     {
00933         if ( d_data->stateMachine )
00934             d_data->stateMachine->reset();
00935 
00936         if (isActive())
00937             end(false);
00938     }
00939     else
00940         transition(ke);
00941 
00942     if ( dx != 0 || dy != 0 )
00943     {
00944         const QRect rect = pickRect();
00945         const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
00946 
00947         int x = pos.x() + dx;
00948         x = qwtMax(rect.left(), x);
00949         x = qwtMin(rect.right(), x);
00950 
00951         int y = pos.y() + dy;
00952         y = qwtMax(rect.top(), y);
00953         y = qwtMin(rect.bottom(), y);
00954 
00955         QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
00956     }
00957 }
00958  
00968 void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
00969 {
00970     transition(ke);
00971 }
00972 
00980 void QwtPicker::transition(const QEvent *e)
00981 {
00982     if ( !d_data->stateMachine )
00983         return;
00984 
00985     QwtPickerMachine::CommandList commandList =
00986         d_data->stateMachine->transition(*this, e);
00987 
00988     QPoint pos;
00989     switch(e->type())
00990     {
00991         case QEvent::MouseButtonDblClick:
00992         case QEvent::MouseButtonPress:
00993         case QEvent::MouseButtonRelease:
00994         case QEvent::MouseMove:
00995         {
00996             const QMouseEvent *me = (QMouseEvent *)e;
00997             pos = me->pos();
00998             break;
00999         }
01000         default:
01001             pos = parentWidget()->mapFromGlobal(QCursor::pos());
01002     }
01003 
01004     for ( uint i = 0; i < (uint)commandList.count(); i++ )
01005     {
01006         switch(commandList[i])
01007         {
01008             case QwtPickerMachine::Begin:
01009             {
01010                 begin();
01011                 break;
01012             }
01013             case QwtPickerMachine::Append:
01014             {
01015                 append(pos);
01016                 break;
01017             }
01018             case QwtPickerMachine::Move:
01019             {
01020                 move(pos);
01021                 break;
01022             }
01023             case QwtPickerMachine::End:
01024             {
01025                 end();
01026                 break;
01027             }
01028         }
01029     }
01030 }
01031 
01037 void QwtPicker::begin()
01038 {
01039     if ( d_data->isActive )
01040         return;
01041 
01042     d_data->selection.resize(0);
01043     d_data->isActive = true;
01044 
01045     if ( trackerMode() != AlwaysOff )
01046     {
01047         if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 ) 
01048         {
01049             QWidget *w = parentWidget();
01050             if ( w )
01051                 d_data->labelPosition = w->mapFromGlobal(QCursor::pos());
01052         }
01053     }
01054 
01055     updateDisplay();
01056     setMouseTracking(true);
01057 }
01058 
01069 bool QwtPicker::end(bool ok)
01070 {
01071     if ( d_data->isActive )
01072     {
01073         setMouseTracking(false);
01074 
01075         d_data->isActive = false;
01076 
01077         if ( trackerMode() == ActiveOnly )
01078             d_data->labelPosition = QPoint(-1, -1);
01079 
01080         if ( ok )
01081             ok = accept(d_data->selection);
01082 
01083         if ( ok )
01084             emit selected(d_data->selection);
01085         else
01086             d_data->selection.resize(0);
01087 
01088         updateDisplay();
01089     }
01090     else
01091         ok = false;
01092 
01093     return ok;
01094 }
01095 
01104 void QwtPicker::append(const QPoint &pos)
01105 {
01106     if ( d_data->isActive )
01107     {
01108         const int idx = d_data->selection.count();
01109         d_data->selection.resize(idx + 1);
01110         d_data->selection[idx] = pos;
01111 
01112         updateDisplay();
01113 
01114         emit appended(pos);
01115     }
01116 }
01117 
01126 void QwtPicker::move(const QPoint &pos)
01127 {
01128     if ( d_data->isActive )
01129     {
01130         const int idx = d_data->selection.count() - 1;
01131         if ( idx >= 0 )
01132         {
01133             if ( d_data->selection[idx] != pos )
01134             {
01135                 d_data->selection[idx] = pos;
01136 
01137                 updateDisplay();
01138 
01139                 emit moved(pos);
01140             }
01141         }
01142     }
01143 }
01144 
01145 bool QwtPicker::accept(QwtPolygon &) const
01146 {
01147     return true;
01148 }
01149 
01154 bool QwtPicker::isActive() const 
01155 {
01156     return d_data->isActive;
01157 }
01158 
01160 const QwtPolygon &QwtPicker::selection() const
01161 {
01162     return d_data->selection;
01163 }
01164 
01174 void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
01175 {
01176     const double xRatio =
01177         double(newSize.width()) / double(oldSize.width());
01178     const double yRatio =
01179         double(newSize.height()) / double(oldSize.height());
01180 
01181     for ( int i = 0; i < int(d_data->selection.count()); i++ )
01182     {
01183         QPoint &p = d_data->selection[i];
01184         p.setX(qRound(p.x() * xRatio));
01185         p.setY(qRound(p.y() * yRatio));
01186 
01187         emit changed(d_data->selection);
01188     }
01189 }
01190 
01204 void QwtPicker::setMouseTracking(bool enable)
01205 {
01206     QWidget *widget = parentWidget();
01207     if ( !widget )
01208         return;
01209 
01210     if ( enable )
01211     {
01212         d_data->mouseTracking = widget->hasMouseTracking();
01213         widget->setMouseTracking(true);
01214     }
01215     else
01216     {
01217         widget->setMouseTracking(d_data->mouseTracking);
01218     }
01219 }
01220 
01226 QRect QwtPicker::pickRect() const
01227 {
01228     QRect rect;
01229 
01230     const QWidget *widget = parentWidget();
01231     if ( !widget )
01232         return rect;
01233 
01234     if ( widget->inherits("QFrame") )
01235         rect = ((QFrame *)widget)->contentsRect();
01236     else
01237         rect = widget->rect();
01238 
01239     return rect;
01240 }
01241 
01242 void QwtPicker::updateDisplay()
01243 {
01244     QWidget *w = parentWidget();
01245 
01246     bool showRubberband = false;
01247     bool showTracker = false;
01248     if ( w && w->isVisible() && d_data->enabled )
01249     {
01250         if ( rubberBand() != NoRubberBand && isActive() &&
01251             rubberBandPen().style() != Qt::NoPen )
01252         {
01253             showRubberband = true;
01254         }
01255 
01256         if ( trackerMode() == AlwaysOn ||
01257             (trackerMode() == ActiveOnly && isActive() ) )
01258         {
01259             if ( trackerPen() != Qt::NoPen )
01260                 showTracker = true;
01261         }
01262     }
01263 
01264 #if QT_VERSION < 0x040000
01265     QGuardedPtr<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
01266 #else
01267     QPointer<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
01268 #endif
01269     if ( showRubberband )
01270     {
01271         if ( rw.isNull() )
01272         {
01273             rw = new PrivateData::PickerWidget(
01274                 this, w, PrivateData::PickerWidget::RubberBand);
01275             rw->resize(w->size());
01276         }
01277         rw->updateMask();
01278     }
01279     else
01280         delete rw;
01281 
01282 #if QT_VERSION < 0x040000
01283     QGuardedPtr<PrivateData::PickerWidget> &tw = d_data->trackerWidget;
01284 #else
01285     QPointer<PrivateData::PickerWidget> &tw = d_data->trackerWidget;
01286 #endif
01287     if ( showTracker )
01288     {
01289         if ( tw.isNull() )
01290         {
01291             tw = new PrivateData::PickerWidget(
01292                 this, w, PrivateData::PickerWidget::Text);
01293             tw->resize(w->size());
01294         }
01295         tw->updateMask();
01296     }
01297     else
01298         delete tw;
01299 }
01300 
01301 const QWidget *QwtPicker::rubberBandWidget() const
01302 {
01303     return d_data->rubberBandWidget;
01304 }
01305 
01306 const QWidget *QwtPicker::trackerWidget() const
01307 {
01308     return d_data->trackerWidget;
01309 }
01310 

Generated on Mon Nov 6 20:32:57 2006 for Qwt User's Guide by  doxygen 1.4.6