1///////////////////////////////////////////////////////////////////////////// 2// Name: listctrl.cpp 3// Purpose: wxListCtrl sample 4// Author: Julian Smart 5// Modified by: 6// Created: 04/01/98 7// RCS-ID: $Id: listtest.cpp 62088 2009-09-24 15:54:53Z JS $ 8// Copyright: (c) Julian Smart 9// Licence: wxWindows license 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx/wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __BORLANDC__ 16#pragma hdrstop 17#endif 18 19#ifndef WX_PRECOMP 20#include "wx/wx.h" 21#endif 22 23#if !defined(__WXMSW__) && !defined(__WXPM__) 24 #include "mondrian.xpm" 25#endif 26 27#ifndef __WXMSW__ 28 #include "bitmaps/toolbrai.xpm" 29 #include "bitmaps/toolchar.xpm" 30 #include "bitmaps/tooldata.xpm" 31 #include "bitmaps/toolnote.xpm" 32 #include "bitmaps/tooltodo.xpm" 33 #include "bitmaps/toolchec.xpm" 34 #include "bitmaps/toolgame.xpm" 35 #include "bitmaps/tooltime.xpm" 36 #include "bitmaps/toolword.xpm" 37 #include "bitmaps/small1.xpm" 38#endif 39 40#include "wx/imaglist.h" 41#include "wx/listctrl.h" 42#include "wx/timer.h" // for wxStopWatch 43#include "wx/colordlg.h" // for wxGetColourFromUser 44#include "wx/settings.h" 45#include "wx/sysopt.h" 46 47#include "listtest.h" 48 49const wxChar *SMALL_VIRTUAL_VIEW_ITEMS[][2] = 50{ 51 { _T("Cat"), _T("meow") }, 52 { _T("Cow"), _T("moo") }, 53 { _T("Crow"), _T("caw") }, 54 { _T("Dog"), _T("woof") }, 55 { _T("Duck"), _T("quack") }, 56 { _T("Mouse"), _T("squeak") }, 57 { _T("Owl"), _T("hoo") }, 58 { _T("Pig"), _T("oink") }, 59 { _T("Pigeon"), _T("coo") }, 60 { _T("Sheep"), _T("baaah") }, 61}; 62 63 64BEGIN_EVENT_TABLE(MyFrame, wxFrame) 65 EVT_SIZE(MyFrame::OnSize) 66 67 EVT_MENU(LIST_QUIT, MyFrame::OnQuit) 68 EVT_MENU(LIST_ABOUT, MyFrame::OnAbout) 69 EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView) 70 EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView) 71 EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView) 72 EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView) 73 EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView) 74 EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView) 75 EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView) 76 EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView) 77 78 EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast) 79 EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel) 80 EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll) 81 EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll) 82 EVT_MENU(LIST_DELETE, MyFrame::OnDelete) 83 EVT_MENU(LIST_ADD, MyFrame::OnAdd) 84 EVT_MENU(LIST_EDIT, MyFrame::OnEdit) 85 EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll) 86 EVT_MENU(LIST_SORT, MyFrame::OnSort) 87 EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour) 88 EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour) 89 EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel) 90 EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo) 91 EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo) 92 EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze) 93 EVT_MENU(LIST_THAW, MyFrame::OnThaw) 94 EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines) 95 EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric) 96 EVT_MENU(LIST_LONG_OPERATION, MyFrame::OnLongOperation) 97 98 EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo) 99 EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel) 100END_EVENT_TABLE() 101 102BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl) 103 EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag) 104 EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag) 105 EVT_LIST_BEGIN_LABEL_EDIT(LIST_CTRL, MyListCtrl::OnBeginLabelEdit) 106 EVT_LIST_END_LABEL_EDIT(LIST_CTRL, MyListCtrl::OnEndLabelEdit) 107 EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem) 108 EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems) 109#if WXWIN_COMPATIBILITY_2_4 110 EVT_LIST_GET_INFO(LIST_CTRL, MyListCtrl::OnGetInfo) 111 EVT_LIST_SET_INFO(LIST_CTRL, MyListCtrl::OnSetInfo) 112#endif 113 EVT_LIST_ITEM_SELECTED(LIST_CTRL, MyListCtrl::OnSelected) 114 EVT_LIST_ITEM_DESELECTED(LIST_CTRL, MyListCtrl::OnDeselected) 115 EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown) 116 EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated) 117 EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused) 118 119 EVT_LIST_COL_CLICK(LIST_CTRL, MyListCtrl::OnColClick) 120 EVT_LIST_COL_RIGHT_CLICK(LIST_CTRL, MyListCtrl::OnColRightClick) 121 EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag) 122 EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging) 123 EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag) 124 125 EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint) 126 127#if USE_CONTEXT_MENU 128 EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu) 129#endif 130 EVT_CHAR(MyListCtrl::OnChar) 131 132 EVT_RIGHT_DOWN(MyListCtrl::OnRightClick) 133END_EVENT_TABLE() 134 135IMPLEMENT_APP(MyApp) 136 137// number of items in list/report view 138static const int NUM_ITEMS = 30; 139 140// number of items in icon/small icon view 141static const int NUM_ICONS = 9; 142 143int wxCALLBACK MyCompareFunction(long item1, long item2, long WXUNUSED(sortData)) 144{ 145 // inverse the order 146 if (item1 < item2) 147 return -1; 148 if (item1 > item2) 149 return 1; 150 151 return 0; 152} 153 154// `Main program' equivalent, creating windows and returning main app frame 155bool MyApp::OnInit() 156{ 157 // Create the main frame window 158 MyFrame *frame = new MyFrame(wxT("wxListCtrl Test")); 159 160 // Show the frame 161 frame->Show(true); 162 163 SetTopWindow(frame); 164 165 return true; 166} 167 168// My frame constructor 169MyFrame::MyFrame(const wxChar *title) 170 : wxFrame(NULL, wxID_ANY, title) 171{ 172 m_listCtrl = NULL; 173 m_logWindow = NULL; 174 m_smallVirtual = false; 175 176 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_SMALL) 177 SetSize(wxSize(450, 340)); 178 179 // Give it an icon 180 SetIcon( wxICON(mondrian) ); 181 182 // Make an image list containing large icons 183 m_imageListNormal = new wxImageList(32, 32, true); 184 m_imageListSmall = new wxImageList(16, 16, true); 185 186#ifdef __WXMSW__ 187 m_imageListNormal->Add( wxIcon(_T("icon1"), wxBITMAP_TYPE_ICO_RESOURCE) ); 188 m_imageListNormal->Add( wxIcon(_T("icon2"), wxBITMAP_TYPE_ICO_RESOURCE) ); 189 m_imageListNormal->Add( wxIcon(_T("icon3"), wxBITMAP_TYPE_ICO_RESOURCE) ); 190 m_imageListNormal->Add( wxIcon(_T("icon4"), wxBITMAP_TYPE_ICO_RESOURCE) ); 191 m_imageListNormal->Add( wxIcon(_T("icon5"), wxBITMAP_TYPE_ICO_RESOURCE) ); 192 m_imageListNormal->Add( wxIcon(_T("icon6"), wxBITMAP_TYPE_ICO_RESOURCE) ); 193 m_imageListNormal->Add( wxIcon(_T("icon7"), wxBITMAP_TYPE_ICO_RESOURCE) ); 194 m_imageListNormal->Add( wxIcon(_T("icon8"), wxBITMAP_TYPE_ICO_RESOURCE) ); 195 m_imageListNormal->Add( wxIcon(_T("icon9"), wxBITMAP_TYPE_ICO_RESOURCE) ); 196 197 m_imageListSmall->Add( wxIcon(_T("iconsmall"), wxBITMAP_TYPE_ICO_RESOURCE) ); 198 199#else 200 m_imageListNormal->Add( wxIcon( toolbrai_xpm ) ); 201 m_imageListNormal->Add( wxIcon( toolchar_xpm ) ); 202 m_imageListNormal->Add( wxIcon( tooldata_xpm ) ); 203 m_imageListNormal->Add( wxIcon( toolnote_xpm ) ); 204 m_imageListNormal->Add( wxIcon( tooltodo_xpm ) ); 205 m_imageListNormal->Add( wxIcon( toolchec_xpm ) ); 206 m_imageListNormal->Add( wxIcon( toolgame_xpm ) ); 207 m_imageListNormal->Add( wxIcon( tooltime_xpm ) ); 208 m_imageListNormal->Add( wxIcon( toolword_xpm ) ); 209 210 m_imageListSmall->Add( wxIcon( small1_xpm) ); 211#endif 212 213 // Make a menubar 214 wxMenu *menuFile = new wxMenu; 215 menuFile->Append(LIST_ABOUT, _T("&About")); 216 menuFile->AppendSeparator(); 217 menuFile->Append(LIST_QUIT, _T("E&xit\tAlt-X")); 218 219 wxMenu *menuView = new wxMenu; 220 menuView->Append(LIST_LIST_VIEW, _T("&List view\tF1")); 221 menuView->Append(LIST_REPORT_VIEW, _T("&Report view\tF2")); 222 menuView->Append(LIST_ICON_VIEW, _T("&Icon view\tF3")); 223 menuView->Append(LIST_ICON_TEXT_VIEW, _T("Icon view with &text\tF4")); 224 menuView->Append(LIST_SMALL_ICON_VIEW, _T("&Small icon view\tF5")); 225 menuView->Append(LIST_SMALL_ICON_TEXT_VIEW, _T("Small icon &view with text\tF6")); 226 menuView->Append(LIST_VIRTUAL_VIEW, _T("&Virtual view\tF7")); 227 menuView->Append(LIST_SMALL_VIRTUAL_VIEW, _T("Small virtual vie&w\tF8")); 228#ifdef __WXMAC__ 229 menuView->AppendCheckItem(LIST_MAC_USE_GENERIC, _T("Mac: Use Generic Control")); 230#endif 231 232 wxMenu *menuList = new wxMenu; 233 menuList->Append(LIST_FOCUS_LAST, _T("&Make last item current\tCtrl-L")); 234 menuList->Append(LIST_TOGGLE_FIRST, _T("To&ggle first item\tCtrl-G")); 235 menuList->Append(LIST_DESELECT_ALL, _T("&Deselect All\tCtrl-D")); 236 menuList->Append(LIST_SELECT_ALL, _T("S&elect All\tCtrl-A")); 237 menuList->AppendSeparator(); 238 menuList->Append(LIST_SHOW_COL_INFO, _T("Show &column info\tCtrl-C")); 239 menuList->Append(LIST_SHOW_SEL_INFO, _T("Show &selected items\tCtrl-S")); 240 menuList->AppendSeparator(); 241 menuList->Append(LIST_SORT, _T("&Sort\tCtrl-S")); 242 menuList->AppendSeparator(); 243 menuList->Append(LIST_ADD, _T("&Append an item\tCtrl-P")); 244 menuList->Append(LIST_EDIT, _T("&Edit the item\tCtrl-E")); 245 menuList->Append(LIST_DELETE, _T("&Delete first item\tCtrl-X")); 246 menuList->Append(LIST_DELETE_ALL, _T("Delete &all items")); 247 menuList->AppendSeparator(); 248 menuList->Append(LIST_FREEZE, _T("Free&ze\tCtrl-Z")); 249 menuList->Append(LIST_THAW, _T("Tha&w\tCtrl-W")); 250 menuList->AppendSeparator(); 251 menuList->AppendCheckItem(LIST_TOGGLE_LINES, _T("Toggle &lines\tCtrl-I")); 252 menuList->Append(LIST_TOGGLE_MULTI_SEL, _T("&Multiple selection\tCtrl-M"), 253 _T("Toggle multiple selection"), true); 254 menuList->AppendSeparator(); 255 menuList->Append(LIST_LONG_OPERATION, _T("&Updates a list during long operation")); 256 257 wxMenu *menuCol = new wxMenu; 258 menuCol->Append(LIST_SET_FG_COL, _T("&Foreground colour...")); 259 menuCol->Append(LIST_SET_BG_COL, _T("&Background colour...")); 260 261 wxMenuBar *menubar = new wxMenuBar; 262 menubar->Append(menuFile, _T("&File")); 263 menubar->Append(menuView, _T("&View")); 264 menubar->Append(menuList, _T("&List")); 265 menubar->Append(menuCol, _T("&Colour")); 266 SetMenuBar(menubar); 267 268 m_panel = new wxPanel(this, wxID_ANY); 269 m_logWindow = new wxTextCtrl(m_panel, wxID_ANY, wxEmptyString, 270 wxDefaultPosition, wxDefaultSize, 271 wxTE_MULTILINE | wxSUNKEN_BORDER); 272 273 m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow)); 274 275 RecreateList(wxLC_REPORT | wxLC_SINGLE_SEL); 276 277#if wxUSE_STATUSBAR 278 CreateStatusBar(3); 279#endif // wxUSE_STATUSBAR 280} 281 282MyFrame::~MyFrame() 283{ 284 delete wxLog::SetActiveTarget(m_logOld); 285 286 delete m_imageListNormal; 287 delete m_imageListSmall; 288} 289 290void MyFrame::OnSize(wxSizeEvent& event) 291{ 292 DoSize(); 293 294 event.Skip(); 295} 296 297void MyFrame::DoSize() 298{ 299 if ( !m_logWindow ) 300 return; 301 302 wxSize size = GetClientSize(); 303 wxCoord y = (2*size.y)/3; 304 m_listCtrl->SetSize(0, 0, size.x, y); 305 m_logWindow->SetSize(0, y + 1, size.x, size.y - y); 306} 307 308bool MyFrame::CheckNonVirtual() const 309{ 310 if ( !m_listCtrl->HasFlag(wxLC_VIRTUAL) ) 311 return true; 312 313 // "this" == whatever 314 wxLogWarning(_T("Can't do this in virtual view, sorry.")); 315 316 return false; 317} 318 319void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 320{ 321 Close(true); 322} 323 324void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) 325{ 326 wxMessageDialog dialog(this, _T("List test sample\nJulian Smart (c) 1997"), 327 _T("About list test"), wxOK|wxCANCEL); 328 329 dialog.ShowModal(); 330} 331 332void MyFrame::OnFreeze(wxCommandEvent& WXUNUSED(event)) 333{ 334 wxLogMessage(_T("Freezing the control")); 335 336 m_listCtrl->Freeze(); 337} 338 339void MyFrame::OnThaw(wxCommandEvent& WXUNUSED(event)) 340{ 341 wxLogMessage(_T("Thawing the control")); 342 343 m_listCtrl->Thaw(); 344} 345 346void MyFrame::OnToggleLines(wxCommandEvent& event) 347{ 348 m_listCtrl->SetSingleStyle(wxLC_HRULES | wxLC_VRULES, event.IsChecked()); 349} 350 351void MyFrame::OnToggleMacUseGeneric(wxCommandEvent& event) 352{ 353 wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), event.IsChecked()); 354} 355 356void MyFrame::OnLongOperation(wxCommandEvent & event) 357{ 358 if ((m_listCtrl->GetWindowStyleFlag() & wxLC_MASK_TYPE) != wxLC_REPORT) 359 { 360 wxLogWarning(_T("need to be in report mode")); 361 return; 362 } 363 364 for (unsigned idx=0; idx<100; ++idx) 365 { 366 m_listCtrl->Freeze(); 367 m_listCtrl->DeleteAllItems(); 368 m_listCtrl->DeleteColumn(2); 369 m_listCtrl->DeleteColumn(1); 370 m_listCtrl->DeleteColumn(0); 371 372 InitWithReportItems (idx); 373 374 m_listCtrl->Thaw(); 375 376 wxApp::GetInstance()->Yield(true); 377 } 378} 379 380void MyFrame::OnFocusLast(wxCommandEvent& WXUNUSED(event)) 381{ 382 long index = m_listCtrl->GetItemCount() - 1; 383 if ( index == -1 ) 384 { 385 return; 386 } 387 388 m_listCtrl->SetItemState(index, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED); 389 m_listCtrl->EnsureVisible(index); 390} 391 392void MyFrame::OnToggleFirstSel(wxCommandEvent& WXUNUSED(event)) 393{ 394 m_listCtrl->SetItemState(0, (~m_listCtrl->GetItemState(0, wxLIST_STATE_SELECTED) ) & wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); 395} 396 397void MyFrame::OnDeselectAll(wxCommandEvent& WXUNUSED(event)) 398{ 399 if ( !CheckNonVirtual() ) 400 return; 401 402 int n = m_listCtrl->GetItemCount(); 403 for (int i = 0; i < n; i++) 404 m_listCtrl->SetItemState(i,0,wxLIST_STATE_SELECTED); 405} 406 407void MyFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event)) 408{ 409 if ( !CheckNonVirtual() ) 410 return; 411 412 int n = m_listCtrl->GetItemCount(); 413 for (int i = 0; i < n; i++) 414 m_listCtrl->SetItemState(i,wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); 415} 416 417// ---------------------------------------------------------------------------- 418// changing listctrl modes 419// ---------------------------------------------------------------------------- 420 421void MyFrame::RecreateList(long flags, bool withText) 422{ 423 // we could avoid recreating it if we don't set/clear the wxLC_VIRTUAL 424 // style, but it is more trouble to do it than not 425#if 0 426 if ( !m_listCtrl || ((flags & wxLC_VIRTUAL) != 427 (m_listCtrl->GetWindowStyleFlag() & wxLC_VIRTUAL)) ) 428#endif 429 { 430 delete m_listCtrl; 431 432 m_listCtrl = new MyListCtrl(m_panel, LIST_CTRL, 433 wxDefaultPosition, wxDefaultSize, 434 flags | 435 wxSUNKEN_BORDER | wxLC_EDIT_LABELS); 436 437 switch ( flags & wxLC_MASK_TYPE ) 438 { 439 case wxLC_LIST: 440 InitWithListItems(); 441 break; 442 443 case wxLC_ICON: 444 InitWithIconItems(withText); 445 break; 446 447 case wxLC_SMALL_ICON: 448 InitWithIconItems(withText, true); 449 break; 450 451 case wxLC_REPORT: 452 if ( flags & wxLC_VIRTUAL ) 453 InitWithVirtualItems(); 454 else 455 InitWithReportItems(0); 456 break; 457 458 default: 459 wxFAIL_MSG( _T("unknown listctrl mode") ); 460 } 461 } 462 463 DoSize(); 464 465 m_logWindow->Clear(); 466} 467 468void MyFrame::OnListView(wxCommandEvent& WXUNUSED(event)) 469{ 470 RecreateList(wxLC_LIST); 471} 472 473void MyFrame::InitWithListItems() 474{ 475 for ( int i = 0; i < NUM_ITEMS; i++ ) 476 { 477 m_listCtrl->InsertItem(i, wxString::Format(_T("Item %d"), i)); 478 } 479} 480 481void MyFrame::OnReportView(wxCommandEvent& WXUNUSED(event)) 482{ 483 RecreateList(wxLC_REPORT); 484} 485 486void MyFrame::InitWithReportItems(int shift) 487{ 488 m_listCtrl->SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL); 489 490 // note that under MSW for SetColumnWidth() to work we need to create the 491 // items with images initially even if we specify dummy image id 492 wxListItem itemCol; 493 itemCol.SetText(_T("Column 1")); 494 itemCol.SetImage(-1); 495 m_listCtrl->InsertColumn(0, itemCol); 496 497 itemCol.SetText(_T("Column 2")); 498 itemCol.SetAlign(wxLIST_FORMAT_CENTRE); 499 m_listCtrl->InsertColumn(1, itemCol); 500 501 itemCol.SetText(_T("Column 3")); 502 itemCol.SetAlign(wxLIST_FORMAT_RIGHT); 503 m_listCtrl->InsertColumn(2, itemCol); 504 505 // to speed up inserting we hide the control temporarily 506 m_listCtrl->Hide(); 507 508 wxStopWatch sw; 509 510 for ( int i = 0; i < NUM_ITEMS; i++ ) 511 { 512 m_listCtrl->InsertItemInReportView(i, shift); 513 } 514 515 m_logWindow->WriteText(wxString::Format(_T("%d items inserted in %ldms\n"), 516 NUM_ITEMS, sw.Time())); 517 m_listCtrl->Show(); 518 519 // we leave all mask fields to 0 and only change the colour 520 wxListItem item; 521 item.m_itemId = 0; 522 item.SetTextColour(*wxRED); 523 m_listCtrl->SetItem( item ); 524 525 item.m_itemId = 2; 526 item.SetTextColour(*wxGREEN); 527 m_listCtrl->SetItem( item ); 528 item.m_itemId = 4; 529 item.SetTextColour(*wxLIGHT_GREY); 530 item.SetFont(*wxITALIC_FONT); 531 item.SetBackgroundColour(*wxRED); 532 m_listCtrl->SetItem( item ); 533 534 m_listCtrl->SetTextColour(*wxBLUE); 535 536 m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE ); 537 m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE ); 538 m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE ); 539 540 // Set images in columns 541 m_listCtrl->SetItemColumnImage(1, 1, 0); 542 543 wxListItem info; 544 info.SetImage(0); 545 info.SetId(3); 546 info.SetColumn(2); 547 m_listCtrl->SetItem(info); 548 549 // test SetItemFont too 550 m_listCtrl->SetItemFont(0, *wxITALIC_FONT); 551} 552 553void MyFrame::InitWithIconItems(bool withText, bool sameIcon) 554{ 555 m_listCtrl->SetImageList(m_imageListNormal, wxIMAGE_LIST_NORMAL); 556 m_listCtrl->SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL); 557 558 for ( int i = 0; i < NUM_ICONS; i++ ) 559 { 560 int image = sameIcon ? 0 : i; 561 562 if ( withText ) 563 { 564 m_listCtrl->InsertItem(i, wxString::Format(_T("Label %d"), i), 565 image); 566 } 567 else 568 { 569 m_listCtrl->InsertItem(i, image); 570 } 571 } 572} 573 574void MyFrame::OnIconView(wxCommandEvent& WXUNUSED(event)) 575{ 576 RecreateList(wxLC_ICON, false); 577} 578 579void MyFrame::OnIconTextView(wxCommandEvent& WXUNUSED(event)) 580{ 581 RecreateList(wxLC_ICON); 582} 583 584void MyFrame::OnSmallIconView(wxCommandEvent& WXUNUSED(event)) 585{ 586 RecreateList(wxLC_SMALL_ICON, false); 587} 588 589void MyFrame::OnSmallIconTextView(wxCommandEvent& WXUNUSED(event)) 590{ 591 RecreateList(wxLC_SMALL_ICON); 592} 593 594void MyFrame::OnVirtualView(wxCommandEvent& WXUNUSED(event)) 595{ 596 m_smallVirtual = false; 597 RecreateList(wxLC_REPORT | wxLC_VIRTUAL); 598} 599 600void MyFrame::OnSmallVirtualView(wxCommandEvent& WXUNUSED(event)) 601{ 602 m_smallVirtual = true; 603 RecreateList(wxLC_REPORT | wxLC_VIRTUAL); 604} 605 606void MyFrame::InitWithVirtualItems() 607{ 608 m_listCtrl->SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL); 609 610 if ( m_smallVirtual ) 611 { 612 m_listCtrl->InsertColumn(0, _T("Animal")); 613 m_listCtrl->InsertColumn(1, _T("Sound")); 614 m_listCtrl->SetItemCount(WXSIZEOF(SMALL_VIRTUAL_VIEW_ITEMS)); 615 } 616 else 617 { 618 m_listCtrl->InsertColumn(0, _T("First Column")); 619 m_listCtrl->InsertColumn(1, _T("Second Column")); 620 m_listCtrl->SetColumnWidth(0, 150); 621 m_listCtrl->SetColumnWidth(1, 150); 622 m_listCtrl->SetItemCount(1000000); 623 } 624} 625 626void MyFrame::OnSort(wxCommandEvent& WXUNUSED(event)) 627{ 628 wxStopWatch sw; 629 630 m_listCtrl->SortItems(MyCompareFunction, 0); 631 632 m_logWindow->WriteText(wxString::Format(_T("Sorting %d items took %ld ms\n"), 633 m_listCtrl->GetItemCount(), 634 sw.Time())); 635} 636 637void MyFrame::OnShowSelInfo(wxCommandEvent& WXUNUSED(event)) 638{ 639 int selCount = m_listCtrl->GetSelectedItemCount(); 640 wxLogMessage(_T("%d items selected:"), selCount); 641 642 // don't show too many items 643 size_t shownCount = 0; 644 645 long item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, 646 wxLIST_STATE_SELECTED); 647 while ( item != -1 ) 648 { 649 wxLogMessage(_T("\t%ld (%s)"), 650 item, m_listCtrl->GetItemText(item).c_str()); 651 652 if ( ++shownCount > 10 ) 653 { 654 wxLogMessage(_T("\t... more selected items snipped...")); 655 break; 656 } 657 658 item = m_listCtrl->GetNextItem(item, wxLIST_NEXT_ALL, 659 wxLIST_STATE_SELECTED); 660 } 661} 662 663void MyFrame::OnShowColInfo(wxCommandEvent& WXUNUSED(event)) 664{ 665 int count = m_listCtrl->GetColumnCount(); 666 wxLogMessage(wxT("%d columns:"), count); 667 for ( int c = 0; c < count; c++ ) 668 { 669 wxLogMessage(wxT("\tcolumn %d has width %d"), c, 670 m_listCtrl->GetColumnWidth(c)); 671 } 672} 673 674void MyFrame::OnUpdateShowColInfo(wxUpdateUIEvent& event) 675{ 676 event.Enable( (m_listCtrl->GetWindowStyleFlag() & wxLC_REPORT) != 0 ); 677} 678 679void MyFrame::OnToggleMultiSel(wxCommandEvent& WXUNUSED(event)) 680{ 681 long flags = m_listCtrl->GetWindowStyleFlag(); 682 if ( flags & wxLC_SINGLE_SEL ) 683 flags &= ~wxLC_SINGLE_SEL; 684 else 685 flags |= wxLC_SINGLE_SEL; 686 687 m_logWindow->WriteText(wxString::Format(wxT("Current selection mode: %sle\n"), 688 (flags & wxLC_SINGLE_SEL) ? _T("sing") : _T("multip"))); 689 690 RecreateList(flags); 691} 692 693void MyFrame::OnUpdateToggleMultiSel(wxUpdateUIEvent& event) 694{ 695 event.Check((m_listCtrl->GetWindowStyleFlag() & wxLC_SINGLE_SEL) == 0); 696} 697 698void MyFrame::OnSetFgColour(wxCommandEvent& WXUNUSED(event)) 699{ 700 m_listCtrl->SetForegroundColour(wxGetColourFromUser(this)); 701 m_listCtrl->Refresh(); 702} 703 704void MyFrame::OnSetBgColour(wxCommandEvent& WXUNUSED(event)) 705{ 706 m_listCtrl->SetBackgroundColour(wxGetColourFromUser(this)); 707 m_listCtrl->Refresh(); 708} 709 710void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event)) 711{ 712 m_listCtrl->InsertItem(m_listCtrl->GetItemCount(), _T("Appended item")); 713} 714 715void MyFrame::OnEdit(wxCommandEvent& WXUNUSED(event)) 716{ 717 long itemCur = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, 718 wxLIST_STATE_FOCUSED); 719 720 if ( itemCur != -1 ) 721 { 722 m_listCtrl->EditLabel(itemCur); 723 } 724 else 725 { 726 m_logWindow->WriteText(_T("No item to edit")); 727 } 728} 729 730void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event)) 731{ 732 if ( m_listCtrl->GetItemCount() ) 733 { 734 m_listCtrl->DeleteItem(0); 735 } 736 else 737 { 738 m_logWindow->WriteText(_T("Nothing to delete")); 739 } 740} 741 742void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event)) 743{ 744 wxStopWatch sw; 745 746 int itemCount = m_listCtrl->GetItemCount(); 747 748 m_listCtrl->DeleteAllItems(); 749 750 m_logWindow->WriteText(wxString::Format(_T("Deleting %d items took %ld ms\n"), 751 itemCount, 752 sw.Time())); 753} 754 755// MyListCtrl 756 757void MyListCtrl::OnCacheHint(wxListEvent& event) 758{ 759 wxLogMessage( wxT("OnCacheHint: cache items %ld..%ld"), 760 event.GetCacheFrom(), event.GetCacheTo() ); 761} 762 763void MyListCtrl::SetColumnImage(int col, int image) 764{ 765 wxListItem item; 766 item.SetMask(wxLIST_MASK_IMAGE); 767 item.SetImage(image); 768 SetColumn(col, item); 769} 770 771void MyListCtrl::OnColClick(wxListEvent& event) 772{ 773 int col = event.GetColumn(); 774 775 // set or unset image 776 static bool x = false; 777 x = !x; 778 SetColumnImage(col, x ? 0 : -1); 779 780 wxLogMessage( wxT("OnColumnClick at %d."), col ); 781} 782 783void MyListCtrl::OnColRightClick(wxListEvent& event) 784{ 785 int col = event.GetColumn(); 786 if ( col != -1 ) 787 { 788 SetColumnImage(col, -1); 789 } 790 791 // Show popupmenu at position 792 wxMenu menu(wxT("Test")); 793 menu.Append(LIST_ABOUT, _T("&About")); 794 PopupMenu(&menu, event.GetPoint()); 795 796 wxLogMessage( wxT("OnColumnRightClick at %d."), event.GetColumn() ); 797} 798 799void MyListCtrl::LogColEvent(const wxListEvent& event, const wxChar *name) 800{ 801 const int col = event.GetColumn(); 802 803 wxLogMessage(wxT("%s: column %d (width = %d or %d)."), 804 name, 805 col, 806 event.GetItem().GetWidth(), 807 GetColumnWidth(col)); 808} 809 810void MyListCtrl::OnColBeginDrag(wxListEvent& event) 811{ 812 LogColEvent( event, wxT("OnColBeginDrag") ); 813 814 if ( event.GetColumn() == 0 ) 815 { 816 wxLogMessage(_T("Resizing this column shouldn't work.")); 817 818 event.Veto(); 819 } 820} 821 822void MyListCtrl::OnColDragging(wxListEvent& event) 823{ 824 LogColEvent( event, wxT("OnColDragging") ); 825} 826 827void MyListCtrl::OnColEndDrag(wxListEvent& event) 828{ 829 LogColEvent( event, wxT("OnColEndDrag") ); 830} 831 832void MyListCtrl::OnBeginDrag(wxListEvent& event) 833{ 834 const wxPoint& pt = event.m_pointDrag; 835 836 int flags; 837 wxLogMessage( wxT("OnBeginDrag at (%d, %d), item %ld."), 838 pt.x, pt.y, HitTest(pt, flags) ); 839} 840 841void MyListCtrl::OnBeginRDrag(wxListEvent& event) 842{ 843 wxLogMessage( wxT("OnBeginRDrag at %d,%d."), 844 event.m_pointDrag.x, event.m_pointDrag.y ); 845} 846 847void MyListCtrl::OnBeginLabelEdit(wxListEvent& event) 848{ 849 wxLogMessage( wxT("OnBeginLabelEdit: %s"), event.m_item.m_text.c_str()); 850} 851 852void MyListCtrl::OnEndLabelEdit(wxListEvent& event) 853{ 854 wxLogMessage( wxT("OnEndLabelEdit: %s"), 855 event.IsEditCancelled() ? _T("[cancelled]") 856 : event.m_item.m_text.c_str()); 857} 858 859void MyListCtrl::OnDeleteItem(wxListEvent& event) 860{ 861 LogEvent(event, _T("OnDeleteItem")); 862 wxLogMessage( wxT("Number of items when delete event is sent: %d"), GetItemCount() ); 863} 864 865void MyListCtrl::OnDeleteAllItems(wxListEvent& event) 866{ 867 LogEvent(event, _T("OnDeleteAllItems")); 868} 869 870#if WXWIN_COMPATIBILITY_2_4 871void MyListCtrl::OnGetInfo(wxListEvent& event) 872{ 873 wxString msg; 874 875 msg << _T("OnGetInfo (") << event.m_item.m_itemId << _T(", ") << event.m_item.m_col << _T(")"); 876 if ( event.m_item.m_mask & wxLIST_MASK_STATE ) 877 msg << _T(" wxLIST_MASK_STATE"); 878 if ( event.m_item.m_mask & wxLIST_MASK_TEXT ) 879 msg << _T(" wxLIST_MASK_TEXT"); 880 if ( event.m_item.m_mask & wxLIST_MASK_IMAGE ) 881 msg << _T(" wxLIST_MASK_IMAGE"); 882 if ( event.m_item.m_mask & wxLIST_MASK_DATA ) 883 msg << _T(" wxLIST_MASK_DATA"); 884 if ( event.m_item.m_mask & wxLIST_SET_ITEM ) 885 msg << _T(" wxLIST_SET_ITEM"); 886 if ( event.m_item.m_mask & wxLIST_MASK_WIDTH ) 887 msg << _T(" wxLIST_MASK_WIDTH"); 888 if ( event.m_item.m_mask & wxLIST_MASK_FORMAT ) 889 msg << _T(" wxLIST_MASK_WIDTH"); 890 891 if ( event.m_item.m_mask & wxLIST_MASK_TEXT ) 892 { 893 event.m_item.m_text = _T("My callback text"); 894 } 895 896 wxLogMessage(msg); 897} 898 899void MyListCtrl::OnSetInfo(wxListEvent& event) 900{ 901 LogEvent(event, _T("OnSetInfo")); 902} 903#endif 904 905void MyListCtrl::OnSelected(wxListEvent& event) 906{ 907 LogEvent(event, _T("OnSelected")); 908 909 if ( GetWindowStyle() & wxLC_REPORT ) 910 { 911 wxListItem info; 912 info.m_itemId = event.m_itemIndex; 913 info.m_col = 1; 914 info.m_mask = wxLIST_MASK_TEXT; 915 if ( GetItem(info) ) 916 { 917 wxLogMessage(wxT("Value of the 2nd field of the selected item: %s"), 918 info.m_text.c_str()); 919 } 920 else 921 { 922 wxFAIL_MSG(wxT("wxListCtrl::GetItem() failed")); 923 } 924 } 925} 926 927void MyListCtrl::OnDeselected(wxListEvent& event) 928{ 929 LogEvent(event, _T("OnDeselected")); 930} 931 932void MyListCtrl::OnActivated(wxListEvent& event) 933{ 934 LogEvent(event, _T("OnActivated")); 935} 936 937void MyListCtrl::OnFocused(wxListEvent& event) 938{ 939 LogEvent(event, _T("OnFocused")); 940 941 event.Skip(); 942} 943 944void MyListCtrl::OnListKeyDown(wxListEvent& event) 945{ 946 long item; 947 948 switch ( event.GetKeyCode() ) 949 { 950 case 'c': // colorize 951 case 'C': 952 { 953 wxListItem info; 954 info.m_itemId = event.GetIndex(); 955 if ( info.m_itemId == -1 ) 956 { 957 // no item 958 break; 959 } 960 961 GetItem(info); 962 963 wxListItemAttr *attr = info.GetAttributes(); 964 if ( !attr || !attr->HasTextColour() ) 965 { 966 info.SetTextColour(*wxCYAN); 967 968 SetItem(info); 969 970 RefreshItem(info.m_itemId); 971 } 972 } 973 break; 974 975 case 'n': // next 976 case 'N': 977 item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); 978 if ( item++ == GetItemCount() - 1 ) 979 { 980 item = 0; 981 } 982 983 wxLogMessage(_T("Focusing item %ld"), item); 984 985 SetItemState(item, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED); 986 EnsureVisible(item); 987 break; 988 989 case 'r': // show bounding Rect 990 case 'R': 991 { 992 item = event.GetIndex(); 993 wxRect r; 994 if ( !GetItemRect(item, r) ) 995 { 996 wxLogError(_T("Failed to retrieve rect of item %ld"), item); 997 break; 998 } 999 1000 wxLogMessage(_T("Bounding rect of item %ld is (%d, %d)-(%d, %d)"), 1001 item, r.x, r.y, r.x + r.width, r.y + r.height); 1002 } 1003 break; 1004 1005 case WXK_DELETE: 1006 item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); 1007 while ( item != -1 ) 1008 { 1009 DeleteItem(item); 1010 1011 wxLogMessage(_T("Item %ld deleted"), item); 1012 1013 // -1 because the indices were shifted by DeleteItem() 1014 item = GetNextItem(item - 1, 1015 wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); 1016 } 1017 break; 1018 1019 case WXK_INSERT: 1020 if ( GetWindowStyle() & wxLC_REPORT ) 1021 { 1022 if ( GetWindowStyle() & wxLC_VIRTUAL ) 1023 { 1024 SetItemCount(GetItemCount() + 1); 1025 } 1026 else // !virtual 1027 { 1028 InsertItemInReportView(event.GetIndex(), 0); 1029 } 1030 } 1031 //else: fall through 1032 1033 default: 1034 LogEvent(event, _T("OnListKeyDown")); 1035 1036 event.Skip(); 1037 } 1038} 1039 1040void MyListCtrl::OnChar(wxKeyEvent& event) 1041{ 1042 wxLogMessage(_T("Got char event.")); 1043 1044 switch ( event.GetKeyCode() ) 1045 { 1046 case 'n': 1047 case 'N': 1048 case 'c': 1049 case 'C': 1050 // these are the keys we process ourselves 1051 break; 1052 1053 default: 1054 event.Skip(); 1055 } 1056} 1057 1058void MyListCtrl::OnRightClick(wxMouseEvent& event) 1059{ 1060 if ( !event.ControlDown() ) 1061 { 1062 event.Skip(); 1063 return; 1064 } 1065 1066 int flags; 1067 long subitem; 1068 long item = HitTest(event.GetPosition(), flags, &subitem); 1069 1070 wxString where; 1071 switch ( flags ) 1072 { 1073 case wxLIST_HITTEST_ABOVE: where = _T("above"); break; 1074 case wxLIST_HITTEST_BELOW: where = _T("below"); break; 1075 case wxLIST_HITTEST_NOWHERE: where = _T("nowhere near"); break; 1076 case wxLIST_HITTEST_ONITEMICON: where = _T("on icon of"); break; 1077 case wxLIST_HITTEST_ONITEMLABEL: where = _T("on label of"); break; 1078 case wxLIST_HITTEST_ONITEMRIGHT: where = _T("right on"); break; 1079 case wxLIST_HITTEST_TOLEFT: where = _T("to the left of"); break; 1080 case wxLIST_HITTEST_TORIGHT: where = _T("to the right of"); break; 1081 default: where = _T("not clear exactly where on"); break; 1082 } 1083 1084 wxLogMessage(_T("Right double click %s item %ld, subitem %ld"), 1085 where.c_str(), item, subitem); 1086} 1087 1088void MyListCtrl::LogEvent(const wxListEvent& event, const wxChar *eventName) 1089{ 1090 wxLogMessage(_T("Item %ld: %s (item text = %s, data = %ld)"), 1091 event.GetIndex(), eventName, 1092 event.GetText().c_str(), event.GetData()); 1093} 1094 1095wxString MyListCtrl::OnGetItemText(long item, long column) const 1096{ 1097 if ( GetItemCount() == WXSIZEOF(SMALL_VIRTUAL_VIEW_ITEMS) ) 1098 { 1099 return SMALL_VIRTUAL_VIEW_ITEMS[item][column]; 1100 } 1101 else 1102 { 1103 return wxString::Format(_T("Column %ld of item %ld"), column, item); 1104 } 1105} 1106 1107int MyListCtrl::OnGetItemColumnImage(long item, long column) const 1108{ 1109 if (!column) 1110 return 0; 1111 1112 if (!(item %3) && column == 1) 1113 return 0; 1114 1115 return -1; 1116} 1117 1118wxListItemAttr *MyListCtrl::OnGetItemAttr(long item) const 1119{ 1120 return item % 2 ? NULL : (wxListItemAttr *)&m_attr; 1121} 1122 1123void MyListCtrl::InsertItemInReportView(int i, int shift) 1124{ 1125 wxString buf; 1126 buf.Printf(_T("This is item %d"), i+shift); 1127 long tmp = InsertItem(i, buf, 0); 1128 SetItemData(tmp, i); 1129 1130 buf.Printf(_T("Col 1, item %d"), i+shift); 1131 SetItem(tmp, 1, buf); 1132 1133 buf.Printf(_T("Item %d in column 2"), i+shift); 1134 SetItem(tmp, 2, buf); 1135} 1136 1137#if USE_CONTEXT_MENU 1138void MyListCtrl::OnContextMenu(wxContextMenuEvent& event) 1139{ 1140 wxPoint point = event.GetPosition(); 1141 // If from keyboard 1142 if (point.x == -1 && point.y == -1) { 1143 wxSize size = GetSize(); 1144 point.x = size.x / 2; 1145 point.y = size.y / 2; 1146 } else { 1147 point = ScreenToClient(point); 1148 } 1149 ShowContextMenu(point); 1150} 1151#endif 1152 1153void MyListCtrl::ShowContextMenu(const wxPoint& pos) 1154{ 1155 wxMenu menu; 1156 1157 menu.Append(wxID_ABOUT, _T("&About")); 1158 menu.AppendSeparator(); 1159 menu.Append(wxID_EXIT, _T("E&xit")); 1160 1161 PopupMenu(&menu, pos.x, pos.y); 1162} 1163