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

📄 qwt_wheel.cpp

📁 软件无线电的平台
💻 CPP
字号:
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** * Qwt Widget Library * Copyright (C) 1997   Josef Wilgen * Copyright (C) 2002   Uwe Rathmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the Qwt License, Version 1.0 *****************************************************************************/#include <qdrawutil.h>#include <qpixmap.h>#include <qpainter.h>#include <qstyle.h>#include "qwt_math.h"#include "qwt_paint_buffer.h"#include "qwt_wheel.h"//! ConstructorQwtWheel::QwtWheel(QWidget *parent, const char *name):     QwtSliderBase(Qt::Horizontal, parent, name, WRepaintNoErase|WResizeNoErase ){    d_viewAngle = 175.0;    d_totalAngle = 360.0;    d_tickCnt = 10;    d_intBorder = 2;    d_borderWidth = 2;    d_colorCnt = 30;    d_wheelWidth = 20;    d_allocContext = 0;    d_colors = new QColor[d_colorCnt];    setUpdateTime(50);}//! DestructorQwtWheel::~QwtWheel()  {    if ( d_allocContext )        QColor::destroyAllocContext( d_allocContext );    delete[] d_colors;}//! Set up the color array for the background pixmap.void QwtWheel::setColorArray(){    if ( !d_colors )         return;    QColorGroup g = colorGroup();    if ( !d_colors[0].isValid() ||        d_colors[0] != g.light() ||        d_colors[d_colorCnt - 1] != g.dark() )    {        if ( d_allocContext )            QColor::destroyAllocContext( d_allocContext );        d_allocContext = QColor::enterAllocContext();        d_colors[0] = g.light();        d_colors[d_colorCnt - 1] = g.dark();        int dh, ds, dv, lh, ls, lv;        d_colors[0].rgb(&lh, &ls, &lv);        d_colors[d_colorCnt - 1].rgb(&dh, &ds, &dv);        for ( int i = 1; i < d_colorCnt - 1; ++i )        {            const double factor = double(i) / double(d_colorCnt);            d_colors[i].setRgb( lh + int( double(dh - lh) * factor ),                      ls + int( double(ds - ls) * factor ),                      lv + int( double(dv - lv) * factor ));        }        QColor::leaveAllocContext();    }}/*!  \brief Adjust the number of grooves in the wheel's surface.  The number of grooves is limited to 6 <= cnt <= 50.  Values outside this range will be clipped.  The default value is 10.  \param cnt Number of grooves per 360 degrees*/void QwtWheel::setTickCnt(int cnt){    d_tickCnt = qwtLim( cnt, 6, 50 );    update();}/*!    \return mass*/double QwtWheel::mass() const{    return QwtSliderBase::mass();}/*!  \brief Set the internal border width of the wheel.  The internal border must not be smaller than 1  and is limited in dependence on the wheel's size.  Values outside the allowed range will be clipped.  The internal border defaults to 2.  \param w border width*/void QwtWheel::setInternalBorder( int w ){    const int d = qwtMin( width(), height() ) / 3;    w = qwtMin( w, d );    d_intBorder = qwtMax( w, 1 );    layoutWheel();}//! Draw the Wheel's background gradientvoid QwtWheel::drawWheelBackground( QPainter *p, const QRect &r ){    p->save();    //    // initialize pens    //    const QColorGroup g = colorGroup();    QPen lightPen;    lightPen.setColor(g.light());    lightPen.setWidth(d_intBorder);    QPen darkPen;    darkPen.setColor(g.dark());    darkPen.setWidth(d_intBorder);    setColorArray();    //    // initialize auxiliary variables    //    const int nFields = d_colorCnt * 13 / 10;    const int hiPos = nFields - d_colorCnt + 1;    if ( orientation() == Qt::Horizontal )    {        const int rx = r.x();        int ry = r.y() + d_intBorder;        const int rh = r.height() - 2* d_intBorder;        const int rw = r.width();        //        //  draw shaded background        //        int x1 = rx;        for (int i = 1; i < nFields; i++ )        {            const int x2 = rx + (rw * i) / nFields;            p->fillRect(x1, ry, x2-x1 + 1 ,rh, d_colors[qwtAbs(i-hiPos)]);            x1 = x2 + 1;        }        p->fillRect(x1, ry, rw - (x1 - rx), rh, d_colors[d_colorCnt - 1]);        //        // draw internal border        //        p->setPen(lightPen);        ry = r.y() + d_intBorder / 2;        p->drawLine(r.x(), ry, r.x() + r.width() , ry);        p->setPen(darkPen);        ry = r.y() + r.height() - (d_intBorder - d_intBorder / 2);        p->drawLine(r.x(), ry , r.x() + r.width(), ry);    }    else // Qt::Vertical    {        int rx = r.x() + d_intBorder;        const int ry = r.y();        const int rh = r.height();        const int rw = r.width() - 2 * d_intBorder;        //        // draw shaded background        //        int y1 = ry;        for ( int i = 1; i < nFields; i++ )        {            const int y2 = ry + (rh * i) / nFields;            p->fillRect(rx, y1, rw, y2-y1 + 1, d_colors[qwtAbs(i-hiPos)]);            y1 = y2 + 1;        }        p->fillRect(rx, y1, rw, rh - (y1 - ry), d_colors[d_colorCnt - 1]);        //        //  draw internal borders        //        p->setPen(lightPen);        rx = r.x() + d_intBorder / 2;        p->drawLine(rx, r.y(), rx, r.y() + r.height());        p->setPen(darkPen);        rx = r.x() + r.width() - (d_intBorder - d_intBorder / 2);        p->drawLine(rx, r.y(), rx , r.y() + r.height());    }    p->restore();}/*!  \brief Set the total angle which the wheel can be turned.  One full turn of the wheel corresponds to an angle of  360 degrees. A total angle of n*360 degrees means  that the wheel has to be turned n times around its axis  to get from the minimum value to the maximum value.  The default setting of the total angle is 360 degrees.  \param angle total angle in degrees*/void QwtWheel::setTotalAngle(double angle){    d_totalAngle = qwtLim( angle, 10.0, 3600.0 );    update();}/*!  \brief Set the wheel's orientation.  \param o Orientation. Allowed values are           Qt::Horizontal and Qt::Vertical.   Defaults to Qt::Horizontal.  \sa QwtSliderBase::orientation()*/void QwtWheel::setOrientation(Qt::Orientation o){    if ( orientation() != o )    {        QwtSliderBase::setOrientation(o);        layoutWheel();    }}/*!  \brief Specify the visible portion of the wheel.  You may use this function for fine-tuning the appearance of  the wheel. The default value is 175 degrees. The value is  limited from 10 to 175 degrees.  \param angle Visible angle in degrees*/void QwtWheel::setViewAngle(double angle){    d_viewAngle = qwtLim( angle, 10.0, 175.0 );    update();}/*!  \brief Redraw the wheel  \param p painter  \param r contents rectangle*/void QwtWheel::drawWheel( QPainter *p, const QRect &r ){    const double sign = (minValue() < maxValue()) ? 1.0 : -1.0;    double cnvFactor = qwtAbs(d_totalAngle / (maxValue() - minValue()));    const double halfIntv = 0.5 * d_viewAngle / cnvFactor;    const double loValue = value() - halfIntv;    const double hiValue = value() + halfIntv;    const double tickWidth = 360.0 / double(d_tickCnt) / cnvFactor;    const double sinArc = sin(d_viewAngle * M_PI / 360.0);    cnvFactor *= M_PI / 180.0;    //    // draw background gradient    //    drawWheelBackground( p, r );    //    // draw grooves    //    if ( orientation() == Qt::Horizontal )    {        const double halfSize = double(r.width()) * 0.5;        int l1 = r.y() + d_intBorder;        int l2 = r.y() + r.height() - d_intBorder - 1;        // draw one point over the border if border > 1        if ( d_intBorder > 1 )        {            l1 --;            l2 ++;        }        const int maxpos = r.x() + r.width() - 2;        const int minpos = r.x() + 2;        //        // draw tick marks        //        for ( double tickValue = ceil(loValue / tickWidth) * tickWidth;            tickValue < hiValue; tickValue += tickWidth )        {            //            //  calculate position            //            const int tickPos = r.x() + r.width()                - int( halfSize                    * (sinArc + sign *  sin((tickValue - value()) * cnvFactor))                    / sinArc);            //            // draw vertical line            //            if ( (tickPos <= maxpos) && (tickPos > minpos) )            {                p->setPen(colorGroup().dark());                p->drawLine(tickPos -1 , l1, tickPos - 1,  l2 );                  p->setPen(colorGroup().light());                p->drawLine(tickPos, l1, tickPos, l2);              }        }    }    else if ( orientation() == Qt::Vertical )    {        const double halfSize = double(r.height()) * 0.5;        int l1 = r.x() + d_intBorder;        int l2 = r.x() + r.width() - d_intBorder - 1;        if ( d_intBorder > 1 )        {            l1--;            l2++;        }        const int maxpos = r.y() + r.height() - 2;        const int minpos = r.y() + 2;        //        // draw tick marks        //        for ( double tickValue = ceil(loValue / tickWidth) * tickWidth;            tickValue < hiValue; tickValue += tickWidth )        {            //            // calculate position            //            const int tickPos = r.y() + int( halfSize *                (sinArc + sign * sin((tickValue - value()) * cnvFactor))                / sinArc);            //            //  draw horizontal line            //            if ( (tickPos <= maxpos) && (tickPos > minpos) )            {                p->setPen(colorGroup().dark());                p->drawLine(l1, tickPos - 1 ,l2, tickPos - 1);                  p->setPen(colorGroup().light());                p->drawLine(l1, tickPos, l2, tickPos);              }        }    }}//! Determine the value corresponding to a specified pointdouble QwtWheel::getValue( const QPoint &p ){    // The reference position is arbitrary, but the    // sign of the offset is important    int w, dx;    if ( orientation() == Qt::Vertical )    {        w = d_sliderRect.height();        dx = d_sliderRect.y() - p.y();    }    else    {        w = d_sliderRect.width();        dx = p.x() - d_sliderRect.x();    }    // w pixels is an arc of viewAngle degrees,    // so we convert change in pixels to change in angle    const double ang = dx * d_viewAngle / w;    // value range maps to totalAngle degrees,    // so convert the change in angle to a change in value    const double val = ang * ( maxValue() - minValue() ) / d_totalAngle;    // Note, range clamping and rasterizing to step is automatically    // handled by QwtSliderBase, so we simply return the change in value    return val;}//! Qt Resize Eventvoid QwtWheel::resizeEvent(QResizeEvent *){    layoutWheel( FALSE );}//! Recalculate the slider's geometry and layout based on//  the current rect and fonts.//  \param update_geometry  notify the layout system and call update//         to redraw the scalevoid QwtWheel::layoutWheel( bool update_geometry ){    const QRect r = this->rect();    d_sliderRect.setRect(r.x() + d_borderWidth, r.y() + d_borderWidth,        r.width() - 2*d_borderWidth, r.height() - 2*d_borderWidth);    if ( update_geometry )    {        updateGeometry();        update();    }}//! Qt Paint Eventvoid QwtWheel::paintEvent(QPaintEvent *e){    // Use double-buffering    const QRect &ur = e->rect();    if ( ur.isValid() )    {        QwtPaintBuffer paintBuffer(this, ur);        draw(paintBuffer.painter(), ur);    }}//! Redraw panel and wheelvoid QwtWheel::draw(QPainter *painter, const QRect&){    QColorGroup cg = colorGroup();    // Rather than maintain a separate color group    // for the outer frame, use our parent's cg    QWidget *parent = parentWidget();    if ( parent )        cg = parent->colorGroup();    qDrawShadePanel( painter, rect().x(), rect().y(),        rect().width(), rect().height(),        cg, TRUE, d_borderWidth );    drawWheel( painter, d_sliderRect );    if ( hasFocus() )    {        QRect r = rect();    #if QT_VERSION < 300        style().drawFocusRect(painter, r, colorGroup());#else        style().drawPrimitive(QStyle::PE_FocusRect, painter,            r, colorGroup());#endif    }}//! Notify value change void QwtWheel::valueChange(){    QwtSliderBase::valueChange();    update();}/*!  \brief Determine the scrolling mode and direction corresponding         to a specified point  \param p point  \param scrollMode scrolling mode  \param direction direction*/void QwtWheel::getScrollMode( const QPoint &p, int &scrollMode, int &direction){    if ( d_sliderRect.contains(p) )        scrollMode = ScrMouse;    else        scrollMode = ScrNone;    direction = 0;}/*!  \brief Set the mass of the wheel  Assigning a mass turns the wheel into a flywheel.  \param val the wheel's mass*/void QwtWheel::setMass(double val){    QwtSliderBase::setMass(val);}/*!  \brief Set the width of the wheel  Corresponds to the wheel height for horizontal orientation,  and the wheel width for vertical orientation.  \param w the wheel's width*/void QwtWheel::setWheelWidth(int w){    d_wheelWidth = w;    layoutWheel();}/*!  \return Preferred/Fixed for horizontal,          Fixed/Preferred for vertical scales.*/QSizePolicy QwtWheel::sizePolicy() const{    QSizePolicy sp;    if ( orientation() == Qt::Horizontal )    {        sp.setHorData( QSizePolicy::Preferred );        sp.setVerData( QSizePolicy::Fixed );    }    else    {        sp.setHorData( QSizePolicy::Fixed );        sp.setVerData( QSizePolicy::Preferred );    }    return sp;}/*!  \return a size hint*/QSize QwtWheel::sizeHint() const{    return minimumSizeHint();}/*!  \brief Return a minimum size hint  \warning The return value is based on the wheel width.*/QSize QwtWheel::minimumSizeHint() const{    QSize sz( 3*d_wheelWidth + 2*d_borderWidth,    d_wheelWidth + 2*d_borderWidth );    if ( orientation() != Qt::Horizontal )        sz.transpose();    return sz;}/*!  \brief Call update() when the palette changes*/void QwtWheel::paletteChange( const QPalette& ){    update();}

⌨️ 快捷键说明

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