fixed Printf() format spec warnings
[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 #if 1
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(150, 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 wxUSE_CHECKLISTBOX
359 if ( m_chkCheck->GetValue() )
360 {
361 m_lbox = new wxCheckListBox(this, ListboxPage_Listbox,
362 wxDefaultPosition, wxDefaultSize,
363 0, NULL,
364 flags);
365 }
366 else // just a listbox
367 #endif
368 {
369 m_lbox = new wxListBox(this, ListboxPage_Listbox,
370 wxDefaultPosition, wxDefaultSize,
371 0, NULL,
372 flags);
373 }
374
375 m_lbox->Set(items);
376 m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
377 m_sizerLbox->Layout();
378 }
379
380 // ----------------------------------------------------------------------------
381 // event handlers
382 // ----------------------------------------------------------------------------
383
384 void ListboxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
385 {
386 Reset();
387
388 CreateLbox();
389 }
390
391 void ListboxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
392 {
393 wxArrayInt selections;
394 int count = m_lbox->GetSelections(selections);
395 wxString s = m_textChange->GetValue();
396 for ( int n = 0; n < count; n++ )
397 {
398 m_lbox->SetString(selections[n], s);
399 }
400 }
401
402 void ListboxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
403 {
404 unsigned long n;
405 if ( !m_textDelete->GetValue().ToULong(&n) ||
406 (n >= (unsigned)m_lbox->GetCount()) )
407 {
408 return;
409 }
410
411 m_lbox->Delete(n);
412 }
413
414 void ListboxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
415 {
416 wxArrayInt selections;
417 int n = m_lbox->GetSelections(selections);
418 while ( n > 0 )
419 {
420 m_lbox->Delete(selections[--n]);
421 }
422 }
423
424 void ListboxWidgetsPage::OnButtonClear(wxCommandEvent& event)
425 {
426 m_lbox->Clear();
427 }
428
429 void ListboxWidgetsPage::OnButtonAdd(wxCommandEvent& event)
430 {
431 static unsigned int s_item = 0;
432
433 wxString s = m_textAdd->GetValue();
434 if ( !m_textAdd->IsModified() )
435 {
436 // update the default string
437 m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
438 }
439
440 m_lbox->Append(s);
441 }
442
443 void ListboxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
444 {
445 // "many" means 1000 here
446 for ( unsigned int n = 0; n < 1000; n++ )
447 {
448 m_lbox->Append(wxString::Format(_T("item #%u"), n));
449 }
450 }
451
452 void ListboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& event)
453 {
454 wxArrayString items;
455 items.Add(_T("First"));
456 items.Add(_T("another one"));
457 items.Add(_T("and the last (very very very very very very very very very very long) one"));
458 m_lbox->InsertItems(items, 0);
459 }
460
461 void ListboxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
462 {
463 event.Enable( (m_radioSelMode->GetSelection() != LboxSel_Single) ||
464 m_chkSort->GetValue() ||
465 !m_chkHScroll->GetValue() ||
466 m_chkVScroll->GetValue() );
467 }
468
469 void ListboxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
470 {
471 unsigned long n;
472 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
473 (n < (unsigned)m_lbox->GetCount()));
474 }
475
476 void ListboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
477 {
478 wxArrayInt selections;
479 event.Enable(m_lbox->GetSelections(selections) != 0);
480 }
481
482 void ListboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
483 {
484 event.Enable(m_lbox->GetCount() != 0);
485 }
486
487 void ListboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
488 {
489 event.Enable(!(m_lbox->GetWindowStyle() & wxLB_SORT));
490 }
491
492 void ListboxWidgetsPage::OnListbox(wxCommandEvent& event)
493 {
494 long sel = event.GetInt();
495 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
496
497 wxLogMessage(_T("Listbox item %ld selected"), sel);
498 }
499
500 void ListboxWidgetsPage::OnListboxDClick(wxCommandEvent& event)
501 {
502 wxLogMessage( _T("Listbox item %ld double clicked"), event.GetInt() );
503 }
504
505 void ListboxWidgetsPage::OnCheckListbox(wxCommandEvent& event)
506 {
507 wxLogMessage( _T("Listbox item %ld toggled"), event.GetInt() );
508 }
509
510 void ListboxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
511 {
512 CreateLbox();
513 }
514
515 #endif