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