Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / src / Renderer / VarioBarRenderer.cpp
blobeb9f5ad7a73435d3547c85cbf259c9a6a1cf77c0
1 /*
2 Copyright_License {
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"
34 #ifdef ENABLE_OPENGL
35 #include "Screen/OpenGL/Scope.hpp"
36 #endif
38 void
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
45 #ifdef ENABLE_OPENGL
46 const GLEnable blend(GL_BLEND);
47 #endif
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 }
65 TCHAR Value[10];
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;
106 } else {
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;
113 dy_variobar = -1;
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;
128 } else {
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;
134 dy_variobar_av = -1;
138 //clip MC Value
139 fixed mc_val = (fixed) glide_polar.GetMC();
140 if (mc_val > fixed(5))
141 mc_val = fixed(5);
142 if (!positive(mc_val)) {
143 dy_variobar_mc = text_size.cy + 2;
144 }else{
145 dy_variobar_mc = -1;
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;
168 // prepare mc arrow
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);
193 } else {
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);
208 } else {
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);
218 //draw MC arrow
219 canvas.Select(look.pen_mc);
220 canvas.Select(look.brush_mc);
222 canvas.DrawPolygon(mc_arrow, 6);
224 //draw text
225 canvas.SetTextColor(COLOR_BLACK);
226 canvas.SetBackgroundColor(COLOR_WHITE);
228 TextInBoxMode style;
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);
235 } else
236 TextInBox(canvas, Value, rc.right-Layout::Scale(18), y0, style, rc);