wxMessageBox off the main thread lost result code.
[wxWidgets.git] / samples / widgets / choice.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWidgets Widgets Sample
3 // Name: choice.cpp
4 // Purpose: Part of the widgets sample showing wxChoice
5 // Created: 23.07.07
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // ============================================================================
10 // declarations
11 // ============================================================================
12
13 // ----------------------------------------------------------------------------
14 // headers
15 // ----------------------------------------------------------------------------
16
17 // for compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #if wxUSE_CHOICE
25
26 // for all others, include the necessary headers
27 #ifndef WX_PRECOMP
28 #include "wx/log.h"
29
30 #include "wx/bitmap.h"
31 #include "wx/button.h"
32 #include "wx/checkbox.h"
33 #include "wx/choice.h"
34 #include "wx/combobox.h"
35 #include "wx/radiobox.h"
36 #include "wx/statbox.h"
37 #include "wx/textctrl.h"
38 #endif
39
40 #include "wx/sizer.h"
41
42 #include "wx/checklst.h"
43
44 #include "itemcontainer.h"
45 #include "widgets.h"
46
47 #include "icons/choice.xpm"
48
49 // ----------------------------------------------------------------------------
50 // constants
51 // ----------------------------------------------------------------------------
52
53 // control ids
54 enum
55 {
56 ChoicePage_Reset = wxID_HIGHEST,
57 ChoicePage_Add,
58 ChoicePage_AddText,
59 ChoicePage_AddSeveral,
60 ChoicePage_AddMany,
61 ChoicePage_Clear,
62 ChoicePage_Change,
63 ChoicePage_ChangeText,
64 ChoicePage_Delete,
65 ChoicePage_DeleteText,
66 ChoicePage_DeleteSel,
67 ChoicePage_Choice,
68 ChoicePage_ContainerTests
69 };
70
71 // ----------------------------------------------------------------------------
72 // ChoiceWidgetsPage
73 // ----------------------------------------------------------------------------
74
75 class ChoiceWidgetsPage : public ItemContainerWidgetsPage
76 {
77 public:
78 ChoiceWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
79
80 virtual wxControl *GetWidget() const { return m_choice; }
81 virtual wxItemContainer* GetContainer() const { return m_choice; }
82 virtual void RecreateWidget() { CreateChoice(); }
83
84 // lazy creation of the content
85 virtual void CreateContent();
86
87 protected:
88 // event handlers
89 void OnButtonReset(wxCommandEvent& event);
90 void OnButtonChange(wxCommandEvent& event);
91 void OnButtonDelete(wxCommandEvent& event);
92 void OnButtonDeleteSel(wxCommandEvent& event);
93 void OnButtonClear(wxCommandEvent& event);
94 void OnButtonAdd(wxCommandEvent& event);
95 void OnButtonAddSeveral(wxCommandEvent& event);
96 void OnButtonAddMany(wxCommandEvent& event);
97
98 void OnChoice(wxCommandEvent& event);
99
100 void OnCheckOrRadioBox(wxCommandEvent& event);
101
102 void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
103 void OnUpdateUIClearButton(wxUpdateUIEvent& event);
104 void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
105 void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
106 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
107
108 // reset the choice parameters
109 void Reset();
110
111 // (re)create the choice
112 void CreateChoice();
113
114 // should it be sorted?
115 bool m_sorted;
116
117 // the controls
118 // ------------
119
120 // the checkboxes
121 wxCheckBox *m_chkSort;
122
123 // the choice itself and the sizer it is in
124 #ifdef __WXWINCE__
125 wxChoiceBase
126 #else
127 wxChoice
128 #endif
129 *m_choice;
130
131 wxSizer *m_sizerChoice;
132
133 // the text entries for "Add/change string" and "Delete" buttons
134 wxTextCtrl *m_textAdd,
135 *m_textChange,
136 *m_textDelete;
137
138 private:
139 DECLARE_EVENT_TABLE()
140 DECLARE_WIDGETS_PAGE(ChoiceWidgetsPage)
141 };
142
143 // ----------------------------------------------------------------------------
144 // event tables
145 // ----------------------------------------------------------------------------
146
147 BEGIN_EVENT_TABLE(ChoiceWidgetsPage, WidgetsPage)
148 EVT_BUTTON(ChoicePage_Reset, ChoiceWidgetsPage::OnButtonReset)
149 EVT_BUTTON(ChoicePage_Change, ChoiceWidgetsPage::OnButtonChange)
150 EVT_BUTTON(ChoicePage_Delete, ChoiceWidgetsPage::OnButtonDelete)
151 EVT_BUTTON(ChoicePage_DeleteSel, ChoiceWidgetsPage::OnButtonDeleteSel)
152 EVT_BUTTON(ChoicePage_Clear, ChoiceWidgetsPage::OnButtonClear)
153 EVT_BUTTON(ChoicePage_Add, ChoiceWidgetsPage::OnButtonAdd)
154 EVT_BUTTON(ChoicePage_AddSeveral, ChoiceWidgetsPage::OnButtonAddSeveral)
155 EVT_BUTTON(ChoicePage_AddMany, ChoiceWidgetsPage::OnButtonAddMany)
156 EVT_BUTTON(ChoicePage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer)
157
158 EVT_TEXT_ENTER(ChoicePage_AddText, ChoiceWidgetsPage::OnButtonAdd)
159 EVT_TEXT_ENTER(ChoicePage_DeleteText, ChoiceWidgetsPage::OnButtonDelete)
160
161 EVT_UPDATE_UI(ChoicePage_Reset, ChoiceWidgetsPage::OnUpdateUIResetButton)
162 EVT_UPDATE_UI(ChoicePage_AddSeveral, ChoiceWidgetsPage::OnUpdateUIAddSeveral)
163 EVT_UPDATE_UI(ChoicePage_Clear, ChoiceWidgetsPage::OnUpdateUIClearButton)
164 EVT_UPDATE_UI(ChoicePage_DeleteText, ChoiceWidgetsPage::OnUpdateUIClearButton)
165 EVT_UPDATE_UI(ChoicePage_Delete, ChoiceWidgetsPage::OnUpdateUIDeleteButton)
166 EVT_UPDATE_UI(ChoicePage_Change, ChoiceWidgetsPage::OnUpdateUIDeleteSelButton)
167 EVT_UPDATE_UI(ChoicePage_ChangeText, ChoiceWidgetsPage::OnUpdateUIDeleteSelButton)
168 EVT_UPDATE_UI(ChoicePage_DeleteSel, ChoiceWidgetsPage::OnUpdateUIDeleteSelButton)
169
170 EVT_CHOICE(ChoicePage_Choice, ChoiceWidgetsPage::OnChoice)
171
172 EVT_CHECKBOX(wxID_ANY, ChoiceWidgetsPage::OnCheckOrRadioBox)
173 EVT_RADIOBOX(wxID_ANY, ChoiceWidgetsPage::OnCheckOrRadioBox)
174 END_EVENT_TABLE()
175
176 // ============================================================================
177 // implementation
178 // ============================================================================
179
180 #if defined(__WXUNIVERSAL__)
181 #define FAMILY_CTRLS UNIVERSAL_CTRLS
182 #else
183 #define FAMILY_CTRLS NATIVE_CTRLS
184 #endif
185
186 IMPLEMENT_WIDGETS_PAGE(ChoiceWidgetsPage, wxT("Choice"),
187 FAMILY_CTRLS | WITH_ITEMS_CTRLS
188 );
189
190 ChoiceWidgetsPage::ChoiceWidgetsPage(WidgetsBookCtrl *book,
191 wxImageList *imaglist)
192 : ItemContainerWidgetsPage(book, imaglist, choice_xpm)
193 {
194 // init everything
195
196 m_chkSort = (wxCheckBox *)NULL;
197
198 m_choice = NULL;
199 m_sizerChoice = (wxSizer *)NULL;
200
201 }
202
203 void ChoiceWidgetsPage::CreateContent()
204 {
205 /*
206 What we create here is a frame having 3 panes: style pane is the
207 leftmost one, in the middle the pane with buttons allowing to perform
208 miscellaneous choice operations and the pane containing the choice
209 itself to the right
210 */
211 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
212
213 // left pane
214 wxStaticBox *box = new wxStaticBox(this, wxID_ANY,
215 wxT("&Set choice parameters"));
216 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
217
218 static const wxString modes[] =
219 {
220 wxT("single"),
221 wxT("extended"),
222 wxT("multiple"),
223 };
224
225 m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Sort items"));
226
227 wxButton *btn = new wxButton(this, ChoicePage_Reset, wxT("&Reset"));
228 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
229
230 // middle pane
231 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
232 wxT("&Change choice contents"));
233 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
234
235 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
236 btn = new wxButton(this, ChoicePage_Add, wxT("&Add this string"));
237 m_textAdd = new wxTextCtrl(this, ChoicePage_AddText, wxT("test item 0"));
238 sizerRow->Add(btn, 0, wxRIGHT, 5);
239 sizerRow->Add(m_textAdd, 1, wxLEFT, 5);
240 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
241
242 btn = new wxButton(this, ChoicePage_AddSeveral, wxT("&Insert a few strings"));
243 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
244
245 btn = new wxButton(this, ChoicePage_AddMany, wxT("Add &many strings"));
246 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
247
248 sizerRow = new wxBoxSizer(wxHORIZONTAL);
249 btn = new wxButton(this, ChoicePage_Change, wxT("C&hange current"));
250 m_textChange = new wxTextCtrl(this, ChoicePage_ChangeText, wxEmptyString);
251 sizerRow->Add(btn, 0, wxRIGHT, 5);
252 sizerRow->Add(m_textChange, 1, wxLEFT, 5);
253 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
254
255 sizerRow = new wxBoxSizer(wxHORIZONTAL);
256 btn = new wxButton(this, ChoicePage_Delete, wxT("&Delete this item"));
257 m_textDelete = new wxTextCtrl(this, ChoicePage_DeleteText, wxEmptyString);
258 sizerRow->Add(btn, 0, wxRIGHT, 5);
259 sizerRow->Add(m_textDelete, 1, wxLEFT, 5);
260 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
261
262 btn = new wxButton(this, ChoicePage_DeleteSel, wxT("Delete &selection"));
263 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
264
265 btn = new wxButton(this, ChoicePage_Clear, wxT("&Clear"));
266 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
267
268 btn = new wxButton(this, ChoicePage_ContainerTests, wxT("Run &tests"));
269 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
270
271 // right pane
272 wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
273 m_choice = new wxChoice(this, ChoicePage_Choice);
274 sizerRight->Add(m_choice, 0, wxALL | wxGROW, 5);
275 sizerRight->SetMinSize(150, 0);
276 m_sizerChoice = sizerRight; // save it to modify it later
277
278 // the 3 panes panes compose the window
279 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
280 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
281 sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
282
283 // final initializations
284 Reset();
285
286 SetSizer(sizerTop);
287 }
288
289 // ----------------------------------------------------------------------------
290 // operations
291 // ----------------------------------------------------------------------------
292
293 void ChoiceWidgetsPage::Reset()
294 {
295 m_chkSort->SetValue(false);
296 }
297
298 void ChoiceWidgetsPage::CreateChoice()
299 {
300 int flags = ms_defaultFlags;
301
302 if ( m_chkSort->GetValue() )
303 flags |= wxCB_SORT;
304
305 wxArrayString items;
306 if ( m_choice )
307 {
308 int count = m_choice->GetCount();
309 for ( int n = 0; n < count; n++ )
310 {
311 items.Add(m_choice->GetString(n));
312 }
313
314 m_sizerChoice->Detach( m_choice );
315 delete m_choice;
316 }
317
318 m_choice = new wxChoice(this, ChoicePage_Choice,
319 wxDefaultPosition, wxDefaultSize,
320 0, NULL,
321 flags);
322
323 m_choice->Set(items);
324 m_sizerChoice->Add(m_choice, 1, wxGROW | wxALL, 5);
325 m_sizerChoice->Layout();
326 }
327
328 // ----------------------------------------------------------------------------
329 // event handlers
330 // ----------------------------------------------------------------------------
331
332 void ChoiceWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
333 {
334 Reset();
335
336 CreateChoice();
337 }
338
339 void ChoiceWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
340 {
341 int selection = m_choice->GetSelection();
342 if(selection != wxNOT_FOUND)
343 {
344 m_choice->SetString(selection, m_textChange->GetValue());
345 }
346 }
347
348 void ChoiceWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
349 {
350 unsigned long n;
351 if ( !m_textDelete->GetValue().ToULong(&n) ||
352 (n >= (unsigned)m_choice->GetCount()) )
353 {
354 return;
355 }
356
357 m_choice->Delete(n);
358 }
359
360 void ChoiceWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
361 {
362 int selection = m_choice->GetSelection();
363 if(selection != wxNOT_FOUND)
364 {
365 m_choice->Delete(selection);
366 }
367 }
368
369 void ChoiceWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
370 {
371 m_choice->Clear();
372 }
373
374 void ChoiceWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
375 {
376 static unsigned int s_item = 0;
377
378 wxString s = m_textAdd->GetValue();
379 if ( !m_textAdd->IsModified() )
380 {
381 // update the default string
382 m_textAdd->SetValue(wxString::Format(wxT("test item %u"), ++s_item));
383 }
384
385 m_choice->Append(s);
386 }
387
388 void ChoiceWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
389 {
390 // "many" means 1000 here
391 wxArrayString strings;
392 for ( unsigned int n = 0; n < 1000; n++ )
393 {
394 strings.Add(wxString::Format(wxT("item #%u"), n));
395 }
396 m_choice->Append(strings);
397 }
398
399 void ChoiceWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
400 {
401 wxArrayString items;
402 items.Add(wxT("First"));
403 items.Add(wxT("another one"));
404 items.Add(wxT("and the last (very very very very very very very very very very long) one"));
405 m_choice->Insert(items, 0);
406 }
407
408 void ChoiceWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
409 {
410 event.Enable( m_chkSort->GetValue() );
411 }
412
413 void ChoiceWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
414 {
415 unsigned long n;
416 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
417 (n < (unsigned)m_choice->GetCount()));
418 }
419
420 void ChoiceWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
421 {
422 wxArrayInt selections;
423 event.Enable(m_choice->GetSelection() != wxNOT_FOUND);
424 }
425
426 void ChoiceWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
427 {
428 event.Enable(m_choice->GetCount() != 0);
429 }
430
431 void ChoiceWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
432 {
433 event.Enable(!m_choice->HasFlag(wxCB_SORT));
434 }
435
436 void ChoiceWidgetsPage::OnChoice(wxCommandEvent& event)
437 {
438 long sel = event.GetSelection();
439 m_textDelete->SetValue(wxString::Format(wxT("%ld"), sel));
440
441 wxLogMessage(wxT("Choice item %ld selected"), sel);
442 }
443
444 void ChoiceWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
445 {
446 CreateChoice();
447 }
448
449 #endif // wxUSE_CHOICE