Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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 ¢er )
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 );
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() );
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 }