Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <math.h>
00013 #include <qpen.h>
00014 #include <qpainter.h>
00015 #include <qfontmetrics.h>
00016 #include "qwt_painter.h"
00017 #include "qwt_scale_div.h"
00018 #include "qwt_scale_map.h"
00019 #include "qwt_round_scale_draw.h"
00020
00021 class QwtRoundScaleDraw::PrivateData
00022 {
00023 public:
00024 PrivateData():
00025 center(50, 50),
00026 radius(50),
00027 startAngle(-135 * 16),
00028 endAngle(135 * 16)
00029 {
00030 }
00031
00032 QPoint center;
00033 int radius;
00034
00035 int startAngle;
00036 int endAngle;
00037 };
00038
00046 QwtRoundScaleDraw::QwtRoundScaleDraw()
00047 {
00048 d_data = new QwtRoundScaleDraw::PrivateData;
00049
00050 setRadius(50);
00051 scaleMap().setPaintInterval(d_data->startAngle, d_data->endAngle);
00052 }
00053
00055 QwtRoundScaleDraw::QwtRoundScaleDraw(const QwtRoundScaleDraw &other):
00056 QwtAbstractScaleDraw(other)
00057 {
00058 d_data = new QwtRoundScaleDraw::PrivateData(*other.d_data);
00059 }
00060
00061
00063 QwtRoundScaleDraw::~QwtRoundScaleDraw()
00064 {
00065 delete d_data;
00066 }
00067
00069 QwtRoundScaleDraw &QwtRoundScaleDraw::operator=(const QwtRoundScaleDraw &other)
00070 {
00071 *(QwtAbstractScaleDraw*)this = (const QwtAbstractScaleDraw &)other;
00072 *d_data = *other.d_data;
00073 return *this;
00074 }
00075
00084 void QwtRoundScaleDraw::setRadius(int radius)
00085 {
00086 d_data->radius = radius;
00087 }
00088
00096 int QwtRoundScaleDraw::radius() const
00097 {
00098 return d_data->radius;
00099 }
00100
00107 void QwtRoundScaleDraw::moveCenter(const QPoint ¢er)
00108 {
00109 d_data->center = center;
00110 }
00111
00113 QPoint QwtRoundScaleDraw::center() const
00114 {
00115 return d_data->center;
00116 }
00117
00135 void QwtRoundScaleDraw::setAngleRange(double angle1, double angle2)
00136 {
00137 angle1 = qwtLim(angle1, -360.0, 360.0);
00138 angle2 = qwtLim(angle2, -360.0, 360.0);
00139
00140 d_data->startAngle = qRound(angle1 * 16.0);
00141 d_data->endAngle = qRound(angle2 * 16.0);
00142
00143 if (d_data->startAngle == d_data->endAngle)
00144 {
00145 d_data->startAngle -= 1;
00146 d_data->endAngle += 1;
00147 }
00148
00149 scaleMap().setPaintInterval(d_data->startAngle, d_data->endAngle);
00150 }
00151
00160 void QwtRoundScaleDraw::drawLabel(QPainter *painter, double value) const
00161 {
00162 const QwtText label = tickLabel(painter->font(), value);
00163 if ( label.isEmpty() )
00164 return;
00165
00166 const int tval = map().transform(value);
00167 if ((tval > d_data->startAngle + 359 * 16)
00168 || (tval < d_data->startAngle - 359 * 16))
00169 {
00170 return;
00171 }
00172
00173 double radius = d_data->radius;
00174 if ( hasComponent(QwtAbstractScaleDraw::Ticks) ||
00175 hasComponent(QwtAbstractScaleDraw::Backbone) )
00176 {
00177 radius += spacing();
00178 }
00179
00180 if ( hasComponent(QwtAbstractScaleDraw::Ticks) )
00181 radius += majTickLength();
00182
00183 const QSize sz = label.textSize(painter->font());
00184 const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
00185
00186 const int x = d_data->center.x() +
00187 qRound((radius + sz.width() / 2.0) * sin(arc));
00188 const int y = d_data->center.y() -
00189 qRound( (radius + sz.height() / 2.0) * cos(arc));
00190
00191 const QRect r(x - sz.width() / 2, y - sz.height() / 2,
00192 sz.width(), sz.height() );
00193 label.draw(painter, r);
00194 }
00195
00205 void QwtRoundScaleDraw::drawTick(QPainter *painter, double value, int len) const
00206 {
00207 if ( len <= 0 )
00208 return;
00209
00210 const int tval = map().transform(value);
00211
00212 const int cx = d_data->center.x();
00213 const int cy = d_data->center.y();
00214 const int radius = d_data->radius;
00215
00216 if ((tval <= d_data->startAngle + 359 * 16)
00217 || (tval >= d_data->startAngle - 359 * 16))
00218 {
00219 const double arc = double(tval) / 16.0 * M_PI / 180.0;
00220
00221 const double sinArc = sin(arc);
00222 const double cosArc = cos(arc);
00223
00224 const int x1 = qRound( cx + radius * sinArc );
00225 const int x2 = qRound( cx + (radius + len) * sinArc );
00226 const int y1 = qRound( cy - radius * cosArc );
00227 const int y2 = qRound( cy - (radius + len) * cosArc );
00228
00229 QwtPainter::drawLine(painter, x1, y1, x2, y2);
00230 }
00231 }
00232
00239 void QwtRoundScaleDraw::drawBackbone(QPainter *painter) const
00240 {
00241 const int a1 = qRound(qwtMin(map().p1(), map().p2()) - 90 * 16);
00242 const int a2 = qRound(qwtMax(map().p1(), map().p2()) - 90 * 16);
00243
00244 const int radius = d_data->radius;
00245 const int x = d_data->center.x() - radius;
00246 const int y = d_data->center.y() - radius;
00247
00248 painter->drawArc(x, y, 2 * radius, 2 * radius,
00249 -a2, a2 - a1 + 1);
00250 }
00251
00267 int QwtRoundScaleDraw::extent(const QPen &pen, const QFont &font) const
00268 {
00269 int d = 0;
00270
00271 if ( hasComponent(QwtAbstractScaleDraw::Labels) )
00272 {
00273 const QwtScaleDiv &sd = scaleDiv();
00274 const QwtValueList &ticks = sd.ticks(QwtScaleDiv::MajorTick);
00275 for (uint i = 0; i < (uint)ticks.count(); i++)
00276 {
00277 const double value = ticks[i];
00278 if ( !sd.contains(value) )
00279 continue;
00280
00281 const QwtText label = tickLabel(font, value);
00282 if ( label.isEmpty() )
00283 continue;
00284
00285 const int tval = map().transform(value);
00286 if ((tval < d_data->startAngle + 360 * 16)
00287 && (tval > d_data->startAngle - 360 * 16))
00288 {
00289 const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
00290
00291 const QSize sz = label.textSize(font);
00292 const double off = qwtMax(sz.width(), sz.height());
00293
00294 double x = off * sin(arc);
00295 double y = off * cos(arc);
00296
00297 const int dist = (int)ceil(sqrt(x * x + y * y) + 1 );
00298 if ( dist > d )
00299 d = dist;
00300 }
00301 }
00302 }
00303
00304 if ( hasComponent(QwtAbstractScaleDraw::Ticks) )
00305 {
00306 d += majTickLength();
00307 }
00308
00309 if ( hasComponent(QwtAbstractScaleDraw::Backbone) )
00310 {
00311 const int pw = qwtMax( 1, pen.width() );
00312 d += pw;
00313 }
00314
00315 if ( hasComponent(QwtAbstractScaleDraw::Labels) &&
00316 ( hasComponent(QwtAbstractScaleDraw::Ticks) ||
00317 hasComponent(QwtAbstractScaleDraw::Backbone) ) )
00318 {
00319 d += spacing();
00320 }
00321
00322 d = qwtMax(d, minimumExtent());
00323
00324 return d;
00325 }