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