Qt Virtual Chart Table (QVCT)
CInstrumentGASpeedVertical.cpp
Go to the documentation of this file.
1 // INDENTING (emacs/vi): -*- mode:c++; tab-width:2; c-basic-offset:2; intent-tabs-mode:nil; -*- ex: set tabstop=2 expandtab:
2 
3 /*
4  * Qt Virtual Chart Table (QVCT)
5  * Copyright (C) 2012 Cedric Dufour <http://cedric.dufour.name>
6  * Author: Cedric Dufour <http://cedric.dufour.name>
7  *
8  * The Qt Virtual Chart Table (QVCT) is free software:
9  * you can redistribute it and/or modify it under the terms of the GNU General
10  * Public License as published by the Free Software Foundation, Version 3.
11  *
12  * The Qt Virtual Chart Table (QVCT) is distributed in the hope
13  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * See the GNU General Public License for more details.
17  */
18 
19 // C/C++
20 #include <cmath>
21 
22 // QT
23 #include <QBrush>
24 #include <QFont>
25 #include <QPainter>
26 #include <QPointF>
27 #include <QPen>
28 #include <QPixmap>
29 #include <QSizeF>
30 #include <QWidget>
31 
32 // QVCT
33 #include "QVCTRuntime.hpp"
35 
36 
37 //------------------------------------------------------------------------------
38 // CONSTRUCTORS / DESTRUCTOR
39 //------------------------------------------------------------------------------
40 
42  : CInstrument( _poVesselCockpit )
43  , bForceRedraw( true )
44  , eUnit( CUnitSpeedVertical::M_S )
45  , fdSpeedVertical( CDataCourse::UNDEFINED_SPEED )
46 {
47 }
48 
49 
50 //------------------------------------------------------------------------------
51 // METHODS: CInstrument (implement/override)
52 //------------------------------------------------------------------------------
53 
55 {
56  // Retrieve parameters and values
57  CVesselPoint* __poVesselPoint = CInstrument::useVesselPoint();
59  double __fdSpeedVertical = __poVesselPoint ? __poVesselPoint->GroundCourse.getSpeedVertical() : 0.0;
60 
61  // Redraw pixmap only if required
62  if( bForceRedraw
63  || qPixmapBuffer.size() != QWidget::size()
64  || eUnit != __eUnit
65  || fdSpeedVertical != __fdSpeedVertical )
66  {
67  // Draw resources
68  if( bForceRedraw
69  || qPixmapBufferBackground.size() != QWidget::size()
70  || eUnit != __eUnit )
71  {
72  drawStatic( __eUnit );
73  }
74  drawDynamic( __eUnit, __poVesselPoint );
75 
76  // Update cache parameters and values
77  bForceRedraw = false;
78  eUnit = __eUnit;
79  fdSpeedVertical = __fdSpeedVertical;
80  }
81 
82  // Draw pixmap
83  QPainter __qPainter;
84  __qPainter.begin( this );
85  __qPainter.setRenderHints( QPainter::SmoothPixmapTransform | QPainter::Antialiasing | QPainter::TextAntialiasing );
86  __qPainter.drawPixmap( 0, 0, qPixmapBuffer );
87  __qPainter.end();
88 }
89 
90 
91 //------------------------------------------------------------------------------
92 // METHODS
93 //------------------------------------------------------------------------------
94 
95 //
96 // OTHER
97 //
98 
100 {
101  // Widget geometry
102  QPointF __qPointFCenter = QPointF( QRectF( QWidget::rect() ).center() );
103  double __fdSizeFactor = ( QWidget::width() < QWidget::height() ? (double)QWidget::width() : (double)QWidget::height() ) / 1200.0;
104  QTransform __qTransform;
105  __qTransform.translate( __qPointFCenter.x(), __qPointFCenter.y() );
106  __qTransform.scale( __fdSizeFactor, __fdSizeFactor );
107 
108  // Painter and resources
109  if( qPixmapBufferBackground.size() != QWidget::size() ) qPixmapBufferBackground = QPixmap( QWidget::size() );
110  qPixmapBufferBackground.fill( Qt::transparent );
111  QPainter __qPainter( &qPixmapBufferBackground );
112  QPen __qPen;
113  QFont __qFont;
114  __qPainter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing );
115 
116  // Draw
117  __qPainter.setWorldTransform( __qTransform );
118  int __iTicksLarge = 0, __iTicksSmall = 0, __iDigitsMax = 0;
119  switch( _eUnit )
120  {
121  case CUnitSpeedVertical::M_S: __iTicksLarge = 5; __iTicksSmall = 10; __iDigitsMax = 10; break;
122  case CUnitSpeedVertical::FT_MIN: __iTicksLarge = 4; __iTicksSmall = 20; __iDigitsMax = 20; break;
123  default: return;
124  }
125 
126  // ... delimiting corona
127  __qPen.setColor( Qt::white );
128  __qPen.setWidth( 10.0 );
129  __qPainter.setPen( __qPen );
130  __qPainter.setBrush( QBrush( QColor( 32, 32, 32, 255 ) ) );
131  __qPainter.drawEllipse( QPointF( 0.0, 0.0 ), 495.0, 495.0 );
132 
133  // ... small ticks
134  for( int __i=-__iTicksSmall; __i<=__iTicksSmall; __i++ )
135  {
136  double __fdAngle = (double)__i * QVCT::PI * 17.0 / 18.0 / __iTicksSmall;
137  QPointF __qPointFAngle( -cos( __fdAngle ), sin( __fdAngle ) );
138  __qPainter.drawLine( 450.0*__qPointFAngle, 480.0*__qPointFAngle );
139  }
140 
141  // ... large ticks and digits
142  __qFont.setPixelSize( 90.0 );
143  __qFont.setBold( true );
144  __qPainter.setFont( __qFont );
145  {
146  QRectF __qRectFText( QPointF( -135.0, -45.0 ), QSizeF( 180.0, 90.0 ) );
147  for( int __i=-__iTicksLarge; __i<=__iTicksLarge; __i++ )
148  {
149  double __fdAngle = (double)__i * QVCT::PI * 17.0 / 18.0 / __iTicksLarge;
150  QPointF __qPointFAngle( -cos( __fdAngle ), -sin( __fdAngle ) );
151  __qPainter.drawLine( 420.0*__qPointFAngle, 480.0*__qPointFAngle );
152  __qPainter.drawText( __qRectFText.translated( 350.0*__qPointFAngle ), Qt::AlignVCenter|Qt::AlignRight, QString::number( __i*__iDigitsMax/__iTicksLarge ) );
153  }
154  }
155 
156  // ... name and units
157  __qPen.setColor( Qt::lightGray );
158  __qPen.setWidth( 5.0 );
159  __qPainter.setPen( __qPen );
160  __qPainter.setBrush( QBrush( QColor( 32, 32, 32, 255 ) ) );
161  __qFont.setPixelSize( 50.0 );
162  __qFont.setBold( false );
163  __qPainter.setFont( __qFont );
164  {
165  QRectF __qRectFText( QPointF( -200.0, -30.0 ), QSizeF( 400.0, 60.0 ) );
166  switch( _eUnit )
167  {
168  case CUnitSpeedVertical::M_S: __qPainter.drawText( __qRectFText.translated( QPointF( 0, -150.0 ) ), Qt::AlignCenter, CUnitSpeedVertical::toSymbol( _eUnit ) ); break;
169  case CUnitSpeedVertical::FT_MIN: __qPainter.drawText( __qRectFText.translated( QPointF( 0, -150.0 ) ), Qt::AlignCenter, "100"+CUnitSpeedVertical::toSymbol( _eUnit ) ); break;
170  default:;
171  }
172  __qPainter.drawText( __qRectFText.translated( QPointF( 0, +150.0 ) ), Qt::AlignCenter, "VSI" );
173  }
174 
175  // ... data
176  {
177  QRectF __qRectFFrame( QPointF( -150.0, -60.0 ), QSizeF( 300.0, 120.0 ) );
178  QRectF __qRectFText( QPointF( -125.0, -30.0 ), QSizeF( 250.0, 60.0 ) );
179  __qPainter.drawRoundedRect( __qRectFFrame.translated( QPointF( +425.0, +515.0 ) ), 10.0, 10.0 );
180  __qPainter.drawText( __qRectFText.translated( QPointF( +440.0, +540.0 ) ), Qt::AlignRight, CUnitSpeedVertical::toSymbol( _eUnit ) );
181  }
182 }
183 
185 {
186  double __fdSpeedVertical = _poVesselPoint ? _poVesselPoint->GroundCourse.getSpeedVertical() : 0.0;
187  double __fdSpeedVerticalConverted = __fdSpeedVertical != CDataCourse::UNDEFINED_SPEED ? CUnitSpeedVertical::toValue( __fdSpeedVertical, _eUnit ) : 0.0;
188 
189  // Widget geometry
190  QPointF __qPointFCenter = QPointF( QRectF( QWidget::rect() ).center() );
191  double __fdSizeFactor = ( QWidget::width() < QWidget::height() ? (double)QWidget::width() : (double)QWidget::height() ) / 1200.0;
192  QTransform __qTransform;
193  __qTransform.translate( __qPointFCenter.x(), __qPointFCenter.y() );
194  __qTransform.scale( __fdSizeFactor, __fdSizeFactor );
195 
196  // Painter and resources
198  QPainter __qPainter( &qPixmapBuffer );
199  QPen __qPen;
200  QFont __qFont;
201  __qPainter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing );
202 
203  // Draw
204  __qPainter.setWorldTransform( __qTransform );
205  double __fdValueMax = 0;
206  switch( _eUnit )
207  {
208  case CUnitSpeedVertical::M_S: __fdValueMax = 10.0; break;
209  case CUnitSpeedVertical::FT_MIN: __fdValueMax = 2000.0; break;
210  default: return;
211  }
212 
213  // ... speed
214  __qPen.setColor( Qt::black );
215  __qPen.setWidth( 0 );
216  __qPainter.setPen( __qPen );
217  __qPainter.setBrush( QBrush( Qt::white ) );
218  __qPainter.rotate( -90.0 );
219  double __fdSpeedVerticalLimited = __fdSpeedVerticalConverted;
220  if( __fdSpeedVerticalLimited > __fdValueMax ) __fdSpeedVerticalLimited = __fdValueMax;
221  else if( __fdSpeedVerticalLimited < -__fdValueMax ) __fdSpeedVerticalLimited = -__fdValueMax;
222  __qPainter.rotate( __fdSpeedVerticalLimited/__fdValueMax * 170.0 );
223  {
224  static const QPointF __pqPointFPolygon[5] =
225  {
226  QPointF( -15.0, -10.0 ),
227  QPointF( -15.0, -370.0 ),
228  QPointF( 0.0, -400.0 ),
229  QPointF( +15.0, -370.0 ),
230  QPointF( +15.0, -10.0 ),
231  };
232  __qPainter.drawConvexPolygon( __pqPointFPolygon, 5 );
233  }
234 
235  // ... center mask
236  __qPainter.setWorldTransform( __qTransform );
237  __qPainter.drawEllipse( QPointF( 0.0, 0.0 ), 40.0, 40.0 );
238  __qPainter.setBrush( QBrush( Qt::black ) );
239  __qPainter.drawEllipse( QPointF( 0.0, 0.0 ), 30.0, 30.0 );
240 
241  // ... data
242  __qPen.setColor( Qt::white );
243  __qPen.setWidth( 0 );
244  __qPainter.setPen( __qPen );
245  __qFont.setPixelSize( 50.0 );
246  __qFont.setBold( false );
247  __qFont.setItalic( !_poVesselPoint || __fdSpeedVertical == CDataCourse::UNDEFINED_SPEED || !_poVesselPoint->GroundCourseValidity.isValidSpeedVertical() );
248  __qPainter.setFont( __qFont );
249  {
250  QRectF __qRectFText( QPointF( -125.0, -30.0 ), QSizeF( 250.0, 60.0 ) );
251  QString __qsVS( "n/a" );
252  if( _poVesselPoint && __fdSpeedVertical != CDataCourse::UNDEFINED_SPEED )
253  {
254  int __iPrecision;
255  switch( _eUnit )
256  {
257  case CUnitSpeedVertical::M_S: __iPrecision = 1; break;
258  default: __iPrecision = 0;
259  }
260  __qsVS = QString::number( __fdSpeedVerticalConverted, 'f', __iPrecision );
261  }
262  __qPainter.drawText( __qRectFText.translated( QPointF( +425.0, +490.0 ) ), Qt::AlignCenter, __qsVS );
263  }
264 
265  // ... OFF flag
266  if( !_poVesselPoint )
267  {
268  __qPen.setColor( Qt::black );
269  __qPainter.setPen( __qPen );
270  __qPainter.setBrush( QBrush( Qt::red ) );
271  __qFont.setBold( true );
272  __qFont.setItalic( false );
273  __qPainter.setFont( __qFont );
274  QRectF __qRectFText( QPointF( -75.0, -30.0 ), QSizeF( 150.0, 60.0 ) );
275  __qPainter.drawRect( __qRectFText.translated( QPointF( +150.0, -50.0 ) ) );
276  __qPainter.drawText( __qRectFText.translated( QPointF( +150.0, -50.0 ) ), Qt::AlignCenter, "OFF" );
277  }
278 }
CDataCourse GroundCourse
Ground course.
CDataCourseValidity GroundCourseValidity
Ground course validity.
bool isValidSpeedVertical() const
Returns the vertical speed's (global) validity status.
(Geographical) Course data [bearing, horizontal/vertical speeds]
Definition: CDataCourse.hpp:34
double getSpeedVertical() const
Returns this course's vertical speed, in meters per second.
static constexpr double UNDEFINED_SPEED
Specific value for an undefined speed.
Definition: CDataCourse.hpp:44
CUnitSpeedVertical::EUnit eUnit
Unit for which the last rendering was achieved.
bool bForceRedraw
Forces the redraw of the instrument (not matter its cache content)
double fdSpeedVertical
Vertical speed at which the last rendering was achieved.
QPixmap qPixmapBufferBackground
Pixmap buffer used to render and cache the instrument's (static) background.
virtual void draw()
Draws the instrument (resets if the vessel is undefined)
QPixmap qPixmapBuffer
Pixmap buffer used to render and cache the instrument.
CInstrumentGASpeedVertical(CVesselCockpit *_poVesselCockpit)
void drawDynamic(CUnitSpeedVertical::EUnit _eUnit, const CVesselPoint *_poVesselPoint)
void drawStatic(CUnitSpeedVertical::EUnit _eUnit)
Generic instrument.
Definition: CInstrument.hpp:39
CVesselPoint * useVesselPoint()
Returns parent cockpit's associated vessel (0 if the vessel is undefined)
Definition: CInstrument.cpp:54
CUnitSpeedVertical::EUnit getUnitSpeedVertical()
[Unit] Returns the vertical speed format/unit
Definition: CSettings.hpp:357
Vertical speed unit (m/s,ft/min) rendering/parsing class.
static double toValue(double _fdValue, EUnit _eUnit)
Returns the converted value, using the specified format/unit.
static QString toSymbol(EUnit _eUnit)
Returns the human-readable symbol corresponding to the given format/unit ID.
@ FT_MIN
feet per minut [ft/min]
@ M_S
meters per second [m/s]
[UI] Generic vessel's cockpit view (window)
[UI] Vessel overlay point (item) / vessel
static CSettings * useSettings()
static constexpr double PI
Definition: QVCT.hpp:45