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
00091 QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob,
00092 const QColor &mid, const QColor &base):
00093 d_style(style),
00094 d_hasKnob(hasKnob),
00095 d_width(-1)
00096 {
00097 QPalette palette;
00098 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00099 {
00100 palette.setColor((QPalette::ColorGroup)i,
00101 QwtPalette::Mid, mid);
00102 palette.setColor((QPalette::ColorGroup)i,
00103 QwtPalette::Base, base);
00104 }
00105
00106 setPalette(palette);
00107 }
00108
00110 void QwtDialSimpleNeedle::setWidth(int width)
00111 {
00112 d_width = width;
00113 }
00114
00118 int QwtDialSimpleNeedle::width() const
00119 {
00120 return d_width;
00121 }
00122
00132 void QwtDialSimpleNeedle::draw(QPainter *painter, const QPoint ¢er,
00133 int length, double direction, QPalette::ColorGroup colorGroup) const
00134 {
00135 if ( d_style == Arrow )
00136 {
00137 drawArrowNeedle(painter, palette(), colorGroup,
00138 center, length, d_width, direction, d_hasKnob);
00139 }
00140 else
00141 {
00142 drawRayNeedle(painter, palette(), colorGroup,
00143 center, length, d_width, direction, d_hasKnob);
00144 }
00145 }
00146
00150 void QwtDialSimpleNeedle::drawRayNeedle(QPainter *painter,
00151 const QPalette &palette, QPalette::ColorGroup colorGroup,
00152 const QPoint ¢er, int length, int width, double direction,
00153 bool hasKnob)
00154 {
00155 if ( width <= 0 )
00156 width = 5;
00157
00158 direction *= M_PI / 180.0;
00159
00160 painter->save();
00161
00162 const QPoint p1(center.x() + 1, center.y() + 2);
00163 const QPoint p2 = qwtPolar2Pos(p1, length, direction);
00164
00165 if ( width == 1 )
00166 {
00167 const QColor midColor =
00168 palette.color(colorGroup, QwtPalette::Mid);
00169
00170 painter->setPen(QPen(midColor, 1));
00171 painter->drawLine(p1, p2);
00172 }
00173 else
00174 {
00175 QwtPolygon pa(4);
00176 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00177 pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
00178 pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
00179 pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00180
00181 painter->setPen(Qt::NoPen);
00182 painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00183 painter->drawPolygon(pa);
00184 }
00185 if ( hasKnob )
00186 {
00187 int knobWidth = qwtMax(qRound(width * 0.7), 5);
00188 if ( knobWidth % 2 == 0 )
00189 knobWidth++;
00190
00191 drawKnob(painter, center, knobWidth,
00192 palette.brush(colorGroup, QwtPalette::Base),
00193 false);
00194 }
00195
00196 painter->restore();
00197 }
00198
00202 void QwtDialSimpleNeedle::drawArrowNeedle(QPainter *painter,
00203 const QPalette &palette, QPalette::ColorGroup colorGroup,
00204 const QPoint ¢er, int length, int width,
00205 double direction, bool hasKnob)
00206 {
00207 direction *= M_PI / 180.0;
00208
00209 painter->save();
00210
00211 if ( width <= 0 )
00212 {
00213 width = (int)qwtMax(length * 0.06, 9.0);
00214 if ( width % 2 == 0 )
00215 width++;
00216 }
00217
00218 const int peak = 3;
00219 const QPoint p1(center.x() + 1, center.y() + 1);
00220 const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
00221 const QPoint p3 = qwtPolar2Pos(p1, length, direction);
00222
00223 QwtPolygon pa(5);
00224 pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00225 pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
00226 pa.setPoint(2, p3);
00227 pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
00228 pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00229
00230 painter->setPen(Qt::NoPen);
00231 painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00232 painter->drawPolygon(pa);
00233
00234 QwtPolygon shadowPa(3);
00235
00236 const int colorOffset = 10;
00237
00238 int i;
00239 for ( i = 0; i < 3; i++ )
00240 shadowPa.setPoint(i, pa[i]);
00241
00242 const QColor midColor = palette.color(colorGroup, QwtPalette::Mid);
00243
00244 painter->setPen(midColor.dark(100 + colorOffset));
00245 painter->drawPolyline(shadowPa);
00246
00247 for ( i = 0; i < 3; i++ )
00248 shadowPa.setPoint(i, pa[i + 2]);
00249
00250 painter->setPen(midColor.dark(100 - colorOffset));
00251 painter->drawPolyline(shadowPa);
00252
00253 if ( hasKnob )
00254 {
00255 drawKnob(painter, center, qRound(width * 1.3),
00256 palette.brush(colorGroup, QwtPalette::Base),
00257 false);
00258 }
00259
00260 painter->restore();
00261 }
00262
00264
00265 QwtCompassMagnetNeedle::QwtCompassMagnetNeedle(Style style,
00266 const QColor &light, const QColor &dark):
00267 d_style(style)
00268 {
00269 QPalette palette;
00270 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00271 {
00272 palette.setColor((QPalette::ColorGroup)i,
00273 QwtPalette::Light, light);
00274 palette.setColor((QPalette::ColorGroup)i,
00275 QwtPalette::Dark, dark);
00276 palette.setColor((QPalette::ColorGroup)i,
00277 QwtPalette::Base, Qt::darkGray);
00278 }
00279
00280 setPalette(palette);
00281 }
00282
00292 void QwtCompassMagnetNeedle::draw(QPainter *painter, const QPoint ¢er,
00293 int length, double direction, QPalette::ColorGroup colorGroup) const
00294 {
00295 if ( d_style == ThinStyle )
00296 {
00297 drawThinNeedle(painter, palette(), colorGroup,
00298 center, length, direction);
00299 }
00300 else
00301 {
00302 drawTriangleNeedle(painter, palette(), colorGroup,
00303 center, length, direction);
00304 }
00305 }
00306
00317 void QwtCompassMagnetNeedle::drawTriangleNeedle(QPainter *painter,
00318 const QPalette &palette, QPalette::ColorGroup colorGroup,
00319 const QPoint ¢er, int length, double direction)
00320 {
00321 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00322 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00323
00324 QBrush brush;
00325
00326 const int width = qRound(length / 3.0);
00327 const int colorOffset = 10;
00328
00329 painter->save();
00330 painter->setPen(Qt::NoPen);
00331
00332 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00333
00334 QwtPolygon pa(3);
00335 pa.setPoint(0, arrowCenter);
00336 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
00337
00338 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00339
00340 brush = darkBrush;
00341 brush.setColor(brush.color().dark(100 + colorOffset));
00342 painter->setBrush(brush);
00343 painter->drawPolygon(pa);
00344
00345 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00346
00347 brush = darkBrush;
00348 brush.setColor(brush.color().dark(100 - colorOffset));
00349 painter->setBrush(brush);
00350 painter->drawPolygon(pa);
00351
00352
00353
00354 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
00355
00356 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00357
00358 brush = lightBrush;
00359 brush.setColor(brush.color().dark(100 + colorOffset));
00360 painter->setBrush(brush);
00361 painter->drawPolygon(pa);
00362
00363 pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00364
00365 brush = lightBrush;
00366 brush.setColor(brush.color().dark(100 - colorOffset));
00367 painter->setBrush(brush);
00368 painter->drawPolygon(pa);
00369
00370 painter->restore();
00371 }
00372
00383 void QwtCompassMagnetNeedle::drawThinNeedle(QPainter *painter,
00384 const QPalette &palette, QPalette::ColorGroup colorGroup,
00385 const QPoint ¢er, int length, double direction)
00386 {
00387 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00388 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00389 const QBrush baseBrush = palette.brush(colorGroup, QwtPalette::Base);
00390
00391 const int colorOffset = 10;
00392 const int width = qwtMax(qRound(length / 6.0), 3);
00393
00394 painter->save();
00395
00396 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00397
00398 drawPointer(painter, darkBrush, colorOffset,
00399 arrowCenter, length, width, direction);
00400 drawPointer(painter, lightBrush, -colorOffset,
00401 arrowCenter, length, width, direction + 180.0);
00402
00403 drawKnob(painter, arrowCenter, width, baseBrush, true);
00404
00405 painter->restore();
00406 }
00407
00419 void QwtCompassMagnetNeedle::drawPointer(
00420 QPainter *painter, const QBrush &brush,
00421 int colorOffset, const QPoint ¢er, int length,
00422 int width, double direction)
00423 {
00424 painter->save();
00425
00426 const int peak = qwtMax(qRound(length / 10.0), 5);
00427
00428 const int knobWidth = width + 8;
00429 QRect knobRect(0, 0, knobWidth, knobWidth);
00430 knobRect.moveCenter(center);
00431
00432 QwtPolygon pa(5);
00433
00434 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
00435 pa.setPoint(1, center);
00436 pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
00437 pa.setPoint(3, qwtDegree2Pos(center, length, direction));
00438 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00439
00440 painter->setPen(Qt::NoPen);
00441
00442 QBrush darkBrush = brush;
00443 darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
00444 painter->setBrush(darkBrush);
00445 painter->drawPolygon(pa);
00446 painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
00447
00448 pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
00449 pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00450
00451 QBrush lightBrush = brush;
00452 lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
00453 painter->setBrush(lightBrush);
00454 painter->drawPolygon(pa);
00455 painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
00456
00457 painter->restore();
00458 }
00459
00467 QwtCompassWindArrow::QwtCompassWindArrow(Style style,
00468 const QColor &light, const QColor &dark):
00469 d_style(style)
00470 {
00471 QPalette palette;
00472 for ( int i = 0; i < QPalette::NColorGroups; i++ )
00473 {
00474 palette.setColor((QPalette::ColorGroup)i,
00475 QwtPalette::Light, light);
00476 palette.setColor((QPalette::ColorGroup)i,
00477 QwtPalette::Dark, dark);
00478 }
00479
00480 setPalette(palette);
00481 }
00482
00492 void QwtCompassWindArrow::draw(QPainter *painter, const QPoint ¢er,
00493 int length, double direction, QPalette::ColorGroup colorGroup) const
00494 {
00495 if ( d_style == Style1 )
00496 {
00497 drawStyle1Needle(painter, palette(), colorGroup,
00498 center, length, direction);
00499 }
00500 else
00501 {
00502 drawStyle2Needle(painter, palette(), colorGroup,
00503 center, length, direction);
00504 }
00505 }
00506
00517 void QwtCompassWindArrow::drawStyle1Needle(QPainter *painter,
00518 const QPalette &palette, QPalette::ColorGroup colorGroup,
00519 const QPoint ¢er, int length, double direction)
00520 {
00521 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00522
00523 const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
00524 const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
00525
00526 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00527
00528 QwtPolygon pa(8);
00529 pa.setPoint(0, arrowCenter);
00530 for (int i=1; i<8; i++)
00531 {
00532 const QPoint p = qwtDegree2Pos(center,
00533 AR1[i] * length, direction + AW1[i]);
00534 pa.setPoint(i, p);
00535 }
00536
00537 painter->save();
00538 painter->setPen(Qt::NoPen);
00539 painter->setBrush(lightBrush);
00540 painter->drawPolygon(pa);
00541 painter->restore();
00542 }
00543
00554 void QwtCompassWindArrow::drawStyle2Needle(QPainter *painter,
00555 const QPalette &palette, QPalette::ColorGroup colorGroup,
00556 const QPoint ¢er, int length, double direction)
00557 {
00558 const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00559 const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00560
00561 painter->save();
00562 painter->setPen(Qt::NoPen);
00563
00564 const double angle = 12.0;
00565 const double ratio = 0.7;
00566
00567 const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00568
00569 QwtPolygon pa(3);
00570
00571 pa.setPoint(0, center);
00572 pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
00573
00574 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
00575 painter->setBrush(darkBrush);
00576 painter->drawPolygon(pa);
00577
00578 pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
00579 painter->setBrush(lightBrush);
00580 painter->drawPolygon(pa);
00581
00582 painter->restore();
00583 }
00584