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