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