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