Small devices adjustements.
[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 = wxID_HIGHEST,
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(WidgetsBookCtrl *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 wxListBoxBase *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 #if defined(__WXUNIVERSAL__)
197 #define FAMILY_CTRLS UNIVERSAL_CTRLS
198 #else
199 #define FAMILY_CTRLS NATIVE_CTRLS
200 #endif
201
202 IMPLEMENT_WIDGETS_PAGE(ListboxWidgetsPage, _T("Listbox"),
203 FAMILY_CTRLS | WITH_ITEMS_CTRLS
204 );
205
206 ListboxWidgetsPage::ListboxWidgetsPage(WidgetsBookCtrl *book,
207 wxImageList *imaglist)
208 : WidgetsPage(book, imaglist, listbox_xpm)
209 {
210 // init everything
211 m_radioSelMode = (wxRadioBox *)NULL;
212
213 m_chkVScroll =
214 m_chkHScroll =
215 m_chkCheck =
216 m_chkSort =
217 m_chkOwnerDraw = (wxCheckBox *)NULL;
218
219 m_lbox = (wxListBoxBase *)NULL;
220 m_sizerLbox = (wxSizer *)NULL;
221
222 /*
223 What we create here is a frame having 3 panes: style pane is the
224 leftmost one, in the middle the pane with buttons allowing to perform
225 miscellaneous listbox operations and the pane containing the listbox
226 itself to the right
227 */
228 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
229
230 // left pane
231 wxStaticBox *box = new wxStaticBox(this, wxID_ANY,
232 _T("&Set listbox parameters"));
233 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
234
235 static const wxString modes[] =
236 {
237 _T("single"),
238 _T("extended"),
239 _T("multiple"),
240 };
241
242 m_radioSelMode = new wxRadioBox(this, wxID_ANY, _T("Selection &mode:"),
243 wxDefaultPosition, wxDefaultSize,
244 WXSIZEOF(modes), modes,
245 1, wxRA_SPECIFY_COLS);
246
247 m_chkVScroll = CreateCheckBoxAndAddToSizer
248 (
249 sizerLeft,
250 _T("Always show &vertical scrollbar")
251 );
252 m_chkHScroll = CreateCheckBoxAndAddToSizer
253 (
254 sizerLeft,
255 _T("Show &horizontal scrollbar")
256 );
257 m_chkCheck = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Check list box"));
258 m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Sort items"));
259 m_chkOwnerDraw = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Owner drawn"));
260
261 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
262 sizerLeft->Add(m_radioSelMode, 0, wxGROW | wxALL, 5);
263
264 wxButton *btn = new wxButton(this, ListboxPage_Reset, _T("&Reset"));
265 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
266
267 // middle pane
268 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
269 _T("&Change listbox contents"));
270 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
271
272 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
273 btn = new wxButton(this, ListboxPage_Add, _T("&Add this string"));
274 m_textAdd = new wxTextCtrl(this, ListboxPage_AddText, _T("test item 0"));
275 sizerRow->Add(btn, 0, wxRIGHT, 5);
276 sizerRow->Add(m_textAdd, 1, wxLEFT, 5);
277 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
278
279 btn = new wxButton(this, ListboxPage_AddSeveral, _T("&Insert a few strings"));
280 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
281
282 btn = new wxButton(this, ListboxPage_AddMany, _T("Add &many strings"));
283 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
284
285 sizerRow = new wxBoxSizer(wxHORIZONTAL);
286 btn = new wxButton(this, ListboxPage_Change, _T("C&hange current"));
287 m_textChange = new wxTextCtrl(this, ListboxPage_ChangeText, wxEmptyString);
288 sizerRow->Add(btn, 0, wxRIGHT, 5);
289 sizerRow->Add(m_textChange, 1, wxLEFT, 5);
290 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
291
292 sizerRow = new wxBoxSizer(wxHORIZONTAL);
293 btn = new wxButton(this, ListboxPage_Delete, _T("&Delete this item"));
294 m_textDelete = new wxTextCtrl(this, ListboxPage_DeleteText, wxEmptyString);
295 sizerRow->Add(btn, 0, wxRIGHT, 5);
296 sizerRow->Add(m_textDelete, 1, wxLEFT, 5);
297 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
298
299 btn = new wxButton(this, ListboxPage_DeleteSel, _T("Delete &selection"));
300 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
301
302 btn = new wxButton(this, ListboxPage_Clear, _T("&Clear"));
303 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
304
305 // right pane
306 wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
307 m_lbox = new wxListBox(this, ListboxPage_Listbox,
308 wxDefaultPosition, wxDefaultSize,
309 0, NULL,
310 wxLB_HSCROLL);
311 sizerRight->Add(m_lbox, 1, wxGROW | wxALL, 5);
312 sizerRight->SetMinSize(150, 0);
313 m_sizerLbox = sizerRight; // save it to modify it later
314
315 // the 3 panes panes compose the window
316 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
317 sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
318 sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
319
320 // final initializations
321 Reset();
322
323 SetSizer(sizerTop);
324
325 sizerTop->Fit(this);
326 }
327
328 // ----------------------------------------------------------------------------
329 // operations
330 // ----------------------------------------------------------------------------
331
332 void ListboxWidgetsPage::Reset()
333 {
334 m_radioSelMode->SetSelection(LboxSel_Single);
335 m_chkVScroll->SetValue(false);
336 m_chkHScroll->SetValue(true);
337 m_chkCheck->SetValue(false);
338 m_chkSort->SetValue(false);
339 m_chkOwnerDraw->SetValue(false);
340 }
341
342 void ListboxWidgetsPage::CreateLbox()
343 {
344 int flags = ms_defaultFlags;
345 switch ( m_radioSelMode->GetSelection() )
346 {
347 default:
348 wxFAIL_MSG( _T("unexpected radio box selection") );
349
350 case LboxSel_Single: flags |= wxLB_SINGLE; break;
351 case LboxSel_Extended: flags |= wxLB_EXTENDED; break;
352 case LboxSel_Multiple: flags |= wxLB_MULTIPLE; break;
353 }
354
355 if ( m_chkVScroll->GetValue() )
356 flags |= wxLB_ALWAYS_SB;
357 if ( m_chkHScroll->GetValue() )
358 flags |= wxLB_HSCROLL;
359 if ( m_chkSort->GetValue() )
360 flags |= wxLB_SORT;
361 if ( m_chkOwnerDraw->GetValue() )
362 flags |= wxLB_OWNERDRAW;
363
364 wxArrayString items;
365 if ( m_lbox )
366 {
367 int count = m_lbox->GetCount();
368 for ( int n = 0; n < count; n++ )
369 {
370 items.Add(m_lbox->GetString(n));
371 }
372
373 m_sizerLbox->Detach( m_lbox );
374 delete m_lbox;
375 }
376
377 #if wxUSE_CHECKLISTBOX
378 if ( m_chkCheck->GetValue() )
379 {
380 m_lbox = new wxCheckListBox(this, ListboxPage_Listbox,
381 wxDefaultPosition, wxDefaultSize,
382 0, NULL,
383 flags);
384 }
385 else // just a listbox
386 #endif
387 {
388 m_lbox = new wxListBox(this, ListboxPage_Listbox,
389 wxDefaultPosition, wxDefaultSize,
390 0, NULL,
391 flags);
392 }
393
394 m_lbox->Set(items);
395 m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
396 m_sizerLbox->Layout();
397 }
398
399 // ----------------------------------------------------------------------------
400 // event handlers
401 // ----------------------------------------------------------------------------
402
403 void ListboxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
404 {
405 Reset();
406
407 CreateLbox();
408 }
409
410 void ListboxWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event))
411 {
412 wxArrayInt selections;
413 int count = m_lbox->GetSelections(selections);
414 wxString s = m_textChange->GetValue();
415 for ( int n = 0; n < count; n++ )
416 {
417 m_lbox->SetString(selections[n], s);
418 }
419 }
420
421 void ListboxWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
422 {
423 unsigned long n;
424 if ( !m_textDelete->GetValue().ToULong(&n) ||
425 (n >= (unsigned)m_lbox->GetCount()) )
426 {
427 return;
428 }
429
430 m_lbox->Delete(n);
431 }
432
433 void ListboxWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
434 {
435 wxArrayInt selections;
436 int n = m_lbox->GetSelections(selections);
437 while ( n > 0 )
438 {
439 m_lbox->Delete(selections[--n]);
440 }
441 }
442
443 void ListboxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
444 {
445 m_lbox->Clear();
446 }
447
448 void ListboxWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
449 {
450 static unsigned int s_item = 0;
451
452 wxString s = m_textAdd->GetValue();
453 if ( !m_textAdd->IsModified() )
454 {
455 // update the default string
456 m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
457 }
458
459 m_lbox->Append(s);
460 }
461
462 void ListboxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
463 {
464 // "many" means 1000 here
465 for ( unsigned int n = 0; n < 1000; n++ )
466 {
467 m_lbox->Append(wxString::Format(_T("item #%u"), n));
468 }
469 }
470
471 void ListboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
472 {
473 wxArrayString items;
474 items.Add(_T("First"));
475 items.Add(_T("another one"));
476 items.Add(_T("and the last (very very very very very very very very very very long) one"));
477 m_lbox->InsertItems(items, 0);
478 }
479
480 void ListboxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
481 {
482 event.Enable( (m_radioSelMode->GetSelection() != LboxSel_Single) ||
483 m_chkSort->GetValue() ||
484 m_chkOwnerDraw->GetValue() ||
485 !m_chkHScroll->GetValue() ||
486 m_chkVScroll->GetValue() );
487 }
488
489 void ListboxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
490 {
491 unsigned long n;
492 event.Enable(m_textDelete->GetValue().ToULong(&n) &&
493 (n < (unsigned)m_lbox->GetCount()));
494 }
495
496 void ListboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
497 {
498 wxArrayInt selections;
499 event.Enable(m_lbox->GetSelections(selections) != 0);
500 }
501
502 void ListboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
503 {
504 event.Enable(m_lbox->GetCount() != 0);
505 }
506
507 void ListboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
508 {
509 event.Enable(!(m_lbox->GetWindowStyle() & wxLB_SORT));
510 }
511
512 void ListboxWidgetsPage::OnListbox(wxCommandEvent& event)
513 {
514 long sel = event.GetSelection();
515 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
516
517 if (event.IsSelection())
518 wxLogMessage(_T("Listbox item %ld selected"), sel);
519 else
520 wxLogMessage(_T("Listbox item %ld deselected"), sel);
521 }
522
523 void ListboxWidgetsPage::OnListboxDClick(wxCommandEvent& event)
524 {
525 wxLogMessage( _T("Listbox item %d double clicked"), event.GetInt() );
526 }
527
528 void ListboxWidgetsPage::OnCheckListbox(wxCommandEvent& event)
529 {
530 wxLogMessage( _T("Listbox item %d toggled"), event.GetInt() );
531 }
532
533 void ListboxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
534 {
535 CreateLbox();
536 }
537
538 #endif // wxUSE_LISTBOX