Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / src / InfoBoxes / Content / Weather.cpp
blob50a61eddb62473964f7eb340bd61b09fe8f8eaf2
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 "InfoBoxes/Content/Weather.hpp"
25 #include "InfoBoxes/Panel/Panel.hpp"
26 #include "InfoBoxes/Panel/WindEdit.hpp"
27 #include "InfoBoxes/Data.hpp"
28 #include "Interface.hpp"
29 #include "Dialogs/dlgInfoBoxAccess.hpp"
30 #include "Util/Macros.hpp"
31 #include "Units/Units.hpp"
32 #include "Language/Language.hpp"
33 #include "Formatter/UserUnits.hpp"
34 #include "Formatter/AngleFormatter.hpp"
35 #include "Screen/Layout.hpp"
36 #include "Renderer/WindArrowRenderer.hpp"
37 #include "UIGlobals.hpp"
38 #include "Look/Look.hpp"
40 #include <tchar.h>
41 #include <stdio.h>
43 void
44 UpdateInfoBoxHumidity(InfoBoxData &data)
46 const NMEAInfo &basic = CommonInterface::Basic();
47 if (!basic.humidity_available) {
48 data.SetInvalid();
49 return;
52 // Set Value
53 data.UnsafeFormatValue( _T("%d"), (int)basic.humidity);
56 void
57 UpdateInfoBoxTemperature(InfoBoxData &data)
59 const NMEAInfo &basic = CommonInterface::Basic();
60 if (!basic.temperature_available) {
61 data.SetInvalid();
62 return;
65 // Set Value
66 data.SetValue(_T("%2.1f"),
67 Units::ToUserTemperature(basic.temperature));
69 data.SetValueUnit(Units::current.temperature_unit);
72 void
73 InfoBoxContentTemperatureForecast::Update(InfoBoxData &data)
75 fixed temperature = CommonInterface::GetComputerSettings().forecast_temperature;
76 data.SetValue(_T("%2.1f"),
77 Units::ToUserTemperature(temperature));
79 data.SetValueUnit(Units::current.temperature_unit);
82 bool
83 InfoBoxContentTemperatureForecast::HandleKey(const InfoBoxKeyCodes keycode)
85 switch(keycode) {
86 case ibkUp:
87 CommonInterface::SetComputerSettings().forecast_temperature += fixed(0.5);
88 return true;
90 case ibkDown:
91 CommonInterface::SetComputerSettings().forecast_temperature -= fixed(0.5);
92 return true;
94 default:
95 break;
98 return false;
102 * Subpart callback function pointers
105 #ifdef __clang__
106 /* gcc gives "redeclaration differs in 'constexpr'" */
107 constexpr
108 #endif
109 const InfoBoxPanel wind_infobox_panels[] = {
110 { N_("Edit"), LoadWindEditPanel },
111 { nullptr, nullptr }
114 const InfoBoxPanel *
115 InfoBoxContentWindArrow::GetDialogContent()
117 return wind_infobox_panels;
120 void
121 UpdateInfoBoxWindSpeed(InfoBoxData &data)
123 const DerivedInfo &info = CommonInterface::Calculated();
124 if (!info.wind_available) {
125 data.SetInvalid();
126 return;
129 // Set Value
130 data.SetValue(_T("%2.0f"),
131 Units::ToUserWindSpeed(info.wind.norm));
133 // Set Unit
134 data.SetValueUnit(Units::current.wind_speed_unit);
136 // Set Comment
137 data.SetComment(info.wind.bearing);
140 void
141 UpdateInfoBoxWindBearing(InfoBoxData &data)
143 const DerivedInfo &info = CommonInterface::Calculated();
144 if (!info.wind_available) {
145 data.SetInvalid();
146 return;
149 data.SetValue(info.wind.bearing);
151 TCHAR buffer[16];
152 FormatUserWindSpeed(info.wind.norm, buffer, true, false);
153 data.SetComment(buffer);
156 void
157 UpdateInfoBoxHeadWind(InfoBoxData &data)
159 const DerivedInfo &info = CommonInterface::Calculated();
160 if (!info.head_wind_available) {
161 data.SetInvalid();
162 return;
165 // Set Value
166 data.SetValue(_T("%2.0f"),
167 Units::ToUserWindSpeed(info.head_wind));
169 // Set Unit
170 data.SetValueUnit(Units::current.wind_speed_unit);
173 void
174 UpdateInfoBoxHeadWindSimplified(InfoBoxData &data)
176 const NMEAInfo &basic = CommonInterface::Basic();
177 if (!basic.ground_speed_available || !basic.airspeed_available) {
178 data.SetInvalid();
179 return;
182 fixed value = basic.true_airspeed - basic.ground_speed;
184 // Set Value
185 data.SetValue(_T("%2.0f"), Units::ToUserWindSpeed(value));
187 // Set Unit
188 data.SetValueUnit(Units::current.wind_speed_unit);
191 void
192 InfoBoxContentWindArrow::Update(InfoBoxData &data)
194 const DerivedInfo &info = CommonInterface::Calculated();
195 if (!info.wind_available || info.wind.IsZero()) {
196 data.SetInvalid();
197 return;
200 data.SetCustom();
202 TCHAR speed_buffer[16], bearing_buffer[16];
203 FormatUserWindSpeed(info.wind.norm, speed_buffer, true, false);
204 FormatBearing(bearing_buffer, ARRAY_SIZE(bearing_buffer), info.wind.bearing);
206 StaticString<32> buffer;
207 buffer.Format(_T("%s / %s"), bearing_buffer, speed_buffer);
208 data.SetComment(buffer);
211 void
212 InfoBoxContentWindArrow::OnCustomPaint(Canvas &canvas, const PixelRect &rc)
214 const auto &info = CommonInterface::Calculated();
216 const RasterPoint pt = rc.GetCenter();
218 UPixelScalar padding = Layout::FastScale(10);
219 UPixelScalar size = std::min(rc.right - rc.left, rc.bottom - rc.top);
221 if (size > padding)
222 size -= padding;
224 // Normalize the size because the Layout::Scale is applied
225 // by the DrawArrow() function again
226 size = size * 100 / Layout::Scale(100);
228 auto angle = info.wind.bearing - CommonInterface::Basic().attitude.heading;
230 PixelScalar length =
231 std::min(size, (UPixelScalar)std::max(10, iround(info.wind.norm * 4)));
233 PixelScalar offset = -length / 2;
235 auto style = CommonInterface::GetMapSettings().wind_arrow_style;
237 WindArrowRenderer renderer(UIGlobals::GetLook().wind_arrow_info_box);
238 renderer.DrawArrow(canvas, pt, angle, length, style, offset);