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"
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"
51 class InfoBoxPreview
: public PaintWindow
{
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
;
79 buttonPaste
->SetEnabled(clipboard_size
> 0);
83 RefreshEditContentDescription()
85 DataFieldEnum
&df
= *(DataFieldEnum
*)edit_content
->GetDataField();
86 edit_content_description
->SetText(df
.GetHelp() != NULL
? df
.GetHelp() :
93 DataFieldEnum
&df
= *(DataFieldEnum
*)edit_content
->GetDataField();
94 df
.Set(data
.contents
[current_preview
]);
95 edit_content
->RefreshDisplay();
96 RefreshEditContentDescription();
103 clipboard_size
= InfoBoxSettings::Panel::MAX_CONTENTS
;
105 RefreshPasteButton();
111 if (clipboard_size
== 0)
114 if(ShowMessageBox(_("Overwrite?"), _("InfoBox paste"),
115 MB_YESNO
| MB_ICONQUESTION
) != IDYES
)
118 for (unsigned item
= 0; item
< clipboard_size
; item
++) {
119 InfoBoxFactory::Type content
= clipboard
.contents
[item
];
120 if (content
>= InfoBoxFactory::NUM_TYPES
)
123 data
.contents
[item
] = content
;
125 if (item
< info_box_layout
.count
)
126 previews
[item
].Invalidate();
129 RefreshEditContent();
133 SetCurrentInfoBox(unsigned _current_preview
)
135 assert(_current_preview
< info_box_layout
.count
);
137 if (_current_preview
== current_preview
)
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();
152 OnSelectAccess(DataField
*Sender
, DataField::DataAccessMode Mode
)
154 const DataFieldEnum
&dfe
= (const DataFieldEnum
&)*Sender
;
156 SetCurrentInfoBox(dfe
.GetValue());
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();
170 InfoBoxPreview::OnMouseDown(PixelScalar x
, PixelScalar y
)
172 SetCurrentInfoBox(this - previews
);
177 InfoBoxPreview::OnMouseDouble(PixelScalar x
, PixelScalar y
)
179 edit_content
->BeginEditing();
184 InfoBoxPreview::OnPaint(Canvas
&canvas
)
186 const unsigned i
= this - previews
;
187 const bool is_current
= i
== current_preview
;
190 canvas
.Clear(COLOR_BLACK
);
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
)
203 caption
= _("Invalid");
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
);
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
)
222 const TCHAR
*name
= InfoBoxFactory::GetName(type
);
227 _stprintf(caption
, _T("%s: %s"), _("InfoBox"), gettext(name
));
229 const TCHAR
*text
= InfoBoxFactory::GetDescription(type
);
231 text
= _("No help available on this item");
233 text
= gettext(text
);
235 dlgHelpShowModal(wf
->GetMainWindow(), caption
, text
);
241 OnKeyDown(unsigned key_code
)
245 /* map the Altair hardware buttons */
248 dfe
= (DataFieldEnum
*)edit_select
->GetDataField();
250 edit_select
->RefreshDisplay();
254 dfe
= (DataFieldEnum
*)edit_select
->GetDataField();
256 edit_select
->RefreshDisplay();
260 dfe
= (DataFieldEnum
*)edit_content
->GetDataField();
262 edit_content
->RefreshDisplay();
266 dfe
= (DataFieldEnum
*)edit_content
->GetDataField();
268 edit_content
->RefreshDisplay();
272 edit_name
->BeginEditing();
276 wf
->SetModalResult(mrOK
);
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
)
306 PixelRect rc
= parent
.GetClientRect();
307 wf
= new WndForm(parent
, dialog_look
, rc
);
311 wf
->SetKeyDownFunction(OnKeyDown
);
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
;
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
,
344 DataFieldString
*dfs
= new DataFieldString(allow_name_change
345 ? (const TCHAR
*)data
.name
346 : gettext(data
.name
),
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
,
358 DataFieldEnum
*dfe
= new DataFieldEnum(OnSelectAccess
);
359 for (unsigned i
= 0; i
< info_box_layout
.count
; ++i
) {
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
,
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
);
379 dfe
->addEnumText(gettext(name
), i
, desc
!= NULL
? gettext(desc
) : NULL
);
382 dfe
->EnableItemHelp(true);
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
,
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);
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();
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
])
438 changed
|= (_tcscmp(data
.name
, data_r
.name
) != 0);