Android release v6.7_preview1
[xcsoar.git] / src / Dialogs / Settings / dlgBasicSettings.cpp
blob104e813a3d5872a999e18f89cf2a6bd4e19101b4
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 "Dialogs/Dialogs.h"
25 #include "Dialogs/WidgetDialog.hpp"
26 #include "Protection.hpp"
27 #include "Blackboard/DeviceBlackboard.hpp"
28 #include "Computer/Settings.hpp"
29 #include "Units/Units.hpp"
30 #include "Formatter/UserUnits.hpp"
31 #include "Atmosphere/Temperature.hpp"
32 #include "Form/DataField/Float.hpp"
33 #include "Form/DataField/Listener.hpp"
34 #include "UIGlobals.hpp"
35 #include "Interface.hpp"
36 #include "Components.hpp"
37 #include "GlideSolvers/GlidePolar.hpp"
38 #include "Task/ProtectedTaskManager.hpp"
39 #include "Widget/RowFormWidget.hpp"
40 #include "Form/Button.hpp"
41 #include "Form/Form.hpp"
42 #include "Form/ButtonPanel.hpp"
43 #include "Language/Language.hpp"
44 #include "Operation/MessageOperationEnvironment.hpp"
45 #include "Event/Timer.hpp"
46 #include "Compiler.h"
48 #include <math.h>
50 enum ControlIndex {
51 Ballast,
52 WingLoading,
53 Bugs,
54 QNH,
55 Altitude,
56 Temperature,
59 enum Actions {
60 DUMP = 100,
63 class FlightSetupPanel final
64 : public RowFormWidget, DataFieldListener,
65 private Timer,
66 public ActionListener {
67 WndButton *dump_button;
69 PolarSettings &polar_settings;
71 fixed last_altitude;
73 public:
74 FlightSetupPanel()
75 :RowFormWidget(UIGlobals::GetDialogLook()),
76 dump_button(NULL),
77 polar_settings(CommonInterface::SetComputerSettings().polar),
78 last_altitude(-2)
81 void SetDumpButton(WndButton *_dump_button) {
82 dump_button = _dump_button;
85 void SetButtons();
86 void SetBallast();
87 void SetBallastTimer(bool active);
88 void FlipBallastTimer();
90 void PublishPolarSettings() {
91 if (protected_task_manager != NULL)
92 protected_task_manager->SetGlidePolar(polar_settings.glide_polar_task);
95 void SetBallastLitres(fixed ballast_litres) {
96 polar_settings.glide_polar_task.SetBallastLitres(ballast_litres);
97 PublishPolarSettings();
98 SetButtons();
99 SetBallast();
102 void ShowAltitude(fixed altitude);
103 void RefreshAltitudeControl();
104 void SetBugs(fixed bugs);
105 void SetQNH(AtmosphericPressure qnh);
107 /* virtual methods from Widget */
108 virtual void Prepare(ContainerWindow &parent,
109 const PixelRect &rc) override;
110 virtual bool Save(bool &changed) override;
112 virtual void Show(const PixelRect &rc) override {
113 RowFormWidget::Show(rc);
114 Timer::Schedule(500);
116 OnTimer();
117 SetButtons();
118 SetBallast();
121 virtual void Hide() override {
122 Timer::Cancel();
123 RowFormWidget::Hide();
126 /* virtual methods from ActionListener */
127 virtual void OnAction(int id) override;
129 private:
130 /* virtual methods from DataFieldListener */
131 virtual void OnModified(DataField &df) override;
132 virtual void OnSpecial(DataField &df) override;
134 /* virtual methods from Timer */
135 virtual void OnTimer() override;
138 void
139 FlightSetupPanel::SetButtons()
141 dump_button->SetVisible(polar_settings.glide_polar_task.HasBallast());
143 const ComputerSettings &settings = CommonInterface::GetComputerSettings();
144 dump_button->SetCaption(settings.polar.ballast_timer_active
145 ? _("Stop") : _("Dump"));
148 void
149 FlightSetupPanel::SetBallast()
151 const bool ballastable = polar_settings.glide_polar_task.IsBallastable();
152 SetRowVisible(Ballast, ballastable);
153 if (ballastable)
154 LoadValue(Ballast, polar_settings.glide_polar_task.GetBallastLitres());
156 const fixed wl = polar_settings.glide_polar_task.GetWingLoading();
157 SetRowVisible(WingLoading, positive(wl));
158 if (positive(wl))
159 LoadValue(WingLoading, wl);
161 if (device_blackboard != NULL) {
162 const Plane &plane = CommonInterface::GetComputerSettings().plane;
163 if (positive(plane.dry_mass)) {
164 fixed fraction = polar_settings.glide_polar_task.GetBallast();
165 fixed overload = (plane.dry_mass + fraction * plane.max_ballast) /
166 plane.dry_mass;
168 MessageOperationEnvironment env;
169 device_blackboard->SetBallast(fraction, overload, env);
174 void
175 FlightSetupPanel::SetBallastTimer(bool active)
177 if (!polar_settings.glide_polar_task.HasBallast())
178 active = false;
180 PolarSettings &settings = CommonInterface::SetComputerSettings().polar;
181 if (active == settings.ballast_timer_active)
182 return;
184 settings.ballast_timer_active = active;
185 SetButtons();
188 void
189 FlightSetupPanel::FlipBallastTimer()
191 const ComputerSettings &settings = CommonInterface::GetComputerSettings();
192 SetBallastTimer(!settings.polar.ballast_timer_active);
195 void
196 FlightSetupPanel::ShowAltitude(fixed altitude)
198 if (fabs(altitude - last_altitude) >= fixed(1)) {
199 last_altitude = altitude;
200 LoadValue(Altitude, altitude, UnitGroup::ALTITUDE);
203 ShowRow(Altitude);
206 void
207 FlightSetupPanel::RefreshAltitudeControl()
209 const NMEAInfo &basic = CommonInterface::Basic();
210 ComputerSettings &settings_computer = CommonInterface::SetComputerSettings();
212 if (basic.pressure_altitude_available && settings_computer.pressure_available)
213 ShowAltitude(settings_computer.pressure.PressureAltitudeToQNHAltitude(
214 basic.pressure_altitude));
215 else if (basic.baro_altitude_available)
216 ShowAltitude(basic.baro_altitude);
217 else
218 HideRow(Altitude);
221 void
222 FlightSetupPanel::SetBugs(fixed bugs) {
223 polar_settings.SetBugs(bugs);
224 PublishPolarSettings();
226 if (device_blackboard != NULL) {
227 MessageOperationEnvironment env;
228 device_blackboard->SetBugs(bugs, env);
232 void
233 FlightSetupPanel::SetQNH(AtmosphericPressure qnh)
235 const NMEAInfo &basic = CommonInterface::Basic();
236 ComputerSettings &settings_computer = CommonInterface::SetComputerSettings();
238 settings_computer.pressure = qnh;
239 settings_computer.pressure_available.Update(basic.clock);
241 if (device_blackboard != NULL) {
242 MessageOperationEnvironment env;
243 device_blackboard->SetQNH(qnh, env);
246 RefreshAltitudeControl();
249 void
250 FlightSetupPanel::OnTimer()
252 const PolarSettings &settings = CommonInterface::GetComputerSettings().polar;
254 if (settings.ballast_timer_active) {
255 /* display the new values on the screen */
256 SetBallast();
259 RefreshAltitudeControl();
262 void
263 FlightSetupPanel::OnModified(DataField &df)
265 if (IsDataField(Ballast, df)) {
266 const DataFieldFloat &dff = (const DataFieldFloat &)df;
267 SetBallastLitres(dff.GetAsFixed());
268 } else if (IsDataField(Bugs, df)) {
269 const DataFieldFloat &dff = (const DataFieldFloat &)df;
270 SetBugs(fixed(1) - (dff.GetAsFixed() / 100));
271 } else if (IsDataField(QNH, df)) {
272 const DataFieldFloat &dff = (const DataFieldFloat &)df;
273 SetQNH(Units::FromUserPressure(dff.GetAsFixed()));
277 void
278 FlightSetupPanel::OnSpecial(DataField &df)
280 if (IsDataField(Ballast, df))
281 FlipBallastTimer();
284 void
285 FlightSetupPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
287 RowFormWidget::Prepare(parent, rc);
289 const ComputerSettings &settings = CommonInterface::GetComputerSettings();
291 AddFloat(_("Ballast"),
292 _("Ballast of the glider. Increase this value if the pilot/cockpit load is greater than the reference pilot weight of the glide polar (typically 75kg). Press ENTER on this field to toggle count-down of the ballast volume according to the dump rate specified in the configuration settings."),
293 _T("%.0f l"), _T("%.0f"),
294 fixed(0), fixed(500), fixed(5), false,
295 fixed(0),
296 this);
298 AddReadOnly(_("Wing loading"), NULL, _T("%.1f kg/m2"), fixed(0));
300 AddFloat(_("Bugs"), /* xgettext:no-c-format */
301 _("How clean the glider is. Set to 0% for clean, larger numbers as the wings "
302 "pick up bugs or gets wet. 50% indicates the glider's sink rate is doubled."),
303 _T("%.0f %%"), _T("%.0f"),
304 fixed(0), fixed(50), fixed(1), false,
305 (fixed(1) - polar_settings.bugs) * 100,
306 this);
308 WndProperty *wp;
309 wp = AddFloat(_("QNH"),
310 _("Area pressure for barometric altimeter calibration. This is set automatically if Vega connected."),
311 GetUserPressureFormat(), GetUserPressureFormat(),
312 Units::ToUserPressure(Units::ToSysUnit(fixed(850), Unit::HECTOPASCAL)),
313 Units::ToUserPressure(Units::ToSysUnit(fixed(1300), Unit::HECTOPASCAL)),
314 GetUserPressureStep(), false,
315 Units::ToUserPressure(settings.pressure), this);
317 DataFieldFloat &df = *(DataFieldFloat *)wp->GetDataField();
318 df.SetUnits(Units::GetPressureName());
319 wp->RefreshDisplay();
322 AddReadOnly(_("Altitude"), NULL, _T("%.0f %s"),
323 UnitGroup::ALTITUDE, fixed(0));
325 wp = AddFloat(_("Max. temp."),
326 _("Set to forecast ground temperature. Used by convection estimator (temperature trace page of Analysis dialog)"),
327 _T("%.0f %s"), _T("%.0f"),
328 Units::ToUserTemperature(CelsiusToKelvin(fixed(-50))),
329 Units::ToUserTemperature(CelsiusToKelvin(fixed(60))),
330 fixed(1), false,
331 Units::ToUserTemperature(settings.forecast_temperature));
333 DataFieldFloat &df = *(DataFieldFloat *)wp->GetDataField();
334 df.SetUnits(Units::GetTemperatureName());
335 wp->RefreshDisplay();
339 bool
340 FlightSetupPanel::Save(bool &changed)
342 ComputerSettings &settings = CommonInterface::SetComputerSettings();
344 changed |= SaveValue(Temperature, UnitGroup::TEMPERATURE,
345 settings.forecast_temperature);
347 return true;
350 void
351 FlightSetupPanel::OnAction(int id)
353 if (id == DUMP)
354 FlipBallastTimer();
357 void
358 dlgBasicSettingsShowModal()
360 FlightSetupPanel *instance = new FlightSetupPanel();
362 const Plane &plane = CommonInterface::GetComputerSettings().plane;
363 StaticString<128> caption(_("Flight Setup"));
364 caption.append(_T(" - "));
365 caption.append(plane.polar_name);
367 WidgetDialog dialog(UIGlobals::GetDialogLook());
368 dialog.CreateAuto(UIGlobals::GetMainWindow(), caption, instance);
369 instance->SetDumpButton(dialog.AddButton(_("Dump"), *instance, DUMP));
370 dialog.AddButton(_("OK"), mrOK);
372 dialog.ShowModal();