Warning fixes.
[wxWidgets.git] / samples / widgets / listbox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWidgets Widgets Sample
3 // Name: listbox.cpp
4 // Purpose: Part of the widgets sample showing wxListbox
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_LISTBOX
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/listbox.h"
38 #include "wx/radiobox.h"
39 #include "wx/statbox.h"
40 #include "wx/textctrl.h"
41 #endif
42
43 #include "wx/sizer.h"
44
45 #include "wx/checklst.h"
46
47 #include "widgets.h"
48
49 #include "icons/listbox.xpm"
50
51 // ----------------------------------------------------------------------------
52 // constants
53 // ----------------------------------------------------------------------------
54
55 // control ids
56 enum
57 {
58 ListboxPage_Reset = 100,
59 ListboxPage_Add,
60 ListboxPage_AddText,
61 ListboxPage_AddSeveral,
62 ListboxPage_AddMany,
63 ListboxPage_Clear,
64 ListboxPage_Change,
65 ListboxPage_ChangeText,
66 ListboxPage_Delete,
67 ListboxPage_DeleteText,
68 ListboxPage_DeleteSel,
69 ListboxPage_Listbox
70 };
71
72 // ----------------------------------------------------------------------------
73 // ListboxWidgetsPage
74 // ----------------------------------------------------------------------------
75
76 class ListboxWidgetsPage : public WidgetsPage
77 {
78 public:
79 ListboxWidgetsPage(wxBookCtrlBase *book, wxImageList *imaglist);
80
81 virtual wxControl *GetWidget() const { return m_lbox; }
82 virtual void RecreateWidget() { CreateLbox(); }
83
84 protected:
85 // event handlers
86 void OnButtonReset(wxCommandEvent& event);
87 void OnButtonChange(wxCommandEvent& event);
88 void OnButtonDelete(wxCommandEvent& event);
89 void OnButtonDeleteSel(wxCommandEvent& event);
90 void OnButtonClear(wxCommandEvent& event);
91 void OnButtonAdd(wxCommandEvent& event);
92 void OnButtonAddSeveral(wxCommandEvent& event);
93 void OnButtonAddMany(wxCommandEvent& event);
94
95 void OnListbox(wxCommandEvent& event);
96 void OnListboxDClick(wxCommandEvent& event);
97 void OnCheckListbox(wxCommandEvent& event);
98
99 void OnCheckOrRadioBox(wxCommandEvent& event);
100
101 void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
102 void OnUpdateUIClearButton(wxUpdateUIEvent& event);
103 void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
104 void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
105 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
106
107 // reset the listbox parameters
108 void Reset();
109
110 // (re)create the listbox
111 void CreateLbox();
112
113 // listbox parameters
114 // ------------------
115
116 // the selection mode
117 enum LboxSelection
118 {
119 LboxSel_Single,
120 LboxSel_Extended,
121 LboxSel_Multiple
122 } m_lboxSelMode;
123
124 // should it be sorted?
125 bool m_sorted;
126
127 // should it have horz scroll/vert scrollbar permanently shown?
128 bool m_horzScroll,
129 m_vertScrollAlways;
130
131 // the controls
132 // ------------
133
134 // the sel mode radiobox
135 wxRadioBox *m_radioSelMode;
136
137 // the checkboxes
138 wxCheckBox *m_chkVScroll,
139 *m_chkHScroll,
140 *m_chkCheck,
141 *m_chkSort,
142 *m_chkOwnerDraw;
143
144 // the listbox itself and the sizer it is in
145 wxListBox *m_lbox;
146 wxSizer *m_sizerLbox;
147
148 // the text entries for "Add/change string" and "Delete" buttons
149 wxTextCtrl *m_textAdd,
150 *m_textChange,
151 *m_textDelete;
152
153 private:
154 DECLARE_EVENT_TABLE()
155 DECLARE_WIDGETS_PAGE(ListboxWidgetsPage)
156 };
157
158 // ----------------------------------------------------------------------------
159 // event tables
160 // ----------------------------------------------------------------------------
161
162 BEGIN_EVENT_TABLE(ListboxWidgetsPage, WidgetsPage)
163 EVT_BUTTON(ListboxPage_Reset, ListboxWidgetsPage::OnButtonReset)
164 EVT_BUTTON(ListboxPage_Change, ListboxWidgetsPage::OnButtonChange)
165 EVT_BUTTON(ListboxPage_Delete, ListboxWidgetsPage::OnButtonDelete)
166 EVT_BUTTON(ListboxPage_DeleteSel, ListboxWidgetsPage::OnButtonDeleteSel)
167 EVT_BUTTON(ListboxPage_Clear, ListboxWidgetsPage::OnButtonClear)
168 EVT_BUTTON(ListboxPage_Add, ListboxWidgetsPage::OnButtonAdd)
169 EVT_BUTTON(ListboxPage_AddSeveral, ListboxWidgetsPage::OnButtonAddSeveral)
170 EVT_BUTTON(ListboxPage_AddMany, ListboxWidgetsPage::OnButtonAddMany)
171
172 EVT_TEXT_ENTER(ListboxPage_AddText, ListboxWidgetsPage::OnButtonAdd)
173 EVT_TEXT_ENTER(ListboxPage_DeleteText, ListboxWidgetsPage::OnButtonDelete)
174
175 EVT_UPDATE_UI(ListboxPage_Reset, ListboxWidgetsPage::OnUpdateUIResetButton)
176 EVT_UPDATE_UI(ListboxPage_AddSeveral, ListboxWidgetsPage::OnUpdateUIAddSeveral)
177 EVT_UPDATE_UI(ListboxPage_Clear, ListboxWidgetsPage::OnUpdateUIClearButton)
178 EVT_UPDATE_UI(ListboxPage_DeleteText, ListboxWidgetsPage::OnUpdateUIClearButton)
179 EVT_UPDATE_UI(ListboxPage_Delete, ListboxWidgetsPage::OnUpdateUIDeleteButton)
180 EVT_UPDATE_UI(ListboxPage_Change, ListboxWidgetsPage::OnUpdateUIDeleteSelButton)
181 EVT_UPDATE_UI(ListboxPage_ChangeText, ListboxWidgetsPage::OnUpdateUIDeleteSelButton)
182 EVT_UPDATE_UI(ListboxPage_DeleteSel, ListboxWidgetsPage::OnUpdateUIDeleteSelButton)
183
184 EVT_LISTBOX(ListboxPage_Listbox, ListboxWidgetsPage::OnListbox)
185 EVT_LISTBOX_DCLICK(ListboxPage_Listbox, ListboxWidgetsPage::OnListboxDClick)
186 EVT_CHECKLISTBOX(ListboxPage_Listbox, ListboxWidgetsPage::OnCheckListbox)
187
188 EVT_CHECKBOX(wxID_ANY, ListboxWidgetsPage::OnCheckOrRadioBox)
189 EVT_RADIOBOX(wxID_ANY, ListboxWidgetsPage::OnCheckOrRadioBox)
190 END_EVENT_TABLE()
191
192 // ============================================================================
193 // implementation
194 // ============================================================================
195
196 IMPLEMENT_WIDGETS_PAGE(ListboxWidgetsPage, _T("Listbox"));
197
198 ListboxWidgetsPage::ListboxWidgetsPage(wxBookCtrlBase *book,
199 wxImageList *imaglist)
200 : WidgetsPage(book)
201 {
202 imaglist->Add(wxBitmap(listbox_xpm));
203
204 // init everything
205 m_radioSelMode = (wxRadioBox *)NULL;
206
207 m_chkVScroll =
208 m_chkHScroll =
209 m_chkCheck =
210 m_chkSort =
211 m_chkOwnerDraw = (wxCheckBox *)NULL;
212
213 m_lbox = (wxListBox *)NULL;
214 m_sizerLbox = (wxSizer *)NULL;
215
216 /*
217 What we create here is a frame having 3 panes: style pane is the
218 leftmost one, in the middle the pane with buttons allowing to perform
219 miscellaneous listbox operations and the pane containing the listbox
220 itself to the right
221 */
222 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
223
224 // left pane
225 wxStaticBox *box = new wxStaticBox(this, wxID_ANY,
226 _T("&Set listbox parameters"));
227 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
228
229 static const wxString modes[] =
230 {
231 _T("single"),
232 _T("extended"),
233 _T("multiple"),
234 };
235
236 m_radioSelMode = new wxRadioBox(this, wxID_ANY, _T("Selection &mode:"),
237 wxDefaultPosition, wxDefaultSize,
238 WXSIZEOF(modes), modes,
239 1, wxRA_SPECIFY_COLS);
240
241 m_chkVScroll = CreateCheckBoxAndAddToSizer
242 (
243 sizerLeft,
244 _T("Always show &vertical scrollbar")
245 );
246 m_chkHScroll = CreateCheckBoxAndAddToSizer
247 (
248 sizerLeft,
249 _T("Show &horizontal scrollbar")
250 );
251 m_chkCheck = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Check list box"));
252 m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Sort items"));
253 m_chkOwnerDraw = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Owner drawn"));
254
255 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
256 sizerLeft->Add(m_radioSelMode, 0, wxGROW | wxALL, 5);
257
258 wxButton *btn = new wxButton(this, ListboxPage_Reset, _T("&Reset"));
259 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
260
261 // middle pane
262 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
263 _T("&Change listbox contents"));
264 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
265
266 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
267 btn = new wxButton(this, ListboxPage_Add, _T("&Add this string"));
268 m_textAdd = new wxTextCtrl(this, ListboxPage_AddText, _T("test item 0"));
269 sizerRow->Add(btn, 0, wxRIGHT, 5);
270 sizerRow->Add(m_textAdd, 1, wxLEFT, 5);
271 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
272
273 btn = new wxButton(this, ListboxPage_AddSeveral, _T("&Insert a few strings"));
274 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
275
276 btn = new wxButton(this, ListboxPage_AddMany, _T("Add &many strings"));
277 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
278
279 sizerRow = new wxBoxSizer(wxHORIZONTAL);
280 btn = new wxButton(this, ListboxPage_Change, _T("C&hange current"));
281 m_textChange = new wxTextCtrl(this, ListboxPage_ChangeText, wxEmptyString);
282 sizerRow->Add(btn, 0, wxRIGHT, 5);
283 sizerRow->Add(m_textChange, 1, wxLEFT, 5);
284 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
285
286 sizerRow = new wxBoxSizer(wxHORIZONTAL);
287 btn = new wxButton(this, ListboxPage_Delete, _T("&Delete this item"));
288 m_textDelete = new wxTextCtrl(this, ListboxPage_DeleteText, wxEmptyString);
289 sizerRow->Add(btn, 0, wxRIGHT, 5);
290 sizerRow->Add(m_textDelete, 1, wxLEFT, 5);
291 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
292
293 btn = new wxButton(this, ListboxPage_DeleteSel, _T("Delete &selection"));
294 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
295
296 btn = new wxButton(this, ListboxPage_Clear, _T("&Clear"));
297 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
298
299 // right pane
300 wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
301 m_lbox = new wxListBox(this, ListboxPage_Listbox,
302 wxDefaultPosition, wxDefaultSize,
303 0, NULL,
304 wxLB_HSCROLL);
305 sizerRight->Add(m_lbox, 1, wxGROW | wxALL, 5);
306 sizerRight->SetMinSize(150, 0);
307 m_sizerLbox = sizerRight; // save it to modify it later
308
309 // the 3 panes panes compose the window
310 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
311 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
312 sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
313
314 // final initializations
315 Reset();
316
317 SetSizer(sizerTop);
318
319 sizerTop->Fit(this);
320 }
321
322 // ----------------------------------------------------------------------------
323 // operations
324 // ----------------------------------------------------------------------------
325
326 void ListboxWidgetsPage::Reset()
327 {
328 m_radioSelMode->SetSelection(LboxSel_Single);
329 m_chkVScroll->SetValue(false);
330 m_chkHScroll->SetValue(true);
331 m_chkCheck->SetValue(false);
332 m_chkSort->SetValue(false);
333 m_chkOwnerDraw->SetValue(false);
334 }
335
336 void ListboxWidgetsPage::CreateLbox()
337 {
338 int flags = ms_defaultFlags;
339 switch ( m_radioSelMode->GetSelection() )
340 {
341 default:
342 wxFAIL_MSG( _T("unexpected radio box selection") );
343
344 case LboxSel_Single: flags |= wxLB_SINGLE; break;
345 case LboxSel_Extended: flags |= wxLB_EXTENDED; break;
346 case LboxSel_Multiple: flags |= wxLB_MULTIPLE; break;
347 }
348
349 if ( m_chkVScroll->GetValue() )
350 flags |= wxLB_ALWAYS_SB;
351 if ( m_chkHScroll->GetValue() )
352 flags |= wxLB_HSCROLL;
353 if ( m_chkSort->GetValue() )
354 flags |= wxLB_SORT;
355 if ( m_chkOwnerDraw->GetValue() )
356 flags |= wxLB_OWNERDRAW;
357
358 wxArrayString items;
359 if ( m_lbox )
360 {
361 int count = m_lbox->GetCount();
362 for ( int n = 0; n < count; n++ )
363 {
364 items.Add(m_lbox->GetString(n));
365 }
366
367 m_sizerLbox->Detach( m_lbox );
368 delete m_lbox;
369 }
370
371 #if wxUSE_CHECKLISTBOX
372 if ( m_chkCheck->GetValue() )
373 {
374 m_lbox = new wxCheckListBox(this, ListboxPage_Listbox,
375 wxDefaultPosition, wxDefaultSize,
376 0, NULL,
377 flags);
378 }
379 else // just a listbox
380 #endif
381 {
382 m_lbox = new wxListBox(this, ListboxPage_Listbox,
383 wxDefaultPosition, wxDefaultSize,
384 0, NULL,
385 flags);
386 }
387
388 m_lbox->Set(items);
389 m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
390 m_sizerLbox->Layout();
391 }
392
393 // ----------------------------------------------------------------------------
394 // event handlers
395 // ----------------------------------------------------------------------------
396
397 void ListboxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
398 {
399 Reset();
400
401 CreateLbox();
402 }
403
404 void ListboxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
405 {
406 wxArrayInt selections;
407 int count = m_lbox->GetSelections(selections);
408 wxString s = m_textChange->GetValue();
409 for ( int n = 0; n < count; n++ )
410 {
411 m_lbox->SetString(selections[n], s);
412 }
413 }
414
415 void ListboxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
416 {
417 unsigned long n;
418 if ( !m_textDelete->GetValue().ToULong(&n) ||
419 (n >= (unsigned)m_lbox->GetCount()) )
420 {
421 return;
422 }
423
424 m_lbox->Delete(n);
425 }
426
427 void ListboxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
428 {
429 wxArrayInt selections;
430 int n = m_lbox->GetSelections(selections);
431 while ( n > 0 )
432 {
433 m_lbox->Delete(selections[--n]);
434 }
435 }
436
437 void ListboxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
438 {
439 m_lbox->Clear();
440 }
441
442 void ListboxWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
443 {
444 static unsigned int s_item = 0;
445
446 wxString s = m_textAdd->GetValue();
447 if ( !m_textAdd->IsModified() )
448 {
449 // update the default string
450 m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
451 }
452
453 m_lbox->Append(s);
454 }
455
456 void ListboxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
457 {
458 // "many" means 1000 here
459 for ( unsigned int n = 0; n < 1000; n++ )
460 {
461 m_lbox->Append(wxString::Format(_T("item #%u"), n));
462 }
463 }
464
465 void ListboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
466 {
467 wxArrayString items;
468 items.Add(_T("First"));
469 items.Add(_T("another one"));
470 items.Add(_T("and the last (very very very very very very very very very very long) one"));
471 m_lbox->InsertItems(items, 0);
472 }
473
474 void ListboxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
475 {
476 event.Enable( (m_radioSelMode->GetSelection() != LboxSel_Single) ||
477 m_chkSort->GetValue() ||
478 m_chkOwnerDraw->GetValue() ||
479 !m_chkHScroll->GetValue() ||
480 m_chkVScroll->GetValue() );
481 }
482
483 void ListboxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
484 {
485 unsigned long n;
486 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
487 (n < (unsigned)m_lbox->GetCount()));
488 }
489
490 void ListboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
491 {
492 wxArrayInt selections;
493 event.Enable(m_lbox->GetSelections(selections) != 0);
494 }
495
496 void ListboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
497 {
498 event.Enable(m_lbox->GetCount() != 0);
499 }
500
501 void ListboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
502 {
503 event.Enable(!(m_lbox->GetWindowStyle() & wxLB_SORT));
504 }
505
506 void ListboxWidgetsPage::OnListbox(wxCommandEvent& event)
507 {
508 long sel = event.GetSelection();
509 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
510
511 if (event.IsSelection())
512 wxLogMessage(_T("Listbox item %ld selected"), sel);
513 else
514 wxLogMessage(_T("Listbox item %ld deselected"), sel);
515 }
516
517 void ListboxWidgetsPage::OnListboxDClick(wxCommandEvent& event)
518 {
519 wxLogMessage( _T("Listbox item %d double clicked"), event.GetInt() );
520 }
521
522 void ListboxWidgetsPage::OnCheckListbox(wxCommandEvent& event)
523 {
524 wxLogMessage( _T("Listbox item %d toggled"), event.GetInt() );
525 }
526
527 void ListboxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
528 {
529 CreateLbox();
530 }
531
532 #endif // wxUSE_LISTBOX