Add missing header.
[wxWidgets.git] / samples / widgets / combobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWindows Widgets Sample
3 // Name: combobox.cpp
4 // Purpose: Part of the widgets sample showing wxComboBox
5 // Author: Vadim Zeitlin
6 // Created: 27.03.01
7 // Id: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin
9 // License: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_COMBOBOX
28
29 // for all others, include the necessary headers
30 #ifndef WX_PRECOMP
31 #include "wx/log.h"
32
33 #include "wx/bitmap.h"
34 #include "wx/button.h"
35 #include "wx/checkbox.h"
36 #include "wx/combobox.h"
37 #include "wx/radiobox.h"
38 #include "wx/statbox.h"
39 #include "wx/textctrl.h"
40 #endif
41
42 #include "wx/sizer.h"
43
44 #include "widgets.h"
45 #if 1
46 #include "icons/combobox.xpm"
47
48 // ----------------------------------------------------------------------------
49 // constants
50 // ----------------------------------------------------------------------------
51
52 // control ids
53 enum
54 {
55 ComboPage_Reset = 100,
56 ComboPage_CurText,
57 ComboPage_Add,
58 ComboPage_AddText,
59 ComboPage_AddSeveral,
60 ComboPage_AddMany,
61 ComboPage_Clear,
62 ComboPage_Change,
63 ComboPage_ChangeText,
64 ComboPage_Delete,
65 ComboPage_DeleteText,
66 ComboPage_DeleteSel,
67 ComboPage_Combo
68 };
69
70 // kinds of comboboxes
71 enum
72 {
73 ComboKind_Default,
74 ComboKind_Simple,
75 ComboKind_DropDown
76 };
77
78 // ----------------------------------------------------------------------------
79 // ComboboxWidgetsPage
80 // ----------------------------------------------------------------------------
81
82 class ComboboxWidgetsPage : public WidgetsPage
83 {
84 public:
85 ComboboxWidgetsPage(wxNotebook *notebook, wxImageList *imaglist);
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 OnComboBox(wxCommandEvent& event);
99 void OnComboText(wxCommandEvent& event);
100
101 void OnCheckOrRadioBox(wxCommandEvent& event);
102
103 void OnUpdateUICurText(wxUpdateUIEvent& event);
104
105 void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
106 void OnUpdateUIClearButton(wxUpdateUIEvent& event);
107 void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
108 void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
109 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
110
111 // reset the combobox parameters
112 void Reset();
113
114 // (re)create the combobox
115 void CreateCombo();
116
117 // the controls
118 // ------------
119
120 // the sel mode radiobox
121 wxRadioBox *m_radioKind;
122
123 // the checkboxes for styles
124 wxCheckBox *m_chkSort,
125 *m_chkReadonly;
126
127 // the combobox itself and the sizer it is in
128 wxComboBox *m_combobox;
129 wxSizer *m_sizerCombo;
130
131 // the text entries for "Add/change string" and "Delete" buttons
132 wxTextCtrl *m_textAdd,
133 *m_textChange,
134 *m_textDelete;
135
136 private:
137 DECLARE_EVENT_TABLE()
138 DECLARE_WIDGETS_PAGE(ComboboxWidgetsPage)
139 };
140
141 // ----------------------------------------------------------------------------
142 // event tables
143 // ----------------------------------------------------------------------------
144
145 BEGIN_EVENT_TABLE(ComboboxWidgetsPage, WidgetsPage)
146 EVT_BUTTON(ComboPage_Reset, ComboboxWidgetsPage::OnButtonReset)
147 EVT_BUTTON(ComboPage_Change, ComboboxWidgetsPage::OnButtonChange)
148 EVT_BUTTON(ComboPage_Delete, ComboboxWidgetsPage::OnButtonDelete)
149 EVT_BUTTON(ComboPage_DeleteSel, ComboboxWidgetsPage::OnButtonDeleteSel)
150 EVT_BUTTON(ComboPage_Clear, ComboboxWidgetsPage::OnButtonClear)
151 EVT_BUTTON(ComboPage_Add, ComboboxWidgetsPage::OnButtonAdd)
152 EVT_BUTTON(ComboPage_AddSeveral, ComboboxWidgetsPage::OnButtonAddSeveral)
153 EVT_BUTTON(ComboPage_AddMany, ComboboxWidgetsPage::OnButtonAddMany)
154
155 EVT_TEXT_ENTER(ComboPage_AddText, ComboboxWidgetsPage::OnButtonAdd)
156 EVT_TEXT_ENTER(ComboPage_DeleteText, ComboboxWidgetsPage::OnButtonDelete)
157
158 EVT_UPDATE_UI(ComboPage_CurText, ComboboxWidgetsPage::OnUpdateUICurText)
159
160 EVT_UPDATE_UI(ComboPage_Reset, ComboboxWidgetsPage::OnUpdateUIResetButton)
161 EVT_UPDATE_UI(ComboPage_AddSeveral, ComboboxWidgetsPage::OnUpdateUIAddSeveral)
162 EVT_UPDATE_UI(ComboPage_Clear, ComboboxWidgetsPage::OnUpdateUIClearButton)
163 EVT_UPDATE_UI(ComboPage_DeleteText, ComboboxWidgetsPage::OnUpdateUIClearButton)
164 EVT_UPDATE_UI(ComboPage_Delete, ComboboxWidgetsPage::OnUpdateUIDeleteButton)
165 EVT_UPDATE_UI(ComboPage_Change, ComboboxWidgetsPage::OnUpdateUIDeleteSelButton)
166 EVT_UPDATE_UI(ComboPage_ChangeText, ComboboxWidgetsPage::OnUpdateUIDeleteSelButton)
167 EVT_UPDATE_UI(ComboPage_DeleteSel, ComboboxWidgetsPage::OnUpdateUIDeleteSelButton)
168
169 EVT_COMBOBOX(ComboPage_Combo, ComboboxWidgetsPage::OnComboBox)
170 EVT_TEXT(ComboPage_Combo, ComboboxWidgetsPage::OnComboText)
171
172 EVT_CHECKBOX(-1, ComboboxWidgetsPage::OnCheckOrRadioBox)
173 EVT_RADIOBOX(-1, ComboboxWidgetsPage::OnCheckOrRadioBox)
174 END_EVENT_TABLE()
175
176 // ============================================================================
177 // implementation
178 // ============================================================================
179
180 IMPLEMENT_WIDGETS_PAGE(ComboboxWidgetsPage, _T("Combobox"));
181
182 ComboboxWidgetsPage::ComboboxWidgetsPage(wxNotebook *notebook,
183 wxImageList *imaglist)
184 : WidgetsPage(notebook)
185 {
186 // init everything
187 m_chkSort =
188 m_chkReadonly = (wxCheckBox *)NULL;
189
190 m_combobox = (wxComboBox *)NULL;
191 m_sizerCombo = (wxSizer *)NULL;
192
193 imaglist->Add(wxBitmap(combobox_xpm));
194
195 /*
196 What we create here is a frame having 3 panes: style pane is the
197 leftmost one, in the middle the pane with buttons allowing to perform
198 miscellaneous combobox operations and the pane containing the combobox
199 itself to the right
200 */
201 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
202
203 // left pane
204 wxStaticBox *box = new wxStaticBox(this, -1, _T("&Set style"));
205
206 // should be in sync with ComboKind_XXX values
207 static const wxString kinds[] =
208 {
209 _T("default"),
210 _T("simple"),
211 _T("drop down"),
212 };
213
214 m_radioKind = new wxRadioBox(this, -1, _T("Combobox &kind:"),
215 wxDefaultPosition, wxDefaultSize,
216 WXSIZEOF(kinds), kinds,
217 1, wxRA_SPECIFY_COLS);
218
219 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
220
221 m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Sort items"));
222 m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Read only"));
223
224 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
225 sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
226
227 wxButton *btn = new wxButton(this, ComboPage_Reset, _T("&Reset"));
228 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
229
230 // middle pane
231 wxStaticBox *box2 = new wxStaticBox(this, -1, _T("&Change combobox contents"));
232 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
233
234 wxSizer *sizerRow;
235
236 wxTextCtrl *text;
237 sizerRow = CreateSizerWithTextAndLabel(_T("Current selection"),
238 ComboPage_CurText,
239 &text);
240 text->SetEditable(FALSE);
241
242 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
243
244 sizerRow = CreateSizerWithTextAndButton(ComboPage_Add,
245 _T("&Add this string"),
246 ComboPage_AddText,
247 &m_textAdd);
248 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
249
250 btn = new wxButton(this, ComboPage_AddSeveral, _T("&Insert a few strings"));
251 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
252
253 btn = new wxButton(this, ComboPage_AddMany, _T("Add &many strings"));
254 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
255
256 sizerRow = CreateSizerWithTextAndButton(ComboPage_Change,
257 _T("C&hange current"),
258 ComboPage_ChangeText,
259 &m_textChange);
260 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
261
262 sizerRow = CreateSizerWithTextAndButton(ComboPage_Delete,
263 _T("&Delete this item"),
264 ComboPage_DeleteText,
265 &m_textDelete);
266 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
267
268 btn = new wxButton(this, ComboPage_DeleteSel, _T("Delete &selection"));
269 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
270
271 btn = new wxButton(this, ComboPage_Clear, _T("&Clear"));
272 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
273
274 // right pane
275 wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
276 m_combobox = new wxComboBox(this, ComboPage_Combo, _T(""),
277 wxDefaultPosition, wxDefaultSize,
278 0, NULL,
279 0);
280 sizerRight->Add(m_combobox, 1, wxGROW | wxALL, 5);
281 sizerRight->SetMinSize(150, 0);
282 m_sizerCombo = sizerRight; // save it to modify it later
283
284 // the 3 panes panes compose the window
285 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
286 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
287 sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
288
289 // final initializations
290 Reset();
291
292 SetAutoLayout(TRUE);
293 SetSizer(sizerTop);
294
295 sizerTop->Fit(this);
296 }
297
298 // ----------------------------------------------------------------------------
299 // operations
300 // ----------------------------------------------------------------------------
301
302 void ComboboxWidgetsPage::Reset()
303 {
304 m_chkSort->SetValue(FALSE);
305 m_chkReadonly->SetValue(FALSE);
306 }
307
308 void ComboboxWidgetsPage::CreateCombo()
309 {
310 int flags = 0;
311
312 if ( m_chkSort->GetValue() )
313 flags |= wxCB_SORT;
314 if ( m_chkReadonly->GetValue() )
315 flags |= wxCB_READONLY;
316
317 switch ( m_radioKind->GetSelection() )
318 {
319 default:
320 wxFAIL_MSG( _T("unknown combo kind") );
321 // fall through
322
323 case ComboKind_Default:
324 break;
325
326 case ComboKind_Simple:
327 flags |= wxCB_SIMPLE;
328 break;
329
330 case ComboKind_DropDown:
331 flags = wxCB_DROPDOWN;
332 break;
333 }
334
335 wxArrayString items;
336 if ( m_combobox )
337 {
338 int count = m_combobox->GetCount();
339 for ( int n = 0; n < count; n++ )
340 {
341 items.Add(m_combobox->GetString(n));
342 }
343
344 m_sizerCombo->Detach( m_combobox );
345 delete m_combobox;
346 }
347
348 m_combobox = new wxComboBox(this, ComboPage_Combo, _T(""),
349 wxDefaultPosition, wxDefaultSize,
350 0, NULL,
351 flags);
352
353 size_t count = items.GetCount();
354 for ( size_t n = 0; n < count; n++ )
355 {
356 m_combobox->Append(items[n]);
357 }
358
359 m_sizerCombo->Add(m_combobox, 1, wxGROW | wxALL, 5);
360 m_sizerCombo->Layout();
361 }
362
363 // ----------------------------------------------------------------------------
364 // event handlers
365 // ----------------------------------------------------------------------------
366
367 void ComboboxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
368 {
369 Reset();
370
371 CreateCombo();
372 }
373
374 void ComboboxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
375 {
376 int sel = m_combobox->GetSelection();
377 if ( sel != -1 )
378 {
379 #ifndef __WXGTK__
380 m_combobox->SetString(sel, m_textChange->GetValue());
381 #else
382 wxLogMessage(_T("Not implemented in wxGTK"));
383 #endif
384 }
385 }
386
387 void ComboboxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
388 {
389 unsigned long n;
390 if ( !m_textDelete->GetValue().ToULong(&n) ||
391 (n >= (unsigned)m_combobox->GetCount()) )
392 {
393 return;
394 }
395
396 m_combobox->Delete(n);
397 }
398
399 void ComboboxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
400 {
401 int sel = m_combobox->GetSelection();
402 if ( sel != -1 )
403 {
404 m_combobox->Delete(sel);
405 }
406 }
407
408 void ComboboxWidgetsPage::OnButtonClear(wxCommandEvent& event)
409 {
410 m_combobox->Clear();
411 }
412
413 void ComboboxWidgetsPage::OnButtonAdd(wxCommandEvent& event)
414 {
415 static unsigned int s_item = 0;
416
417 wxString s = m_textAdd->GetValue();
418 if ( !m_textAdd->IsModified() )
419 {
420 // update the default string
421 m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
422 }
423
424 m_combobox->Append(s);
425 }
426
427 void ComboboxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
428 {
429 // "many" means 1000 here
430 for ( unsigned int n = 0; n < 1000; n++ )
431 {
432 m_combobox->Append(wxString::Format(_T("item #%u"), n));
433 }
434 }
435
436 void ComboboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& event)
437 {
438 m_combobox->Append(_T("First"));
439 m_combobox->Append(_T("another one"));
440 m_combobox->Append(_T("and the last (very very very very very very very very very very long) one"));
441 }
442
443 void ComboboxWidgetsPage::OnUpdateUICurText(wxUpdateUIEvent& event)
444 {
445 if (m_combobox)
446 event.SetText( wxString::Format(_T("%d"), m_combobox->GetSelection()) );
447 }
448
449 void ComboboxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
450 {
451 if (m_combobox)
452 event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() );
453 }
454
455 void ComboboxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
456 {
457 if (m_combobox)
458 {
459 unsigned long n;
460 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
461 (n < (unsigned)m_combobox->GetCount()));
462 }
463 }
464
465 void ComboboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
466 {
467 if (m_combobox)
468 event.Enable(m_combobox->GetSelection() != -1);
469 }
470
471 void ComboboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
472 {
473 if (m_combobox)
474 event.Enable(m_combobox->GetCount() != 0);
475 }
476
477 void ComboboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
478 {
479 if (m_combobox)
480 event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT));
481 }
482
483 void ComboboxWidgetsPage::OnComboText(wxCommandEvent& event)
484 {
485 if (!m_combobox)
486 return;
487
488 wxString s = event.GetString();
489
490 wxASSERT_MSG( s == m_combobox->GetValue(),
491 _T("event and combobox values should be the same") );
492
493 wxLogMessage(_T("Combobox text changed (now '%s')"), s.c_str());
494 }
495
496 void ComboboxWidgetsPage::OnComboBox(wxCommandEvent& event)
497 {
498 long sel = event.GetInt();
499 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
500
501 wxLogMessage(_T("Combobox item %ld selected"), sel);
502 }
503
504 void ComboboxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
505 {
506 CreateCombo();
507 }
508
509 #endif //wxUSE_COMBOBOX
510
511 #endif