listtest.cpp 40 KB

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