]> git.saurik.com Git - wxWidgets.git/blame - samples/widgets/listbox.cpp
use wxDC::GetMultiLineTextExtent() instead of duplicating its code in wxButton::DoGet...
[wxWidgets.git] / samples / widgets / listbox.cpp
CommitLineData
32b8ec41 1/////////////////////////////////////////////////////////////////////////////
be5a51fb 2// Program: wxWidgets Widgets Sample
32b8ec41
VZ
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
eecdb000
WS
27#if wxUSE_LISTBOX
28
32b8ec41
VZ
29// for all others, include the necessary headers
30#ifndef WX_PRECOMP
31 #include "wx/log.h"
32
3bb70c40 33 #include "wx/bitmap.h"
32b8ec41
VZ
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"
eecdb000 48
32b8ec41
VZ
49#include "icons/listbox.xpm"
50
51// ----------------------------------------------------------------------------
52// constants
53// ----------------------------------------------------------------------------
54
55// control ids
56enum
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
76class ListboxWidgetsPage : public WidgetsPage
77{
78public:
61c083e7 79 ListboxWidgetsPage(wxBookCtrl *book, wxImageList *imaglist);
32b8ec41 80
195df7a7
VZ
81 virtual wxControl *GetWidget() const { return m_lbox; }
82
32b8ec41
VZ
83protected:
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
151private:
5e173f35
GD
152 DECLARE_EVENT_TABLE()
153 DECLARE_WIDGETS_PAGE(ListboxWidgetsPage)
32b8ec41
VZ
154};
155
156// ----------------------------------------------------------------------------
157// event tables
158// ----------------------------------------------------------------------------
159
160BEGIN_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
206d3a16
JS
186 EVT_CHECKBOX(wxID_ANY, ListboxWidgetsPage::OnCheckOrRadioBox)
187 EVT_RADIOBOX(wxID_ANY, ListboxWidgetsPage::OnCheckOrRadioBox)
32b8ec41
VZ
188END_EVENT_TABLE()
189
190// ============================================================================
191// implementation
192// ============================================================================
193
194IMPLEMENT_WIDGETS_PAGE(ListboxWidgetsPage, _T("Listbox"));
195
61c083e7 196ListboxWidgetsPage::ListboxWidgetsPage(wxBookCtrl *book,
32b8ec41 197 wxImageList *imaglist)
61c083e7 198 : WidgetsPage(book)
32b8ec41
VZ
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
206d3a16
JS
222 wxStaticBox *box = new wxStaticBox(this, wxID_ANY,
223 _T("&Set listbox parameters"));
32b8ec41
VZ
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
206d3a16 233 m_radioSelMode = new wxRadioBox(this, wxID_ANY, _T("Selection &mode:"),
32b8ec41
VZ
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
206d3a16
JS
258 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY,
259 _T("&Change listbox contents"));
32b8ec41
VZ
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"));
206d3a16 277 m_textChange = new wxTextCtrl(this, ListboxPage_ChangeText, wxEmptyString);
32b8ec41
VZ
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"));
206d3a16 284 m_textDelete = new wxTextCtrl(this, ListboxPage_DeleteText, wxEmptyString);
32b8ec41
VZ
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);
7b127900 302 sizerRight->SetMinSize(150, 0);
32b8ec41
VZ
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
32b8ec41
VZ
313 SetSizer(sizerTop);
314
315 sizerTop->Fit(this);
316}
317
318// ----------------------------------------------------------------------------
319// operations
320// ----------------------------------------------------------------------------
321
322void ListboxWidgetsPage::Reset()
323{
324 m_radioSelMode->SetSelection(LboxSel_Single);
206d3a16
JS
325 m_chkSort->SetValue(false);
326 m_chkCheck->SetValue(false);
327 m_chkHScroll->SetValue(true);
328 m_chkVScroll->SetValue(false);
32b8ec41
VZ
329}
330
331void 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
12a3f227 360 m_sizerLbox->Detach( m_lbox );
32b8ec41
VZ
361 delete m_lbox;
362 }
363
e640f823 364#if wxUSE_CHECKLISTBOX
32b8ec41
VZ
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
e640f823 373#endif
32b8ec41
VZ
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
390void ListboxWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
391{
392 Reset();
393
394 CreateLbox();
395}
396
397void 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
408void 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
420void 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
c02e5a31 430void ListboxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
32b8ec41
VZ
431{
432 m_lbox->Clear();
433}
434
c02e5a31 435void ListboxWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
32b8ec41 436{
0c61716c 437 static unsigned int s_item = 0;
32b8ec41
VZ
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
449void ListboxWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
450{
451 // "many" means 1000 here
0c61716c 452 for ( unsigned int n = 0; n < 1000; n++ )
32b8ec41
VZ
453 {
454 m_lbox->Append(wxString::Format(_T("item #%u"), n));
455 }
456}
457
c02e5a31 458void ListboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
32b8ec41
VZ
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
467void 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
475void 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
482void ListboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
483{
484 wxArrayInt selections;
485 event.Enable(m_lbox->GetSelections(selections) != 0);
486}
487
488void ListboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
489{
490 event.Enable(m_lbox->GetCount() != 0);
491}
492
493void ListboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
494{
495 event.Enable(!(m_lbox->GetWindowStyle() & wxLB_SORT));
496}
497
498void ListboxWidgetsPage::OnListbox(wxCommandEvent& event)
499{
a0086878 500 long sel = event.GetSelection();
32b8ec41
VZ
501 m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
502
a0086878
JS
503 if (event.IsSelection())
504 wxLogMessage(_T("Listbox item %ld selected"), sel);
505 else
506 wxLogMessage(_T("Listbox item %ld deselected"), sel);
32b8ec41
VZ
507}
508
509void ListboxWidgetsPage::OnListboxDClick(wxCommandEvent& event)
510{
aec18ff7 511 wxLogMessage( _T("Listbox item %ld double clicked"), event.GetInt() );
32b8ec41
VZ
512}
513
514void ListboxWidgetsPage::OnCheckListbox(wxCommandEvent& event)
515{
aec18ff7 516 wxLogMessage( _T("Listbox item %ld toggled"), event.GetInt() );
32b8ec41
VZ
517}
518
c02e5a31 519void ListboxWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
32b8ec41
VZ
520{
521 CreateLbox();
522}
523
eecdb000 524#endif // wxUSE_LISTBOX