Qt Virtual Chart Table (QVCT)
CInstrumentGAAltimeter.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( CUnitElevation::FT )
45  , fdElevation( CDataPosition::UNDEFINED_ELEVATION )
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 __fdElevation = __poVesselPoint ? __poVesselPoint->getElevation() : 0.0;
60 
61  // Redraw pixmap only if required
62  if( bForceRedraw
63  || qPixmapBuffer.size() != QWidget::size()
64  || eUnit != __eUnit
65  || fdElevation != __fdElevation )
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  fdElevation = __fdElevation;
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 
119  // ... delimiting corona
120  __qPen.setColor( Qt::white );
121  __qPen.setWidth( 10.0 );
122  __qPainter.setPen( __qPen );
123  __qPainter.setBrush( QBrush( QColor( 32, 32, 32, 255 ) ) );
124  __qPainter.drawEllipse( QPointF( 0.0, 0.0 ), 495.0, 495.0 );
125 
126  // ... small ticks
127  for( int __i=0; __i<50; __i++ )
128  {
129  double __fdAngle = (double)__i * QVCT::PI / 25.0;
130  QPointF __qPointFAngle( sin( __fdAngle ), -cos( __fdAngle ) );
131  __qPainter.drawLine( 450.0*__qPointFAngle, 480.0*__qPointFAngle );
132  }
133 
134  // ... large ticks and digits
135  __qFont.setPixelSize( 120.0 );
136  __qFont.setBold( true );
137  __qPainter.setFont( __qFont );
138  {
139  QRectF __qRectFText( QPointF( -60.0, -60.0 ), QSizeF( 120.0, 120.0 ) );
140  for( int __i=0; __i<10; __i++ )
141  {
142  double __fdAngle = (double)__i * QVCT::PI / 5.0;
143  QPointF __qPointFAngle( sin( __fdAngle ), -cos( __fdAngle ) );
144  __qPainter.drawLine( 420.0*__qPointFAngle, 480.0*__qPointFAngle );
145  __qPainter.drawText( __qRectFText.translated( 350.0*__qPointFAngle ), Qt::AlignCenter, QString::number( __i ) );
146  }
147  }
148 
149  // ... name and units
150  __qPen.setColor( Qt::lightGray );
151  __qPen.setWidth( 5.0 );
152  __qPainter.setPen( __qPen );
153  __qPainter.setBrush( QBrush( QColor( 32, 32, 32, 255 ) ) );
154  __qFont.setPixelSize( 50.0 );
155  __qFont.setBold( false );
156  __qPainter.setFont( __qFont );
157  {
158  QRectF __qRectFText( QPointF( -200.0, -30.0 ), QSizeF( 400.0, 60.0 ) );
159  __qPainter.drawText( __qRectFText.translated( QPointF( 0, -150.0 ) ), Qt::AlignCenter, CUnitElevation::toSymbol( _eUnit ) );
160  __qPainter.drawText( __qRectFText.translated( QPointF( 0, +150.0 ) ), Qt::AlignCenter, "ALT" );
161  }
162 
163  // ... data
164  {
165  QRectF __qRectFFrame( QPointF( -150.0, -60.0 ), QSizeF( 300.0, 120.0 ) );
166  QRectF __qRectFText( QPointF( -125.0, -30.0 ), QSizeF( 250.0, 60.0 ) );
167  __qPainter.drawRoundedRect( __qRectFFrame.translated( QPointF( +425.0, +515.0 ) ), 10.0, 10.0 );
168  __qPainter.drawText( __qRectFText.translated( QPointF( +440.0, +540.0 ) ), Qt::AlignRight, "ALT" );
169  }
170 }
171 
173 {
174  double __fdElevation = _poVesselPoint ? _poVesselPoint->getElevation() : 0.0;
175  double __fdElevationConverted = __fdElevation != CDataPosition::UNDEFINED_ELEVATION ? CUnitElevation::toValue( __fdElevation, _eUnit ) : 0.0;
176 
177  // Widget geometry
178  QPointF __qPointFCenter = QPointF( QRectF( QWidget::rect() ).center() );
179  double __fdSizeFactor = ( QWidget::width() < QWidget::height() ? (double)QWidget::width() : (double)QWidget::height() ) / 1200.0;
180  QTransform __qTransform;
181  __qTransform.translate( __qPointFCenter.x(), __qPointFCenter.y() );
182  __qTransform.scale( __fdSizeFactor, __fdSizeFactor );
183 
184  // Painter and resources
186  QPainter __qPainter( &qPixmapBuffer );
187  QPen __qPen;
188  QFont __qFont;
189  __qPainter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing );
190 
191  // Draw
192  __qPainter.setWorldTransform( __qTransform );
193 
194  // ... ten-thousands
195  __qPen.setColor( Qt::black );
196  __qPen.setWidth( 0 );
197  __qPainter.setPen( __qPen );
198  __qPainter.setBrush( QBrush( Qt::white ) );
199  __qPainter.rotate( __fdElevationConverted*0.0036 );
200  {
201  static const QPointF __pqPointFPolygon[3] =
202  {
203  QPointF( -60.0, -480.0 ),
204  QPointF( 0.0, -420.0 ),
205  QPointF( +60.0, -480.0 ),
206  };
207  __qPainter.drawConvexPolygon( __pqPointFPolygon, 3 );
208  }
209 
210  // ... thousands
211  __qPainter.setWorldTransform( __qTransform );
212  __qPainter.rotate( fmod( __fdElevationConverted, 10000.0 )*0.036 );
213  {
214  static const QPointF __pqPointFPolygon[5] =
215  {
216  QPointF( -25.0, -10.0 ),
217  QPointF( -35.0, -150.0 ),
218  QPointF( 0.0, -250.0 ),
219  QPointF( +35.0, -150.0 ),
220  QPointF( +25.0, -10.0 ),
221  };
222  __qPainter.drawConvexPolygon( __pqPointFPolygon, 5 );
223  }
224 
225  // ... hundreds
226  __qPainter.setWorldTransform( __qTransform );
227  __qPainter.rotate( fmod( __fdElevationConverted, 1000.0 )*0.36 );
228  {
229  static const QPointF __pqPointFPolygon[5] =
230  {
231  QPointF( -15.0, -10.0 ),
232  QPointF( -15.0, -370.0 ),
233  QPointF( 0.0, -400.0 ),
234  QPointF( +15.0, -370.0 ),
235  QPointF( +15.0, -10.0 ),
236  };
237  __qPainter.drawConvexPolygon( __pqPointFPolygon, 5 );
238  }
239 
240  // ... center mask
241  __qPainter.setWorldTransform( __qTransform );
242  __qPainter.drawEllipse( QPointF( 0.0, 0.0 ), 40.0, 40.0 );
243  __qPainter.setBrush( QBrush( Qt::black ) );
244  __qPainter.drawEllipse( QPointF( 0.0, 0.0 ), 30.0, 30.0 );
245 
246  // ... data
247  __qPen.setColor( Qt::white );
248  __qPen.setWidth( 0 );
249  __qPainter.setPen( __qPen );
250  __qFont.setPixelSize( 50.0 );
251  __qFont.setBold( false );
252  __qFont.setItalic( !_poVesselPoint || __fdElevation == CDataPosition::UNDEFINED_ELEVATION || !_poVesselPoint->isValidElevation() );
253  __qPainter.setFont( __qFont );
254  {
255  QRectF __qRectFText( QPointF( -125.0, -30.0 ), QSizeF( 250.0, 60.0 ) );
256  QString __qsALT( "n/a" );
257  if( _poVesselPoint && __fdElevation != CDataPosition::UNDEFINED_ELEVATION )
258  {
259  __qsALT = CUnitElevation::toString( __fdElevation, _eUnit, 0 );
260  }
261  __qPainter.drawText( __qRectFText.translated( QPointF( +425.0, +490.0 ) ), Qt::AlignCenter, __qsALT );
262  }
263 
264  // ... OFF flag
265  __qPainter.setWorldTransform( __qTransform );
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 }
bool isValidElevation() const
Returns the elevation's (global) validity status.
(Geographical) Position data [long,lat,elev]
double getElevation() const
Returns this position's elevation, in meters.
static constexpr double UNDEFINED_ELEVATION
Specific value for an undefined elevation.
bool bForceRedraw
Forces the redraw of the instrument (not matter its cache content)
virtual void draw()
Draws the instrument (resets if the vessel is undefined)
double fdElevation
Elevation at which the last rendering was achieved.
CUnitElevation::EUnit eUnit
Unit for which the last rendering was achieved.
void drawStatic(CUnitElevation::EUnit _eUnit)
QPixmap qPixmapBufferBackground
Pixmap buffer used to render and cache the instrument's (static) background.
QPixmap qPixmapBuffer
Pixmap buffer used to render and cache the instrument.
CInstrumentGAAltimeter(CVesselCockpit *_poVesselCockpit)
void drawDynamic(CUnitElevation::EUnit _eUnit, const CVesselPoint *_poVesselPoint)
Generic instrument.
Definition: CInstrument.hpp:39
CVesselPoint * useVesselPoint()
Returns parent cockpit's associated vessel (0 if the vessel is undefined)
Definition: CInstrument.cpp:54
CUnitElevation::EUnit getUnitElevation()
[Unit] Returns the elevation format/unit
Definition: CSettings.hpp:355
Elevation unit (m,ft) rendering/parsing class.
static double toValue(double _fdValue, EUnit _eUnit)
Returns the converted value, using the specified format/unit.
static QString toString(double _fdValue, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
EUnit
Format/unit ID.
static QString toSymbol(EUnit _eUnit)
Returns the human-readable symbol corresponding to the given format/unit ID.
[UI] Generic vessel's cockpit view (window)
[UI] Vessel overlay point (item) / vessel
static CSettings * useSettings()
static constexpr double PI
Definition: QVCT.hpp:45