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