Пример #1
0
/*!
  \brief Draw the marker at the knob's front

  \param painter Painter
  \param rect Bounding rectangle of the knob without scale
  \param angle Angle of the marker in degrees
               ( clockwise, 0 at the 12 o'clock position )
*/
void QwtKnob::drawMarker( QPainter *painter,
    const QRectF &rect, double angle ) const
{
    if ( d_data->markerStyle == NoMarker || !isValid() )
        return;

    const double radians = qwtRadians( angle );
    const double sinA = -qFastSin( radians );
    const double cosA = qFastCos( radians );

    const double xm = rect.center().x();
    const double ym = rect.center().y();
    const double margin = 4.0;

    double radius = 0.5 * ( rect.width() - d_data->borderWidth ) - margin;
    if ( radius < 1.0 )
        radius = 1.0;

    int markerSize = d_data->markerSize;
    if ( markerSize <= 0 )
        markerSize = qRound( 0.4 * radius );

    switch ( d_data->markerStyle )
    {
        case Notch:
        case Nub:
        {
            const double dotWidth =
                qMin( double( markerSize ), radius);

            const double dotCenterDist = radius - 0.5 * dotWidth;
            if ( dotCenterDist > 0.0 )
            {
                const QPointF center( xm - sinA * dotCenterDist,
                    ym - cosA * dotCenterDist );

                QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth );
                ellipse.moveCenter( center );

                QColor c1 = palette().color( QPalette::Light );
                QColor c2 = palette().color( QPalette::Mid );

                if ( d_data->markerStyle == Notch )
                    qSwap( c1, c2 );

                QLinearGradient gradient(
                    ellipse.topLeft(), ellipse.bottomRight() );
                gradient.setColorAt( 0.0, c1 );
                gradient.setColorAt( 1.0, c2 );

                painter->setPen( Qt::NoPen );
                painter->setBrush( gradient );

                painter->drawEllipse( ellipse );
            }
            break;
        }
        case Dot:
        {
            const double dotWidth =
                qMin( double( markerSize ), radius);

            const double dotCenterDist = radius - 0.5 * dotWidth;
            if ( dotCenterDist > 0.0 )
            {
                const QPointF center( xm - sinA * dotCenterDist,
                    ym - cosA * dotCenterDist );

                QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth );
                ellipse.moveCenter( center );

                painter->setPen( Qt::NoPen );
                painter->setBrush( palette().color( QPalette::ButtonText ) );
                painter->drawEllipse( ellipse );
            }

            break;
        }
        case Tick:
        {
            const double rb = qMax( radius - markerSize, 1.0 );
            const double re = radius;

            const QLineF line( xm - sinA * rb, ym - cosA * rb,
                xm - sinA * re, ym - cosA * re );

            QPen pen( palette().color( QPalette::ButtonText ), 0 );
            pen.setCapStyle( Qt::FlatCap );
            painter->setPen( pen );
            painter->drawLine ( line );

            break;
        }
        case Triangle:
        {
            const double rb = qMax( radius - markerSize, 1.0 );
            const double re = radius;

            painter->translate( rect.center() );
            painter->rotate( angle - 90.0 );

            QPolygonF polygon;
            polygon += QPointF( re, 0.0 );
            polygon += QPointF( rb, 0.5 * ( re - rb ) );
            polygon += QPointF( rb, -0.5 * ( re - rb ) );

            painter->setPen( Qt::NoPen );
            painter->setBrush( palette().color( QPalette::ButtonText ) );
            painter->drawPolygon( polygon );

            painter->resetTransform();

            break;
        }
        default:
            break;
    }
}
Пример #2
0
int QwtScaleDraw::minLabelDist( const QFont &font ) const
{
    if ( !hasComponent( QwtAbstractScaleDraw::Labels ) )
        return 0;

    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
    if ( ticks.isEmpty() )
        return 0;

    const QFontMetrics fm( font );

    const bool vertical = ( orientation() == Qt::Vertical );

    QRectF bRect1;
    QRectF bRect2 = labelRect( font, ticks[0] );
    if ( vertical )
    {
        bRect2.setRect( -bRect2.bottom(), 0.0, bRect2.height(), bRect2.width() );
    }

    double maxDist = 0.0;

    for ( int i = 1; i < ticks.count(); i++ )
    {
        bRect1 = bRect2;
        bRect2 = labelRect( font, ticks[i] );
        if ( vertical )
        {
            bRect2.setRect( -bRect2.bottom(), 0.0,
                            bRect2.height(), bRect2.width() );
        }

        double dist = fm.leading(); // space between the labels
        if ( bRect1.right() > 0 )
            dist += bRect1.right();
        if ( bRect2.left() < 0 )
            dist += -bRect2.left();

        if ( dist > maxDist )
            maxDist = dist;
    }

    double angle = qwtRadians( labelRotation() );
    if ( vertical )
        angle += M_PI / 2;

    const double sinA = qFastSin( angle ); // qreal -> double
    if ( qFuzzyCompare( sinA + 1.0, 1.0 ) )
        return qCeil( maxDist );

    const int fmHeight = fm.ascent() - 2;

    // The distance we need until there is
    // the height of the label font. This height is needed
    // for the neighbored label.

    double labelDist = fmHeight / qFastSin( angle ) * qFastCos( angle );
    if ( labelDist < 0 )
        labelDist = -labelDist;

    // For text orientations close to the scale orientation

    if ( labelDist > maxDist )
        labelDist = maxDist;

    // For text orientations close to the opposite of the
    // scale orientation

    if ( labelDist < fmHeight )
        labelDist = fmHeight;

    return qCeil( labelDist );
}
Пример #3
0
/*!
   Draw the rose

   \param painter Painter
   \param palette Palette
   \param center Center of the rose
   \param radius Radius of the rose
   \param north Position pointing to north
   \param width Width of the rose
   \param numThorns Number of thorns
   \param numThornLevels Number of thorn levels
   \param shrinkFactor Factor to shrink the thorns with each level
*/
void QwtSimpleCompassRose::drawRose(
    QPainter *painter,
    const QPalette &palette,
    const QPointF &center, double radius, double north, double width,
    int numThorns, int numThornLevels, double shrinkFactor )
{
    if ( numThorns < 4 )
        numThorns = 4;

    if ( numThorns % 4 )
        numThorns += 4 - numThorns % 4;

    if ( numThornLevels <= 0 )
        numThornLevels = numThorns / 4;

    if ( shrinkFactor >= 1.0 )
        shrinkFactor = 1.0;

    if ( shrinkFactor <= 0.5 )
        shrinkFactor = 0.5;

    painter->save();

    painter->setPen( Qt::NoPen );

    for ( int j = 1; j <= numThornLevels; j++ )
    {
        double step =  qPow( 2.0, j ) * M_PI / numThorns;
        if ( step > M_PI_2 )
            break;

        double r = radius;
        for ( int k = 0; k < 3; k++ )
        {
            if ( j + k < numThornLevels )
                r *= shrinkFactor;
        }

        double leafWidth = r * width;
        if ( 2.0 * M_PI / step > 32 )
            leafWidth = 16;

        const double origin = qwtRadians( north );
        for ( double angle = origin;
            angle < 2.0 * M_PI + origin; angle += step )
        {
            const QPointF p = qwtPolar2Pos( center, r, angle );
            const QPointF p1 = qwtPolar2Pos( center, leafWidth, angle + M_PI_2 );
            const QPointF p2 = qwtPolar2Pos( center, leafWidth, angle - M_PI_2 );
            const QPointF p3 = qwtPolar2Pos( center, r, angle + step / 2.0 );
            const QPointF p4 = qwtPolar2Pos( center, r, angle - step / 2.0 );

            QPainterPath darkPath;
            darkPath.moveTo( center );
            darkPath.lineTo( p );
            darkPath.lineTo( qwtIntersection( center, p3, p1, p ) );

            painter->setBrush( palette.brush( QPalette::Dark ) );
            painter->drawPath( darkPath );

            QPainterPath lightPath;
            lightPath.moveTo( center );
            lightPath.lineTo( p );
            lightPath.lineTo( qwtIntersection( center, p4, p2, p ) );

            painter->setBrush( palette.brush( QPalette::Light ) );
            painter->drawPath( lightPath );
        }
    }
    painter->restore();
}
Пример #4
0
/*!
   Draw the Wheel's ticks

   \param painter Painter
   \param rect Geometry for the wheel
*/
void QwtWheel::drawTicks( QPainter *painter, const QRectF &rect )
{
    const double range = d_data->maximum - d_data->minimum;

    if ( range == 0.0 || d_data->totalAngle == 0.0 )
    {
        return;
    }

    const QPen lightPen( palette().color( QPalette::Light ),
        0, Qt::SolidLine, Qt::FlatCap );
    const QPen darkPen( palette().color( QPalette::Dark ),
        0, Qt::SolidLine, Qt::FlatCap );

    const double cnvFactor = qAbs( d_data->totalAngle / range );
    const double halfIntv = 0.5 * d_data->viewAngle / cnvFactor;
    const double loValue = value() - halfIntv;
    const double hiValue = value() + halfIntv;
    const double tickWidth = 360.0 / double( d_data->tickCount ) / cnvFactor;
    const double sinArc = qFastSin( d_data->viewAngle * M_PI / 360.0 );

    if ( d_data->orientation == Qt::Horizontal )
    {
        const double radius = rect.width() * 0.5;

        double l1 = rect.top() + d_data->wheelBorderWidth;
        double l2 = rect.bottom() - d_data->wheelBorderWidth - 1;

        // draw one point over the border if border > 1
        if ( d_data->wheelBorderWidth > 1 )
        {
            l1--;
            l2++;
        }

        const double maxpos = rect.right() - 2;
        const double minpos = rect.left() + 2;

        // draw tick marks
        for ( double tickValue = ::ceil( loValue / tickWidth ) * tickWidth;
            tickValue < hiValue; tickValue += tickWidth )
        {
            const double angle = qwtRadians( tickValue - value() );
            const double s = qFastSin( angle * cnvFactor );

            const double off = radius * ( sinArc + s ) / sinArc;

            double tickPos;
            if ( d_data->inverted )
                tickPos = rect.left() + off;
            else
                tickPos = rect.right() - off;

            if ( ( tickPos <= maxpos ) && ( tickPos > minpos ) )
            {
                painter->setPen( darkPen );
                painter->drawLine( QPointF( tickPos - 1 , l1 ),
                    QPointF( tickPos - 1,  l2 ) );
                painter->setPen( lightPen );
                painter->drawLine( QPointF( tickPos, l1 ),
                    QPointF( tickPos, l2 ) );
            }
        }
    }
    else // Qt::Vertical
    {
        const double radius = rect.height() * 0.5;

        double l1 = rect.left() + d_data->wheelBorderWidth;
        double l2 = rect.right() - d_data->wheelBorderWidth - 1;

        if ( d_data->wheelBorderWidth > 1 )
        {
            l1--;
            l2++;
        }

        const double maxpos = rect.bottom() - 2;
        const double minpos = rect.top() + 2;

        for ( double tickValue = ::ceil( loValue / tickWidth ) * tickWidth;
            tickValue < hiValue; tickValue += tickWidth )
        {
            const double angle = qwtRadians( tickValue - value() );
            const double s = qFastSin( angle * cnvFactor );

            const double off = radius * ( sinArc + s ) / sinArc;

            double tickPos;

            if ( d_data->inverted )
                tickPos = rect.bottom() - off;
            else
                tickPos = rect.top() + off;

            if ( ( tickPos <= maxpos ) && ( tickPos > minpos ) )
            {
                painter->setPen( darkPen );
                painter->drawLine( QPointF( l1, tickPos - 1 ),
                    QPointF( l2, tickPos - 1 ) );
                painter->setPen( lightPen );
                painter->drawLine( QPointF( l1, tickPos ),
                    QPointF( l2, tickPos ) );
            }
        }
    }
}