qwt_round_scale_draw.cpp
Go to the documentation of this file.
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 "qwt_round_scale_draw.h"
00011 #include "qwt_painter.h"
00012 #include "qwt_scale_div.h"
00013 #include "qwt_scale_map.h"
00014 #include "qwt_math.h"
00015 #include <qpen.h>
00016 #include <qpainter.h>
00017 #include <qfontmetrics.h>
00018 #include <qmath.h>
00019 
00020 class QwtRoundScaleDraw::PrivateData
00021 {
00022 public:
00023     PrivateData():
00024         center( 50.0, 50.0 ),
00025         radius( 50.0 ),
00026         startAngle( -135.0 ),
00027         endAngle( 135.0 )
00028     {
00029     }
00030 
00031     QPointF center;
00032     double radius;
00033 
00034     double startAngle;
00035     double endAngle;
00036 };
00037 
00045 QwtRoundScaleDraw::QwtRoundScaleDraw()
00046 {
00047     d_data = new QwtRoundScaleDraw::PrivateData;
00048 
00049     setRadius( 50 );
00050     scaleMap().setPaintInterval( d_data->startAngle, d_data->endAngle );
00051 }
00052 
00054 QwtRoundScaleDraw::~QwtRoundScaleDraw()
00055 {
00056     delete d_data;
00057 }
00058 
00067 void QwtRoundScaleDraw::setRadius( double radius )
00068 {
00069     d_data->radius = radius;
00070 }
00071 
00080 double QwtRoundScaleDraw::radius() const
00081 {
00082     return d_data->radius;
00083 }
00084 
00091 void QwtRoundScaleDraw::moveCenter( const QPointF &center )
00092 {
00093     d_data->center = center;
00094 }
00095 
00097 QPointF QwtRoundScaleDraw::center() const
00098 {
00099     return d_data->center;
00100 }
00101 
00119 void QwtRoundScaleDraw::setAngleRange( double angle1, double angle2 )
00120 {
00121 #if 0
00122     angle1 = qBound( -360.0, angle1, 360.0 );
00123     angle2 = qBound( -360.0, angle2, 360.0 );
00124 #endif
00125 
00126     d_data->startAngle = angle1;
00127     d_data->endAngle = angle2;
00128 
00129     if ( d_data->startAngle == d_data->endAngle )
00130     {
00131         d_data->startAngle -= 1;
00132         d_data->endAngle += 1;
00133     }
00134 
00135     scaleMap().setPaintInterval( d_data->startAngle, d_data->endAngle );
00136 }
00137 
00146 void QwtRoundScaleDraw::drawLabel( QPainter *painter, double value ) const
00147 {
00148     const double tval = scaleMap().transform( value );
00149     if ( ( tval >= d_data->startAngle + 360.0 )
00150         || ( tval <= d_data->startAngle - 360.0 ) )
00151     {
00152         return;
00153     }
00154 
00155     const QwtText label = tickLabel( painter->font(), value );
00156     if ( label.isEmpty() )
00157         return;
00158 
00159     double radius = d_data->radius;
00160     if ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
00161         hasComponent( QwtAbstractScaleDraw::Backbone ) )
00162     {
00163         radius += spacing();
00164     }
00165 
00166     if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
00167         radius += tickLength( QwtScaleDiv::MajorTick );
00168 
00169     const QSizeF sz = label.textSize( painter->font() );
00170     const double arc = qwtRadians( tval );
00171 
00172     const double x = d_data->center.x() +
00173         ( radius + sz.width() / 2.0 ) * qSin( arc );
00174     const double y = d_data->center.y() -
00175         ( radius + sz.height() / 2.0 ) * qCos( arc );
00176 
00177     const QRectF r( x - sz.width() / 2, y - sz.height() / 2,
00178         sz.width(), sz.height() );
00179     label.draw( painter, r );
00180 }
00181 
00191 void QwtRoundScaleDraw::drawTick( QPainter *painter, double value, double len ) const
00192 {
00193     if ( len <= 0 )
00194         return;
00195 
00196     const double tval = scaleMap().transform( value );
00197 
00198     const double cx = d_data->center.x();
00199     const double cy = d_data->center.y();
00200     const double radius = d_data->radius;
00201 
00202     if ( ( tval < d_data->startAngle + 360.0 )
00203         && ( tval > d_data->startAngle - 360.0 ) )
00204     {
00205         const double arc = qwtRadians( tval );
00206 
00207         const double sinArc = qSin( arc );
00208         const double cosArc = qCos( arc );
00209 
00210         const double x1 = cx + radius * sinArc;
00211         const double x2 = cx + ( radius + len ) * sinArc;
00212         const double y1 = cy - radius * cosArc;
00213         const double y2 = cy - ( radius + len ) * cosArc;
00214 
00215         QwtPainter::drawLine( painter, x1, y1, x2, y2 );
00216     }
00217 }
00218 
00225 void QwtRoundScaleDraw::drawBackbone( QPainter *painter ) const
00226 {
00227     const double deg1 = scaleMap().p1();
00228     const double deg2 = scaleMap().p2();
00229 
00230     const int a1 = qRound( qMin( deg1, deg2 ) - 90 );
00231     const int a2 = qRound( qMax( deg1, deg2 ) - 90 );
00232 
00233     const double radius = d_data->radius;
00234     const double x = d_data->center.x() - radius;
00235     const double y = d_data->center.y() - radius;
00236 
00237     painter->drawArc( QRectF( x, y, 2 * radius, 2 * radius ),
00238         -a2 * 16, ( a2 - a1 + 1 ) * 16 );          // counterclockwise
00239 }
00240 
00256 double QwtRoundScaleDraw::extent( const QFont &font ) const
00257 {
00258     double d = 0.0;
00259 
00260     if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
00261     {
00262         const QwtScaleDiv &sd = scaleDiv();
00263         const QList<double> &ticks = sd.ticks( QwtScaleDiv::MajorTick );
00264         for ( int i = 0; i < ticks.count(); i++ )
00265         {
00266             const double value = ticks[i];
00267             if ( !sd.contains( value ) )
00268                 continue;
00269 
00270             const double tval = scaleMap().transform( value );
00271             if ( ( tval < d_data->startAngle + 360 )
00272                 && ( tval > d_data->startAngle - 360 ) )
00273             {
00274                 const QwtText label = tickLabel( font, value );
00275                 if ( label.isEmpty() )
00276                     continue;
00277 
00278                 const double arc = qwtRadians( tval );
00279 
00280                 const QSizeF sz = label.textSize( font );
00281                 const double off = qMax( sz.width(), sz.height() );
00282 
00283                 double x = off * qSin( arc );
00284                 double y = off * qCos( arc );
00285 
00286                 const double dist = qSqrt( x * x + y * y );
00287                 if ( dist > d )
00288                     d = dist;
00289             }
00290         }
00291     }
00292 
00293     if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
00294     {
00295         d += maxTickLength();
00296     }
00297 
00298     if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
00299     {
00300         const double pw = qMax( 1, penWidth() );  // pen width can be zero
00301         d += pw;
00302     }
00303 
00304     if ( hasComponent( QwtAbstractScaleDraw::Labels ) &&
00305         ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
00306             hasComponent( QwtAbstractScaleDraw::Backbone ) ) )
00307     {
00308         d += spacing();
00309     }
00310 
00311     d = qMax( d, minimumExtent() );
00312 
00313     return d;
00314 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56