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_polygon.h"
00016 #include "qwt_dial_needle.h"
00017
00018 #if QT_VERSION < 0x040000
00019 typedef QColorGroup QwtPalette;
00020 #else
00021 typedef QPalette QwtPalette;
00022 #endif
00023
00025 QwtDialNeedle::QwtDialNeedle():
00026 d_palette(QApplication::palette())
00027 {
00028 }
00029
00031 QwtDialNeedle::~QwtDialNeedle()
00032 {
00033 }
00034
00040 void QwtDialNeedle::setPalette(const QPalette &palette)
00041 {
00042 d_palette = palette;
00043 }
00044
00048 const QPalette &QwtDialNeedle::palette() const
00049 {
00050 return d_palette;
00051 }
00052
00054 void QwtDialNeedle::drawKnob(QPainter *painter,
00055 const QPoint &pos, int width, const QBrush &brush, bool sunken)
00056 {
00057 painter->save();
00058
00059 QRect rect(0, 0, width, width);
00060 rect.moveCenter(pos);
00061
00062 painter->setPen(Qt::NoPen);
00063 painter->setBrush(brush);
00064 painter->drawEllipse(rect);
00065
00066 painter->setBrush(Qt::NoBrush);
00067
00068 const int colorOffset = 20;
00069
00070 int startAngle = 45;
00071 if ( sunken )
00072 startAngle += 180;
00073
00074 QPen pen;
00075 pen.setWidth(1);
00076
00077 pen.setColor(brush.color().dark(100 - colorOffset));
00078 painter->setPen(pen);
00079 painter->drawArc(rect, startAngle * 16, 180 * 16);
00080
00081 pen.setColor(brush.color().dark(100 + colorOffset));
00082 painter->setPen(pen);
00083 painter->drawArc(rect, (startAngle + 180) * 16, 180 * 16);
00084
00085 painter->restore();
00086 }
00087
00096 QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob,
00097 const QColor &mid, const QColor &base):
00098 d_style(style),
00099 d_hasKnob(hasKnob),
00100 d_width(-1)
00101 {
00102 QPalette palette;
00103 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00104 {
00105 palette.setColor((QPalette::ColorGroup)i,
00106 QwtPalette::Mid, mid);
00107 palette.setColor((QPalette::ColorGroup)i,
00108 QwtPalette::Base, base);
00109 }
00110
00111 setPalette(palette);
00112 }
00113
00119 void QwtDialSimpleNeedle::setWidth(int width)
00120 {
00121 d_width = width;
00122 }
00123
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 colorGroup) const
00144 {
00145 if ( d_style == Arrow )
00146 {
00147 drawArrowNeedle(painter, palette(), colorGroup,
00148 center, length, d_width, direction, d_hasKnob);
00149 }
00150 else
00151 {
00152 drawRayNeedle(painter, palette(), colorGroup,
00153 center, length, d_width, direction, d_hasKnob);
00154 }
00155 }
00156
00169 void QwtDialSimpleNeedle::drawRayNeedle(QPainter *painter,
00170 const QPalette &palette, QPalette::ColorGroup colorGroup,
00171 const QPoint ¢er, int length, int width, double direction,
00172 bool hasKnob)
00173 {
00174 if ( width <= 0 )
00175 width = 5;
00176
00177 direction *= M_PI / 180.0;
00178
00179 painter->save();
00180
00181 const QPoint p1(center.x() + 1, center.y() + 2);
00182 const QPoint p2 = qwtPolar2Pos(p1, length, direction);
00183
00184 if ( width == 1 )
00185 {
00186 const QColor midColor =
00187 palette.color(colorGroup, QwtPalette::Mid);
00188
00189 painter->setPen(QPen(midColor, 1));
00190 painter->drawLine(p1, p2);
00191 }
00192 else
00193 {
00194 QwtPolygon pa(4);
00195 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00196 pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
00197 pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
00198 pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00199
00200 painter->setPen(Qt::NoPen);
00201 painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00202 painter->drawPolygon(pa);
00203 }
00204 if ( hasKnob )
00205 {
00206 int knobWidth = qwtMax(qRound(width * 0.7), 5);
00207 if ( knobWidth % 2 == 0 )
00208 knobWidth++;
00209
00210 drawKnob(painter, center, knobWidth,
00211 palette.brush(colorGroup, QwtPalette::Base),
00212 false);
00213 }
00214
00215 painter->restore();
00216 }
00217
00230 void QwtDialSimpleNeedle::drawArrowNeedle(QPainter *painter,
00231 const QPalette &palette, QPalette::ColorGroup colorGroup,
00232 const QPoint ¢er, int length, int width,
00233 double direction, bool hasKnob)
00234 {
00235 direction *= M_PI / 180.0;
00236
00237 painter->save();
00238
00239 if ( width <= 0 )
00240 {
00241 width = (int)qwtMax(length * 0.06, 9.0);
00242 if ( width % 2 == 0 )
00243 width++;
00244 }
00245
00246 const int peak = 3;
00247 const QPoint p1(center.x() + 1, center.y() + 1);
00248 const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
00249 const QPoint p3 = qwtPolar2Pos(p1, length, direction);
00250
00251 QwtPolygon pa(5);
00252 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00253 pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
00254 pa.setPoint(2, p3);
00255 pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
00256 pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00257
00258 painter->setPen(Qt::NoPen);
00259 painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00260 painter->drawPolygon(pa);
00261
00262 QwtPolygon shadowPa(3);
00263
00264 const int colorOffset = 10;
00265
00266 int i;
00267 for ( i = 0; i < 3; i++ )
00268 shadowPa.setPoint(i, pa[i]);
00269
00270 const QColor midColor = palette.color(colorGroup, QwtPalette::Mid);
00271
00272 painter->setPen(midColor.dark(100 + colorOffset));
00273 painter->drawPolyline(shadowPa);
00274
00275 for ( i = 0; i < 3; i++ )
00276 shadowPa.setPoint(i, pa[i + 2]);
00277
00278 painter->setPen(midColor.dark(100 - colorOffset));
00279 painter->drawPolyline(shadowPa);
00280
00281 if ( hasKnob )
00282 {
00283 drawKnob(painter, center, qRound(width * 1.3),
00284 palette.brush(colorGroup, QwtPalette::Base),
00285 false);
00286 }
00287
00288 painter->restore();
00289 }
00290
00292
00293 QwtCompassMagnetNeedle::QwtCompassMagnetNeedle(Style style,
00294 const QColor &light, const QColor &dark):
00295 d_style(style)
00296 {
00297 QPalette palette;
00298 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00299 {
00300 palette.setColor((QPalette::ColorGroup)i,
00301 QwtPalette::Light, light);
00302 palette.setColor((QPalette::ColorGroup)i,
00303 QwtPalette::Dark, dark);
00304 palette.setColor((QPalette::ColorGroup)i,
00305 QwtPalette::Base, Qt::darkGray);
00306 }
00307
00308 setPalette(palette);
00309 }
00310
00320 void QwtCompassMagnetNeedle::draw(QPainter *painter, const QPoint ¢er,
00321 int length, double direction, QPalette::ColorGroup colorGroup) const
00322 {
00323 if ( d_style == ThinStyle )
00324 {
00325 drawThinNeedle(painter, palette(), colorGroup,
00326 center, length, direction);
00327 }
00328 else
00329 {
00330 drawTriangleNeedle(painter, palette(), colorGroup,
00331 center, length, direction);
00332 }
00333 }
00334
00345 void QwtCompassMagnetNeedle::drawTriangleNeedle(QPainter *painter,
00346 const QPalette &palette, QPalette::ColorGroup colorGroup,
00347 const QPoint ¢er, int length, double direction)
00348 {
00349 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00350 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00351
00352 QBrush brush;
00353
00354 const int width = qRound(length / 3.0);
00355 const int colorOffset = 10;
00356
00357 painter->save();
00358 painter->setPen(Qt::NoPen);
00359
00360 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00361
00362 QwtPolygon pa(3);
00363 pa.setPoint(0, arrowCenter);
00364 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
00365
00366 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00367
00368 brush = darkBrush;
00369 brush.setColor(brush.color().dark(100 + colorOffset));
00370 painter->setBrush(brush);
00371 painter->drawPolygon(pa);
00372
00373 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00374
00375 brush = darkBrush;
00376 brush.setColor(brush.color().dark(100 - colorOffset));
00377 painter->setBrush(brush);
00378 painter->drawPolygon(pa);
00379
00380
00381
00382 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
00383
00384 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00385
00386 brush = lightBrush;
00387 brush.setColor(brush.color().dark(100 + colorOffset));
00388 painter->setBrush(brush);
00389 painter->drawPolygon(pa);
00390
00391 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00392
00393 brush = lightBrush;
00394 brush.setColor(brush.color().dark(100 - colorOffset));
00395 painter->setBrush(brush);
00396 painter->drawPolygon(pa);
00397
00398 painter->restore();
00399 }
00400
00411 void QwtCompassMagnetNeedle::drawThinNeedle(QPainter *painter,
00412 const QPalette &palette, QPalette::ColorGroup colorGroup,
00413 const QPoint ¢er, int length, double direction)
00414 {
00415 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00416 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00417 const QBrush baseBrush = palette.brush(colorGroup, QwtPalette::Base);
00418
00419 const int colorOffset = 10;
00420 const int width = qwtMax(qRound(length / 6.0), 3);
00421
00422 painter->save();
00423
00424 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00425
00426 drawPointer(painter, darkBrush, colorOffset,
00427 arrowCenter, length, width, direction);
00428 drawPointer(painter, lightBrush, -colorOffset,
00429 arrowCenter, length, width, direction + 180.0);
00430
00431 drawKnob(painter, arrowCenter, width, baseBrush, true);
00432
00433 painter->restore();
00434 }
00435
00447 void QwtCompassMagnetNeedle::drawPointer(
00448 QPainter *painter, const QBrush &brush,
00449 int colorOffset, const QPoint ¢er, int length,
00450 int width, double direction)
00451 {
00452 painter->save();
00453
00454 const int peak = qwtMax(qRound(length / 10.0), 5);
00455
00456 const int knobWidth = width + 8;
00457 QRect knobRect(0, 0, knobWidth, knobWidth);
00458 knobRect.moveCenter(center);
00459
00460 QwtPolygon pa(5);
00461
00462 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
00463 pa.setPoint(1, center);
00464 pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
00465 pa.setPoint(3, qwtDegree2Pos(center, length, direction));
00466 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00467
00468 painter->setPen(Qt::NoPen);
00469
00470 QBrush darkBrush = brush;
00471 darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
00472 painter->setBrush(darkBrush);
00473 painter->drawPolygon(pa);
00474 painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
00475
00476 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
00477 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00478
00479 QBrush lightBrush = brush;
00480 lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
00481 painter->setBrush(lightBrush);
00482 painter->drawPolygon(pa);
00483 painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
00484
00485 painter->restore();
00486 }
00487
00495 QwtCompassWindArrow::QwtCompassWindArrow(Style style,
00496 const QColor &light, const QColor &dark):
00497 d_style(style)
00498 {
00499 QPalette palette;
00500 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00501 {
00502 palette.setColor((QPalette::ColorGroup)i,
00503 QwtPalette::Light, light);
00504 palette.setColor((QPalette::ColorGroup)i,
00505 QwtPalette::Dark, dark);
00506 }
00507
00508 setPalette(palette);
00509 }
00510
00520 void QwtCompassWindArrow::draw(QPainter *painter, const QPoint ¢er,
00521 int length, double direction, QPalette::ColorGroup colorGroup) const
00522 {
00523 if ( d_style == Style1 )
00524 {
00525 drawStyle1Needle(painter, palette(), colorGroup,
00526 center, length, direction);
00527 }
00528 else
00529 {
00530 drawStyle2Needle(painter, palette(), colorGroup,
00531 center, length, direction);
00532 }
00533 }
00534
00545 void QwtCompassWindArrow::drawStyle1Needle(QPainter *painter,
00546 const QPalette &palette, QPalette::ColorGroup colorGroup,
00547 const QPoint ¢er, int length, double direction)
00548 {
00549 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00550
00551 const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
00552 const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
00553
00554 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00555
00556 QwtPolygon pa(8);
00557 pa.setPoint(0, arrowCenter);
00558 for (int i=1; i<8; i++)
00559 {
00560 const QPoint p = qwtDegree2Pos(center,
00561 AR1[i] * length, direction + AW1[i]);
00562 pa.setPoint(i, p);
00563 }
00564
00565 painter->save();
00566 painter->setPen(Qt::NoPen);
00567 painter->setBrush(lightBrush);
00568 painter->drawPolygon(pa);
00569 painter->restore();
00570 }
00571
00582 void QwtCompassWindArrow::drawStyle2Needle(QPainter *painter,
00583 const QPalette &palette, QPalette::ColorGroup colorGroup,
00584 const QPoint ¢er, int length, double direction)
00585 {
00586 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00587 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00588
00589 painter->save();
00590 painter->setPen(Qt::NoPen);
00591
00592 const double angle = 12.0;
00593 const double ratio = 0.7;
00594
00595 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00596
00597 QwtPolygon pa(3);
00598
00599 pa.setPoint(0, center);
00600 pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
00601
00602 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
00603 painter->setBrush(darkBrush);
00604 painter->drawPolygon(pa);
00605
00606 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
00607 painter->setBrush(lightBrush);
00608 painter->drawPolygon(pa);
00609
00610 painter->restore();
00611 }
00612