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