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 #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             // Antialiased fonts are broken on the Mac.
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 

Generated on Mon Feb 26 21:22:37 2007 for Qwt User's Guide by  doxygen 1.4.6