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
00017 #if QT_VERSION < 0x040000
00018 #include <qpointarray.h>
00019 #define QwtPointArray QPointArray
00020 typedef QColorGroup QwtPalette;
00021 #else
00022 #include <qpolygon.h>
00023 #define QwtPointArray QPolygon
00024 typedef QPalette QwtPalette;
00025 #endif
00026
00028 QwtDialNeedle::QwtDialNeedle():
00029 d_palette(QApplication::palette())
00030 {
00031 }
00032
00034 QwtDialNeedle::~QwtDialNeedle()
00035 {
00036 }
00037
00043 void QwtDialNeedle::setPalette(const QPalette &palette)
00044 {
00045 d_palette = palette;
00046 }
00047
00051 const QPalette &QwtDialNeedle::palette() const
00052 {
00053 return d_palette;
00054 }
00055
00057 void QwtDialNeedle::drawKnob(QPainter *painter,
00058 const QPoint &pos, int width, const QBrush &brush, bool sunken)
00059 {
00060 painter->save();
00061
00062 QRect rect(0, 0, width, width);
00063 rect.moveCenter(pos);
00064
00065 painter->setPen(Qt::NoPen);
00066 painter->setBrush(brush);
00067 painter->drawEllipse(rect);
00068
00069 painter->setBrush(Qt::NoBrush);
00070
00071 const int colorOffset = 20;
00072
00073 int startAngle = 45;
00074 if ( sunken )
00075 startAngle += 180;
00076
00077 QPen pen;
00078 pen.setWidth(1);
00079
00080 pen.setColor(brush.color().dark(100 - colorOffset));
00081 painter->setPen(pen);
00082 painter->drawArc(rect, startAngle * 16, 180 * 16);
00083
00084 pen.setColor(brush.color().dark(100 + colorOffset));
00085 painter->setPen(pen);
00086 painter->drawArc(rect, (startAngle + 180) * 16, 180 * 16);
00087
00088 painter->restore();
00089 }
00090
00094 QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob,
00095 const QColor &mid, const QColor &base):
00096 d_style(style),
00097 d_hasKnob(hasKnob),
00098 d_width(-1)
00099 {
00100 QPalette palette;
00101 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00102 {
00103 palette.setColor((QPalette::ColorGroup)i,
00104 QwtPalette::Mid, mid);
00105 palette.setColor((QPalette::ColorGroup)i,
00106 QwtPalette::Base, base);
00107 }
00108
00109 setPalette(palette);
00110 }
00111
00113 void QwtDialSimpleNeedle::setWidth(int width)
00114 {
00115 d_width = width;
00116 }
00117
00121 int QwtDialSimpleNeedle::width() const
00122 {
00123 return d_width;
00124 }
00125
00135 void QwtDialSimpleNeedle::draw(QPainter *painter, const QPoint ¢er,
00136 int length, double direction, QPalette::ColorGroup colorGroup) const
00137 {
00138 if ( d_style == Arrow )
00139 {
00140 drawArrowNeedle(painter, palette(), colorGroup,
00141 center, length, d_width, direction, d_hasKnob);
00142 }
00143 else
00144 {
00145 drawRayNeedle(painter, palette(), colorGroup,
00146 center, length, d_width, direction, d_hasKnob);
00147 }
00148 }
00149
00153 void QwtDialSimpleNeedle::drawRayNeedle(QPainter *painter,
00154 const QPalette &palette, QPalette::ColorGroup colorGroup,
00155 const QPoint ¢er, int length, int width, double direction,
00156 bool hasKnob)
00157 {
00158 if ( width <= 0 )
00159 width = 5;
00160
00161 direction *= M_PI / 180.0;
00162
00163 painter->save();
00164
00165 const QPoint p1(center.x() + 1, center.y() + 2);
00166 const QPoint p2 = qwtPolar2Pos(p1, length, direction);
00167
00168 if ( width == 1 )
00169 {
00170 const QColor midColor =
00171 palette.color(colorGroup, QwtPalette::Mid);
00172
00173 painter->setPen(QPen(midColor, 1));
00174 painter->drawLine(p1, p2);
00175 }
00176 else
00177 {
00178 QwtPointArray pa(4);
00179 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00180 pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
00181 pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
00182 pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00183
00184 painter->setPen(Qt::NoPen);
00185 painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00186 painter->drawPolygon(pa);
00187 }
00188 if ( hasKnob )
00189 {
00190 int knobWidth = qwtMax(qRound(width * 0.7), 5);
00191 if ( knobWidth % 2 == 0 )
00192 knobWidth++;
00193
00194 drawKnob(painter, center, knobWidth,
00195 palette.brush(colorGroup, QwtPalette::Base),
00196 false);
00197 }
00198
00199 painter->restore();
00200 }
00201
00205 void QwtDialSimpleNeedle::drawArrowNeedle(QPainter *painter,
00206 const QPalette &palette, QPalette::ColorGroup colorGroup,
00207 const QPoint ¢er, int length, int width,
00208 double direction, bool hasKnob)
00209 {
00210 direction *= M_PI / 180.0;
00211
00212 painter->save();
00213
00214 if ( width <= 0 )
00215 {
00216 width = (int)qwtMax(length * 0.06, 9.0);
00217 if ( width % 2 == 0 )
00218 width++;
00219 }
00220
00221 const int peak = 3;
00222 const QPoint p1(center.x() + 1, center.y() + 1);
00223 const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
00224 const QPoint p3 = qwtPolar2Pos(p1, length, direction);
00225
00226 QwtPointArray pa(5);
00227 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00228 pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
00229 pa.setPoint(2, p3);
00230 pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
00231 pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00232
00233 painter->setPen(Qt::NoPen);
00234 painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00235 painter->drawPolygon(pa);
00236
00237 QwtPointArray shadowPa(3);
00238
00239 const int colorOffset = 10;
00240
00241 int i;
00242 for ( i = 0; i < 3; i++ )
00243 shadowPa.setPoint(i, pa[i]);
00244
00245 const QColor midColor = palette.color(colorGroup, QwtPalette::Mid);
00246
00247 painter->setPen(midColor.dark(100 + colorOffset));
00248 painter->drawPolyline(shadowPa);
00249
00250 for ( i = 0; i < 3; i++ )
00251 shadowPa.setPoint(i, pa[i + 2]);
00252
00253 painter->setPen(midColor.dark(100 - colorOffset));
00254 painter->drawPolyline(shadowPa);
00255
00256 if ( hasKnob )
00257 {
00258 drawKnob(painter, center, qRound(width * 1.3),
00259 palette.brush(colorGroup, QwtPalette::Base),
00260 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 QwtPalette::Light, light);
00277 palette.setColor((QPalette::ColorGroup)i,
00278 QwtPalette::Dark, dark);
00279 palette.setColor((QPalette::ColorGroup)i,
00280 QwtPalette::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 colorGroup) const
00297 {
00298 if ( d_style == ThinStyle )
00299 {
00300 drawThinNeedle(painter, palette(), colorGroup,
00301 center, length, direction);
00302 }
00303 else
00304 {
00305 drawTriangleNeedle(painter, palette(), colorGroup,
00306 center, length, direction);
00307 }
00308 }
00309
00313 void QwtCompassMagnetNeedle::drawTriangleNeedle(QPainter *painter,
00314 const QPalette &palette, QPalette::ColorGroup colorGroup,
00315 const QPoint ¢er, int length, double direction)
00316 {
00317 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00318 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00319
00320 QBrush brush;
00321
00322 const int width = qRound(length / 3.0);
00323 const int colorOffset = 10;
00324
00325 painter->save();
00326 painter->setPen(Qt::NoPen);
00327
00328 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00329
00330 QwtPointArray pa(3);
00331 pa.setPoint(0, arrowCenter);
00332 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
00333
00334 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00335
00336 brush = darkBrush;
00337 brush.setColor(brush.color().dark(100 + colorOffset));
00338 painter->setBrush(brush);
00339 painter->drawPolygon(pa);
00340
00341 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00342
00343 brush = darkBrush;
00344 brush.setColor(brush.color().dark(100 - colorOffset));
00345 painter->setBrush(brush);
00346 painter->drawPolygon(pa);
00347
00348
00349
00350 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
00351
00352 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00353
00354 brush = lightBrush;
00355 brush.setColor(brush.color().dark(100 + colorOffset));
00356 painter->setBrush(brush);
00357 painter->drawPolygon(pa);
00358
00359 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00360
00361 brush = lightBrush;
00362 brush.setColor(brush.color().dark(100 - colorOffset));
00363 painter->setBrush(brush);
00364 painter->drawPolygon(pa);
00365
00366 painter->restore();
00367 }
00368
00372 void QwtCompassMagnetNeedle::drawThinNeedle(QPainter *painter,
00373 const QPalette &palette, QPalette::ColorGroup colorGroup,
00374 const QPoint ¢er, int length, double direction)
00375 {
00376 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00377 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00378 const QBrush baseBrush = palette.brush(colorGroup, QwtPalette::Base);
00379
00380 const int colorOffset = 10;
00381 const int width = qwtMax(qRound(length / 6.0), 3);
00382
00383 painter->save();
00384
00385 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00386
00387 drawPointer(painter, darkBrush, colorOffset,
00388 arrowCenter, length, width, direction);
00389 drawPointer(painter, lightBrush, -colorOffset,
00390 arrowCenter, length, width, direction + 180.0);
00391
00392 drawKnob(painter, arrowCenter, width, baseBrush, true);
00393
00394 painter->restore();
00395 }
00396
00400 void QwtCompassMagnetNeedle::drawPointer(
00401 QPainter *painter, const QBrush &brush,
00402 int colorOffset, const QPoint ¢er, int length,
00403 int width, double direction)
00404 {
00405 painter->save();
00406
00407 const int peak = qwtMax(qRound(length / 10.0), 5);
00408
00409 const int knobWidth = width + 8;
00410 QRect knobRect(0, 0, knobWidth, knobWidth);
00411 knobRect.moveCenter(center);
00412
00413 QwtPointArray pa(5);
00414
00415 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
00416 pa.setPoint(1, center);
00417 pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
00418 pa.setPoint(3, qwtDegree2Pos(center, length, direction));
00419 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00420
00421 painter->setPen(Qt::NoPen);
00422
00423 QBrush darkBrush = brush;
00424 darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
00425 painter->setBrush(darkBrush);
00426 painter->drawPolygon(pa);
00427 painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
00428
00429 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
00430 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00431
00432 QBrush lightBrush = brush;
00433 lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
00434 painter->setBrush(lightBrush);
00435 painter->drawPolygon(pa);
00436 painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
00437
00438 painter->restore();
00439 }
00440
00442
00443 QwtCompassWindArrow::QwtCompassWindArrow(Style style,
00444 const QColor &light, const QColor &dark):
00445 d_style(style)
00446 {
00447 QPalette palette;
00448 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00449 {
00450 palette.setColor((QPalette::ColorGroup)i,
00451 QwtPalette::Light, light);
00452 palette.setColor((QPalette::ColorGroup)i,
00453 QwtPalette::Dark, dark);
00454 }
00455
00456 setPalette(palette);
00457 }
00458
00468 void QwtCompassWindArrow::draw(QPainter *painter, const QPoint ¢er,
00469 int length, double direction, QPalette::ColorGroup colorGroup) const
00470 {
00471 if ( d_style == Style1 )
00472 {
00473 drawStyle1Needle(painter, palette(), colorGroup,
00474 center, length, direction);
00475 }
00476 else
00477 {
00478 drawStyle2Needle(painter, palette(), colorGroup,
00479 center, length, direction);
00480 }
00481 }
00482
00486 void QwtCompassWindArrow::drawStyle1Needle(QPainter *painter,
00487 const QPalette &palette, QPalette::ColorGroup colorGroup,
00488 const QPoint ¢er, int length, double direction)
00489 {
00490 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00491
00492 const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
00493 const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
00494
00495 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00496
00497 QwtPointArray pa(8);
00498 pa.setPoint(0, arrowCenter);
00499 for (int i=1; i<8; i++)
00500 {
00501 const QPoint p = qwtDegree2Pos(center,
00502 AR1[i] * length, direction + AW1[i]);
00503 pa.setPoint(i, p);
00504 }
00505
00506 painter->save();
00507 painter->setPen(Qt::NoPen);
00508 painter->setBrush(lightBrush);
00509 painter->drawPolygon(pa);
00510 painter->restore();
00511 }
00512
00516 void QwtCompassWindArrow::drawStyle2Needle(QPainter *painter,
00517 const QPalette &palette, QPalette::ColorGroup colorGroup,
00518 const QPoint ¢er, int length, double direction)
00519 {
00520 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00521 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00522
00523 painter->save();
00524 painter->setPen(Qt::NoPen);
00525
00526 const double angle = 12.0;
00527 const double ratio = 0.7;
00528
00529 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00530
00531 QwtPointArray pa(3);
00532
00533 pa.setPoint(0, center);
00534 pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
00535
00536 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
00537 painter->setBrush(darkBrush);
00538 painter->drawPolygon(pa);
00539
00540 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
00541 painter->setBrush(lightBrush);
00542 painter->drawPolygon(pa);
00543
00544 painter->restore();
00545 }
00546