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