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