TaskManager: allocate the task objects dynamically
[xcsoar.git] / src / Renderer / FlightStatisticsRenderer.cpp
blobbf0c946fa6cd1c9164e2d024568b728d2b1efadd
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 "FlightStatisticsRenderer.hpp"
25 #include "ChartRenderer.hpp"
26 #include "FlightStatistics.hpp"
27 #include "Util/Macros.hpp"
28 #include "Look/MapLook.hpp"
29 #include "Task/ProtectedTaskManager.hpp"
30 #include "Engine/Task/Ordered/OrderedTask.hpp"
31 #include "Screen/Canvas.hpp"
32 #include "Screen/Layout.hpp"
33 #include "NMEA/Info.hpp"
34 #include "NMEA/Derived.hpp"
35 #include "Formatter/UserUnits.hpp"
36 #include "Formatter/TimeFormatter.hpp"
37 #include "Units/Units.hpp"
38 #include "Language/Language.hpp"
39 #include "ComputerSettings.hpp"
40 #include "MapSettings.hpp"
41 #include "GlideSolvers/GlidePolar.hpp"
42 #include "Projection/ChartProjection.hpp"
43 #include "Renderer/TaskRenderer.hpp"
44 #include "Renderer/TaskPointRenderer.hpp"
45 #include "Renderer/OZRenderer.hpp"
46 #include "Renderer/AircraftRenderer.hpp"
47 #include "Computer/TraceComputer.hpp"
49 #include <algorithm>
51 #include <stdio.h>
53 using std::max;
55 FlightStatisticsRenderer::FlightStatisticsRenderer(const ChartLook &_chart_look,
56 const MapLook &_map_look)
57 :chart_look(_chart_look),
58 map_look(_map_look),
59 trail_renderer(map_look.trail) {}
61 void
62 FlightStatisticsRenderer::RenderOLC(Canvas &canvas, const PixelRect rc,
63 const NMEAInfo &nmea_info,
64 const ComputerSettings &settings_computer,
65 const MapSettings &settings_map,
66 const ContestStatistics &contest,
67 const TraceComputer &trace_computer) const
69 if (!trail_renderer.LoadTrace(trace_computer)) {
70 ChartRenderer chart(chart_look, canvas, rc);
71 chart.DrawNoData();
72 return;
75 TaskProjection task_projection(trail_renderer.GetBounds(nmea_info.location));
77 /* scan all solutions to make sure they are all visible */
78 for (unsigned i = 0; i < 3; ++i) {
79 if (contest.GetResult(i).IsDefined()) {
80 const ContestTraceVector &solution = contest.GetSolution(i);
81 for (auto j = solution.begin(), end = solution.end(); j != end; ++j)
82 task_projection.Scan(j->location);
87 const ChartProjection proj(rc, task_projection);
89 RasterPoint aircraft_pos = proj.GeoToScreen(nmea_info.location);
90 AircraftRenderer::Draw(canvas, settings_map, map_look.aircraft,
91 nmea_info.attitude.heading, aircraft_pos);
93 trail_renderer.Draw(canvas, proj);
95 for (unsigned i=0; i< 3; ++i) {
96 if (contest.GetResult(i).IsDefined()) {
97 canvas.Select(map_look.contest_pens[i]);
98 trail_renderer.DrawTraceVector(canvas, proj, contest.GetSolution(i));
103 void
104 FlightStatisticsRenderer::CaptionOLC(TCHAR *sTmp,
105 const ContestSettings &settings,
106 const DerivedInfo &derived)
108 if (settings.contest == Contest::OLC_PLUS) {
109 const ContestResult& result =
110 derived.contest_stats.GetResult(2);
112 const ContestResult& result_classic =
113 derived.contest_stats.GetResult(0);
115 const ContestResult& result_fai =
116 derived.contest_stats.GetResult(1);
118 TCHAR timetext1[100];
119 FormatSignedTimeHHMM(timetext1, (int)result.time);
120 TCHAR distance_classic[100];
121 FormatUserDistanceSmart(result_classic.distance, distance_classic, 100);
122 TCHAR distance_fai[100];
123 FormatUserDistanceSmart(result_fai.distance, distance_fai, 100);
124 TCHAR speed[100];
125 FormatUserTaskSpeed(result.GetSpeed(), speed, ARRAY_SIZE(speed));
126 _stprintf(sTmp,
127 (Layout::landscape
128 ? _T("%s:\r\n%s\r\n%s (FAI)\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n")
129 : _T("%s: %s\r\n%s (FAI)\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n")),
130 _("Distance"), distance_classic, distance_fai,
131 _("Score"), (double)result.score, _("pts"),
132 _("Time"), timetext1,
133 _("Speed"), speed);
134 } else if (settings.contest == Contest::DHV_XC ||
135 settings.contest == Contest::XCONTEST) {
136 const ContestResult& result_free =
137 derived.contest_stats.GetResult(0);
139 const ContestResult& result_triangle =
140 derived.contest_stats.GetResult(1);
142 TCHAR timetext1[100];
143 FormatSignedTimeHHMM(timetext1, (int)result_free.time);
144 TCHAR distance[100];
145 FormatUserDistanceSmart(result_free.distance, distance, 100);
146 TCHAR distance_fai[100];
147 FormatUserDistanceSmart(result_triangle.distance, distance_fai, 100);
148 TCHAR speed[100];
149 FormatUserTaskSpeed(result_free.GetSpeed(), speed, ARRAY_SIZE(speed));
150 _stprintf(sTmp,
151 (Layout::landscape
152 ? _T("%s:\r\n%s (Free)\r\n%s (Triangle)\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n")
153 : _T("%s: %s (Free)\r\n%s (Triangle)\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n")),
154 _("Distance"), distance, distance_fai,
155 _("Score"), (double)result_free.score, _("pts"),
156 _("Time"), timetext1,
157 _("Speed"), speed);
158 } else {
159 unsigned result_index;
160 switch (settings.contest) {
161 case Contest::OLC_LEAGUE:
162 result_index = 0;
163 break;
165 default:
166 result_index = -1;
167 break;
170 const ContestResult& result_olc =
171 derived.contest_stats.GetResult(result_index);
173 TCHAR timetext1[100];
174 FormatSignedTimeHHMM(timetext1, (int)result_olc.time);
175 TCHAR distance[100];
176 FormatUserDistanceSmart(result_olc.distance, distance, 100);
177 TCHAR speed[100];
178 FormatUserTaskSpeed(result_olc.GetSpeed(), speed, ARRAY_SIZE(speed));
179 _stprintf(sTmp,
180 (Layout::landscape
181 ? _T("%s:\r\n%s\r\n%s:\r\n%.1f %s\r\n%s: %s\r\n%s: %s\r\n")
182 : _T("%s: %s\r\n%s: %.1f %s\r\n%s: %s\r\n%s: %s\r\n")),
183 _("Distance"), distance,
184 _("Score"), (double)result_olc.score, _("pts"),
185 _("Time"), timetext1,
186 _("Speed"), speed);
190 void
191 FlightStatisticsRenderer::RenderTask(Canvas &canvas, const PixelRect rc,
192 const NMEAInfo &nmea_info,
193 const ComputerSettings &settings_computer,
194 const MapSettings &settings_map,
195 const ProtectedTaskManager &_task_manager,
196 const TraceComputer *trace_computer) const
198 ChartRenderer chart(chart_look, canvas, rc);
200 ChartProjection proj;
203 ProtectedTaskManager::Lease task_manager(_task_manager);
204 const OrderedTask &task = task_manager->GetOrderedTask();
206 if (!task.CheckTask()) {
207 chart.DrawNoData();
208 return;
211 proj.Set(rc, task, nmea_info.location);
213 OZRenderer ozv(map_look.task, map_look.airspace, settings_map.airspace);
214 TaskPointRenderer tpv(canvas, proj, map_look.task,
215 task.GetTaskProjection(),
216 ozv, false, TaskPointRenderer::ALL,
217 nmea_info.location_available, nmea_info.location);
218 ::TaskRenderer dv(tpv, proj.GetScreenBounds());
219 dv.Draw(task);
222 if (trace_computer != NULL)
223 trail_renderer.Draw(canvas, *trace_computer, proj, 0);
225 if (nmea_info.location_available) {
226 RasterPoint aircraft_pos = proj.GeoToScreen(nmea_info.location);
227 AircraftRenderer::Draw(canvas, settings_map, map_look.aircraft,
228 nmea_info.attitude.heading, aircraft_pos);
232 void
233 FlightStatisticsRenderer::CaptionTask(TCHAR *sTmp, const DerivedInfo &derived)
235 const TaskStats &task_stats = derived.ordered_task_stats;
236 const CommonStats &common = derived.common_stats;
238 if (!task_stats.task_valid ||
239 !derived.task_stats.total.remaining.IsDefined()) {
240 _tcscpy(sTmp, _("No task"));
241 } else {
242 const fixed d_remaining = derived.task_stats.total.remaining.GetDistance();
243 TCHAR timetext1[100];
244 TCHAR timetext2[100];
245 if (common.ordered_has_targets) {
246 FormatSignedTimeHHMM(timetext1, (int)task_stats.total.time_remaining);
247 FormatSignedTimeHHMM(timetext2, (int)common.aat_time_remaining);
249 if (Layout::landscape) {
250 _stprintf(sTmp,
251 _T("%s:\r\n %s\r\n%s:\r\n %s\r\n%s:\r\n %5.0f %s\r\n%s:\r\n %5.0f %s\r\n"),
252 _("Task to go"), timetext1, _("AAT to go"), timetext2,
253 _("Distance to go"),
254 (double)Units::ToUserDistance(d_remaining),
255 Units::GetDistanceName(), _("Target speed"),
256 (double)Units::ToUserTaskSpeed(common.aat_speed_remaining),
257 Units::GetTaskSpeedName());
258 } else {
259 _stprintf(sTmp,
260 _T("%s: %s\r\n%s: %s\r\n%s: %5.0f %s\r\n%s: %5.0f %s\r\n"),
261 _("Task to go"), timetext1, _("AAT to go"), timetext2,
262 _("Distance to go"),
263 (double)Units::ToUserDistance(d_remaining),
264 Units::GetDistanceName(),
265 _("Target speed"),
266 (double)Units::ToUserTaskSpeed(common.aat_speed_remaining),
267 Units::GetTaskSpeedName());
269 } else {
270 FormatSignedTimeHHMM(timetext1, (int)task_stats.total.time_remaining);
271 _stprintf(sTmp, _T("%s: %s\r\n%s: %5.0f %s\r\n"),
272 _("Task to go"), timetext1, _("Distance to go"),
273 (double)Units::ToUserDistance(d_remaining),
274 Units::GetDistanceName());