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"
63 class FlightSetupPanel final
64 : public RowFormWidget
, DataFieldListener
,
66 public ActionListener
{
67 WndButton
*dump_button
;
69 PolarSettings
&polar_settings
;
75 :RowFormWidget(UIGlobals::GetDialogLook()),
77 polar_settings(CommonInterface::SetComputerSettings().polar
),
81 void SetDumpButton(WndButton
*_dump_button
) {
82 dump_button
= _dump_button
;
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();
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);
121 virtual void Hide() override
{
123 RowFormWidget::Hide();
126 /* virtual methods from ActionListener */
127 virtual void OnAction(int id
) override
;
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
;
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"));
149 FlightSetupPanel::SetBallast()
151 const bool ballastable
= polar_settings
.glide_polar_task
.IsBallastable();
152 SetRowVisible(Ballast
, 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
));
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
) /
168 MessageOperationEnvironment env
;
169 device_blackboard
->SetBallast(fraction
, overload
, env
);
175 FlightSetupPanel::SetBallastTimer(bool active
)
177 if (!polar_settings
.glide_polar_task
.HasBallast())
180 PolarSettings
&settings
= CommonInterface::SetComputerSettings().polar
;
181 if (active
== settings
.ballast_timer_active
)
184 settings
.ballast_timer_active
= active
;
189 FlightSetupPanel::FlipBallastTimer()
191 const ComputerSettings
&settings
= CommonInterface::GetComputerSettings();
192 SetBallastTimer(!settings
.polar
.ballast_timer_active
);
196 FlightSetupPanel::ShowAltitude(fixed altitude
)
198 if (fabs(altitude
- last_altitude
) >= fixed(1)) {
199 last_altitude
= altitude
;
200 LoadValue(Altitude
, altitude
, UnitGroup::ALTITUDE
);
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
);
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
);
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();
250 FlightSetupPanel::OnTimer()
252 const PolarSettings
&settings
= CommonInterface::GetComputerSettings().polar
;
254 if (settings
.ballast_timer_active
) {
255 /* display the new values on the screen */
259 RefreshAltitudeControl();
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()));
278 FlightSetupPanel::OnSpecial(DataField
&df
)
280 if (IsDataField(Ballast
, df
))
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,
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,
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))),
331 Units::ToUserTemperature(settings
.forecast_temperature
));
333 DataFieldFloat
&df
= *(DataFieldFloat
*)wp
->GetDataField();
334 df
.SetUnits(Units::GetTemperatureName());
335 wp
->RefreshDisplay();
340 FlightSetupPanel::Save(bool &changed
)
342 ComputerSettings
&settings
= CommonInterface::SetComputerSettings();
344 changed
|= SaveValue(Temperature
, UnitGroup::TEMPERATURE
,
345 settings
.forecast_temperature
);
351 FlightSetupPanel::OnAction(int id
)
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
);