4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "VarioBarRenderer.hpp"
25 #include "TextInBox.hpp"
26 #include "Screen/Canvas.hpp"
27 #include "Screen/Layout.hpp"
28 #include "NMEA/MoreData.hpp"
29 #include "NMEA/Derived.hpp"
30 #include "Look/VarioBarLook.hpp"
31 #include "Look/TaskLook.hpp"
32 #include "Formatter/UserUnits.hpp"
33 #include "Util/Macros.hpp"
35 #include "Screen/OpenGL/Scope.hpp"
39 VarioBarRenderer::Draw(Canvas
&canvas
, const PixelRect
&rc
,
40 const MoreData
&basic
,
41 const DerivedInfo
&calculated
,
42 const GlidePolar
&glide_polar
,
43 const bool vario_bar_avg_enabled
) const
46 const GLEnable
blend(GL_BLEND
);
49 RasterPoint VarioBar
[6] = {
50 { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, 0 }, { 9, 0 }, { 0, 0 }
52 RasterPoint VarioBarAvg
[4] = {
53 { 0, 0 }, { 9, -9 }, { 9, 0 }, { 0, 0 }
55 RasterPoint clipping_arrow
[6] = {
56 { 0, 0 }, { 9, 9 }, { 18, 0 }, { 18, 6 }, { 9, 15 }, { 0, 6 }
58 RasterPoint clipping_arrow_av
[4] = {
59 { 0, 0 }, { 9, 9 }, { 9, 15 }, { 0, 6 }
61 RasterPoint mc_arrow
[6] = {
62 { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, -2 }, { 9, -11 }, { 0, -2 }
67 const int y0
= (rc
.bottom
+ rc
.top
) / 2;
69 /* NOTE: size_divisor replaces the fixed value 9 that was used throughout
70 * the code sink which caused fixed size rendering regardless of
71 * map size (except the effects of Layout::Scale()). This method
72 * is not usable with variable map sizes (e.g. because of the cross-section
73 * area). size_divisor is used to introduce a screen size dependent scaling.
74 * That workaround is an ugly hack and needs a rework. */
75 const fixed size_divisor
=
76 std::max((fixed
) Layout::Scale(70 / (rc
.bottom
- rc
.top
)), fixed(0.15));
78 PixelScalar dy_variobar
= 0;
79 PixelScalar dy_variobar_av
= 0;
80 PixelScalar dy_variobar_mc
= 0;
82 PixelScalar clipping_arrow_offset
= Layout::Scale(4);
83 PixelScalar clipping_arrow_av_offset
= Layout::Scale(4);
84 // PixelScalar clipping_arrow_mc_offset = Layout::Scale(4);
86 fixed vario_gross
= (fixed
) basic
.brutto_vario
;
88 FormatUserVerticalSpeed(vario_gross
, Value
, false, true);
89 canvas
.Select(*look
.font
);
90 const PixelSize text_size
= canvas
.CalcTextSize(Value
);
92 fixed vario_avg
= (fixed
) calculated
.average
;
94 // cut vario_gross at +- 5 meters/s
95 if (vario_gross
> fixed(5))
96 vario_gross
= fixed(5);
97 if (vario_gross
< fixed(-5))
98 vario_gross
= fixed(-5);
100 int Offset
= (int)(vario_gross
/ size_divisor
);
102 Offset
= Layout::Scale(Offset
);
103 if (!positive(vario_gross
)) {
104 VarioBar
[1].y
= Layout::Scale(9);
105 dy_variobar
= text_size
.cy
+ 2;
107 VarioBar
[1].y
= -Layout::Scale(9);
108 clipping_arrow
[1].y
= -clipping_arrow
[1].y
;
109 clipping_arrow
[3].y
= -clipping_arrow
[3].y
;
110 clipping_arrow
[4].y
= -clipping_arrow
[4].y
;
111 clipping_arrow
[5].y
= -clipping_arrow
[5].y
;
112 clipping_arrow_offset
= -clipping_arrow_offset
;
116 // cut vario_avg at +- 5 meters/s
117 if (vario_avg
> fixed(5))
118 vario_avg
= fixed(5);
119 if (vario_avg
< fixed(-5))
120 vario_avg
= fixed(-5);
122 int OffsetAvg
= int(vario_avg
/ size_divisor
);
124 OffsetAvg
= Layout::Scale(OffsetAvg
);
125 if (!positive(vario_avg
)) {
126 VarioBarAvg
[1].y
= Layout::Scale(9);
127 dy_variobar_av
= text_size
.cy
+ 2;
129 VarioBarAvg
[1].y
= -Layout::Scale(9);
130 clipping_arrow_av
[1].y
= -clipping_arrow_av
[1].y
;
131 clipping_arrow_av
[2].y
= -clipping_arrow_av
[2].y
;
132 clipping_arrow_av
[3].y
= -clipping_arrow_av
[3].y
;
133 clipping_arrow_av_offset
= -clipping_arrow_av_offset
;
139 fixed mc_val
= (fixed
) glide_polar
.GetMC();
140 if (mc_val
> fixed(5))
142 if (!positive(mc_val
)) {
143 dy_variobar_mc
= text_size
.cy
+ 2;
148 int OffsetMC
= int(mc_val
/ size_divisor
);
149 OffsetMC
= Layout::Scale(OffsetMC
);
151 for (unsigned i
= 0; i
< 6; i
++) {
152 VarioBar
[i
].y
+= y0
+ dy_variobar
;
153 VarioBar
[i
].x
= rc
.right
- Layout::Scale(VarioBar
[i
].x
);
156 VarioBar
[0].y
-= Offset
;
157 VarioBar
[1].y
-= Offset
;
158 VarioBar
[2].y
-= Offset
;
160 for (unsigned i
= 0; i
< 4; i
++) {
161 VarioBarAvg
[i
].y
+= y0
+ dy_variobar_av
;
162 VarioBarAvg
[i
].x
= rc
.right
-Layout::Scale(VarioBarAvg
[i
].x
);
165 VarioBarAvg
[0].y
-= OffsetAvg
;
166 VarioBarAvg
[1].y
-= OffsetAvg
;
169 for (unsigned i
= 0; i
< 6; i
++) {
170 mc_arrow
[i
].y
= Layout::Scale(mc_arrow
[i
].y
) + y0
171 - OffsetMC
+ dy_variobar_mc
;
172 mc_arrow
[i
].x
= rc
.right
- Layout::Scale(mc_arrow
[i
].x
);
175 // prepare clipping arrow
176 for (unsigned i
= 0; i
< 6; i
++) {
177 clipping_arrow
[i
].y
= Layout::Scale(clipping_arrow
[i
].y
) + y0
- Offset
178 + clipping_arrow_offset
+ dy_variobar
;
179 clipping_arrow
[i
].x
= rc
.right
- Layout::Scale(clipping_arrow
[i
].x
);
182 // prepare clipping avg
183 for (unsigned i
= 0; i
< 4; i
++) {
184 clipping_arrow_av
[i
].y
= Layout::Scale(clipping_arrow_av
[i
].y
) + y0
- OffsetAvg
185 + clipping_arrow_av_offset
+ dy_variobar_av
;
186 clipping_arrow_av
[i
].x
= rc
.right
-Layout::Scale(clipping_arrow_av
[i
].x
);
189 // draw actual vario bar
190 if (!positive(vario_gross
)) {
191 canvas
.Select(look
.pen_sink
);
192 canvas
.Select(look
.brush_sink
);
194 canvas
.Select(look
.pen_climb
);
195 canvas
.Select(look
.brush_climb
);
198 canvas
.DrawPolygon(VarioBar
, 6);
200 // draw clipping arrow
201 if (vario_gross
<= fixed(-5) || vario_gross
>= fixed(5))
202 canvas
.DrawPolygon(clipping_arrow
, 6);
204 // draw avg vario bar
205 if (!positive(vario_avg
) && vario_bar_avg_enabled
) {
206 canvas
.Select(look
.pen_sink
);
207 canvas
.Select(look
.brush_sink_avg
);
209 canvas
.Select(look
.pen_climb
);
210 canvas
.Select(look
.brush_climb_avg
);
213 canvas
.DrawPolygon(VarioBarAvg
, 4);
215 if (vario_avg
<= fixed(-5.0) || vario_avg
>= fixed(5.0))
216 canvas
.DrawPolygon(clipping_arrow_av
, 4);
219 canvas
.Select(look
.pen_mc
);
220 canvas
.Select(look
.brush_mc
);
222 canvas
.DrawPolygon(mc_arrow
, 6);
225 canvas
.SetTextColor(COLOR_BLACK
);
226 canvas
.SetBackgroundColor(COLOR_WHITE
);
229 style
.shape
= LabelShape::ROUNDED_BLACK
;
230 style
.move_in_view
= true;
232 if (text_size
.cx
< Layout::Scale(18)) {
233 style
.align
= TextInBoxMode::Alignment::RIGHT
;
234 TextInBox(canvas
, Value
, rc
.right
, y0
, style
, rc
);
236 TextInBox(canvas
, Value
, rc
.right
-Layout::Scale(18), y0
, style
, rc
);