00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <math.h>
00011 #include <qapplication.h>
00012 #include <qpainter.h>
00013 #include "qwt_math.h"
00014 #include "qwt_painter.h"
00015 #include "qwt_dial_needle.h"
00016
00018 QwtDialNeedle::QwtDialNeedle():
00019 d_palette(QApplication::palette())
00020 {
00021 }
00022
00024 QwtDialNeedle::~QwtDialNeedle()
00025 {
00026 }
00027
00033 void QwtDialNeedle::setPalette(const QPalette &palette)
00034 {
00035 d_palette = palette;
00036 }
00037
00041 const QPalette &QwtDialNeedle::palette() const
00042 {
00043 return d_palette;
00044 }
00045
00047 void QwtDialNeedle::drawKnob(QPainter *painter,
00048 const QPoint &pos, int width, const QBrush &brush, bool sunken)
00049 {
00050 painter->save();
00051
00052 QRect rect(0, 0, width, width);
00053 rect.moveCenter(pos);
00054
00055 painter->setPen(Qt::NoPen);
00056 painter->setBrush(brush);
00057 painter->drawEllipse(rect);
00058
00059 painter->setBrush(Qt::NoBrush);
00060
00061 const int colorOffset = 20;
00062
00063 int startAngle = 45;
00064 if ( sunken )
00065 startAngle += 180;
00066
00067 QPen pen;
00068 pen.setWidth(1);
00069
00070 pen.setColor(brush.color().dark(100 - colorOffset));
00071 painter->setPen(pen);
00072 painter->drawArc(rect, startAngle * 16, 180 * 16);
00073
00074 pen.setColor(brush.color().dark(100 + colorOffset));
00075 painter->setPen(pen);
00076 painter->drawArc(rect, (startAngle + 180) * 16, 180 * 16);
00077
00078 painter->restore();
00079 }
00080
00085 const QColorGroup &QwtDialNeedle::colorGroup(QPalette::ColorGroup cg) const
00086 {
00087 switch(cg)
00088 {
00089 case QPalette::Disabled:
00090 return d_palette.disabled();
00091 case QPalette::Inactive:
00092 return d_palette.inactive();
00093 default:
00094 return d_palette.active();
00095 }
00096 }
00097
00101 QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob,
00102 const QColor &mid, const QColor &base):
00103 d_style(style),
00104 d_hasKnob(hasKnob),
00105 d_width(-1)
00106 {
00107 QPalette palette;
00108 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00109 {
00110 palette.setColor((QPalette::ColorGroup)i,
00111 QColorGroup::Mid, mid);
00112 palette.setColor((QPalette::ColorGroup)i,
00113 QColorGroup::Base, base);
00114 }
00115
00116 setPalette(palette);
00117 }
00118
00120 void QwtDialSimpleNeedle::setWidth(int width)
00121 {
00122 d_width = width;
00123 }
00124
00128 int QwtDialSimpleNeedle::width() const
00129 {
00130 return d_width;
00131 }
00132
00142 void QwtDialSimpleNeedle::draw(QPainter *painter, const QPoint ¢er,
00143 int length, double direction, QPalette::ColorGroup cg) const
00144 {
00145 if ( d_style == Arrow )
00146 {
00147 drawArrowNeedle(painter, colorGroup(cg),
00148 center, length, d_width, direction, d_hasKnob);
00149 }
00150 else
00151 {
00152 drawRayNeedle(painter, colorGroup(cg), center, length, d_width,
00153 direction, d_hasKnob);
00154 }
00155 }
00156
00160 void QwtDialSimpleNeedle::drawRayNeedle(
00161 QPainter *painter, const QColorGroup &cg,
00162 const QPoint ¢er, int length, int width, double direction,
00163 bool hasKnob)
00164 {
00165 if ( width <= 0 )
00166 width = 5;
00167
00168 direction *= M_PI / 180.0;
00169
00170 painter->save();
00171
00172 const QPoint p1(center.x() + 1, center.y() + 2);
00173 const QPoint p2 = qwtPolar2Pos(p1, length, direction);
00174
00175 if ( width == 1 )
00176 {
00177 painter->setPen(QPen(cg.mid(), 1));
00178 painter->drawLine(p1, p2);
00179 }
00180 else
00181 {
00182 QPointArray pa(4);
00183 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00184 pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
00185 pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
00186 pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00187
00188 painter->setPen(Qt::NoPen);
00189 painter->setBrush(cg.brush(QColorGroup::Mid));
00190 painter->drawPolygon(pa);
00191 }
00192 if ( hasKnob )
00193 {
00194 int knobWidth = QMAX(qRound(width * 0.7), 5);
00195 if ( knobWidth % 2 == 0 )
00196 knobWidth++;
00197
00198 drawKnob(painter, center, knobWidth,
00199 cg.brush(QColorGroup::Base), FALSE);
00200 }
00201
00202 painter->restore();
00203 }
00204
00208 void QwtDialSimpleNeedle::drawArrowNeedle(
00209 QPainter *painter, const QColorGroup &cg,
00210 const QPoint ¢er, int length, int width,
00211 double direction, bool hasKnob)
00212 {
00213 direction *= M_PI / 180.0;
00214
00215 painter->save();
00216
00217 if ( width <= 0 )
00218 {
00219 width = (int)QMAX(length * 0.06, 9);
00220 if ( width % 2 == 0 )
00221 width++;
00222 }
00223
00224 const int peak = 3;
00225 const QPoint p1(center.x() + 1, center.y() + 1);
00226 const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
00227 const QPoint p3 = qwtPolar2Pos(p1, length, direction);
00228
00229 QPointArray pa(5);
00230 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00231 pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
00232 pa.setPoint(2, p3);
00233 pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
00234 pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00235
00236 painter->setPen(Qt::NoPen);
00237 painter->setBrush(cg.brush(QColorGroup::Mid));
00238 painter->drawPolygon(pa);
00239
00240 QPointArray shadowPa(3);
00241
00242 const int colorOffset = 10;
00243
00244 int i;
00245 for ( i = 0; i < 3; i++ )
00246 shadowPa.setPoint(i, pa[i]);
00247
00248 painter->setPen(cg.mid().dark(100 + colorOffset));
00249 painter->drawPolyline(shadowPa);
00250
00251 for ( i = 0; i < 3; i++ )
00252 shadowPa.setPoint(i, pa[i + 2]);
00253
00254 painter->setPen(cg.mid().dark(100 - colorOffset));
00255 painter->drawPolyline(shadowPa);
00256
00257 if ( hasKnob )
00258 {
00259 drawKnob(painter, center, qRound(width * 1.3),
00260 cg.brush(QColorGroup::Base), FALSE);
00261 }
00262
00263 painter->restore();
00264 }
00265
00267
00268 QwtCompassMagnetNeedle::QwtCompassMagnetNeedle(Style style,
00269 const QColor &light, const QColor &dark):
00270 d_style(style)
00271 {
00272 QPalette palette;
00273 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00274 {
00275 palette.setColor((QPalette::ColorGroup)i,
00276 QColorGroup::Light, light);
00277 palette.setColor((QPalette::ColorGroup)i,
00278 QColorGroup::Dark, dark);
00279 palette.setColor((QPalette::ColorGroup)i,
00280 QColorGroup::Base, Qt::darkGray);
00281 }
00282
00283 setPalette(palette);
00284 }
00285
00295 void QwtCompassMagnetNeedle::draw(QPainter *painter, const QPoint ¢er,
00296 int length, double direction, QPalette::ColorGroup cg) const
00297 {
00298 if ( d_style == ThinStyle )
00299 {
00300 drawThinNeedle(painter, colorGroup(cg),
00301 center, length, direction);
00302 }
00303 else
00304 {
00305 drawTriangleNeedle(painter, colorGroup(cg),
00306 center, length, direction);
00307 }
00308 }
00309
00313 void QwtCompassMagnetNeedle::drawTriangleNeedle(
00314 QPainter *painter, const QColorGroup &cg,
00315 const QPoint ¢er, int length, double direction)
00316 {
00317 QBrush brush;
00318
00319 const int width = qRound(length / 3.0);
00320 const int colorOffset = 10;
00321
00322 painter->save();
00323 painter->setPen(Qt::NoPen);
00324
00325 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00326
00327 QPointArray pa(3);
00328 pa.setPoint(0, arrowCenter);
00329 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
00330
00331 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00332
00333 brush = cg.brush(QColorGroup::Dark);
00334 brush.setColor(brush.color().dark(100 + colorOffset));
00335 painter->setBrush(brush);
00336 painter->drawPolygon(pa);
00337
00338 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00339
00340 brush = cg.brush(QColorGroup::Dark);
00341 brush.setColor(brush.color().dark(100 - colorOffset));
00342 painter->setBrush(brush);
00343 painter->drawPolygon(pa);
00344
00345
00346
00347 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
00348
00349 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00350
00351 brush = cg.brush(QColorGroup::Light);
00352 brush.setColor(brush.color().dark(100 + colorOffset));
00353 painter->setBrush(brush);
00354 painter->drawPolygon(pa);
00355
00356 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00357
00358 brush = cg.brush(QColorGroup::Light);
00359 brush.setColor(brush.color().dark(100 - colorOffset));
00360 painter->setBrush(brush);
00361 painter->drawPolygon(pa);
00362
00363 painter->restore();
00364 }
00365
00369 void QwtCompassMagnetNeedle::drawThinNeedle(
00370 QPainter *painter, const QColorGroup &cg,
00371 const QPoint ¢er, int length, double direction)
00372 {
00373 const int colorOffset = 10;
00374 const int width = QMAX(qRound(length / 6.0), 3);
00375
00376 painter->save();
00377
00378 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00379
00380 drawPointer(painter, cg.brush(QColorGroup::Dark), colorOffset,
00381 arrowCenter, length, width, direction);
00382 drawPointer(painter, cg.brush(QColorGroup::Light), -colorOffset,
00383 arrowCenter, length, width, direction + 180.0);
00384
00385 drawKnob(painter, arrowCenter, width,
00386 cg.brush(QColorGroup::Base), TRUE);
00387
00388 painter->restore();
00389 }
00390
00394 void QwtCompassMagnetNeedle::drawPointer(
00395 QPainter *painter, const QBrush &brush,
00396 int colorOffset, const QPoint ¢er, int length,
00397 int width, double direction)
00398 {
00399 painter->save();
00400
00401 const int peak = QMAX(qRound(length / 10.0), 5);
00402
00403 const int knobWidth = width + 8;
00404 QRect knobRect(0, 0, knobWidth, knobWidth);
00405 knobRect.moveCenter(center);
00406
00407 QPointArray pa(5);
00408
00409 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
00410 pa.setPoint(1, center);
00411 pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
00412 pa.setPoint(3, qwtDegree2Pos(center, length, direction));
00413 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00414
00415 painter->setPen(Qt::NoPen);
00416
00417 QBrush darkBrush = brush;
00418 darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
00419 painter->setBrush(darkBrush);
00420 painter->drawPolygon(pa);
00421 painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
00422
00423 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
00424 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00425
00426 QBrush lightBrush = brush;
00427 lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
00428 painter->setBrush(lightBrush);
00429 painter->drawPolygon(pa);
00430 painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
00431
00432 painter->restore();
00433 }
00434
00436
00437 QwtCompassWindArrow::QwtCompassWindArrow(Style style,
00438 const QColor &light, const QColor &dark):
00439 d_style(style)
00440 {
00441 QPalette palette;
00442 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00443 {
00444 palette.setColor((QPalette::ColorGroup)i,
00445 QColorGroup::Light, light);
00446 palette.setColor((QPalette::ColorGroup)i,
00447 QColorGroup::Dark, dark);
00448 }
00449
00450 setPalette(palette);
00451 }
00452
00462 void QwtCompassWindArrow::draw(QPainter *painter, const QPoint ¢er,
00463 int length, double direction, QPalette::ColorGroup cg) const
00464 {
00465 if ( d_style == Style1 )
00466 {
00467 drawStyle1Needle(painter, colorGroup(cg),
00468 center, length, direction);
00469 }
00470 else
00471 {
00472 drawStyle2Needle(painter, colorGroup(cg),
00473 center, length, direction);
00474 }
00475 }
00476
00480 void QwtCompassWindArrow::drawStyle1Needle(
00481 QPainter *painter, const QColorGroup &cg,
00482 const QPoint ¢er, int length, double direction)
00483 {
00484 const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
00485 const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
00486
00487 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00488
00489 QPointArray pa(8);
00490 pa.setPoint(0, arrowCenter);
00491 for (int i=1; i<8; i++)
00492 {
00493 const QPoint p = qwtDegree2Pos(center,
00494 AR1[i] * length, direction + AW1[i]);
00495 pa.setPoint(i, p);
00496 }
00497
00498 painter->save();
00499 painter->setPen(Qt::NoPen);
00500 painter->setBrush(cg.brush(QColorGroup::Light));
00501 painter->drawPolygon(pa);
00502 painter->restore();
00503 }
00504
00508 void QwtCompassWindArrow::drawStyle2Needle(
00509 QPainter *painter, const QColorGroup &cg,
00510 const QPoint ¢er, int length, double direction)
00511 {
00512 painter->save();
00513 painter->setPen(Qt::NoPen);
00514
00515 const double angle = 12.0;
00516 const double ratio = 0.7;
00517
00518 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00519
00520 QPointArray pa(3);
00521
00522 pa.setPoint(0, center);
00523 pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
00524
00525 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
00526 painter->setBrush(cg.brush(QColorGroup::Dark));
00527 painter->drawPolygon(pa);
00528
00529 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
00530 painter->setBrush(cg.brush(QColorGroup::Light));
00531 painter->drawPolygon(pa);
00532
00533 painter->restore();
00534 }
00535