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

# qwt_dial.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 <math.h>
    00011 #include <qpainter.h>
    00012 #include <qpixmap.h>
    00013 #include <qevent.h>
    00014 #include "qwt_math.h"
    00015 #include "qwt_paint_buffer.h"
    00016 #include "qwt_painter.h"
    00017 #include "qwt_dial_needle.h"
    00018 #include "qwt_dial.h"
    00019
    00020 double QwtDial::d_previousDir = -1.0;
    00021
    00027 QwtDialScaleDraw::QwtDialScaleDraw(QwtDial *parent):
    00028     d_parent(parent),
    00029     d_penWidth(1),
    00030     d_visibleLabels(TRUE)
    00031 {
    00032 }
    00033
    00043 void QwtDialScaleDraw::showLabels(bool enable)
    00044 {
    00045     d_visibleLabels = enable;
    00046 }
    00047
    00052 bool QwtDialScaleDraw::visibleLabels() const
    00053 {
    00054     return d_visibleLabels;
    00055 }
    00056
    00064 void QwtDialScaleDraw::setPenWidth(uint penWidth)
    00065 {
    00066     d_penWidth = penWidth;
    00067 }
    00068
    00073 uint QwtDialScaleDraw::penWidth() const
    00074 {
    00075     return d_penWidth;
    00076 }
    00077
    00085 QString QwtDialScaleDraw::label(double value) const
    00086 {
    00087     if ( !d_visibleLabels )
    00088         return QString::null;
    00089
    00090     if ( d_parent == NULL )
    00091         return QwtScaleDraw::label(value);
    00092
    00093     return d_parent->scaleLabel(value);
    00094 }
    00095
    00107 QwtDial::QwtDial(QWidget* parent, const char* name):
    00108         QwtSliderBase(Qt::Horizontal, parent, name,
    00109             Qt::WRepaintNoErase|Qt::WResizeNoErase),
    00110     d_visibleBackground(FALSE),
    00111     d_frameShadow(Sunken),
    00112     d_lineWidth(0),
    00113     d_mode(RotateNeedle),
    00114     d_origin(90.0),
    00115     d_minScaleArc(0.0),
    00116     d_maxScaleArc(0.0),
    00117     d_scaleDraw(0),
    00118     d_maxMajIntv(36),
    00119     d_maxMinIntv(10),
    00120     d_scaleStep(0.0),
    00121     d_needle(0)
    00122 {
    00123     setBackgroundMode(NoBackground);
    00124     setFocusPolicy(QWidget::TabFocus);
    00125
    00126     QPalette p = palette();
    00127     for ( int i = 0; i < QPalette::NColorGroups; i++ )
    00128     {
    00129         const QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
    00130
    00131         // Base: background color of the circle inside the frame.
    00132         // Foreground: background color of the circle inside the scale
    00133
    00134         p.setColor(cg, QColorGroup::Foreground,
    00135             p.color(cg, QColorGroup::Base));
    00136     }
    00137     setPalette(p);
    00138
    00139     d_scaleDraw = new QwtDialScaleDraw(this);
    00140     d_scaleDraw->setGeometry(0, 0, 0, QwtScaleDraw::Round);
    00141
    00142     setScaleArc(0.0, 360.0); // scale as a full circle
    00143     setRange(0.0, 360.0, 1.0, 10); // degrees as deafult
    00144 }
    00145
    00147 QwtDial::~QwtDial()
    00148 {
    00149     delete d_scaleDraw;
    00150     delete d_needle;
    00151 }
    00152
    00161 void QwtDial::showBackground(bool show)
    00162 {
    00163     if ( d_visibleBackground != show )
    00164     {
    00165         d_visibleBackground = show;
    00166
    00167         if ( d_visibleBackground )
    00168             clearMask();
    00169         else
    00170             setMask(QRegion(boundingRect(), QRegion::Ellipse));
    00171
    00172         update();
    00173     }
    00174 }
    00175
    00181 bool QwtDial::hasVisibleBackground() const
    00182 {
    00183     return d_visibleBackground;
    00184 }
    00185
    00191 void QwtDial::setFrameShadow(Shadow shadow)
    00192 {
    00193     if ( shadow != d_frameShadow )
    00194     {
    00195         d_frameShadow = shadow;
    00196         if ( lineWidth() > 0 )
    00197             update();
    00198     }
    00199 }
    00200
    00206 QwtDial::Shadow QwtDial::frameShadow() const
    00207 {
    00208     return d_frameShadow;
    00209 }
    00210
    00217 void QwtDial::setLineWidth(int lineWidth)
    00218 {
    00219     if ( lineWidth < 0 )
    00220         lineWidth = 0;
    00221
    00222     if ( d_lineWidth != lineWidth )
    00223     {
    00224         d_lineWidth = lineWidth;
    00225         update();
    00226     }
    00227 }
    00228
    00234 int QwtDial::lineWidth() const
    00235 {
    00236     return d_lineWidth;
    00237 }
    00238
    00243 QRect QwtDial::contentsRect() const
    00244 {
    00245     const int lw = lineWidth();
    00246
    00247     QRect r = boundingRect();
    00248     if ( lw > 0 )
    00249     {
    00250         r.setRect(r.x() + lw, r.y() + lw,
    00251             r.width() - 2 * lw, r.height() - 2 * lw);
    00252     }
    00253     return r;
    00254 }
    00255
    00260 QRect QwtDial::boundingRect() const
    00261 {
    00262     const int radius = QMIN(width(), height()) / 2;
    00263
    00264     QRect r(0, 0, 2 * radius, 2 * radius);
    00265     r.moveCenter(rect().center());
    00266     return r;
    00267 }
    00268
    00273 QRect QwtDial::scaleContentsRect() const
    00274 {
    00275     const QPen scalePen(colorGroup().text(), 0, Qt::NoPen);
    00276
    00277     int scaleDist = 0;
    00278     if ( d_scaleDraw )
    00279     {
    00280         scaleDist = QMAX(
    00281             d_scaleDraw->maxWidth(scalePen, fontMetrics()),
    00282             d_scaleDraw->maxHeight(scalePen, fontMetrics()));
    00283         scaleDist++; // margin
    00284     }
    00285
    00286     const QRect rect = contentsRect();
    00287     return QRect(rect.x() + scaleDist, rect.y() + scaleDist,
    00288         rect.width() - 2 * scaleDist, rect.height() - 2 * scaleDist);
    00289 }
    00290
    00306 void QwtDial::setMode(Mode mode)
    00307 {
    00308     if ( mode != d_mode )
    00309     {
    00310         d_mode = mode;
    00311         update();
    00312     }
    00313 }
    00314
    00329 QwtDial::Mode QwtDial::mode() const
    00330 {
    00331     return d_mode;
    00332 }
    00333
    00344 void QwtDial::setWrapping(bool wrapping)
    00345 {
    00346     setPeriodic(wrapping);
    00347 }
    00348
    00357 bool QwtDial::wrapping() const
    00358 {
    00359     return periodic();
    00360 }
    00361
    00363 void QwtDial::resizeEvent(QResizeEvent *e)
    00364 {
    00365     QWidget::resizeEvent(e);
    00366
    00367     if ( !hasVisibleBackground() )
    00368         setMask(QRegion(boundingRect(), QRegion::Ellipse));
    00369 }
    00370
    00372 void QwtDial::paintEvent(QPaintEvent *e)
    00373 {
    00374     const QRect &ur = e->rect();
    00375     if ( ur.isValid() )
    00376     {
    00377         QwtPaintBuffer paintBuffer(this, ur);
    00378
    00379         QPainter *painter = paintBuffer.painter();
    00380
    00381         drawContents(painter);
    00382         drawFrame(painter);
    00383
    00384         if ( hasFocus() )
    00385             drawFocusIndicator(painter);
    00386     }
    00387 }
    00388
    00394 void QwtDial::drawFocusIndicator(QPainter *painter) const
    00395 {
    00396     if ( !isReadOnly() )
    00397     {
    00398         QRect focusRect = contentsRect();
    00399
    00400         const int margin = 2;
    00401         focusRect.setRect(
    00402             focusRect.x() + margin,
    00403             focusRect.y() + margin,
    00404             focusRect.width() - 2 * margin,
    00405             focusRect.height() - 2 * margin);
    00406
    00407         QColor color = colorGroup().color(QColorGroup::Base);
    00408         if (color.isValid())
    00409         {
    00410             int h, s, v;
    00411             color.hsv(&h, &s, &v);
    00412             color = (v > 128) ? Qt::gray.dark(120) : Qt::gray.light(120);
    00413         }
    00414         else
    00415             color = Qt::darkGray;
    00416
    00417         painter->save();
    00418         painter->setBrush(Qt::NoBrush);
    00419         painter->setPen(QPen(color, 0, Qt::DotLine));
    00420         painter->drawEllipse(focusRect);
    00421         painter->restore();
    00422     }
    00423 }
    00424
    00431 void QwtDial::drawFrame(QPainter *painter)
    00432 {
    00433     const int lw = lineWidth();
    00434     const int off = (lw + 1) % 2;
    00435
    00436     QRect r = boundingRect();
    00437     r.setRect(r.x() + lw / 2 - off, r.y() + lw / 2 - off,
    00438         r.width() - lw + off + 1, r.height() - lw + off + 1);
    00439
    00440     if ( lw > 0 )
    00441     {
    00442         switch(d_frameShadow)
    00443         {
    00444             case QwtDial::Raised:
    00445                 QwtPainter::drawRoundFrame(painter, r,
    00446                     lw, colorGroup(), FALSE);
    00447                 break;
    00448             case QwtDial::Sunken:
    00449                 QwtPainter::drawRoundFrame(painter, r,
    00450                     lw, colorGroup(), TRUE);
    00451                 break;
    00452             default: // Plain
    00453             {
    00454                 painter->save();
    00455                 painter->setPen(QPen(Qt::black, lw));
    00456                 painter->setBrush(Qt::NoBrush);
    00457                 painter->drawEllipse(r);
    00458                 painter->restore();
    00459             }
    00460         }
    00461     }
    00462 }
    00463
    00475 void QwtDial::drawContents(QPainter *painter) const
    00476 {
    00477     if ( backgroundMode() == NoBackground ||
    00478         colorGroup().brush(QColorGroup::Base) !=
    00479             colorGroup().brush(QColorGroup::Background) )
    00480     {
    00481         // Donīt use QPainter::drawEllipse. There are some pixels
    00482         // different compared to the region in the mask, leaving
    00483         // them in background color.
    00484
    00485         painter->save();
    00486         painter->setPen(Qt::NoPen);
    00487         painter->setBrush(colorGroup().brush(QColorGroup::Base));
    00488
    00489         // Even if we want to fill the contentsRect only, we fill the
    00490         // complete boundingRect. The frame will be painted later
    00491         // above, but we want to have the base color below it
    00492         // because round objects doesnīt cover all pixels.
    00493
    00494         QRect br = boundingRect();
    00495 #if QT_VERSION < 300
    00496 #ifdef _WS_WIN32_
    00497         // Qt-230-NC draws ellipses not as nicely as Qt-2.3.x on X Windows
    00498         br.setTop(br.top()-1);
    00499         br.setLeft(br.left()-1);
    00500         br.setBottom(br.bottom()+1);
    00501         br.setRight(br.right()+1);
    00502 #endif
    00503 #endif
    00504         painter->setClipRegion(QRegion(painter->xForm(br), QRegion::Ellipse));
    00505         painter->drawRect(br);
    00506         painter->restore();
    00507     }
    00508
    00509
    00510     const QRect insideScaleRect = scaleContentsRect();
    00511     if ( colorGroup().brush(QColorGroup::Foreground) !=
    00512         colorGroup().brush(QColorGroup::Base) )
    00513     {
    00514         painter->save();
    00515         painter->setPen(Qt::NoPen);
    00516         painter->setBrush(colorGroup().brush(QColorGroup::Foreground));
    00517
    00518         painter->setClipRegion(
    00519             QRegion(painter->xForm(insideScaleRect), QRegion::Ellipse));
    00520         painter->drawRect(insideScaleRect);
    00521         painter->restore();
    00522     }
    00523
    00524     const QPoint center = insideScaleRect.center();
    00525     const int radius = insideScaleRect.width() / 2;
    00526
    00527     painter->save();
    00528     drawScaleContents(painter, center, radius);
    00529     painter->restore();
    00530
    00531     double direction = d_origin;
    00532
    00533     if (isValid())
    00534     {
    00535         direction = d_origin + d_minScaleArc;
    00536         if ( maxValue() > minValue() && d_maxScaleArc > d_minScaleArc )
    00537         {
    00538             const double ratio =
    00539                 (value() - minValue()) / (maxValue() - minValue());
    00540             direction += ratio * (d_maxScaleArc - d_minScaleArc);
    00541         }
    00542
    00543         if ( direction >= 360.0 )
    00544             direction -= 360.0;
    00545     }
    00546
    00547     double origin = d_origin;
    00548     if ( mode() == RotateScale )
    00549     {
    00550         origin -= direction - d_origin;
    00551         direction = d_origin;
    00552     }
    00553
    00554     painter->save();
    00555     drawScale(painter, center, radius, origin, d_minScaleArc, d_maxScaleArc);
    00556     painter->restore();
    00557
    00558     if ( isValid() )
    00559     {
    00560         QPalette::ColorGroup cg;
    00561         if ( isEnabled() )
    00562             cg = hasFocus() ? QPalette::Active : QPalette::Inactive;
    00563         else
    00564             cg = QPalette::Disabled;
    00565
    00566         painter->save();
    00567         drawNeedle(painter, center, radius, direction, cg);
    00568         painter->restore();
    00569     }
    00570 }
    00571
    00584 void QwtDial::drawNeedle(QPainter *painter, const QPoint &center,
    00585     int radius, double direction, QPalette::ColorGroup cg) const
    00586 {
    00587     if ( d_needle )
    00588     {
    00589         direction = 360.0 - direction; // counter clockwise
    00590         d_needle->draw(painter, center, radius, direction, cg);
    00591     }
    00592 }
    00593
    00606 void QwtDial::drawScale(QPainter *painter, const QPoint &center,
    00607     int radius, double origin, double minArc, double maxArc) const
    00608 {
    00609     if ( d_scaleDraw == NULL )
    00610         return;
    00611
    00612     origin -= 270.0; // hardcoded origin of QwtScaleDraw
    00613
    00614     double angle = maxArc - minArc;
    00615     if ( angle > 360.0 )
    00616         angle = fmod(angle, 360.0);
    00617
    00618     minArc += origin;
    00619     if ( minArc < -360.0 )
    00620         minArc = fmod(minArc, 360.0);
    00621
    00622     maxArc = minArc + angle;
    00623     if ( maxArc > 360.0 )
    00624     {
    00625         // QwtScaleDraw::setAngleRange accepts only values
    00626         // in the range [-360.0..360.0]
    00627         minArc -= 360.0;
    00628         maxArc -= 360.0;
    00629     }
    00630
    00631     painter->setFont(font());
    00632     painter->setPen(QPen(colorGroup().text(), d_scaleDraw->penWidth()));
    00633
    00634     d_scaleDraw->setAngleRange(minArc, maxArc);
    00635     d_scaleDraw->setGeometry(
    00636         center.x() - radius + 1,
    00637         center.y() - radius + 1,
    00638         2 * radius, QwtScaleDraw::Round);
    00639
    00640     d_scaleDraw->draw(painter);
    00641 }
    00642
    00643 void QwtDial::drawScaleContents(QPainter *,
    00644     const QPoint &, int) const
    00645 {
    00646     // empty default implementation
    00647 }
    00648
    00659 void QwtDial::setNeedle(QwtDialNeedle *needle)
    00660 {
    00661     if ( needle != d_needle )
    00662     {
    00663         if ( d_needle )
    00664             delete d_needle;
    00665
    00666         d_needle = needle;
    00667         update();
    00668     }
    00669 }
    00670
    00675 const QwtDialNeedle *QwtDial::needle() const
    00676 {
    00677     return d_needle;
    00678 }
    00679
    00684 QwtDialNeedle *QwtDial::needle()
    00685 {
    00686     return d_needle;
    00687 }
    00688
    00690 void QwtDial::rangeChange()
    00691 {
    00692     updateScale();
    00693 }
    00694
    00699 void QwtDial::updateScale()
    00700 {
    00701     if ( d_scaleDraw )
    00702     {
    00703         d_scaleDraw->setScale(minValue(), maxValue(),
    00704             d_maxMajIntv, d_maxMinIntv, d_scaleStep);
    00705     }
    00706 }
    00707
    00713 void QwtDial::setScaleDraw(QwtDialScaleDraw *scaleDraw)
    00714 {
    00715     if ( scaleDraw != d_scaleDraw )
    00716     {
    00717         if ( d_scaleDraw )
    00718             delete d_scaleDraw;
    00719
    00720         d_scaleDraw = scaleDraw;
    00721         updateScale();
    00722         update();
    00723     }
    00724 }
    00725
    00730 void QwtDial::setScale(int maxMajIntv, int maxMinIntv, double step)
    00731 {
    00732     d_maxMajIntv = maxMajIntv;
    00733     d_maxMinIntv = maxMinIntv;
    00734     d_scaleStep = step;
    00735
    00736     updateScale();
    00737 }
    00738
    00754 void QwtDial::setScaleOptions(int options)
    00755 {
    00756     if ( options == 0 )
    00757         setScaleDraw(NULL);
    00758
    00759     if ( d_scaleDraw == NULL )
    00760         return;
    00761
    00762     int flags = d_scaleDraw->options();
    00763     if ( options & ScaleBackbone )
    00764         flags |= QwtScaleDraw::Backbone;
    00765     else
    00766         flags &= ~QwtScaleDraw::Backbone;
    00767     d_scaleDraw->setOptions(flags);
    00768
    00769     if ( !(options & ScaleTicks) )
    00770         d_scaleDraw->setTickLength(0, 0, 0);
    00771
    00772     d_scaleDraw->showLabels(options & ScaleLabel);
    00773 }
    00774
    00776 void QwtDial::setScaleTicks(int minLen, int medLen,
    00777     int majLen, int penWidth)
    00778 {
    00779     if ( d_scaleDraw )
    00780     {
    00781         d_scaleDraw->setTickLength(minLen, medLen, majLen);
    00782         d_scaleDraw->setPenWidth(penWidth);
    00783     }
    00784 }
    00785
    00789 QString QwtDial::scaleLabel(double value) const
    00790 {
    00791 #if 1
    00792     if ( value == -0 )
    00793         value = 0;
    00794 #endif
    00795
    00796     QString text;
    00797     text.sprintf("%g", value);
    00798
    00799     return text;
    00800 }
    00801
    00810 void QwtDial::setOrigin(double origin)
    00811 {
    00812     d_origin = origin;
    00813     update();
    00814 }
    00815
    00822 double QwtDial::origin() const
    00823 {
    00824     return d_origin;
    00825 }
    00826
    00833 void QwtDial::setScaleArc(double minArc, double maxArc)
    00834 {
    00835     if ( minArc != 360.0 && minArc != -360.0 )
    00836         minArc = fmod(minArc, 360.0);
    00837     if ( maxArc != 360.0 && maxArc != -360.0 )
    00838         maxArc = fmod(maxArc, 360.0);
    00839
    00840     d_minScaleArc = QMIN(minArc, maxArc);
    00841     d_maxScaleArc = QMAX(minArc, maxArc);
    00842     if ( d_maxScaleArc - d_minScaleArc > 360.0 )
    00843         d_maxScaleArc = d_minScaleArc + 360.0;
    00844
    00845     update();
    00846 }
    00847
    00849 void QwtDial::valueChange()
    00850 {
    00851     update();
    00852     QwtSliderBase::valueChange();
    00853 }
    00854
    00858 QSize QwtDial::sizeHint() const
    00859 {
    00860     int sh = 0;
    00861     if ( d_scaleDraw )
    00862         sh = d_scaleDraw->minHeight( QPen(), fontMetrics() );
    00863
    00864     const int d = 6 * sh + 2 * lineWidth();
    00865
    00866     return QSize( d, d );
    00867 }
    00868
    00874 QSize QwtDial::minimumSizeHint() const
    00875 {
    00876     int sh = 0;
    00877     if ( d_scaleDraw )
    00878         sh = d_scaleDraw->minHeight( QPen(), fontMetrics() );
    00879
    00880     const int d = 3 * sh + 2 * lineWidth();
    00881
    00882     return QSize( d, d );
    00883 }
    00884
    00885 static double line2Radians(const QPoint &p1, const QPoint &p2)
    00886 {
    00887     const QPoint p = p2 - p1;
    00888
    00889     double angle;
    00890     if ( p.x() == 0 )
    00891         angle = ( p.y() <= 0 ) ? M_PI_2 : 3 * M_PI_2;
    00892     else
    00893     {
    00894         angle = atan(double(-p.y()) / double(p.x()));
    00895         if ( p.x() < 0 )
    00896             angle += M_PI;
    00897         if ( angle < 0.0 )
    00898             angle += 2 * M_PI;
    00899     }
    00900     return 360.0 - angle * 180.0 / M_PI;
    00901 }
    00902
    00909 double QwtDial::getValue(const QPoint &pos)
    00910 {
    00911     if ( d_maxScaleArc == d_minScaleArc || maxValue() == minValue() )
    00912         return minValue();
    00913
    00914     double dir = line2Radians(rect().center(), pos) - d_origin;
    00915     if ( dir < 0.0 )
    00916         dir += 360.0;
    00917
    00918     if ( mode() == RotateScale )
    00919         dir = 360.0 - dir;
    00920
    00921     // The position might be in the area that is outside the scale arc.
    00922     // We need the range of the scale if it was a complete circle.
    00923
    00924     const double completeCircle = 360.0 / (d_maxScaleArc - d_minScaleArc)
    00925         * (maxValue() - minValue());
    00926
    00927     double posValue = minValue() + completeCircle * dir / 360.0;
    00928
    00929     if ( d_scrollMode == ScrMouse )
    00930     {
    00931         if ( d_previousDir >= 0.0 ) // valid direction
    00932         {
    00933             // We have to find out whether the mouse is moving
    00934             // clock or counter clockwise
    00935
    00936             bool clockWise = FALSE;
    00937
    00938             const double angle = dir - d_previousDir;
    00939             if ( (angle >= 0.0 && angle <= 180.0) || angle < -180.0 )
    00940                 clockWise = TRUE;
    00941
    00942             if ( clockWise )
    00943             {
    00944                 if ( dir < d_previousDir && d_mouseOffset > 0.0 )
    00945                 {
    00946                     // We passed 360 -> 0
    00947                     d_mouseOffset -= completeCircle;
    00948                 }
    00949
    00950                 if ( wrapping() )
    00951                 {
    00952                     if ( posValue - d_mouseOffset > maxValue() )
    00953                     {
    00954                         // We passed maxValue and the value will be set
    00955                         // to minValue. We have to adjust the d_mouseOffset.
    00956
    00957                         d_mouseOffset = posValue - minValue();
    00958                     }
    00959                 }
    00960                 else
    00961                 {
    00962                     if ( posValue - d_mouseOffset > maxValue() ||
    00963                         value() == maxValue() )
    00964                     {
    00965                         // We fix the value at maxValue by adjusting
    00966                         // the mouse offset.
    00967
    00968                         d_mouseOffset = posValue - maxValue();
    00969                     }
    00970                 }
    00971             }
    00972             else
    00973             {
    00974                 if ( dir > d_previousDir && d_mouseOffset < 0.0 )
    00975                 {
    00976                     // We passed 0 -> 360
    00977                     d_mouseOffset += completeCircle;
    00978                 }
    00979
    00980                 if ( wrapping() )
    00981                 {
    00982                     if ( posValue - d_mouseOffset < minValue() )
    00983                     {
    00984                         // We passed minValue and the value will be set
    00985                         // to maxValue. We have to adjust the d_mouseOffset.
    00986
    00987                         d_mouseOffset = posValue - maxValue();
    00988                     }
    00989                 }
    00990                 else
    00991                 {
    00992                     if ( posValue - d_mouseOffset < minValue() ||
    00993                         value() == minValue() )
    00994                     {
    00995                         // We fix the value at minValue by adjusting
    00996                         // the mouse offset.
    00997
    00998                         d_mouseOffset = posValue - minValue();
    00999                     }
    01000                 }
    01001             }
    01002         }
    01003         d_previousDir = dir;
    01004     }
    01005
    01006     return posValue;
    01007 }
    01008
    01012 void QwtDial::getScrollMode(const QPoint &p, int &scrollMode, int &direction)
    01013 {
    01014     direction = 0;
    01015     scrollMode = ScrNone;
    01016
    01017     const QRegion region(contentsRect(), QRegion::Ellipse);
    01018     if ( region.contains(p) && p != rect().center() )
    01019     {
    01020         scrollMode = ScrMouse;
    01021         d_previousDir = -1.0;
    01022     }
    01023 }
    01024
    01044 void QwtDial::keyPressEvent(QKeyEvent *e)
    01045 {
    01046     if ( isReadOnly() )
    01047     {
    01048 #if QT_VERSION >= 300
    01049         e->ignore();
    01050 #endif
    01051         return;
    01052     }
    01053
    01054     if ( !isValid() )
    01055         return;
    01056
    01057     double previous = prevValue();
    01058     switch ( e->key() )
    01059     {
    01060         case Qt::Key_Down:
    01061         case Qt::Key_Left:
    01062             QwtDblRange::incValue(-1);
    01063             break;
    01064         case Qt::Key_Prior:
    01065             QwtDblRange::incValue(-pageSize());
    01066             break;
    01067         case Qt::Key_Home:
    01068             setValue(minValue());
    01069             break;
    01070
    01071         case Qt::Key_Up:
    01072         case Qt::Key_Right:
    01073             QwtDblRange::incValue(1);
    01074             break;
    01075         case Qt::Key_Next:
    01076             QwtDblRange::incValue(pageSize());
    01077             break;
    01078         case Qt::Key_End:
    01079             setValue(maxValue());
    01080             break;
    01081         default:;
    01082 #if QT_VERSION >= 300
    01083             e->ignore();
    01084 #endif
    01085     }
    01086
    01087     if (value() != previous)
    01088         emit sliderMoved(value());
    01089 }
    01090