File: attitude_indicator.cpp

package info (click to toggle)
qwt 6.1.4-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 23,808 kB
  • sloc: cpp: 57,687; xml: 182; makefile: 32
file content (127 lines) | stat: -rw-r--r-- 3,406 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "attitude_indicator.h"
#include <qwt_point_polar.h>
#include <qwt_round_scale_draw.h>
#include <qevent.h>
#include <qpainter.h>
#include <qpolygon.h>

AttitudeIndicatorNeedle::AttitudeIndicatorNeedle( const QColor &color )
{
    QPalette palette;
    palette.setColor( QPalette::Text, color );
    setPalette( palette );
}

void AttitudeIndicatorNeedle::drawNeedle( QPainter *painter,
    double length, QPalette::ColorGroup colorGroup ) const
{
    double triangleSize = length * 0.1;
    double pos = length - 2.0;

    QPainterPath path;
    path.moveTo( pos, 0 );
    path.lineTo( pos - 2 * triangleSize, triangleSize );
    path.lineTo( pos - 2 * triangleSize, -triangleSize );
    path.closeSubpath();

    painter->setBrush( palette().brush( colorGroup, QPalette::Text ) );
    painter->drawPath( path );

    double l = length - 2;
    painter->setPen( QPen( palette().color( colorGroup, QPalette::Text ), 3 ) );
    painter->drawLine( QPointF( 0.0, -l ), QPointF( 0.0, l ) );
}

AttitudeIndicator::AttitudeIndicator(
    QWidget *parent ):
    QwtDial( parent ),
    d_gradient( 0.0 )
{
    QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw();
    scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
    scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, false );
    setScaleDraw( scaleDraw );

    setMode( RotateScale );
    setWrapping( true );

    setOrigin( 270.0 );

    setScaleMaxMinor( 0 );
    setScaleStepSize( 30.0 );
    setScale( 0.0, 360.0 );

    const QColor color = palette().color( QPalette::Text );
    setNeedle( new AttitudeIndicatorNeedle( color ) );
}

void AttitudeIndicator::setGradient( double gradient )
{
    if ( gradient < -1.0 )
        gradient = -1.0;
    else if ( gradient > 1.0 )
        gradient = 1.0;

    if ( d_gradient != gradient )
    {
        d_gradient = gradient;
        update();
    }
}

void AttitudeIndicator::drawScale( QPainter *painter,
    const QPointF &center, double radius ) const
{
    const double offset = 4.0;

    const QPointF p0 = qwtPolar2Pos( center, offset, 1.5 * M_PI );

    const double w = innerRect().width();

    QPainterPath path;
    path.moveTo( qwtPolar2Pos( p0, w, 0.0 ) );
    path.lineTo( qwtPolar2Pos( path.currentPosition(), 2 * w, M_PI ) );
    path.lineTo( qwtPolar2Pos( path.currentPosition(), w, 0.5 * M_PI ) );
    path.lineTo( qwtPolar2Pos( path.currentPosition(), w, 0.0 ) );

    painter->save();
    painter->setClipPath( path ); // swallow 180 - 360 degrees

    QwtDial::drawScale( painter, center, radius );

    painter->restore();
}

void AttitudeIndicator::drawScaleContents( QPainter *painter,
        const QPointF &, double ) const
{
    int dir = 360 - qRound( origin() - value() ); // counter clockwise
    int arc = 90 + qRound( gradient() * 90 );

    const QColor skyColor( 38, 151, 221 );

    painter->save();
    painter->setBrush( skyColor );
    painter->drawChord( scaleInnerRect(),
        ( dir - arc ) * 16, 2 * arc * 16 );
    painter->restore();
}

void AttitudeIndicator::keyPressEvent( QKeyEvent *event )
{
    switch( event->key() )
    {
        case Qt::Key_Plus:
        {
            setGradient( gradient() + 0.05 );
            break;
        }
        case Qt::Key_Minus:
        {
            setGradient( gradient() - 0.05 );
            break;
        }
        default:
            QwtDial::keyPressEvent( event );
    }
}