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