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