⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwt_dial.cpp

📁 QWT5.01用于Qt开发的二维图形库程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:

/*!
  Set an individual scale draw

  \param scaleDraw Scale draw
  \warning The previous scale draw is deleted
*/
void QwtDial::setScaleDraw(QwtDialScaleDraw *scaleDraw)
{
    if ( scaleDraw != d_data->scaleDraw )
    {
        if ( d_data->scaleDraw )
            delete d_data->scaleDraw;
    
        d_data->scaleDraw = scaleDraw;
        updateScale();
        update();
    }
}

/*!
  Change the intervals of the scale
  \sa QwtAbstractScaleDraw::setScale
*/
void QwtDial::setScale(int maxMajIntv, int maxMinIntv, double step)
{
    d_data->maxMajIntv = maxMajIntv;
    d_data->maxMinIntv = maxMinIntv;
    d_data->scaleStep = step;

    updateScale();
}

/*!
  A wrapper method for accessing the scale draw. 

  - options == 0\n
    No visible scale: setScaleDraw(NULL)
  - options & ScaleBackbone\n
    En/disable the backbone of the scale.
  - options & ScaleTicks\n
    En/disable the ticks of the scale.
  - options & ScaleLabel\n
    En/disable scale labels
    
  \sa QwtAbstractScaleDraw::enableComponent 
*/
void QwtDial::setScaleOptions(int options)
{
    if ( options == 0 )
        setScaleDraw(NULL);

    QwtDialScaleDraw *sd = d_data->scaleDraw;
    if ( sd == NULL )
        return;

    sd->enableComponent(QwtAbstractScaleDraw::Backbone, 
        options & ScaleBackbone);

    sd->enableComponent(QwtAbstractScaleDraw::Ticks, 
        options & ScaleTicks);
    
    sd->enableComponent(QwtAbstractScaleDraw::Labels, 
        options & ScaleLabel);
}

//! See: QwtAbstractScaleDraw::setTickLength, QwtDialScaleDraw::setPenWidth
void QwtDial::setScaleTicks(int minLen, int medLen, 
    int majLen, int penWidth)
{
    QwtDialScaleDraw *sd = d_data->scaleDraw;
    if ( sd )
    {
        sd->setTickLength(QwtScaleDiv::MinorTick, minLen);
        sd->setTickLength(QwtScaleDiv::MediumTick, medLen);
        sd->setTickLength(QwtScaleDiv::MajorTick, majLen);
        sd->setPenWidth(penWidth);
    }
}

/*!
   Find the label for a value

   \param value Value
   \return label 
*/
QwtText QwtDial::scaleLabel(double value) const
{
#if 1
    if ( value == -0 )
        value = 0;
#endif

    return QString::number(value);
}

//! \return Lower limit of the scale arc
double QwtDial::minScaleArc() const 
{ 
    return d_data->minScaleArc; 
}

//! \return Upper limit of the scale arc
double QwtDial::maxScaleArc() const 
{ 
    return d_data->maxScaleArc; 
}

/*!
  \brief Change the origin 
 
  The origin is the angle where scale and needle is relative to.

  \param origin New origin
  \sa origin()
*/
void QwtDial::setOrigin(double origin)
{
    d_data->origin = origin;
    update();
}

/*!
  The origin is the angle where scale and needle is relative to.

  \return Origin of the dial
  \sa setOrigin()
*/
double QwtDial::origin() const
{
    return d_data->origin;
}

/*!
  Change the arc of the scale

  \param minArc Lower limit
  \param maxArc Upper limit
*/
void QwtDial::setScaleArc(double minArc, double maxArc)
{
    if ( minArc != 360.0 && minArc != -360.0 )
        minArc = fmod(minArc, 360.0);
    if ( maxArc != 360.0 && maxArc != -360.0 )
        maxArc = fmod(maxArc, 360.0);

    d_data->minScaleArc = qwtMin(minArc, maxArc);
    d_data->maxScaleArc = qwtMax(minArc, maxArc);
    if ( d_data->maxScaleArc - d_data->minScaleArc > 360.0 )
        d_data->maxScaleArc = d_data->minScaleArc + 360.0;
    
    update();
}

//! QwtDoubleRange update hook
void QwtDial::valueChange()
{
    update();
    QwtAbstractSlider::valueChange();
}

/*!
  \return Size hint
*/
QSize QwtDial::sizeHint() const
{
    int sh = 0;
    if ( d_data->scaleDraw )
        sh = d_data->scaleDraw->extent( QPen(), font() );

    const int d = 6 * sh + 2 * lineWidth();
    
    return QSize( d, d );
}

/*! 
  \brief Return a minimum size hint
  \warning The return value of QwtDial::minimumSizeHint() depends on the
           font and the scale.
*/  
QSize QwtDial::minimumSizeHint() const
{   
    int sh = 0;
    if ( d_data->scaleDraw )
        sh = d_data->scaleDraw->extent(QPen(), font() );

    const int d = 3 * sh + 2 * lineWidth();
    
    return QSize( d, d );
}

static double line2Radians(const QPoint &p1, const QPoint &p2)
{
    const QPoint p = p2 - p1;

    double angle;
    if ( p.x() == 0 )
        angle = ( p.y() <= 0 ) ? M_PI_2 : 3 * M_PI_2;
    else
    {
        angle = atan(double(-p.y()) / double(p.x()));
        if ( p.x() < 0 )
            angle += M_PI;
        if ( angle < 0.0 )
            angle += 2 * M_PI;
    }
    return 360.0 - angle * 180.0 / M_PI;
}

/*!
  Find the value for a given position

  \param pos Position
  \return Value
*/
double QwtDial::getValue(const QPoint &pos)
{
    if ( d_data->maxScaleArc == d_data->minScaleArc || maxValue() == minValue() )
        return minValue();

    double dir = line2Radians(rect().center(), pos) - d_data->origin;
    if ( dir < 0.0 )
        dir += 360.0;

    if ( mode() == RotateScale )
        dir = 360.0 - dir;

    // The position might be in the area that is outside the scale arc.
    // We need the range of the scale if it was a complete circle.

    const double completeCircle = 360.0 / (d_data->maxScaleArc - d_data->minScaleArc) 
        * (maxValue() - minValue());

    double posValue = minValue() + completeCircle * dir / 360.0;

    if ( scrollMode() == ScrMouse )
    {
        if ( d_data->previousDir >= 0.0 ) // valid direction
        {
            // We have to find out whether the mouse is moving
            // clock or counter clockwise

            bool clockWise = false;

            const double angle = dir - d_data->previousDir;
            if ( (angle >= 0.0 && angle <= 180.0) || angle < -180.0 )
                clockWise = true;

            if ( clockWise )
            {
                if ( dir < d_data->previousDir && mouseOffset() > 0.0 )
                {
                    // We passed 360 -> 0
                    setMouseOffset(mouseOffset() - completeCircle);
                }

                if ( wrapping() )
                {
                    if ( posValue - mouseOffset() > maxValue() )
                    {
                        // We passed maxValue and the value will be set
                        // to minValue. We have to adjust the mouseOffset.

                        setMouseOffset(posValue - minValue());
                    }
                }
                else
                {
                    if ( posValue - mouseOffset() > maxValue() ||
                        value() == maxValue() )
                    {
                        // We fix the value at maxValue by adjusting
                        // the mouse offset.

                        setMouseOffset(posValue - maxValue());
                    }
                }
            }
            else
            {
                if ( dir > d_data->previousDir && mouseOffset() < 0.0 )
                {
                    // We passed 0 -> 360 
                    setMouseOffset(mouseOffset() + completeCircle);    
                }

                if ( wrapping() )
                {
                    if ( posValue - mouseOffset() < minValue() )
                    {
                        // We passed minValue and the value will be set
                        // to maxValue. We have to adjust the mouseOffset.

                        setMouseOffset(posValue - maxValue());
                    }
                }
                else
                {
                    if ( posValue - mouseOffset() < minValue() ||
                        value() == minValue() )
                    {
                        // We fix the value at minValue by adjusting
                        // the mouse offset.

                        setMouseOffset(posValue - minValue());
                    }
                }
            }
        }
        d_data->previousDir = dir;
    }

    return posValue;
}

/*!
  \sa QwtAbstractSlider::getScrollMode
*/
void QwtDial::getScrollMode(const QPoint &p, int &scrollMode, int &direction)
{
    direction = 0;
    scrollMode = ScrNone;

    const QRegion region(contentsRect(), QRegion::Ellipse);
    if ( region.contains(p) && p != rect().center() )
    {
        scrollMode = ScrMouse;
        d_data->previousDir = -1.0;
    }
}

/*! 
  Handles key events

  - Key_Down, KeyLeft\n
    Decrement by 1
  - Key_Prior\n
    Decrement by pageSize()
  - Key_Home\n
    Set the value to minValue()

  - Key_Up, KeyRight\n
    Increment by 1
  - Key_Next\n
    Increment by pageSize()
  - Key_End\n
    Set the value to maxValue()

  \sa isReadOnly()
*/
void QwtDial::keyPressEvent(QKeyEvent *e)
{
    if ( isReadOnly() )
    {
        e->ignore();
        return;
    }

    if ( !isValid() )
        return;

    double previous = prevValue();
    switch ( e->key() )
    {
        case Qt::Key_Down:
        case Qt::Key_Left:
            QwtDoubleRange::incValue(-1);
            break;
#if QT_VERSION < 0x040000
        case Qt::Key_Prior:
#else
        case Qt::Key_PageUp:
#endif
            QwtDoubleRange::incValue(-pageSize());
            break;
        case Qt::Key_Home:
            setValue(minValue());
            break;

        case Qt::Key_Up:
        case Qt::Key_Right:
            QwtDoubleRange::incValue(1);
            break;
#if QT_VERSION < 0x040000
        case Qt::Key_Next:
#else
        case Qt::Key_PageDown:
#endif
            QwtDoubleRange::incValue(pageSize());
            break;
        case Qt::Key_End:
            setValue(maxValue());
            break;
        default:;
            e->ignore();
    }

    if (value() != previous)
        emit sliderMoved(value());
}

/*!
   \brief Update the mask of the dial

   In case of "hasVisibleBackground() == false", the backgound is
   transparent by a mask.

   \sa showBackground(), hasVisibleBackground()
*/
void QwtDial::updateMask()
{
    if ( d_data->visibleBackground )
        clearMask();
    else
        setMask(QRegion(boundingRect(), QRegion::Ellipse));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -