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