1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the Qwt License, Version 1.0
8
*****************************************************************************/
11
#include <qapplication.h>
14
#include "qwt_painter.h"
15
#include "qwt_polygon.h"
16
#include "qwt_dial_needle.h"
18
#if QT_VERSION < 0x040000
19
typedef QColorGroup QwtPalette;
21
typedef QPalette QwtPalette;
25
QwtDialNeedle::QwtDialNeedle():
26
d_palette(QApplication::palette())
31
QwtDialNeedle::~QwtDialNeedle()
36
Sets the palette for the needle.
38
\param palette New Palette
40
void QwtDialNeedle::setPalette(const QPalette &palette)
46
\return the palette of the needle.
48
const QPalette &QwtDialNeedle::palette() const
54
void QwtDialNeedle::drawKnob(QPainter *painter,
55
const QPoint &pos, int width, const QBrush &brush, bool sunken)
59
QRect rect(0, 0, width, width);
62
painter->setPen(Qt::NoPen);
63
painter->setBrush(brush);
64
painter->drawEllipse(rect);
66
painter->setBrush(Qt::NoBrush);
68
const int colorOffset = 20;
77
pen.setColor(brush.color().dark(100 - colorOffset));
79
painter->drawArc(rect, startAngle * 16, 180 * 16);
81
pen.setColor(brush.color().dark(100 + colorOffset));
83
painter->drawArc(rect, (startAngle + 180) * 16, 180 * 16);
92
\param hasKnob With/Without knob
93
\param mid Middle color
94
\param base Base color
96
QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob,
97
const QColor &mid, const QColor &base):
103
for ( int i = 0; i < QPalette::NColorGroups; i++ )
105
palette.setColor((QPalette::ColorGroup)i,
106
QwtPalette::Mid, mid);
107
palette.setColor((QPalette::ColorGroup)i,
108
QwtPalette::Base, base);
115
Set the width of the needle
119
void QwtDialSimpleNeedle::setWidth(int width)
125
\return the width of the needle
128
int QwtDialSimpleNeedle::width() const
136
\param painter Painter
137
\param center Center of the dial, start position for the needle
138
\param length Length of the needle
139
\param direction Direction of the needle, in degrees counter clockwise
140
\param colorGroup Color group, used for painting
142
void QwtDialSimpleNeedle::draw(QPainter *painter, const QPoint ¢er,
143
int length, double direction, QPalette::ColorGroup colorGroup) const
145
if ( d_style == Arrow )
147
drawArrowNeedle(painter, palette(), colorGroup,
148
center, length, d_width, direction, d_hasKnob);
152
drawRayNeedle(painter, palette(), colorGroup,
153
center, length, d_width, direction, d_hasKnob);
158
Draw a needle looking like a ray
160
\param painter Painter
161
\param palette Palette
162
\param colorGroup Color group
163
\param center center of the needle
164
\param length Length of the needle
165
\param width Width of the needle
166
\param direction Current Direction
167
\param hasKnob With/Without knob
169
void QwtDialSimpleNeedle::drawRayNeedle(QPainter *painter,
170
const QPalette &palette, QPalette::ColorGroup colorGroup,
171
const QPoint ¢er, int length, int width, double direction,
177
direction *= M_PI / 180.0;
181
const QPoint p1(center.x() + 1, center.y() + 2);
182
const QPoint p2 = qwtPolar2Pos(p1, length, direction);
186
const QColor midColor =
187
palette.color(colorGroup, QwtPalette::Mid);
189
painter->setPen(QPen(midColor, 1));
190
painter->drawLine(p1, p2);
195
pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
196
pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
197
pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
198
pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
200
painter->setPen(Qt::NoPen);
201
painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
202
painter->drawPolygon(pa);
206
int knobWidth = qwtMax(qRound(width * 0.7), 5);
207
if ( knobWidth % 2 == 0 )
210
drawKnob(painter, center, knobWidth,
211
palette.brush(colorGroup, QwtPalette::Base),
219
Draw a needle looking like an arrow
221
\param painter Painter
222
\param palette Palette
223
\param colorGroup Color group
224
\param center center of the needle
225
\param length Length of the needle
226
\param width Width of the needle
227
\param direction Current Direction
228
\param hasKnob With/Without knob
230
void QwtDialSimpleNeedle::drawArrowNeedle(QPainter *painter,
231
const QPalette &palette, QPalette::ColorGroup colorGroup,
232
const QPoint ¢er, int length, int width,
233
double direction, bool hasKnob)
235
direction *= M_PI / 180.0;
241
width = (int)qwtMax(length * 0.06, 9.0);
242
if ( width % 2 == 0 )
247
const QPoint p1(center.x() + 1, center.y() + 1);
248
const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
249
const QPoint p3 = qwtPolar2Pos(p1, length, direction);
252
pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
253
pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
255
pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
256
pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
258
painter->setPen(Qt::NoPen);
259
painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
260
painter->drawPolygon(pa);
262
QwtPolygon shadowPa(3);
264
const int colorOffset = 10;
267
for ( i = 0; i < 3; i++ )
268
shadowPa.setPoint(i, pa[i]);
270
const QColor midColor = palette.color(colorGroup, QwtPalette::Mid);
272
painter->setPen(midColor.dark(100 + colorOffset));
273
painter->drawPolyline(shadowPa);
275
for ( i = 0; i < 3; i++ )
276
shadowPa.setPoint(i, pa[i + 2]);
278
painter->setPen(midColor.dark(100 - colorOffset));
279
painter->drawPolyline(shadowPa);
283
drawKnob(painter, center, qRound(width * 1.3),
284
palette.brush(colorGroup, QwtPalette::Base),
293
QwtCompassMagnetNeedle::QwtCompassMagnetNeedle(Style style,
294
const QColor &light, const QColor &dark):
298
for ( int i = 0; i < QPalette::NColorGroups; i++ )
300
palette.setColor((QPalette::ColorGroup)i,
301
QwtPalette::Light, light);
302
palette.setColor((QPalette::ColorGroup)i,
303
QwtPalette::Dark, dark);
304
palette.setColor((QPalette::ColorGroup)i,
305
QwtPalette::Base, Qt::darkGray);
314
\param painter Painter
315
\param center Center of the dial, start position for the needle
316
\param length Length of the needle
317
\param direction Direction of the needle, in degrees counter clockwise
318
\param colorGroup Color group, used for painting
320
void QwtCompassMagnetNeedle::draw(QPainter *painter, const QPoint ¢er,
321
int length, double direction, QPalette::ColorGroup colorGroup) const
323
if ( d_style == ThinStyle )
325
drawThinNeedle(painter, palette(), colorGroup,
326
center, length, direction);
330
drawTriangleNeedle(painter, palette(), colorGroup,
331
center, length, direction);
336
Draw a compass needle
338
\param painter Painter
339
\param palette Palette
340
\param colorGroup Color group
341
\param center Center, where the needle starts
342
\param length Length of the needle
343
\param direction Direction
345
void QwtCompassMagnetNeedle::drawTriangleNeedle(QPainter *painter,
346
const QPalette &palette, QPalette::ColorGroup colorGroup,
347
const QPoint ¢er, int length, double direction)
349
const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
350
const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
354
const int width = qRound(length / 3.0);
355
const int colorOffset = 10;
358
painter->setPen(Qt::NoPen);
360
const QPoint arrowCenter(center.x() + 1, center.y() + 1);
363
pa.setPoint(0, arrowCenter);
364
pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
366
pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
369
brush.setColor(brush.color().dark(100 + colorOffset));
370
painter->setBrush(brush);
371
painter->drawPolygon(pa);
373
pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
376
brush.setColor(brush.color().dark(100 - colorOffset));
377
painter->setBrush(brush);
378
painter->drawPolygon(pa);
382
pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
384
pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
387
brush.setColor(brush.color().dark(100 + colorOffset));
388
painter->setBrush(brush);
389
painter->drawPolygon(pa);
391
pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
394
brush.setColor(brush.color().dark(100 - colorOffset));
395
painter->setBrush(brush);
396
painter->drawPolygon(pa);
402
Draw a compass needle
404
\param painter Painter
405
\param palette Palette
406
\param colorGroup Color group
407
\param center Center, where the needle starts
408
\param length Length of the needle
409
\param direction Direction
411
void QwtCompassMagnetNeedle::drawThinNeedle(QPainter *painter,
412
const QPalette &palette, QPalette::ColorGroup colorGroup,
413
const QPoint ¢er, int length, double direction)
415
const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
416
const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
417
const QBrush baseBrush = palette.brush(colorGroup, QwtPalette::Base);
419
const int colorOffset = 10;
420
const int width = qwtMax(qRound(length / 6.0), 3);
424
const QPoint arrowCenter(center.x() + 1, center.y() + 1);
426
drawPointer(painter, darkBrush, colorOffset,
427
arrowCenter, length, width, direction);
428
drawPointer(painter, lightBrush, -colorOffset,
429
arrowCenter, length, width, direction + 180.0);
431
drawKnob(painter, arrowCenter, width, baseBrush, true);
437
Draw a compass needle
439
\param painter Painter
441
\param colorOffset Color offset
442
\param center Center, where the needle starts
443
\param length Length of the needle
444
\param width Width of the needle
445
\param direction Direction
447
void QwtCompassMagnetNeedle::drawPointer(
448
QPainter *painter, const QBrush &brush,
449
int colorOffset, const QPoint ¢er, int length,
450
int width, double direction)
454
const int peak = qwtMax(qRound(length / 10.0), 5);
456
const int knobWidth = width + 8;
457
QRect knobRect(0, 0, knobWidth, knobWidth);
458
knobRect.moveCenter(center);
462
pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
463
pa.setPoint(1, center);
464
pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
465
pa.setPoint(3, qwtDegree2Pos(center, length, direction));
466
pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
468
painter->setPen(Qt::NoPen);
470
QBrush darkBrush = brush;
471
darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
472
painter->setBrush(darkBrush);
473
painter->drawPolygon(pa);
474
painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
476
pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
477
pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
479
QBrush lightBrush = brush;
480
lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
481
painter->setBrush(lightBrush);
482
painter->drawPolygon(pa);
483
painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
491
\param style Arrow style
492
\param light Light color
493
\param dark Dark color
495
QwtCompassWindArrow::QwtCompassWindArrow(Style style,
496
const QColor &light, const QColor &dark):
500
for ( int i = 0; i < QPalette::NColorGroups; i++ )
502
palette.setColor((QPalette::ColorGroup)i,
503
QwtPalette::Light, light);
504
palette.setColor((QPalette::ColorGroup)i,
505
QwtPalette::Dark, dark);
514
\param painter Painter
515
\param center Center of the dial, start position for the needle
516
\param length Length of the needle
517
\param direction Direction of the needle, in degrees counter clockwise
518
\param colorGroup Color group, used for painting
520
void QwtCompassWindArrow::draw(QPainter *painter, const QPoint ¢er,
521
int length, double direction, QPalette::ColorGroup colorGroup) const
523
if ( d_style == Style1 )
525
drawStyle1Needle(painter, palette(), colorGroup,
526
center, length, direction);
530
drawStyle2Needle(painter, palette(), colorGroup,
531
center, length, direction);
536
Draw a compass needle
538
\param painter Painter
539
\param palette Palette
540
\param colorGroup colorGroup
541
\param center Center of the dial, start position for the needle
542
\param length Length of the needle
543
\param direction Direction of the needle, in degrees counter clockwise
545
void QwtCompassWindArrow::drawStyle1Needle(QPainter *painter,
546
const QPalette &palette, QPalette::ColorGroup colorGroup,
547
const QPoint ¢er, int length, double direction)
549
const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
551
const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
552
const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
554
const QPoint arrowCenter(center.x() + 1, center.y() + 1);
557
pa.setPoint(0, arrowCenter);
558
for (int i=1; i<8; i++)
560
const QPoint p = qwtDegree2Pos(center,
561
AR1[i] * length, direction + AW1[i]);
566
painter->setPen(Qt::NoPen);
567
painter->setBrush(lightBrush);
568
painter->drawPolygon(pa);
573
Draw a compass needle
575
\param painter Painter
576
\param palette Palette
577
\param colorGroup colorGroup
578
\param center Center of the dial, start position for the needle
579
\param length Length of the needle
580
\param direction Direction of the needle, in degrees counter clockwise
582
void QwtCompassWindArrow::drawStyle2Needle(QPainter *painter,
583
const QPalette &palette, QPalette::ColorGroup colorGroup,
584
const QPoint ¢er, int length, double direction)
586
const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
587
const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
590
painter->setPen(Qt::NoPen);
592
const double angle = 12.0;
593
const double ratio = 0.7;
595
const QPoint arrowCenter(center.x() + 1, center.y() + 1);
599
pa.setPoint(0, center);
600
pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
602
pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
603
painter->setBrush(darkBrush);
604
painter->drawPolygon(pa);
606
pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
607
painter->setBrush(lightBrush);
608
painter->drawPolygon(pa);