1 #include <qevent.h>
2 #include <qpainter.h>
3 #include <qwt_math.h>
4 #include <qwt_polygon.h>
5 #include "attitude_indicator.h"
6 
AttitudeIndicatorNeedle(const QColor & c)7 AttitudeIndicatorNeedle::AttitudeIndicatorNeedle(const QColor &c)
8 {
9     QPalette palette;
10     for ( int i = 0; i < QPalette::NColorGroups; i++ )
11     {
12 #if QT_VERSION < 0x040000
13         palette.setColor((QPalette::ColorGroup)i,
14             QColorGroup::Text, c);
15 #else
16         palette.setColor((QPalette::ColorGroup)i,
17             QPalette::Text, c);
18 #endif
19     }
20     setPalette(palette);
21 }
22 
draw(QPainter * painter,const QPoint & center,int length,double direction,QPalette::ColorGroup cg) const23 void AttitudeIndicatorNeedle::draw(QPainter *painter, const QPoint &center,
24     int length, double direction, QPalette::ColorGroup cg) const
25 {
26     direction *= M_PI / 180.0;
27     int triangleSize = qRound(length * 0.1);
28 
29     painter->save();
30 
31     const QPoint p0(QPoint(center.x() + 1, center.y() + 1));
32 
33     const QPoint p1 = qwtPolar2Pos(p0,
34         length - 2 * triangleSize - 2, direction);
35 
36     QwtPolygon pa(3);
37     pa.setPoint(0, qwtPolar2Pos(p1, 2 * triangleSize, direction));
38     pa.setPoint(1, qwtPolar2Pos(p1, triangleSize, direction + M_PI_2));
39     pa.setPoint(2, qwtPolar2Pos(p1, triangleSize, direction - M_PI_2));
40 
41     const QColor color =
42 #if QT_VERSION < 0x040000
43         palette().color(cg, QColorGroup::Text);
44 #else
45         palette().color(cg, QPalette::Text);
46 #endif
47     painter->setBrush(color);
48     painter->drawPolygon(pa);
49 
50     painter->setPen(QPen(color, 3));
51     painter->drawLine(qwtPolar2Pos(p0, length - 2, direction + M_PI_2),
52         qwtPolar2Pos(p0, length - 2, direction - M_PI_2));
53 
54     painter->restore();
55 }
56 
AttitudeIndicator(QWidget * parent)57 AttitudeIndicator::AttitudeIndicator(
58         QWidget *parent):
59     QwtDial(parent),
60     d_gradient(0.0)
61 {
62     setMode(RotateScale);
63     setWrapping(true);
64 
65     setOrigin(270.0);
66     setScaleOptions(ScaleTicks);
67     setScale(0, 0, 30.0);
68 
69     const QColor color =
70 #if QT_VERSION < 0x040000
71         colorGroup().text();
72 #else
73         palette().color(QPalette::Text);
74 #endif
75 
76     setNeedle(new AttitudeIndicatorNeedle(color));
77 }
78 
setGradient(double gradient)79 void AttitudeIndicator::setGradient(double gradient)
80 {
81     if ( gradient < -1.0 )
82          gradient = -1.0;
83     else if ( gradient > 1.0 )
84         gradient = 1.0;
85 
86     if ( d_gradient != gradient )
87     {
88         d_gradient = gradient;
89         update();
90     }
91 }
92 
drawScale(QPainter * painter,const QPoint & center,int radius,double origin,double minArc,double maxArc) const93 void AttitudeIndicator::drawScale(QPainter *painter, const QPoint &center,
94     int radius, double origin, double minArc, double maxArc) const
95 {
96     double dir = (360.0 - origin) * M_PI / 180.0; // counter clockwise, radian
97 
98     int offset = 4;
99 
100     const QPoint p0 = qwtPolar2Pos(center, offset, dir + M_PI);
101 
102     const int w = contentsRect().width();
103 
104     QwtPolygon pa(4);
105     pa.setPoint(0, qwtPolar2Pos(p0, w, dir - M_PI_2));
106     pa.setPoint(1, qwtPolar2Pos(pa.point(0), 2 * w, dir + M_PI_2));
107     pa.setPoint(2, qwtPolar2Pos(pa.point(1), w, dir));
108     pa.setPoint(3, qwtPolar2Pos(pa.point(2), 2 * w, dir - M_PI_2));
109 
110     painter->save();
111     painter->setClipRegion(pa); // swallow 180 - 360 degrees
112 
113     QwtDial::drawScale(painter, center, radius, origin,
114         minArc, maxArc);
115 
116     painter->restore();
117 }
118 
drawScaleContents(QPainter * painter,const QPoint &,int) const119 void AttitudeIndicator::drawScaleContents(QPainter *painter,
120     const QPoint &, int) const
121 {
122     int dir = 360 - qRound(origin() - value()); // counter clockwise
123     int arc = 90 + qRound(gradient() * 90);
124 
125     const QColor skyColor(38, 151, 221);
126 
127     painter->save();
128     painter->setBrush(skyColor);
129     painter->drawChord(scaleContentsRect(),
130         (dir - arc) * 16, 2 * arc * 16 );
131     painter->restore();
132 }
133 
keyPressEvent(QKeyEvent * e)134 void AttitudeIndicator::keyPressEvent(QKeyEvent *e)
135 {
136     switch(e->key())
137     {
138         case Qt::Key_Plus:
139             setGradient(gradient() + 0.05);
140             break;
141 
142         case Qt::Key_Minus:
143             setGradient(gradient() - 0.05);
144             break;
145 
146         default:
147             QwtDial::keyPressEvent(e);
148     }
149 }
150