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.
25 #include "InfoBoxes/InfoBoxManager.hpp"
26 #include "InfoBoxes/InfoBoxWindow.hpp"
27 #include "InfoBoxes/InfoBoxLayout.hpp"
28 #include "Look/InfoBoxLook.hpp"
29 #include "InfoBoxes/Content/Factory.hpp"
30 #include "InfoBoxes/Content/Base.hpp"
31 #include "Profile/InfoBoxConfig.hpp"
32 #include "Screen/Layout.hpp"
33 #include "Hardware/Battery.hpp"
34 #include "Language/Language.hpp"
35 #include "Form/DataField/ComboList.hpp"
36 #include "Dialogs/HelpDialog.hpp"
37 #include "Dialogs/ComboPicker.hpp"
38 #include "Profile/InfoBoxConfig.hpp"
39 #include "Interface.hpp"
40 #include "UIState.hpp"
41 #include "UIGlobals.hpp"
48 namespace InfoBoxManager
50 InfoBoxLayout::Layout layout
;
53 * Is this the initial DisplayInfoBox() call? If yes, then all
54 * content objects need to be created.
58 static void DisplayInfoBox();
59 static void InfoBoxDrawIfDirty();
62 static int GetFocused();
65 static bool infoboxes_dirty
= false;
66 static bool infoboxes_hidden
= false;
68 static InfoBoxWindow
*infoboxes
[InfoBoxSettings::Panel::MAX_CONTENTS
];
72 InfoBoxManager::Hide()
77 infoboxes_hidden
= true;
79 for (unsigned i
= 0; i
< layout
.count
; i
++)
80 infoboxes
[i
]->FastHide();
84 InfoBoxManager::Show()
86 if (!infoboxes_hidden
)
89 infoboxes_hidden
= false;
91 for (unsigned i
= 0; i
< layout
.count
; i
++)
98 InfoBoxManager::GetFocused()
100 for (unsigned i
= 0; i
< layout
.count
; i
++)
101 if (infoboxes
[i
]->HasFocus())
108 InfoBoxManager::Event_Select(int i
)
110 int InfoFocus
= GetFocused();
113 InfoFocus
= (i
>= 0 ? 0 : layout
.count
- 1);
117 if (InfoFocus
< 0 || (unsigned)InfoFocus
>= layout
.count
)
122 infoboxes
[InfoFocus
]->SetFocus();
124 infoboxes
[0]->FocusParent();
128 InfoBoxManager::Event_Change(int i
)
130 InfoBoxFactory::Type j
= InfoBoxFactory::MIN_TYPE_VAL
;
131 InfoBoxFactory::Type k
;
133 int InfoFocus
= GetFocused();
137 InfoBoxSettings
&settings
= CommonInterface::SetUISettings().info_boxes
;
138 const unsigned panel_index
= CommonInterface::GetUIState().panel_index
;
139 InfoBoxSettings::Panel
&panel
= settings
.panels
[panel_index
];
141 k
= panel
.contents
[InfoFocus
];
143 j
= InfoBoxFactory::GetNext(k
);
145 j
= InfoBoxFactory::GetPrevious(k
);
147 // TODO code: if i==0, go to default or reset
152 panel
.contents
[InfoFocus
] = j
;
154 infoboxes
[InfoFocus
]->UpdateContent();
158 InfoBoxManager::DisplayInfoBox()
160 static int DisplayTypeLast
[InfoBoxSettings::Panel::MAX_CONTENTS
];
162 // JMW note: this is updated every GPS time step
164 const unsigned panel
= CommonInterface::GetUIState().panel_index
;
166 const InfoBoxSettings::Panel
&settings
=
167 CommonInterface::GetUISettings().info_boxes
.panels
[panel
];
169 for (unsigned i
= 0; i
< layout
.count
; i
++) {
170 // All calculations are made in a separate thread. Slow calculations
171 // should apply to the function DoCalculationsSlow()
172 // Do not put calculations here!
174 InfoBoxFactory::Type DisplayType
= settings
.contents
[i
];
175 if ((unsigned)DisplayType
> (unsigned)InfoBoxFactory::MAX_TYPE_VAL
)
176 DisplayType
= InfoBoxFactory::NavAltitude
;
178 bool needupdate
= ((DisplayType
!= DisplayTypeLast
[i
]) || first
);
181 infoboxes
[i
]->SetTitle(gettext(InfoBoxFactory::GetCaption(DisplayType
)));
182 infoboxes
[i
]->SetContentProvider(InfoBoxFactory::Create(DisplayType
));
183 DisplayTypeLast
[i
] = DisplayType
;
186 infoboxes
[i
]->UpdateContent();
193 InfoBoxManager::InfoBoxDrawIfDirty()
195 // No need to redraw map or infoboxes if screen is blanked.
196 // This should save lots of battery power due to CPU usage
197 // of drawing the screen
199 if (infoboxes_dirty
&& !infoboxes_hidden
&&
200 !CommonInterface::GetUIState().screen_blanked
) {
202 infoboxes_dirty
= false;
207 InfoBoxManager::SetDirty()
209 infoboxes_dirty
= true;
213 InfoBoxManager::ProcessTimer()
215 InfoBoxDrawIfDirty();
219 InfoBoxManager::Create(ContainerWindow
&parent
,
220 const InfoBoxLayout::Layout
&_layout
,
221 const InfoBoxLook
&look
, const UnitsLook
&units_look
)
223 const InfoBoxSettings
&settings
=
224 CommonInterface::GetUISettings().info_boxes
;
232 // create infobox windows
233 for (unsigned i
= layout
.count
; i
-- > 0;) {
234 const PixelRect
&rc
= layout
.positions
[i
];
236 settings
.border_style
== InfoBoxSettings::BorderStyle::TAB
238 /* layout.geometry is the effective layout, while
239 settings.geometry is the configured layout */
240 : InfoBoxLayout::GetBorder(layout
.geometry
, i
);
242 infoboxes
[i
] = new InfoBoxWindow(parent
, rc
,
243 Border
, settings
, look
, units_look
,
247 infoboxes_hidden
= true;
251 InfoBoxManager::Destroy()
253 for (unsigned i
= 0; i
< layout
.count
; i
++) {
259 static const ComboList
*info_box_combo_list
;
262 OnInfoBoxHelp(unsigned item
)
264 InfoBoxFactory::Type type
= (InfoBoxFactory::Type
)
265 (*info_box_combo_list
)[item
].DataFieldIndex
;
267 StaticString
<100> caption
;
268 caption
.Format(_T("%s: %s"), _("InfoBox"),
269 gettext(InfoBoxFactory::GetName(type
)));
271 const TCHAR
* text
= InfoBoxFactory::GetDescription(type
);
273 text
= N_("No help available on this item");
275 dlgHelpShowModal(UIGlobals::GetMainWindow(), caption
, gettext(text
));
279 InfoBoxManager::ShowInfoBoxPicker(const int id
)
283 if (id
< 0) i
= GetFocused();
289 InfoBoxSettings
&settings
= CommonInterface::SetUISettings().info_boxes
;
290 const unsigned panel_index
= CommonInterface::GetUIState().panel_index
;
291 InfoBoxSettings::Panel
&panel
= settings
.panels
[panel_index
];
293 const InfoBoxFactory::Type old_type
= panel
.contents
[i
];
296 for (unsigned j
= InfoBoxFactory::MIN_TYPE_VAL
; j
< InfoBoxFactory::NUM_TYPES
; j
++) {
297 const TCHAR
*desc
= InfoBoxFactory::GetDescription((InfoBoxFactory::Type
)j
);
298 list
.Append(j
, gettext(InfoBoxFactory::GetName((InfoBoxFactory::Type
)j
)),
299 gettext(InfoBoxFactory::GetName((InfoBoxFactory::Type
)j
)),
300 desc
!= NULL
? gettext(desc
) : NULL
);
304 list
.ComboPopupItemSavedIndex
= list
.LookUp(old_type
);
306 /* let the user select */
308 StaticString
<20> caption
;
309 caption
.Format(_T("%s: %d"), _("InfoBox"), i
+ 1);
310 info_box_combo_list
= &list
;
311 int result
= ComboPicker(caption
, list
, OnInfoBoxHelp
, true);
315 /* was there a modification? */
317 InfoBoxFactory::Type new_type
= (InfoBoxFactory::Type
)list
[result
].DataFieldIndex
;
318 if (new_type
== old_type
)
321 /* yes: apply and save it */
323 panel
.contents
[i
] = new_type
;
326 Profile::Save(panel
, panel_index
);