Android release v6.7_preview1
[xcsoar.git] / src / Dialogs / Settings / dlgConfigInfoboxes.cpp
blob8371ef7d28d506895a0d2fb745c9ce731f7bfbb2
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 "dlgConfigInfoboxes.hpp"
25 #include "Dialogs/Message.hpp"
26 #include "Dialogs/HelpDialog.hpp"
27 #include "Dialogs/TextEntry.hpp"
28 #include "Form/Form.hpp"
29 #include "Form/Frame.hpp"
30 #include "Form/Button.hpp"
31 #include "Form/Edit.hpp"
32 #include "Screen/Canvas.hpp"
33 #include "Screen/Layout.hpp"
34 #include "Screen/SingleWindow.hpp"
35 #include "Screen/Key.h"
36 #include "Form/DataField/Enum.hpp"
37 #include "Form/DataField/String.hpp"
38 #include "Compiler.h"
39 #include "InfoBoxes/InfoBoxSettings.hpp"
40 #include "InfoBoxes/InfoBoxLayout.hpp"
41 #include "InfoBoxes/InfoBoxManager.hpp"
42 #include "InfoBoxes/Content/Factory.hpp"
43 #include "Look/InfoBoxLook.hpp"
44 #include "Language/Language.hpp"
45 #include "Compiler.h"
47 #include <assert.h>
48 #include <cstdio>
49 #include <algorithm>
51 class InfoBoxPreview : public PaintWindow {
52 protected:
53 /* virtual methods from class Window */
54 virtual bool OnMouseDown(PixelScalar x, PixelScalar y) override;
55 virtual bool OnMouseDouble(PixelScalar x, PixelScalar y) override;
57 /* virtual methods from class PaintWindow */
58 virtual void OnPaint(Canvas &canvas) override;
61 static const InfoBoxLook *look;
62 static InfoBoxSettings::Panel data;
63 static WndForm *wf = NULL;
64 static InfoBoxSettings::Panel clipboard;
65 static unsigned clipboard_size;
66 static InfoBoxLayout::Layout info_box_layout;
67 static InfoBoxPreview previews[InfoBoxSettings::Panel::MAX_CONTENTS];
68 static unsigned current_preview;
70 static WndProperty *edit_name;
71 static WndProperty *edit_select;
72 static WndProperty *edit_content;
73 static WndButton *buttonPaste;
74 static WndFrame *edit_content_description;
76 static void
77 RefreshPasteButton()
79 buttonPaste->SetEnabled(clipboard_size > 0);
82 static void
83 RefreshEditContentDescription()
85 DataFieldEnum &df = *(DataFieldEnum *)edit_content->GetDataField();
86 edit_content_description->SetText(df.GetHelp() != NULL ? df.GetHelp() :
87 _T(""));
90 static void
91 RefreshEditContent()
93 DataFieldEnum &df = *(DataFieldEnum *)edit_content->GetDataField();
94 df.Set(data.contents[current_preview]);
95 edit_content->RefreshDisplay();
96 RefreshEditContentDescription();
99 static void
100 OnCopy()
102 clipboard = data;
103 clipboard_size = InfoBoxSettings::Panel::MAX_CONTENTS;
105 RefreshPasteButton();
108 static void
109 OnPaste()
111 if (clipboard_size == 0)
112 return;
114 if(ShowMessageBox(_("Overwrite?"), _("InfoBox paste"),
115 MB_YESNO | MB_ICONQUESTION) != IDYES)
116 return;
118 for (unsigned item = 0; item < clipboard_size; item++) {
119 InfoBoxFactory::Type content = clipboard.contents[item];
120 if (content >= InfoBoxFactory::NUM_TYPES)
121 continue;
123 data.contents[item] = content;
125 if (item < info_box_layout.count)
126 previews[item].Invalidate();
129 RefreshEditContent();
132 static void
133 SetCurrentInfoBox(unsigned _current_preview)
135 assert(_current_preview < info_box_layout.count);
137 if (_current_preview == current_preview)
138 return;
140 previews[current_preview].Invalidate();
141 current_preview = _current_preview;
142 previews[current_preview].Invalidate();
144 DataFieldEnum &df = *(DataFieldEnum *)edit_select->GetDataField();
145 df.Set(current_preview);
146 edit_select->RefreshDisplay();
148 RefreshEditContent();
151 static void
152 OnSelectAccess(DataField *Sender, DataField::DataAccessMode Mode)
154 const DataFieldEnum &dfe = (const DataFieldEnum &)*Sender;
156 SetCurrentInfoBox(dfe.GetValue());
159 static void
160 OnContentAccess(DataField *Sender, DataField::DataAccessMode Mode)
162 const DataFieldEnum &dfe = (const DataFieldEnum &)*Sender;
164 data.contents[current_preview] = (InfoBoxFactory::Type)dfe.GetValue();
165 previews[current_preview].Invalidate();
166 RefreshEditContentDescription();
169 bool
170 InfoBoxPreview::OnMouseDown(PixelScalar x, PixelScalar y)
172 SetCurrentInfoBox(this - previews);
173 return true;
176 bool
177 InfoBoxPreview::OnMouseDouble(PixelScalar x, PixelScalar y)
179 edit_content->BeginEditing();
180 return true;
183 void
184 InfoBoxPreview::OnPaint(Canvas &canvas)
186 const unsigned i = this - previews;
187 const bool is_current = i == current_preview;
189 if (is_current)
190 canvas.Clear(COLOR_BLACK);
191 else
192 canvas.ClearWhite();
194 canvas.SelectHollowBrush();
195 canvas.SelectBlackPen();
196 canvas.Rectangle(0, 0, canvas.GetWidth() - 1, canvas.GetHeight() - 1);
198 InfoBoxFactory::Type type = data.contents[i];
199 const TCHAR *caption = type < InfoBoxFactory::NUM_TYPES
200 ? InfoBoxFactory::GetCaption(type)
201 : NULL;
202 if (caption == NULL)
203 caption = _("Invalid");
204 else
205 caption = gettext(caption);
207 canvas.Select(*look->title.font);
208 canvas.SetBackgroundTransparent();
209 canvas.SetTextColor(is_current ? COLOR_WHITE : COLOR_BLACK);
210 canvas.DrawText(2, 2, caption);
213 static void
214 OnContentHelp(WindowControl *Sender)
216 WndProperty *wp = (WndProperty*)Sender;
217 const DataFieldEnum &df = *(const DataFieldEnum *)wp->GetDataField();
218 InfoBoxFactory::Type type = (InfoBoxFactory::Type)df.GetValue();
219 if (type >= InfoBoxFactory::NUM_TYPES)
220 return;
222 const TCHAR *name = InfoBoxFactory::GetName(type);
223 if (name == NULL)
224 return;
226 TCHAR caption[100];
227 _stprintf(caption, _T("%s: %s"), _("InfoBox"), gettext(name));
229 const TCHAR *text = InfoBoxFactory::GetDescription(type);
230 if (text == NULL)
231 text = _("No help available on this item");
232 else
233 text = gettext(text);
235 dlgHelpShowModal(wf->GetMainWindow(), caption, text);
238 #ifdef _WIN32_WCE
240 static bool
241 OnKeyDown(unsigned key_code)
243 DataFieldEnum *dfe;
245 /* map the Altair hardware buttons */
246 switch (key_code){
247 case KEY_UP:
248 dfe = (DataFieldEnum *)edit_select->GetDataField();
249 dfe->Dec();
250 edit_select->RefreshDisplay();
251 return true;
253 case KEY_DOWN:
254 dfe = (DataFieldEnum *)edit_select->GetDataField();
255 dfe->Inc();
256 edit_select->RefreshDisplay();
257 return true;
259 case KEY_LEFT:
260 dfe = (DataFieldEnum *)edit_content->GetDataField();
261 dfe->Dec();
262 edit_content->RefreshDisplay();
263 return true;
265 case KEY_RIGHT:
266 dfe = (DataFieldEnum *)edit_content->GetDataField();
267 dfe->Inc();
268 edit_content->RefreshDisplay();
269 return true;
271 case KEY_APP1:
272 edit_name->BeginEditing();
273 return true;
275 case '6':
276 wf->SetModalResult(mrOK);
277 return true;
279 case '7':
280 OnCopy();
281 return true;
283 case '8':
284 OnPaste();
285 return true;
287 default:
288 return false;
292 #endif
294 bool
295 dlgConfigInfoboxesShowModal(SingleWindow &parent,
296 const DialogLook &dialog_look,
297 const InfoBoxLook &_look,
298 InfoBoxSettings::Geometry geometry,
299 InfoBoxSettings::Panel &data_r,
300 bool allow_name_change)
302 current_preview = 0;
303 look = &_look;
304 data = data_r;
306 PixelRect rc = parent.GetClientRect();
307 wf = new WndForm(parent, dialog_look, rc);
309 #ifdef _WIN32_WCE
310 if (IsAltair())
311 wf->SetKeyDownFunction(OnKeyDown);
312 #endif
314 ContainerWindow &client_area = wf->GetClientAreaWindow();
315 rc = client_area.GetClientRect();
316 rc.Grow(Layout::FastScale(-2));
317 info_box_layout = InfoBoxLayout::Calculate(rc, geometry);
319 WindowStyle preview_style;
320 preview_style.EnableDoubleClicks();
321 for (unsigned i = 0; i < info_box_layout.count; ++i) {
322 rc = info_box_layout.positions[i];
323 previews[i].Create(client_area, rc, preview_style);
326 rc = info_box_layout.remaining;
328 WindowStyle style;
329 style.TabStop();
331 PixelRect control_rc = rc;
332 control_rc.right -= Layout::FastScale(2);
334 const UPixelScalar height = Layout::Scale(22);
335 const UPixelScalar caption_width = Layout::Scale(60);
337 ButtonWindowStyle button_style;
338 button_style.TabStop();
340 control_rc.bottom = control_rc.top + height;
341 edit_name = new WndProperty(client_area, dialog_look, _("Name"),
342 control_rc, caption_width,
343 style);
344 DataFieldString *dfs = new DataFieldString(allow_name_change
345 ? (const TCHAR *)data.name
346 : gettext(data.name),
347 NULL);
348 edit_name->SetDataField(dfs);
349 edit_name->SetReadOnly(!allow_name_change);
351 control_rc.top = control_rc.bottom;
352 control_rc.bottom = control_rc.top + height;
354 edit_select = new WndProperty(client_area, dialog_look, _("InfoBox"),
355 control_rc, caption_width,
356 style);
358 DataFieldEnum *dfe = new DataFieldEnum(OnSelectAccess);
359 for (unsigned i = 0; i < info_box_layout.count; ++i) {
360 TCHAR label[32];
361 _stprintf(label, _T("%u"), i + 1);
362 dfe->addEnumText(label, i);
365 edit_select->SetDataField(dfe);
367 control_rc.top += height;
368 control_rc.bottom += height;
370 edit_content = new WndProperty(client_area, dialog_look, _("Content"),
371 control_rc, caption_width,
372 style);
374 dfe = new DataFieldEnum(OnContentAccess);
375 for (unsigned i = InfoBoxFactory::MIN_TYPE_VAL; i < InfoBoxFactory::NUM_TYPES; i++) {
376 const TCHAR *name = InfoBoxFactory::GetName((InfoBoxFactory::Type) i);
377 const TCHAR *desc = InfoBoxFactory::GetDescription((InfoBoxFactory::Type) i);
378 if (name != NULL)
379 dfe->addEnumText(gettext(name), i, desc != NULL ? gettext(desc) : NULL);
382 dfe->EnableItemHelp(true);
383 dfe->Sort(0);
385 edit_content->SetDataField(dfe);
386 edit_content->SetOnHelpCallback(OnContentHelp);
388 control_rc.top += height;
389 control_rc.bottom += height * 5;
390 edit_content_description = new WndFrame(client_area, dialog_look,
391 control_rc, style);
393 RefreshEditContent();
395 const UPixelScalar button_width = Layout::Scale(60);
396 const UPixelScalar button_height = Layout::Scale(28);
398 PixelRect button_rc = rc;
399 button_rc.right = button_rc.left + button_width;
400 button_rc.top = button_rc.bottom - button_height;
402 WndButton *close_button =
403 new WndButton(client_area, dialog_look, _("Close"),
404 button_rc, button_style, *wf, mrOK);
406 button_rc.left += button_width + Layout::Scale(2);
407 button_rc.right += button_width + Layout::Scale(2);
408 WndButton *copy_button =
409 new WndButton(client_area, dialog_look, _("Copy"),
410 button_rc, button_style, OnCopy);
412 button_rc.left += button_width + Layout::Scale(2);
413 button_rc.right += button_width + Layout::Scale(2);
414 buttonPaste =
415 new WndButton(client_area, dialog_look, _("Paste"),
416 button_rc, button_style, OnPaste);
418 RefreshPasteButton();
420 int result = wf->ShowModal();
422 if (result == mrOK && allow_name_change)
423 data.name = edit_name->GetDataField()->GetAsString();
425 delete wf;
426 delete edit_name;
427 delete edit_select;
428 delete edit_content;
429 delete close_button;
430 delete copy_button;
431 delete buttonPaste;
433 bool changed = false;
434 if (result == mrOK) {
435 for (unsigned i = 0; i < InfoBoxSettings::Panel::MAX_CONTENTS; ++i)
436 if (data.contents[i] != data_r.contents[i])
437 changed = true;
438 changed |= (_tcscmp(data.name, data_r.name) != 0);
440 if (changed)
441 data_r = data;
444 return changed;