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