1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxTreeCtrl sample 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx/wx.h". 
  13 #include "wx/wxprec.h" 
  24 #include "wx/colordlg.h" 
  25 #include "wx/numdlg.h" 
  27 #include "wx/artprov.h" 
  29 #include "wx/imaglist.h" 
  30 #include "wx/treectrl.h" 
  32 #include "wx/renderer.h" 
  35     // this is not supported by native control 
  36     #define NO_VARIABLE_HEIGHT 
  53 #include "unchecked.xpm" 
  54 #include "checked.xpm" 
  57     #include "../sample.xpm" 
  60 // verify that the item is ok and insult the user if it is not 
  61 #define CHECK_ITEM( item ) if ( !item.IsOk() ) {                                 \ 
  62                              wxMessageBox(wxT("Please select some item first!"), \ 
  63                                           wxT("Tree sample error"),              \ 
  64                                           wxOK | wxICON_EXCLAMATION,             \ 
  69 #define MENU_LINK(name) EVT_MENU(TreeTest_##name, MyFrame::On##name) 
  71 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
) 
  72     EVT_IDLE(MyFrame::OnIdle
) 
  73     EVT_SIZE(MyFrame::OnSize
) 
  83     MENU_LINK(TogHideRoot
) 
  84     MENU_LINK(TogRootLines
) 
  86     MENU_LINK(TogFullHighlight
) 
  87     MENU_LINK(SetFgColour
) 
  88     MENU_LINK(SetBgColour
) 
  93 #ifndef NO_MULTIPLE_SELECTION 
  94     MENU_LINK(DumpSelected
) 
  98 #endif // NO_MULTIPLE_SELECTION 
 107     MENU_LINK(DeleteChildren
) 
 110     MENU_LINK(ToggleImages
) 
 111     MENU_LINK(ToggleStates
) 
 112     MENU_LINK(ToggleAlternateImages
) 
 113     MENU_LINK(ToggleAlternateStates
) 
 114     MENU_LINK(ToggleButtons
) 
 115     MENU_LINK(SetImageSize
) 
 116     MENU_LINK(CollapseAndReset
) 
 117     MENU_LINK(EnsureVisible
) 
 119     MENU_LINK(InsertItem
) 
 122     MENU_LINK(IncSpacing
) 
 123     MENU_LINK(DecSpacing
) 
 124     MENU_LINK(ToggleIcon
) 
 125     MENU_LINK(ToggleState
) 
 126     MENU_LINK(SelectRoot
) 
 128     MENU_LINK(ShowFirstVisible
) 
 129 #ifdef wxHAS_LAST_VISIBLE 
 130     MENU_LINK(ShowLastVisible
) 
 131 #endif // wxHAS_LAST_VISIBLE 
 132     MENU_LINK(ShowNextVisible
) 
 133     MENU_LINK(ShowPrevVisible
) 
 134     MENU_LINK(ShowParent
) 
 135     MENU_LINK(ShowPrevSibling
) 
 136     MENU_LINK(ShowNextSibling
) 
 141 #if USE_GENERIC_TREECTRL 
 142 BEGIN_EVENT_TABLE(MyTreeCtrl
, wxGenericTreeCtrl
) 
 144 BEGIN_EVENT_TABLE(MyTreeCtrl
, wxTreeCtrl
) 
 146     EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl
, MyTreeCtrl::OnBeginDrag
) 
 147     EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl
, MyTreeCtrl::OnBeginRDrag
) 
 148     EVT_TREE_END_DRAG(TreeTest_Ctrl
, MyTreeCtrl::OnEndDrag
) 
 149     EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl
, MyTreeCtrl::OnBeginLabelEdit
) 
 150     EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl
, MyTreeCtrl::OnEndLabelEdit
) 
 151     EVT_TREE_DELETE_ITEM(TreeTest_Ctrl
, MyTreeCtrl::OnDeleteItem
) 
 152 #if 0       // there are so many of those that logging them causes flicker 
 153     EVT_TREE_GET_INFO(TreeTest_Ctrl
, MyTreeCtrl::OnGetInfo
) 
 155     EVT_TREE_SET_INFO(TreeTest_Ctrl
, MyTreeCtrl::OnSetInfo
) 
 156     EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl
, MyTreeCtrl::OnItemExpanded
) 
 157     EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl
, MyTreeCtrl::OnItemExpanding
) 
 158     EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl
, MyTreeCtrl::OnItemCollapsed
) 
 159     EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl
, MyTreeCtrl::OnItemCollapsing
) 
 161     EVT_TREE_SEL_CHANGED(TreeTest_Ctrl
, MyTreeCtrl::OnSelChanged
) 
 162     EVT_TREE_SEL_CHANGING(TreeTest_Ctrl
, MyTreeCtrl::OnSelChanging
) 
 163     EVT_TREE_KEY_DOWN(TreeTest_Ctrl
, MyTreeCtrl::OnTreeKeyDown
) 
 164     EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl
, MyTreeCtrl::OnItemActivated
) 
 165     EVT_TREE_STATE_IMAGE_CLICK(TreeTest_Ctrl
, MyTreeCtrl::OnItemStateClick
) 
 167     // so many different ways to handle right mouse button clicks... 
 168     EVT_CONTEXT_MENU(MyTreeCtrl::OnContextMenu
) 
 169     // EVT_TREE_ITEM_MENU is the preferred event for creating context menus 
 170     // on a tree control, because it includes the point of the click or item, 
 171     // meaning that no additional placement calculations are required. 
 172     EVT_TREE_ITEM_MENU(TreeTest_Ctrl
, MyTreeCtrl::OnItemMenu
) 
 173     EVT_TREE_ITEM_RIGHT_CLICK(TreeTest_Ctrl
, MyTreeCtrl::OnItemRClick
) 
 175     EVT_RIGHT_DOWN(MyTreeCtrl::OnRMouseDown
) 
 176     EVT_RIGHT_UP(MyTreeCtrl::OnRMouseUp
) 
 177     EVT_RIGHT_DCLICK(MyTreeCtrl::OnRMouseDClick
) 
 184     if ( !wxApp::OnInit() ) 
 187     // Create the main frame window 
 188     MyFrame 
*frame 
= new MyFrame(wxT("wxTreeCtrl Test"), 50, 50, 450, 600); 
 198 // My frame constructor 
 199 MyFrame::MyFrame(const wxString
& title
, int x
, int y
, int w
, int h
) 
 200        : wxFrame((wxFrame 
*)NULL
, wxID_ANY
, title
, wxPoint(x
, y
), wxSize(w
, h
)), 
 206     // This reduces flicker effects - even better would be to define 
 207     // OnEraseBackground to do nothing. When the tree control's scrollbars are 
 208     // show or hidden, the frame is sent a background erase event. 
 209     SetBackgroundColour(wxColour(255, 255, 255)); 
 212     SetIcon(wxICON(sample
)); 
 216     wxMenu 
*file_menu 
= new wxMenu
, 
 217            *style_menu 
= new wxMenu
, 
 218            *tree_menu 
= new wxMenu
, 
 219            *item_menu 
= new wxMenu
; 
 221     file_menu
->Append(TreeTest_ClearLog
, wxT("&Clear log\tCtrl-L")); 
 222     file_menu
->AppendSeparator(); 
 223     file_menu
->Append(TreeTest_About
, wxT("&About...")); 
 224     file_menu
->AppendSeparator(); 
 225     file_menu
->Append(TreeTest_Quit
, wxT("E&xit\tAlt-X")); 
 227     style_menu
->AppendCheckItem(TreeTest_TogButtons
, wxT("Toggle &normal buttons")); 
 228     style_menu
->AppendCheckItem(TreeTest_TogTwist
, wxT("Toggle &twister buttons")); 
 229     style_menu
->AppendCheckItem(TreeTest_ToggleButtons
, wxT("Toggle image &buttons")); 
 230     style_menu
->AppendSeparator(); 
 231     style_menu
->AppendCheckItem(TreeTest_TogLines
, wxT("Toggle &connecting lines")); 
 232     style_menu
->AppendCheckItem(TreeTest_TogRootLines
, wxT("Toggle &lines at root")); 
 233     style_menu
->AppendCheckItem(TreeTest_TogHideRoot
, wxT("Toggle &hidden root")); 
 234     style_menu
->AppendCheckItem(TreeTest_TogBorder
, wxT("Toggle &item border")); 
 235     style_menu
->AppendCheckItem(TreeTest_TogFullHighlight
, wxT("Toggle &full row highlight")); 
 236     style_menu
->AppendCheckItem(TreeTest_TogEdit
, wxT("Toggle &edit mode")); 
 237 #ifndef NO_MULTIPLE_SELECTION 
 238     style_menu
->AppendCheckItem(TreeTest_ToggleSel
, wxT("Toggle &selection mode\tCtrl-S")); 
 239 #endif // NO_MULTIPLE_SELECTION 
 240     style_menu
->AppendCheckItem(TreeTest_ToggleImages
, wxT("Toggle show ima&ges")); 
 241     style_menu
->AppendCheckItem(TreeTest_ToggleStates
, wxT("Toggle show st&ates")); 
 242     style_menu
->AppendCheckItem(TreeTest_ToggleAlternateImages
, wxT("Toggle alternate images")); 
 243     style_menu
->AppendCheckItem(TreeTest_ToggleAlternateStates
, wxT("Toggle alternate state images")); 
 244     style_menu
->Append(TreeTest_SetImageSize
, wxT("Set image si&ze...")); 
 245     style_menu
->AppendSeparator(); 
 246     style_menu
->Append(TreeTest_SetFgColour
, wxT("Set &foreground colour...")); 
 247     style_menu
->Append(TreeTest_SetBgColour
, wxT("Set &background colour...")); 
 248     style_menu
->AppendSeparator(); 
 249     style_menu
->Append(TreeTest_ResetStyle
, wxT("&Reset to default\tF10")); 
 251     tree_menu
->Append(TreeTest_Recreate
, wxT("&Recreate the tree")); 
 252     tree_menu
->Append(TreeTest_CollapseAndReset
, wxT("C&ollapse and reset")); 
 253     tree_menu
->AppendSeparator(); 
 254     tree_menu
->Append(TreeTest_AddItem
, wxT("Append a &new item")); 
 255     tree_menu
->Append(TreeTest_InsertItem
, wxT("&Insert a new item")); 
 256     tree_menu
->Append(TreeTest_Delete
, wxT("&Delete this item")); 
 257     tree_menu
->Append(TreeTest_DeleteChildren
, wxT("Delete &children")); 
 258     tree_menu
->Append(TreeTest_DeleteAll
, wxT("Delete &all items")); 
 259     tree_menu
->Append(TreeTest_SelectRoot
, wxT("Select root item")); 
 260     tree_menu
->AppendSeparator(); 
 261     tree_menu
->Append(TreeTest_Count
, wxT("Count children of current item")); 
 262     tree_menu
->Append(TreeTest_CountRec
, wxT("Recursively count children of current item")); 
 263     tree_menu
->AppendSeparator(); 
 264     tree_menu
->Append(TreeTest_Sort
, wxT("Sort children of current item")); 
 265     tree_menu
->Append(TreeTest_SortRev
, wxT("Sort in reversed order")); 
 266     tree_menu
->AppendSeparator(); 
 267     tree_menu
->Append(TreeTest_EnsureVisible
, wxT("Make the last item &visible")); 
 268     tree_menu
->AppendSeparator(); 
 269     tree_menu
->Append(TreeTest_IncIndent
, wxT("Add 5 points to indentation\tAlt-I")); 
 270     tree_menu
->Append(TreeTest_DecIndent
, wxT("Reduce indentation by 5 points\tAlt-R")); 
 271     tree_menu
->AppendSeparator(); 
 272     tree_menu
->Append(TreeTest_IncSpacing
, wxT("Add 5 points to spacing\tCtrl-I")); 
 273     tree_menu
->Append(TreeTest_DecSpacing
, wxT("Reduce spacing by 5 points\tCtrl-R")); 
 275     item_menu
->Append(TreeTest_Dump
, wxT("&Dump item children")); 
 276     item_menu
->Append(TreeTest_Rename
, wxT("&Rename item...")); 
 278     item_menu
->AppendSeparator(); 
 279     item_menu
->Append(TreeTest_SetBold
, wxT("Make item &bold")); 
 280     item_menu
->Append(TreeTest_ClearBold
, wxT("Make item ¬ bold")); 
 281     item_menu
->AppendSeparator(); 
 282     item_menu
->Append(TreeTest_ToggleIcon
, wxT("Toggle the item's &icon")); 
 283     item_menu
->Append(TreeTest_ToggleState
, wxT("Toggle the item's &state")); 
 284     item_menu
->AppendSeparator(); 
 285     item_menu
->Append(TreeTest_ShowFirstVisible
, wxT("Show &first visible")); 
 286 #ifdef wxHAS_LAST_VISIBLE 
 287     item_menu
->Append(TreeTest_ShowLastVisible
, wxT("Show &last visible")); 
 288 #endif // wxHAS_LAST_VISIBLE 
 289     item_menu
->Append(TreeTest_ShowNextVisible
, wxT("Show &next visible")); 
 290     item_menu
->Append(TreeTest_ShowPrevVisible
, wxT("Show &previous visible")); 
 291     item_menu
->AppendSeparator(); 
 292     item_menu
->Append(TreeTest_ShowParent
, "Show pa&rent"); 
 293     item_menu
->Append(TreeTest_ShowPrevSibling
, "Show &previous sibling"); 
 294     item_menu
->Append(TreeTest_ShowNextSibling
, "Show &next sibling"); 
 296 #ifndef NO_MULTIPLE_SELECTION 
 297     item_menu
->AppendSeparator(); 
 298     item_menu
->Append(TreeTest_DumpSelected
, wxT("Dump selected items\tAlt-D")); 
 299     item_menu
->Append(TreeTest_Select
, wxT("Select current item\tAlt-S")); 
 300     item_menu
->Append(TreeTest_Unselect
, wxT("Unselect everything\tAlt-U")); 
 301 #endif // NO_MULTIPLE_SELECTION 
 303     wxMenuBar 
*menu_bar 
= new wxMenuBar
; 
 304     menu_bar
->Append(file_menu
, wxT("&File")); 
 305     menu_bar
->Append(style_menu
, wxT("&Style")); 
 306     menu_bar
->Append(tree_menu
, wxT("&Tree")); 
 307     menu_bar
->Append(item_menu
, wxT("&Item")); 
 308     SetMenuBar(menu_bar
); 
 309 #endif // wxUSE_MENUS 
 311     m_panel 
= new wxPanel(this); 
 314     // create the controls 
 315     m_textCtrl 
= new wxTextCtrl(m_panel
, wxID_ANY
, wxT(""), 
 316                                 wxDefaultPosition
, wxDefaultSize
, 
 317                                 wxTE_MULTILINE 
| wxSUNKEN_BORDER
); 
 320     CreateTreeWithDefStyle(); 
 322     menu_bar
->Check(TreeTest_ToggleImages
, true); 
 323     menu_bar
->Check(TreeTest_ToggleStates
, true); 
 324     menu_bar
->Check(TreeTest_ToggleAlternateImages
, false); 
 325     menu_bar
->Check(TreeTest_ToggleAlternateStates
, false); 
 328     // create a status bar 
 330 #endif // wxUSE_STATUSBAR 
 334     // For some reason, we get a memcpy crash in wxLogStream::DoLogStream 
 335     // on gcc/wxMotif, if we use wxLogTextCtl. Maybe it's just gcc? 
 336     delete wxLog::SetActiveTarget(new wxLogStderr
); 
 338     // set our text control as the log target 
 339     wxLogTextCtrl 
*logWindow 
= new wxLogTextCtrl(m_textCtrl
); 
 340     delete wxLog::SetActiveTarget(logWindow
); 
 348     delete wxLog::SetActiveTarget(NULL
); 
 352 void MyFrame::CreateTreeWithDefStyle() 
 354     long style 
= wxTR_DEFAULT_STYLE 
| 
 355 #ifndef NO_VARIABLE_HEIGHT 
 356                  wxTR_HAS_VARIABLE_ROW_HEIGHT 
| 
 360     CreateTree(style 
| wxSUNKEN_BORDER
); 
 362     // as we don't know what wxTR_DEFAULT_STYLE could contain, test for 
 364     wxMenuBar 
*mbar 
= GetMenuBar(); 
 365     mbar
->Check(TreeTest_TogButtons
, (style 
& wxTR_HAS_BUTTONS
) != 0); 
 366     mbar
->Check(TreeTest_TogButtons
, (style 
& wxTR_TWIST_BUTTONS
) != 0); 
 367     mbar
->Check(TreeTest_TogLines
, (style 
& wxTR_NO_LINES
) == 0); 
 368     mbar
->Check(TreeTest_TogRootLines
, (style 
& wxTR_LINES_AT_ROOT
) != 0); 
 369     mbar
->Check(TreeTest_TogHideRoot
, (style 
& wxTR_HIDE_ROOT
) != 0); 
 370     mbar
->Check(TreeTest_TogEdit
, (style 
& wxTR_EDIT_LABELS
) != 0); 
 371     mbar
->Check(TreeTest_TogBorder
, (style 
& wxTR_ROW_LINES
) != 0); 
 372     mbar
->Check(TreeTest_TogFullHighlight
, (style 
& wxTR_FULL_ROW_HIGHLIGHT
) != 0); 
 375 void MyFrame::CreateTree(long style
) 
 377     m_treeCtrl 
= new MyTreeCtrl(m_panel
, TreeTest_Ctrl
, 
 378                                 wxDefaultPosition
, wxDefaultSize
, 
 381     GetMenuBar()->Enable(TreeTest_SelectRoot
, !(style 
& wxTR_HIDE_ROOT
)); 
 386 void MyFrame::TogStyle(int id
, long flag
) 
 388     long style 
= m_treeCtrl
->GetWindowStyle() ^ flag
; 
 390     // most treectrl styles can't be changed on the fly using the native 
 391     // control and the tree must be recreated 
 393     m_treeCtrl
->SetWindowStyle(style
); 
 399     GetMenuBar()->Check(id
, (style 
& flag
) != 0); 
 402 void MyFrame::OnIdle(wxIdleEvent
& event
) 
 407         wxTreeItemId idRoot 
= m_treeCtrl
->GetRootItem(); 
 411             wxTreeItemId idLast 
= m_treeCtrl
->GetLastChild(idRoot
); 
 412             status 
= wxString::Format( 
 413                 _T("Root/last item is %svisible/%svisible"), 
 414                 m_treeCtrl
->IsVisible(idRoot
) ? _T("") : _T("not "), 
 415                 idLast
.IsOk() && m_treeCtrl
->IsVisible(idLast
) 
 416                     ? _T("") : _T("not ")); 
 419             status 
= _T("No root item"); 
 421         SetStatusText(status
, 1); 
 423 #endif // wxUSE_STATUSBAR 
 428 void MyFrame::OnSize(wxSizeEvent
& event
) 
 442 void MyFrame::Resize() 
 444     wxSize size 
= GetClientSize(); 
 445     m_treeCtrl
->SetSize(0, 0, size
.x
, size
.y
 
 448     m_textCtrl
->SetSize(0, 2*size
.y
/3, size
.x
, size
.y
/3 
 453 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
)) 
 458 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
)) 
 460     wxMessageBox(wxT("Tree test sample\n") 
 461                  wxT("(c) Julian Smart 1997, Vadim Zeitlin 1998"), 
 462                  wxT("About tree test"), 
 463                  wxOK 
| wxICON_INFORMATION
, this); 
 466 void MyFrame::OnClearLog(wxCommandEvent
& WXUNUSED(event
)) 
 471 void MyFrame::OnRename(wxCommandEvent
& WXUNUSED(event
)) 
 473     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 477     // old code - now we edit in place 
 479     static wxString s_text
; 
 480     s_text 
= wxGetTextFromUser(wxT("New name: "), wxT("Tree sample question"), 
 482     if ( !s_text
.empty() ) 
 484         m_treeCtrl
->SetItemText(item
, s_text
); 
 488     // TODO demonstrate creating a custom edit control... 
 489     (void)m_treeCtrl
->EditLabel(item
); 
 492 void MyFrame::OnCount(wxCommandEvent
& WXUNUSED(event
)) 
 494     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 498     int i 
= m_treeCtrl
->GetChildrenCount( item
, false ); 
 500     wxLogMessage(wxT("%d children"), i
); 
 503 void MyFrame::OnCountRec(wxCommandEvent
& WXUNUSED(event
)) 
 505     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 509     int i 
= m_treeCtrl
->GetChildrenCount( item 
); 
 511     wxLogMessage(wxT("%d children"), i
); 
 514 void MyFrame::DoSort(bool reverse
) 
 516     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 520     m_treeCtrl
->DoSortChildren(item
, reverse
); 
 523 void MyFrame::OnHighlight(wxCommandEvent
& WXUNUSED(event
)) 
 525     wxTreeItemId id 
= m_treeCtrl
->GetSelection(); 
 530     if ( !m_treeCtrl
->GetBoundingRect(id
, r
, true /* text, not full row */) ) 
 532         wxLogMessage(_T("Failed to get bounding item rect")); 
 536     wxClientDC 
dc(m_treeCtrl
); 
 538     dc
.SetPen(*wxTRANSPARENT_PEN
); 
 540     m_treeCtrl
->Update(); 
 543 void MyFrame::OnDump(wxCommandEvent
& WXUNUSED(event
)) 
 545     wxTreeItemId root 
= m_treeCtrl
->GetSelection(); 
 549     m_treeCtrl
->GetItemsRecursively(root
); 
 552 #ifndef NO_MULTIPLE_SELECTION 
 554 void MyFrame::OnToggleSel(wxCommandEvent
& event
) 
 556     TogStyle(event
.GetId(), wxTR_MULTIPLE
); 
 559 void MyFrame::OnDumpSelected(wxCommandEvent
& WXUNUSED(event
)) 
 561     wxArrayTreeItemIds array
; 
 563     size_t count 
= m_treeCtrl
->GetSelections(array
); 
 564     wxLogMessage(wxT("%u items selected"), unsigned(count
)); 
 566     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 568         wxLogMessage(wxT("\t%s"), m_treeCtrl
->GetItemText(array
.Item(n
)).c_str()); 
 572 void MyFrame::OnSelect(wxCommandEvent
& WXUNUSED(event
)) 
 574     m_treeCtrl
->SelectItem(m_treeCtrl
->GetSelection()); 
 577 void MyFrame::OnSelectRoot(wxCommandEvent
& WXUNUSED(event
)) 
 579     if ( !m_treeCtrl
->HasFlag(wxTR_HIDE_ROOT
) ) 
 580         m_treeCtrl
->SelectItem(m_treeCtrl
->GetRootItem()); 
 583 void MyFrame::OnUnselect(wxCommandEvent
& WXUNUSED(event
)) 
 585     m_treeCtrl
->UnselectAll(); 
 588 #endif // NO_MULTIPLE_SELECTION 
 590 void MyFrame::DoSetBold(bool bold
) 
 592     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 596     m_treeCtrl
->SetItemBold(item
, bold
); 
 599 void MyFrame::OnDelete(wxCommandEvent
& WXUNUSED(event
)) 
 601     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 605     m_treeCtrl
->Delete(item
); 
 608 void MyFrame::OnDeleteChildren(wxCommandEvent
& WXUNUSED(event
)) 
 610     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 614     m_treeCtrl
->DeleteChildren(item
); 
 617 void MyFrame::OnDeleteAll(wxCommandEvent
& WXUNUSED(event
)) 
 619     m_treeCtrl
->DeleteAllItems(); 
 622 void MyFrame::OnRecreate(wxCommandEvent
& event
) 
 625     m_treeCtrl
->AddTestItemsToTree(5, 2); 
 628 void MyFrame::OnSetImageSize(wxCommandEvent
& WXUNUSED(event
)) 
 630     int size 
= wxGetNumberFromUser(wxT("Enter the size for the images to use"), 
 632                                     wxT("TreeCtrl sample"), 
 633                                     m_treeCtrl
->ImageSize()); 
 637     m_treeCtrl
->CreateImageList(size
); 
 638     wxGetApp().SetShowImages(true); 
 641 void MyFrame::OnToggleImages(wxCommandEvent
& WXUNUSED(event
)) 
 643     if ( wxGetApp().ShowImages() ) 
 645         m_treeCtrl
->CreateImageList(-1); 
 646         wxGetApp().SetShowImages(false); 
 650         m_treeCtrl
->CreateImageList(0); 
 651         wxGetApp().SetShowImages(true); 
 655 void MyFrame::OnToggleStates(wxCommandEvent
& WXUNUSED(event
)) 
 657     if ( wxGetApp().ShowStates() ) 
 659         m_treeCtrl
->CreateStateImageList(true); 
 660         wxGetApp().SetShowStates(false); 
 664         m_treeCtrl
->CreateStateImageList(false); 
 665         wxGetApp().SetShowStates(true); 
 669 void MyFrame::OnToggleAlternateImages(wxCommandEvent
& WXUNUSED(event
)) 
 671     bool alternateImages 
= m_treeCtrl
->AlternateImages(); 
 673     m_treeCtrl
->SetAlternateImages(!alternateImages
); 
 674     m_treeCtrl
->CreateImageList(0); 
 677 void MyFrame::OnToggleAlternateStates(wxCommandEvent
& WXUNUSED(event
)) 
 679     bool alternateStates 
= m_treeCtrl
->AlternateStates(); 
 681     m_treeCtrl
->SetAlternateStates(!alternateStates
); 
 682     m_treeCtrl
->CreateStateImageList(); 
 685 void MyFrame::OnToggleButtons(wxCommandEvent
& WXUNUSED(event
)) 
 687 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) 
 688     if ( wxGetApp().ShowButtons() ) 
 690         m_treeCtrl
->CreateButtonsImageList(-1); 
 691         wxGetApp().SetShowButtons(false); 
 695         m_treeCtrl
->CreateButtonsImageList(15); 
 696         wxGetApp().SetShowButtons(true); 
 701 void MyFrame::OnCollapseAndReset(wxCommandEvent
& WXUNUSED(event
)) 
 703     m_treeCtrl
->CollapseAndReset(m_treeCtrl
->GetRootItem()); 
 706 void MyFrame::OnEnsureVisible(wxCommandEvent
& WXUNUSED(event
)) 
 708     m_treeCtrl
->DoEnsureVisible(); 
 711 void MyFrame::OnInsertItem(wxCommandEvent
& WXUNUSED(event
)) 
 713     int image 
= wxGetApp().ShowImages() ? MyTreeCtrl::TreeCtrlIcon_File 
: -1; 
 714     m_treeCtrl
->InsertItem(m_treeCtrl
->GetRootItem(), image
, wxT("2nd item")); 
 717 void MyFrame::OnAddItem(wxCommandEvent
& WXUNUSED(event
)) 
 719     static int s_num 
= 0; 
 722     text
.Printf(wxT("Item #%d"), ++s_num
); 
 724     m_treeCtrl
->AppendItem(m_treeCtrl
->GetRootItem(), 
 726                            MyTreeCtrl::TreeCtrlIcon_File */ ); 
 729 void MyFrame::OnIncIndent(wxCommandEvent
& WXUNUSED(event
)) 
 731     unsigned int indent 
= m_treeCtrl
->GetIndent(); 
 733         m_treeCtrl
->SetIndent( indent
+5 ); 
 736 void MyFrame::OnDecIndent(wxCommandEvent
& WXUNUSED(event
)) 
 738     unsigned int indent 
= m_treeCtrl
->GetIndent(); 
 740         m_treeCtrl
->SetIndent( indent
-5 ); 
 743 void MyFrame::OnIncSpacing(wxCommandEvent
& WXUNUSED(event
)) 
 745     unsigned int indent 
= m_treeCtrl
->GetSpacing(); 
 747         m_treeCtrl
->SetSpacing( indent
+5 ); 
 750 void MyFrame::OnDecSpacing(wxCommandEvent
& WXUNUSED(event
)) 
 752     unsigned int indent 
= m_treeCtrl
->GetSpacing(); 
 754         m_treeCtrl
->SetSpacing( indent
-5 ); 
 757 void MyFrame::OnToggleIcon(wxCommandEvent
& WXUNUSED(event
)) 
 759     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 763     m_treeCtrl
->DoToggleIcon(item
); 
 766 void MyFrame::OnToggleState(wxCommandEvent
& WXUNUSED(event
)) 
 768     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 772     m_treeCtrl
->DoToggleState(item
); 
 775 void MyFrame::DoShowFirstOrLast(TreeFunc0_t pfn
, const wxString
& label
) 
 777     const wxTreeItemId item 
= (m_treeCtrl
->*pfn
)(); 
 780         wxLogMessage("There is no %s item", label
); 
 782         wxLogMessage("The %s item is \"%s\"", 
 783                      label
, m_treeCtrl
->GetItemText(item
)); 
 786 void MyFrame::DoShowRelativeItem(TreeFunc1_t pfn
, const wxString
& label
) 
 788     wxTreeItemId item 
= m_treeCtrl
->GetSelection(); 
 792     if ((pfn 
== (TreeFunc1_t
) &wxTreeCtrl::GetPrevVisible
 
 793          || pfn 
== (TreeFunc1_t
) &wxTreeCtrl::GetNextVisible
) 
 794         && !m_treeCtrl
->IsVisible(item
)) 
 796         wxLogMessage("The selected item must be visible."); 
 800     wxTreeItemId new_item 
= (m_treeCtrl
->*pfn
)(item
); 
 802     if ( !new_item
.IsOk() ) 
 803         wxLogMessage("There is no %s item", label
); 
 805         wxLogMessage("The %s item is \"%s\"", 
 806                      label
, m_treeCtrl
->GetItemText(new_item
)); 
 809 void MyFrame::OnSetFgColour(wxCommandEvent
& WXUNUSED(event
)) 
 811     wxColour col 
= wxGetColourFromUser(this, m_treeCtrl
->GetForegroundColour()); 
 813         m_treeCtrl
->SetForegroundColour(col
); 
 816 void MyFrame::OnSetBgColour(wxCommandEvent
& WXUNUSED(event
)) 
 818     wxColour col 
= wxGetColourFromUser(this, m_treeCtrl
->GetBackgroundColour()); 
 820         m_treeCtrl
->SetBackgroundColour(col
); 
 823 // MyTreeCtrl implementation 
 824 #if USE_GENERIC_TREECTRL 
 825 IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl
, wxGenericTreeCtrl
) 
 827 IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl
, wxTreeCtrl
) 
 830 MyTreeCtrl::MyTreeCtrl(wxWindow 
*parent
, const wxWindowID id
, 
 831                        const wxPoint
& pos
, const wxSize
& size
, 
 833           : wxTreeCtrl(parent
, id
, pos
, size
, style
), 
 834             m_alternateImages(false), 
 835             m_alternateStates(false) 
 837     m_reverseSort 
= false; 
 840     CreateStateImageList(); 
 842     // Add some items to the tree 
 843     AddTestItemsToTree(5, 2); 
 846 void MyTreeCtrl::CreateImageList(int size
) 
 858     // Make an image list containing small icons 
 859     wxImageList 
*images 
= new wxImageList(size
, size
, true); 
 861     // should correspond to TreeCtrlIcon_xxx enum 
 865     if (m_alternateImages
) 
 867         icons
[TreeCtrlIcon_File
] = wxIcon(icon1_xpm
); 
 868         icons
[TreeCtrlIcon_FileSelected
] = wxIcon(icon2_xpm
); 
 869         icons
[TreeCtrlIcon_Folder
] = wxIcon(icon3_xpm
); 
 870         icons
[TreeCtrlIcon_FolderSelected
] = wxIcon(icon4_xpm
); 
 871         icons
[TreeCtrlIcon_FolderOpened
] = wxIcon(icon5_xpm
); 
 875         wxSize 
iconSize(size
, size
); 
 877         icons
[TreeCtrlIcon_File
] = 
 878         icons
[TreeCtrlIcon_FileSelected
] = wxArtProvider::GetIcon(wxART_NORMAL_FILE
, wxART_LIST
, iconSize
); 
 879         icons
[TreeCtrlIcon_Folder
] = 
 880         icons
[TreeCtrlIcon_FolderSelected
] = 
 881         icons
[TreeCtrlIcon_FolderOpened
] = wxArtProvider::GetIcon(wxART_FOLDER
, wxART_LIST
, iconSize
); 
 884     for ( size_t i 
= 0; i 
< WXSIZEOF(icons
); i
++ ) 
 886         int sizeOrig 
= icons
[0].GetWidth(); 
 887         if ( size 
== sizeOrig 
) 
 889             images
->Add(icons
[i
]); 
 893             images
->Add(wxBitmap(wxBitmap(icons
[i
]).ConvertToImage().Rescale(size
, size
))); 
 897     AssignImageList(images
); 
 900 void MyTreeCtrl::CreateStateImageList(bool del
) 
 904         SetStateImageList(NULL
); 
 911     if (m_alternateStates
) 
 914         icons
[0] = wxIcon(state1_xpm
);  // yellow 
 915         icons
[1] = wxIcon(state2_xpm
);  // green 
 916         icons
[2] = wxIcon(state3_xpm
);  // red 
 917         icons
[3] = wxIcon(state4_xpm
);  // blue 
 918         icons
[4] = wxIcon(state5_xpm
);  // black 
 920         int width  
= icons
[0].GetWidth(), 
 921             height 
= icons
[0].GetHeight(); 
 923         // Make an state image list containing small icons 
 924         states 
= new wxImageList(width
, height
, true); 
 926         for ( size_t i 
= 0; i 
< WXSIZEOF(icons
); i
++ ) 
 927             states
->Add(icons
[i
]); 
 932         icons
[0] = wxIcon(unchecked_xpm
); 
 933         icons
[1] = wxIcon(checked_xpm
); 
 935         int width  
= icons
[0].GetWidth(), 
 936             height 
= icons
[0].GetHeight(); 
 938         // Make an state image list containing small icons 
 939         states 
= new wxImageList(width
, height
, true); 
 941         for ( size_t i 
= 0; i 
< WXSIZEOF(icons
); i
++ ) 
 942             states
->Add(icons
[i
]); 
 945     AssignStateImageList(states
); 
 948 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) 
 949 void MyTreeCtrl::CreateButtonsImageList(int size
) 
 953         SetButtonsImageList(NULL
); 
 957     // Make an image list containing small icons 
 958     wxImageList 
*images 
= new wxImageList(size
, size
, true); 
 960     // should correspond to TreeCtrlIcon_xxx enum 
 964     if (m_alternateImages
) 
 966         icons
[0] = wxIcon(icon3_xpm
);   // closed 
 967         icons
[1] = wxIcon(icon3_xpm
);   // closed, selected 
 968         icons
[2] = wxIcon(icon5_xpm
);   // open 
 969         icons
[3] = wxIcon(icon5_xpm
);   // open, selected 
 973         wxSize 
iconSize(size
, size
); 
 976         icons
[1] = wxArtProvider::GetIcon(wxART_FOLDER
, wxART_LIST
, iconSize
);     // closed, selected 
 978         icons
[3] = wxArtProvider::GetIcon(wxART_FOLDER_OPEN
, wxART_LIST
, iconSize
);// open, selected 
 981    for ( size_t i 
= 0; i 
< WXSIZEOF(icons
); i
++ ) 
 983         int sizeOrig 
= icons
[i
].GetWidth(); 
 984         if ( size 
== sizeOrig 
) 
 986             images
->Add(icons
[i
]); 
 990             images
->Add(wxBitmap(wxBitmap(icons
[i
]).ConvertToImage().Rescale(size
, size
))); 
 994     AssignButtonsImageList(images
); 
 996 void MyTreeCtrl::CreateButtonsImageList(int WXUNUSED(size
)) 
1001 int MyTreeCtrl::OnCompareItems(const wxTreeItemId
& item1
, 
1002                                const wxTreeItemId
& item2
) 
1004     if ( m_reverseSort 
) 
1006         // just exchange 1st and 2nd items 
1007         return wxTreeCtrl::OnCompareItems(item2
, item1
); 
1011         return wxTreeCtrl::OnCompareItems(item1
, item2
); 
1015 void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId
& idParent
, 
1022         bool hasChildren 
= depth 
> 1; 
1025         for ( size_t n 
= 0; n 
< numChildren
; n
++ ) 
1027             // at depth 1 elements won't have any more children 
1029                 str
.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n 
+ 1)); 
1031                 str
.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder
), unsigned(n 
+ 1)); 
1033             // here we pass to AppendItem() normal and selected item images (we 
1034             // suppose that selected image follows the normal one in the enum) 
1035             int image
, imageSel
; 
1036             if ( wxGetApp().ShowImages() ) 
1038                 image 
= depth 
== 1 ? TreeCtrlIcon_File 
: TreeCtrlIcon_Folder
; 
1039                 imageSel 
= image 
+ 1; 
1043                 image 
= imageSel 
= -1; 
1045             wxTreeItemId id 
= AppendItem(idParent
, str
, image
, imageSel
, 
1046                                          new MyTreeItemData(str
)); 
1048             if ( wxGetApp().ShowStates() ) 
1049                 SetItemState(id
, 0); 
1051             // and now we also set the expanded one (only for the folders) 
1052             if ( hasChildren 
&& wxGetApp().ShowImages() ) 
1054                 SetItemImage(id
, TreeCtrlIcon_FolderOpened
, 
1055                              wxTreeItemIcon_Expanded
); 
1058             // remember the last child for OnEnsureVisible() 
1059             if ( !hasChildren 
&& n 
== numChildren 
- 1 ) 
1064             AddItemsRecursively(id
, numChildren
, depth 
- 1, n 
+ 1); 
1070 void MyTreeCtrl::AddTestItemsToTree(size_t numChildren
, 
1073     int image 
= wxGetApp().ShowImages() ? MyTreeCtrl::TreeCtrlIcon_Folder 
: -1; 
1074     wxTreeItemId rootId 
= AddRoot(wxT("Root"), 
1076                                   new MyTreeItemData(wxT("Root item"))); 
1077     if ( !HasFlag(wxTR_HIDE_ROOT
) && image 
!= -1 ) 
1079         SetItemImage(rootId
, TreeCtrlIcon_FolderOpened
, wxTreeItemIcon_Expanded
); 
1082     AddItemsRecursively(rootId
, numChildren
, depth
, 0); 
1084     // set some colours/fonts for testing 
1085     if ( !HasFlag(wxTR_HIDE_ROOT
) ) 
1086         SetItemFont(rootId
, *wxITALIC_FONT
); 
1088     wxTreeItemIdValue cookie
; 
1089     wxTreeItemId id 
= GetFirstChild(rootId
, cookie
); 
1090     SetItemTextColour(id
, *wxBLUE
); 
1092     id 
= GetNextChild(rootId
, cookie
); 
1093     id 
= GetNextChild(rootId
, cookie
); 
1094     SetItemTextColour(id
, *wxRED
); 
1095     SetItemBackgroundColour(id
, *wxLIGHT_GREY
); 
1098 void MyTreeCtrl::GetItemsRecursively(const wxTreeItemId
& idParent
, 
1099                                      wxTreeItemIdValue cookie
) 
1104         id 
= GetFirstChild(idParent
, cookie
); 
1106         id 
= GetNextChild(idParent
, cookie
); 
1111     wxString text 
= GetItemText(id
); 
1114     if (ItemHasChildren(id
)) 
1115         GetItemsRecursively(id
); 
1117     GetItemsRecursively(idParent
, cookie
); 
1120 void MyTreeCtrl::DoToggleIcon(const wxTreeItemId
& item
) 
1122     int image 
= GetItemImage(item
) == TreeCtrlIcon_Folder
 
1124                     : TreeCtrlIcon_Folder
; 
1125     SetItemImage(item
, image
, wxTreeItemIcon_Normal
); 
1127     image 
= GetItemImage(item
, wxTreeItemIcon_Selected
) == TreeCtrlIcon_FolderSelected
 
1128                     ? TreeCtrlIcon_FileSelected
 
1129                     : TreeCtrlIcon_FolderSelected
; 
1130     SetItemImage(item
, image
, wxTreeItemIcon_Selected
); 
1133 void MyTreeCtrl::DoToggleState(const wxTreeItemId
& item
) 
1135     if ( m_alternateStates 
) 
1137         // sets random state unlike current 
1138         int state 
= GetItemState(item
); 
1143             nState 
= rand() % GetStateImageList()->GetImageCount(); 
1144         } while (nState 
== state
); 
1146         SetItemState(item
, nState
); 
1150         // we have only 2 checkbox states, so next state will be reversed 
1151         SetItemState(item
, wxTREE_ITEMSTATE_NEXT
); 
1155 void MyTreeCtrl::LogEvent(const wxChar 
*name
, const wxTreeEvent
& event
) 
1157     wxTreeItemId item 
= event
.GetItem(); 
1160         text 
<< _T('"') << GetItemText(item
).c_str() << _T('"'); 
1162         text 
= _T("invalid item"); 
1163     wxLogMessage(wxT("%s(%s)"), name
, text
.c_str()); 
1167 #define TREE_EVENT_HANDLER(name)                                 \ 
1168 void MyTreeCtrl::name(wxTreeEvent& event)                        \ 
1170     LogEvent(_T(#name), event);                                  \ 
1171     SetLastItem(wxTreeItemId());                                 \ 
1175 TREE_EVENT_HANDLER(OnBeginRDrag
) 
1176 TREE_EVENT_HANDLER(OnDeleteItem
) 
1177 TREE_EVENT_HANDLER(OnGetInfo
) 
1178 TREE_EVENT_HANDLER(OnSetInfo
) 
1179 TREE_EVENT_HANDLER(OnItemExpanded
) 
1180 TREE_EVENT_HANDLER(OnItemExpanding
) 
1181 TREE_EVENT_HANDLER(OnItemCollapsed
) 
1182 TREE_EVENT_HANDLER(OnSelChanged
) 
1183 TREE_EVENT_HANDLER(OnSelChanging
) 
1185 #undef TREE_EVENT_HANDLER 
1187 void LogKeyEvent(const wxChar 
*name
, const wxKeyEvent
& event
) 
1190     long keycode 
= event
.GetKeyCode(); 
1194             case WXK_BACK
: key 
= wxT("BACK"); break; 
1195             case WXK_TAB
: key 
= wxT("TAB"); break; 
1196             case WXK_RETURN
: key 
= wxT("RETURN"); break; 
1197             case WXK_ESCAPE
: key 
= wxT("ESCAPE"); break; 
1198             case WXK_SPACE
: key 
= wxT("SPACE"); break; 
1199             case WXK_DELETE
: key 
= wxT("DELETE"); break; 
1200             case WXK_START
: key 
= wxT("START"); break; 
1201             case WXK_LBUTTON
: key 
= wxT("LBUTTON"); break; 
1202             case WXK_RBUTTON
: key 
= wxT("RBUTTON"); break; 
1203             case WXK_CANCEL
: key 
= wxT("CANCEL"); break; 
1204             case WXK_MBUTTON
: key 
= wxT("MBUTTON"); break; 
1205             case WXK_CLEAR
: key 
= wxT("CLEAR"); break; 
1206             case WXK_SHIFT
: key 
= wxT("SHIFT"); break; 
1207             case WXK_ALT
: key 
= wxT("ALT"); break; 
1208             case WXK_CONTROL
: key 
= wxT("CONTROL"); break; 
1209             case WXK_MENU
: key 
= wxT("MENU"); break; 
1210             case WXK_PAUSE
: key 
= wxT("PAUSE"); break; 
1211             case WXK_CAPITAL
: key 
= wxT("CAPITAL"); break; 
1212             case WXK_END
: key 
= wxT("END"); break; 
1213             case WXK_HOME
: key 
= wxT("HOME"); break; 
1214             case WXK_LEFT
: key 
= wxT("LEFT"); break; 
1215             case WXK_UP
: key 
= wxT("UP"); break; 
1216             case WXK_RIGHT
: key 
= wxT("RIGHT"); break; 
1217             case WXK_DOWN
: key 
= wxT("DOWN"); break; 
1218             case WXK_SELECT
: key 
= wxT("SELECT"); break; 
1219             case WXK_PRINT
: key 
= wxT("PRINT"); break; 
1220             case WXK_EXECUTE
: key 
= wxT("EXECUTE"); break; 
1221             case WXK_SNAPSHOT
: key 
= wxT("SNAPSHOT"); break; 
1222             case WXK_INSERT
: key 
= wxT("INSERT"); break; 
1223             case WXK_HELP
: key 
= wxT("HELP"); break; 
1224             case WXK_NUMPAD0
: key 
= wxT("NUMPAD0"); break; 
1225             case WXK_NUMPAD1
: key 
= wxT("NUMPAD1"); break; 
1226             case WXK_NUMPAD2
: key 
= wxT("NUMPAD2"); break; 
1227             case WXK_NUMPAD3
: key 
= wxT("NUMPAD3"); break; 
1228             case WXK_NUMPAD4
: key 
= wxT("NUMPAD4"); break; 
1229             case WXK_NUMPAD5
: key 
= wxT("NUMPAD5"); break; 
1230             case WXK_NUMPAD6
: key 
= wxT("NUMPAD6"); break; 
1231             case WXK_NUMPAD7
: key 
= wxT("NUMPAD7"); break; 
1232             case WXK_NUMPAD8
: key 
= wxT("NUMPAD8"); break; 
1233             case WXK_NUMPAD9
: key 
= wxT("NUMPAD9"); break; 
1234             case WXK_MULTIPLY
: key 
= wxT("MULTIPLY"); break; 
1235             case WXK_ADD
: key 
= wxT("ADD"); break; 
1236             case WXK_SEPARATOR
: key 
= wxT("SEPARATOR"); break; 
1237             case WXK_SUBTRACT
: key 
= wxT("SUBTRACT"); break; 
1238             case WXK_DECIMAL
: key 
= wxT("DECIMAL"); break; 
1239             case WXK_DIVIDE
: key 
= wxT("DIVIDE"); break; 
1240             case WXK_F1
: key 
= wxT("F1"); break; 
1241             case WXK_F2
: key 
= wxT("F2"); break; 
1242             case WXK_F3
: key 
= wxT("F3"); break; 
1243             case WXK_F4
: key 
= wxT("F4"); break; 
1244             case WXK_F5
: key 
= wxT("F5"); break; 
1245             case WXK_F6
: key 
= wxT("F6"); break; 
1246             case WXK_F7
: key 
= wxT("F7"); break; 
1247             case WXK_F8
: key 
= wxT("F8"); break; 
1248             case WXK_F9
: key 
= wxT("F9"); break; 
1249             case WXK_F10
: key 
= wxT("F10"); break; 
1250             case WXK_F11
: key 
= wxT("F11"); break; 
1251             case WXK_F12
: key 
= wxT("F12"); break; 
1252             case WXK_F13
: key 
= wxT("F13"); break; 
1253             case WXK_F14
: key 
= wxT("F14"); break; 
1254             case WXK_F15
: key 
= wxT("F15"); break; 
1255             case WXK_F16
: key 
= wxT("F16"); break; 
1256             case WXK_F17
: key 
= wxT("F17"); break; 
1257             case WXK_F18
: key 
= wxT("F18"); break; 
1258             case WXK_F19
: key 
= wxT("F19"); break; 
1259             case WXK_F20
: key 
= wxT("F20"); break; 
1260             case WXK_F21
: key 
= wxT("F21"); break; 
1261             case WXK_F22
: key 
= wxT("F22"); break; 
1262             case WXK_F23
: key 
= wxT("F23"); break; 
1263             case WXK_F24
: key 
= wxT("F24"); break; 
1264             case WXK_NUMLOCK
: key 
= wxT("NUMLOCK"); break; 
1265             case WXK_SCROLL
: key 
= wxT("SCROLL"); break; 
1266             case WXK_PAGEUP
: key 
= wxT("PAGEUP"); break; 
1267             case WXK_PAGEDOWN
: key 
= wxT("PAGEDOWN"); break; 
1268             case WXK_NUMPAD_SPACE
: key 
= wxT("NUMPAD_SPACE"); break; 
1269             case WXK_NUMPAD_TAB
: key 
= wxT("NUMPAD_TAB"); break; 
1270             case WXK_NUMPAD_ENTER
: key 
= wxT("NUMPAD_ENTER"); break; 
1271             case WXK_NUMPAD_F1
: key 
= wxT("NUMPAD_F1"); break; 
1272             case WXK_NUMPAD_F2
: key 
= wxT("NUMPAD_F2"); break; 
1273             case WXK_NUMPAD_F3
: key 
= wxT("NUMPAD_F3"); break; 
1274             case WXK_NUMPAD_F4
: key 
= wxT("NUMPAD_F4"); break; 
1275             case WXK_NUMPAD_HOME
: key 
= wxT("NUMPAD_HOME"); break; 
1276             case WXK_NUMPAD_LEFT
: key 
= wxT("NUMPAD_LEFT"); break; 
1277             case WXK_NUMPAD_UP
: key 
= wxT("NUMPAD_UP"); break; 
1278             case WXK_NUMPAD_RIGHT
: key 
= wxT("NUMPAD_RIGHT"); break; 
1279             case WXK_NUMPAD_DOWN
: key 
= wxT("NUMPAD_DOWN"); break; 
1280             case WXK_NUMPAD_PAGEUP
: key 
= wxT("NUMPAD_PAGEUP"); break; 
1281             case WXK_NUMPAD_PAGEDOWN
: key 
= wxT("NUMPAD_PAGEDOWN"); break; 
1282             case WXK_NUMPAD_END
: key 
= wxT("NUMPAD_END"); break; 
1283             case WXK_NUMPAD_BEGIN
: key 
= wxT("NUMPAD_BEGIN"); break; 
1284             case WXK_NUMPAD_INSERT
: key 
= wxT("NUMPAD_INSERT"); break; 
1285             case WXK_NUMPAD_DELETE
: key 
= wxT("NUMPAD_DELETE"); break; 
1286             case WXK_NUMPAD_EQUAL
: key 
= wxT("NUMPAD_EQUAL"); break; 
1287             case WXK_NUMPAD_MULTIPLY
: key 
= wxT("NUMPAD_MULTIPLY"); break; 
1288             case WXK_NUMPAD_ADD
: key 
= wxT("NUMPAD_ADD"); break; 
1289             case WXK_NUMPAD_SEPARATOR
: key 
= wxT("NUMPAD_SEPARATOR"); break; 
1290             case WXK_NUMPAD_SUBTRACT
: key 
= wxT("NUMPAD_SUBTRACT"); break; 
1291             case WXK_NUMPAD_DECIMAL
: key 
= wxT("NUMPAD_DECIMAL"); break; 
1295                if ( keycode 
< 128 && wxIsprint((int)keycode
) ) 
1296                    key
.Printf(wxT("'%c'"), (char)keycode
); 
1297                else if ( keycode 
> 0 && keycode 
< 27 ) 
1298                    key
.Printf(_("Ctrl-%c"), wxT('A') + keycode 
- 1); 
1300                    key
.Printf(wxT("unknown (%ld)"), keycode
); 
1305     wxLogMessage( wxT("%s event: %s (flags = %c%c%c%c)"), 
1308                   event
.ControlDown() ? wxT('C') : wxT('-'), 
1309                   event
.AltDown() ? wxT('A') : wxT('-'), 
1310                   event
.ShiftDown() ? wxT('S') : wxT('-'), 
1311                   event
.MetaDown() ? wxT('M') : wxT('-')); 
1314 void MyTreeCtrl::OnTreeKeyDown(wxTreeEvent
& event
) 
1316     LogKeyEvent(wxT("Tree key down "), event
.GetKeyEvent()); 
1321 void MyTreeCtrl::OnBeginDrag(wxTreeEvent
& event
) 
1323     // need to explicitly allow drag 
1324     if ( event
.GetItem() != GetRootItem() ) 
1326         m_draggedItem 
= event
.GetItem(); 
1328         wxPoint clientpt 
= event
.GetPoint(); 
1329         wxPoint screenpt 
= ClientToScreen(clientpt
); 
1331         wxLogMessage(wxT("OnBeginDrag: started dragging %s at screen coords (%i,%i)"), 
1332                      GetItemText(m_draggedItem
).c_str(), 
1333                      screenpt
.x
, screenpt
.y
); 
1339         wxLogMessage(wxT("OnBeginDrag: this item can't be dragged.")); 
1343 void MyTreeCtrl::OnEndDrag(wxTreeEvent
& event
) 
1345     wxTreeItemId itemSrc 
= m_draggedItem
, 
1346                  itemDst 
= event
.GetItem(); 
1347     m_draggedItem 
= (wxTreeItemId
)0l; 
1349     // where to copy the item? 
1350     if ( itemDst
.IsOk() && !ItemHasChildren(itemDst
) ) 
1352         // copy to the parent then 
1353         itemDst 
= GetItemParent(itemDst
); 
1356     if ( !itemDst
.IsOk() ) 
1358         wxLogMessage(wxT("OnEndDrag: can't drop here.")); 
1363     wxString text 
= GetItemText(itemSrc
); 
1364     wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."), 
1365                  text
.c_str(), GetItemText(itemDst
).c_str()); 
1367     // just do append here - we could also insert it just before/after the item 
1368     // on which it was dropped, but this requires slightly more work... we also 
1369     // completely ignore the client data and icon of the old item but could 
1370     // copy them as well. 
1372     // Finally, we only copy one item here but we might copy the entire tree if 
1373     // we were dragging a folder. 
1374     int image 
= wxGetApp().ShowImages() ? TreeCtrlIcon_File 
: -1; 
1375     wxTreeItemId id 
= AppendItem(itemDst
, text
, image
); 
1377     if ( wxGetApp().ShowStates() ) 
1378         SetItemState(id
, GetItemState(itemSrc
)); 
1381 void MyTreeCtrl::OnBeginLabelEdit(wxTreeEvent
& event
) 
1383     wxLogMessage(wxT("OnBeginLabelEdit")); 
1385     // for testing, prevent this item's label editing 
1386     wxTreeItemId itemId 
= event
.GetItem(); 
1387     if ( IsTestItem(itemId
) ) 
1389         wxMessageBox(wxT("You can't edit this item.")); 
1393     else if ( itemId 
== GetRootItem() ) 
1395         // test that it is possible to change the text of the item being edited 
1396         SetItemText(itemId
, _T("Editing root item")); 
1400 void MyTreeCtrl::OnEndLabelEdit(wxTreeEvent
& event
) 
1402     wxLogMessage(wxT("OnEndLabelEdit")); 
1404     // don't allow anything except letters in the labels 
1405     if ( !event
.GetLabel().IsWord() ) 
1407         wxMessageBox(wxT("The new label should be a single word.")); 
1413 void MyTreeCtrl::OnItemCollapsing(wxTreeEvent
& event
) 
1415     wxLogMessage(wxT("OnItemCollapsing")); 
1417     // for testing, prevent the user from collapsing the first child folder 
1418     wxTreeItemId itemId 
= event
.GetItem(); 
1419     if ( IsTestItem(itemId
) ) 
1421         wxMessageBox(wxT("You can't collapse this item.")); 
1427 void MyTreeCtrl::OnItemActivated(wxTreeEvent
& event
) 
1429     // show some info about this item 
1430     wxTreeItemId itemId 
= event
.GetItem(); 
1431     MyTreeItemData 
*item 
= (MyTreeItemData 
*)GetItemData(itemId
); 
1435         item
->ShowInfo(this); 
1438     wxLogMessage(wxT("OnItemActivated")); 
1441 void MyTreeCtrl::OnItemStateClick(wxTreeEvent
& event
) 
1443     // toggle item state 
1444     wxTreeItemId itemId 
= event
.GetItem(); 
1445     DoToggleState(itemId
); 
1447     wxLogMessage(wxT("Item \"%s\" state changed to %d"), 
1448                  GetItemText(itemId
), GetItemState(itemId
)); 
1451 void MyTreeCtrl::OnItemMenu(wxTreeEvent
& event
) 
1453     wxTreeItemId itemId 
= event
.GetItem(); 
1454     MyTreeItemData 
*item 
= itemId
.IsOk() ? (MyTreeItemData 
*)GetItemData(itemId
) 
1456     wxPoint clientpt 
= event
.GetPoint(); 
1457     wxPoint screenpt 
= ClientToScreen(clientpt
); 
1459     wxLogMessage(wxT("OnItemMenu for item \"%s\" at screen coords (%i, %i)"), 
1460                  item 
? item
->GetDesc() : _T(""), screenpt
.x
, screenpt
.y
); 
1462     ShowMenu(itemId
, clientpt
); 
1466 void MyTreeCtrl::OnContextMenu(wxContextMenuEvent
& event
) 
1468     wxPoint pt 
= event
.GetPosition(); 
1470     wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt
.x
, pt
.y
); 
1473 void MyTreeCtrl::ShowMenu(wxTreeItemId id
, const wxPoint
& pt
) 
1478         title 
<< wxT("Menu for ") << GetItemText(id
); 
1482         title 
= wxT("Menu for no particular item"); 
1487     menu
.Append(TreeTest_About
, wxT("&About...")); 
1488     menu
.AppendSeparator(); 
1489     menu
.Append(TreeTest_Highlight
, wxT("&Highlight item")); 
1490     menu
.Append(TreeTest_Dump
, wxT("&Dump")); 
1492     PopupMenu(&menu
, pt
); 
1493 #endif // wxUSE_MENUS 
1496 void MyTreeCtrl::OnItemRClick(wxTreeEvent
& event
) 
1498     wxTreeItemId itemId 
= event
.GetItem(); 
1499     MyTreeItemData 
*item 
= itemId
.IsOk() ? (MyTreeItemData 
*)GetItemData(itemId
) 
1502     wxLogMessage(wxT("Item \"%s\" right clicked"), item 
? item
->GetDesc() 
1508 void MyTreeCtrl::OnRMouseDown(wxMouseEvent
& event
) 
1510     wxLogMessage(wxT("Right mouse button down")); 
1515 void MyTreeCtrl::OnRMouseUp(wxMouseEvent
& event
) 
1517     wxLogMessage(wxT("Right mouse button up")); 
1522 void MyTreeCtrl::OnRMouseDClick(wxMouseEvent
& event
) 
1524     wxTreeItemId id 
= HitTest(event
.GetPosition()); 
1526         wxLogMessage(wxT("No item under mouse")); 
1529         MyTreeItemData 
*item 
= (MyTreeItemData 
*)GetItemData(id
); 
1531             wxLogMessage(wxT("Item '%s' under mouse"), item
->GetDesc()); 
1537 static inline const wxChar 
*Bool2String(bool b
) 
1539     return b 
? wxT("") : wxT("not "); 
1542 void MyTreeItemData::ShowInfo(wxTreeCtrl 
*tree
) 
1544     wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n") 
1545                  wxT("%u children (%u immediately under this item)."), 
1547                  Bool2String(tree
->IsSelected(GetId())), 
1548                  Bool2String(tree
->IsExpanded(GetId())), 
1549                  Bool2String(tree
->IsBold(GetId())), 
1550                  unsigned(tree
->GetChildrenCount(GetId())), 
1551                  unsigned(tree
->GetChildrenCount(GetId(), false)));