1. Implemented support for different icons for different states (expanded,
[wxWidgets.git] / samples / treectrl / treetest.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: treetest.cpp
3 // Purpose: wxTreeCtrl sample
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #pragma interface
15 #endif
16
17 // For compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/wx.h"
26 #endif
27
28 #include "wx/log.h"
29
30 #include "wx/image.h"
31 #include "wx/imaglist.h"
32 #include "wx/treectrl.h"
33
34 #include "math.h"
35
36 #ifdef __WXMSW__
37 #define NO_MULTIPLE_SELECTION
38 #define NO_VARIABLE_HEIGHT
39 #endif
40
41 #include "treetest.h"
42
43 // under Windows the icons are in the .rc file
44 #ifndef __WXMSW__
45 #include "icon1.xpm"
46 #include "icon2.xpm"
47 #include "icon3.xpm"
48 #include "icon4.xpm"
49 #include "mondrian.xpm"
50 #endif
51
52 // verify that the item is ok and insult the user if it is not
53 #define CHECK_ITEM( item ) if ( !item.IsOk() ) { \
54 wxMessageBox("Please select some item first!", \
55 "Tree sample error", \
56 wxOK | wxICON_EXCLAMATION, \
57 this); \
58 return; \
59 }
60
61 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
62 EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
63 EVT_MENU(TreeTest_About, MyFrame::OnAbout)
64 EVT_MENU(TreeTest_Dump, MyFrame::OnDump)
65 #ifndef NO_MULTIPLE_SELECTION
66 EVT_MENU(TreeTest_DumpSelected, MyFrame::OnDumpSelected)
67 EVT_MENU(TreeTest_Select, MyFrame::OnSelect)
68 EVT_MENU(TreeTest_Unselect, MyFrame::OnUnselect)
69 #endif // NO_MULTIPLE_SELECTION
70 EVT_MENU(TreeTest_Rename, MyFrame::OnRename)
71 EVT_MENU(TreeTest_Sort, MyFrame::OnSort)
72 EVT_MENU(TreeTest_SortRev, MyFrame::OnSortRev)
73 EVT_MENU(TreeTest_Bold, MyFrame::OnSetBold)
74 EVT_MENU(TreeTest_UnBold, MyFrame::OnClearBold)
75 EVT_MENU(TreeTest_Delete, MyFrame::OnDelete)
76 EVT_MENU(TreeTest_DeleteChildren, MyFrame::OnDeleteChildren)
77 EVT_MENU(TreeTest_DeleteAll, MyFrame::OnDeleteAll)
78 EVT_MENU(TreeTest_Recreate, MyFrame::OnRecreate)
79 EVT_MENU(TreeTest_CollapseAndReset, MyFrame::OnCollapseAndReset)
80 EVT_MENU(TreeTest_EnsureVisible, MyFrame::OnEnsureVisible)
81 EVT_MENU(TreeTest_AddItem, MyFrame::OnAddItem)
82 EVT_MENU(TreeTest_IncIndent, MyFrame::OnIncIndent)
83 EVT_MENU(TreeTest_DecIndent, MyFrame::OnDecIndent)
84 EVT_MENU(TreeTest_IncSpacing, MyFrame::OnIncSpacing)
85 EVT_MENU(TreeTest_DecSpacing, MyFrame::OnDecSpacing)
86 EVT_MENU(TreeTest_ToggleIcon, MyFrame::OnToggleIcon)
87 END_EVENT_TABLE()
88
89 BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
90 EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginDrag)
91 EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginRDrag)
92 EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnBeginLabelEdit)
93 EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnEndLabelEdit)
94 EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, MyTreeCtrl::OnDeleteItem)
95 #if 0 // there are so many of those that logging them causes flicker
96 EVT_TREE_GET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnGetInfo)
97 #endif
98 EVT_TREE_SET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnSetInfo)
99 EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanded)
100 EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanding)
101 EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsed)
102 EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsing)
103 EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, MyTreeCtrl::OnSelChanged)
104 EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, MyTreeCtrl::OnSelChanging)
105 EVT_TREE_KEY_DOWN(TreeTest_Ctrl, MyTreeCtrl::OnTreeKeyDown)
106 EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, MyTreeCtrl::OnItemActivated)
107 EVT_RIGHT_DCLICK(MyTreeCtrl::OnRMouseDClick)
108 END_EVENT_TABLE()
109
110 IMPLEMENT_APP(MyApp)
111
112 bool MyApp::OnInit()
113 {
114 // Create the main frame window
115 MyFrame *frame = new MyFrame("wxTreeCtrl Test", 50, 50, 450, 340);
116
117 // Show the frame
118 frame->Show(TRUE);
119 SetTopWindow(frame);
120
121 return TRUE;
122 }
123
124
125 // My frame constructor
126 MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
127 : wxFrame((wxFrame *)NULL, -1, title, wxPoint(x, y), wxSize(w, h))
128 {
129 // This reduces flicker effects - even better would be to define
130 // OnEraseBackground to do nothing. When the tree control's scrollbars are
131 // show or hidden, the frame is sent a background erase event.
132 SetBackgroundColour(wxColour(255, 255, 255));
133
134 // Give it an icon
135 SetIcon(wxICON(mondrian));
136
137 // Make a menubar
138 wxMenu *file_menu = new wxMenu,
139 *tree_menu = new wxMenu,
140 *item_menu = new wxMenu;
141
142 file_menu->Append(TreeTest_About, "&About...");
143 file_menu->AppendSeparator();
144 file_menu->Append(TreeTest_Quit, "E&xit");
145
146 tree_menu->Append(TreeTest_Recreate, "&Recreate the tree");
147 tree_menu->Append(TreeTest_CollapseAndReset, "C&ollapse and reset");
148 tree_menu->AppendSeparator();
149 tree_menu->Append(TreeTest_AddItem, "Append a &new item");
150 tree_menu->Append(TreeTest_Delete, "&Delete this item");
151 tree_menu->Append(TreeTest_DeleteChildren, "Delete &children");
152 tree_menu->Append(TreeTest_DeleteAll, "Delete &all items");
153 tree_menu->AppendSeparator();
154 tree_menu->Append(TreeTest_Sort, "Sort children of current item");
155 tree_menu->Append(TreeTest_SortRev, "Sort in reversed order");
156 tree_menu->AppendSeparator();
157 tree_menu->Append(TreeTest_EnsureVisible, "Make the last item &visible");
158 tree_menu->AppendSeparator();
159 tree_menu->Append(TreeTest_IncIndent, "Add 5 points to indentation\tAlt-I");
160 tree_menu->Append(TreeTest_DecIndent, "Reduce indentation by 5 points\tAlt-R");
161 tree_menu->AppendSeparator();
162 tree_menu->Append(TreeTest_IncSpacing, "Add 5 points to spacing\tCtrl-I");
163 tree_menu->Append(TreeTest_DecSpacing, "Reduce spacing by 5 points\tCtrl-R");
164
165 item_menu->Append(TreeTest_Dump, "&Dump item children");
166 item_menu->Append(TreeTest_Rename, "&Rename item...");
167
168 item_menu->AppendSeparator();
169 item_menu->Append(TreeTest_Bold, "Make item &bold");
170 item_menu->Append(TreeTest_UnBold, "Make item &not bold");
171 item_menu->AppendSeparator();
172 item_menu->Append(TreeTest_ToggleIcon, "Toggle the items &icon");
173
174 #ifndef NO_MULTIPLE_SELECTION
175 item_menu->AppendSeparator();
176 item_menu->Append(TreeTest_DumpSelected, "Dump selected items\tAlt-D");
177 item_menu->Append(TreeTest_Select, "Select current item\tAlt-S");
178 item_menu->Append(TreeTest_Unselect, "Unselect everything\tAlt-U");
179 #endif
180
181 wxMenuBar *menu_bar = new wxMenuBar;
182 menu_bar->Append(file_menu, "&File");
183 menu_bar->Append(tree_menu, "&Tree");
184 menu_bar->Append(item_menu, "&Item");
185 SetMenuBar(menu_bar);
186
187 m_treeCtrl = new MyTreeCtrl(this, TreeTest_Ctrl,
188 wxDefaultPosition, wxDefaultSize,
189 wxTR_HAS_BUTTONS |
190 wxTR_EDIT_LABELS |
191 #ifndef NO_MULTIPLE_SELECTION
192 wxTR_MULTIPLE |
193 #endif
194 #ifndef NO_VARIABLE_HEIGHT
195 wxTR_HAS_VARIABLE_ROW_HEIGHT |
196 #endif
197 wxSUNKEN_BORDER);
198 wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "",
199 wxDefaultPosition, wxDefaultSize,
200 wxTE_MULTILINE | wxSUNKEN_BORDER);
201
202 wxLayoutConstraints *c = new wxLayoutConstraints;
203 c->top.SameAs(this, wxTop);
204 c->left.SameAs(this, wxLeft);
205 c->right.SameAs(this, wxRight);
206 c->height.PercentOf(this, wxHeight, 66);
207 m_treeCtrl->SetConstraints(c);
208
209 c = new wxLayoutConstraints;
210 c->top.Below(m_treeCtrl);
211 c->left.SameAs(this, wxLeft);
212 c->right.SameAs(this, wxRight);
213 c->bottom.SameAs(this, wxBottom);
214 textCtrl->SetConstraints(c);
215 SetAutoLayout(TRUE);
216
217 // create a status bar with 3 panes
218 CreateStatusBar(3);
219 SetStatusText("", 0);
220
221 #ifdef __WXMOTIF__
222 // For some reason, we get a memcpy crash in wxLogStream::DoLogStream
223 // on gcc/wxMotif, if we use wxLogTextCtl. Maybe it's just gcc?
224 delete wxLog::SetActiveTarget(new wxLogStderr);
225 #else
226 // set our text control as the log target
227 wxLogTextCtrl *logWindow = new wxLogTextCtrl(textCtrl);
228 delete wxLog::SetActiveTarget(logWindow);
229 #endif
230 }
231
232 MyFrame::~MyFrame()
233 {
234 delete wxLog::SetActiveTarget(NULL);
235 }
236
237 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
238 {
239 Close(TRUE);
240 }
241
242 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
243 {
244 wxMessageBox("Tree test sample\n"
245 "(c) Julian Smart 1997, Vadim Zeitlin 1998",
246 "About tree test",
247 wxOK | wxICON_INFORMATION, this);
248 }
249
250 void MyFrame::OnRename(wxCommandEvent& WXUNUSED(event))
251 {
252 wxTreeItemId item = m_treeCtrl->GetSelection();
253
254 CHECK_ITEM( item );
255
256 // old code - now we edit in place
257 #if 0
258 static wxString s_text;
259 s_text = wxGetTextFromUser("New name: ", "Tree sample question",
260 s_text, this);
261 if ( !s_text.IsEmpty() )
262 {
263 m_treeCtrl->SetItemText(item, s_text);
264 }
265 #endif // 0
266
267 // TODO demonstrate creating a custom edit control...
268 (void)m_treeCtrl->EditLabel(item);
269 }
270
271 void MyFrame::DoSort(bool reverse)
272 {
273 wxTreeItemId item = m_treeCtrl->GetSelection();
274
275 CHECK_ITEM( item );
276
277 m_treeCtrl->DoSortChildren(item, reverse);
278 }
279
280 void MyFrame::OnDump(wxCommandEvent& WXUNUSED(event))
281 {
282 wxTreeItemId root = m_treeCtrl->GetSelection();
283
284 CHECK_ITEM( root );
285
286 m_treeCtrl->GetItemsRecursively(root, -1);
287 }
288
289 #ifndef NO_MULTIPLE_SELECTION
290
291 void MyFrame::OnDumpSelected(wxCommandEvent& WXUNUSED(event))
292 {
293 wxArrayTreeItemIds array;
294
295 size_t count = m_treeCtrl->GetSelections(array);
296 wxLogMessage(_T("%u items selected"), count);
297
298 for ( size_t n = 0; n < count; n++ )
299 {
300 wxLogMessage("\t%s", m_treeCtrl->GetItemText(array.Item(n)).c_str());
301 }
302 }
303
304 void MyFrame::OnSelect(wxCommandEvent& event)
305 {
306 m_treeCtrl->SelectItem(m_treeCtrl->GetSelection());
307 }
308
309 void MyFrame::OnUnselect(wxCommandEvent& event)
310 {
311 m_treeCtrl->UnselectAll();
312 }
313
314 #endif // NO_MULTIPLE_SELECTION
315
316 void MyFrame::DoSetBold(bool bold)
317 {
318 wxTreeItemId item = m_treeCtrl->GetSelection();
319
320 CHECK_ITEM( item );
321
322 m_treeCtrl->SetItemBold(item, bold);
323 }
324
325 void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
326 {
327 wxTreeItemId item = m_treeCtrl->GetSelection();
328
329 CHECK_ITEM( item );
330
331 m_treeCtrl->Delete(item);
332 }
333
334 void MyFrame::OnDeleteChildren(wxCommandEvent& WXUNUSED(event))
335 {
336 wxTreeItemId item = m_treeCtrl->GetSelection();
337
338 CHECK_ITEM( item );
339
340 m_treeCtrl->DeleteChildren(item);
341 }
342
343 void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event))
344 {
345 m_treeCtrl->DeleteAllItems();
346 }
347
348 void MyFrame::OnRecreate(wxCommandEvent& event)
349 {
350 OnDeleteAll(event);
351 m_treeCtrl->AddTestItemsToTree(3, 2);
352 }
353
354 void MyFrame::OnCollapseAndReset(wxCommandEvent& event)
355 {
356 m_treeCtrl->CollapseAndReset(m_treeCtrl->GetRootItem());
357 }
358
359 void MyFrame::OnEnsureVisible(wxCommandEvent& event)
360 {
361 m_treeCtrl->DoEnsureVisible();
362 }
363
364 void MyFrame::OnAddItem(wxCommandEvent& WXUNUSED(event))
365 {
366 static int s_num = 0;
367
368 wxString text;
369 text.Printf("Item #%d", ++s_num);
370
371 m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(),
372 text /*,
373 MyTreeCtrl::TreeCtrlIcon_File */ );
374 }
375
376 void MyFrame::OnIncIndent(wxCommandEvent& WXUNUSED(event))
377 {
378 unsigned int indent = m_treeCtrl->GetIndent();
379 if (indent < 100)
380 m_treeCtrl->SetIndent( indent+5 );
381 }
382
383 void MyFrame::OnDecIndent(wxCommandEvent& WXUNUSED(event))
384 {
385 unsigned int indent = m_treeCtrl->GetIndent();
386 if (indent > 10)
387 m_treeCtrl->SetIndent( indent-5 );
388 }
389
390 void MyFrame::OnIncSpacing(wxCommandEvent& WXUNUSED(event))
391 {
392 unsigned int indent = m_treeCtrl->GetSpacing();
393 if (indent < 100)
394 m_treeCtrl->SetSpacing( indent+5 );
395 }
396
397 void MyFrame::OnDecSpacing(wxCommandEvent& WXUNUSED(event))
398 {
399 unsigned int indent = m_treeCtrl->GetSpacing();
400 if (indent > 10)
401 m_treeCtrl->SetSpacing( indent-5 );
402 }
403
404 void MyFrame::OnToggleIcon(wxCommandEvent& WXUNUSED(event))
405 {
406 wxTreeItemId item = m_treeCtrl->GetSelection();
407
408 CHECK_ITEM( item );
409
410 m_treeCtrl->DoToggleIcon(item);
411 }
412
413 // MyTreeCtrl implementation
414 IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl)
415
416 MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
417 const wxPoint& pos, const wxSize& size,
418 long style)
419 : wxTreeCtrl(parent, id, pos, size, style)
420 {
421 #ifndef NO_VARIABLE_HEIGHT
422 #if wxUSE_LIBJPEG
423 wxImage::AddHandler(new wxJPEGHandler);
424 wxImage image;
425
426 image.LoadFile(wxString("horse.jpg"), wxBITMAP_TYPE_JPEG );
427 #endif
428 #endif
429
430 m_reverseSort = FALSE;
431
432 // Make an image list containing small icons
433 m_imageListNormal = new wxImageList(16, 16, TRUE);
434
435 // should correspond to TreeCtrlIcon_xxx enum
436 #if defined(__WXMSW__) && defined(__WIN16__)
437 // This is required in 16-bit Windows mode only because we can't load a specific (16x16)
438 // icon image, so it comes out stretched
439 # ifndef NO_VARIABLE_HEIGHT
440 m_imageListNormal->Add(image.ConvertToBitmap());
441 # else
442 m_imageListNormal->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE));
443 # endif
444 m_imageListNormal->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE));
445 m_imageListNormal->Add(wxBitmap("bitmap3", wxBITMAP_TYPE_BMP_RESOURCE));
446 m_imageListNormal->Add(wxBitmap("bitmap4", wxBITMAP_TYPE_BMP_RESOURCE));
447 m_imageListNormal->Add(wxBitmap("bitmap5", wxBITMAP_TYPE_BMP_RESOURCE));
448 #else
449 # ifndef NO_VARIABLE_HEIGHT
450 m_imageListNormal->Add(image.ConvertToBitmap());
451 # else
452 m_imageListNormal->Add(wxICON(icon1));
453 # endif
454 m_imageListNormal->Add(wxICON(icon2));
455 m_imageListNormal->Add(wxICON(icon3));
456 m_imageListNormal->Add(wxICON(icon4));
457 m_imageListNormal->Add(wxICON(icon5));
458 #endif
459
460 SetImageList(m_imageListNormal);
461
462 // Add some items to the tree
463 AddTestItemsToTree(3, 2);
464 }
465
466 MyTreeCtrl::~MyTreeCtrl()
467 {
468 delete m_imageListNormal;
469 }
470
471 int MyTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
472 const wxTreeItemId& item2)
473 {
474 if ( m_reverseSort )
475 {
476 // just exchange 1st and 2nd items
477 return wxTreeCtrl::OnCompareItems(item2, item1);
478 }
479 else
480 {
481 return wxTreeCtrl::OnCompareItems(item1, item2);
482 }
483 }
484
485 void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent,
486 size_t numChildren,
487 size_t depth,
488 size_t folder)
489 {
490 if ( depth > 0 )
491 {
492 bool hasChildren = depth > 1;
493
494 wxString str;
495 for ( size_t n = 0; n < numChildren; n++ )
496 {
497 // at depth 1 elements won't have any more children
498 if ( hasChildren )
499 str.Printf("%s child %d", "Folder", n + 1);
500 else
501 str.Printf("%s child %d.%d", "File", folder, n + 1);
502
503 // here we pass to AppendItem() normal and selected item images (we
504 // suppose that selected image follows the normal one in the enum)
505 int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
506 wxTreeItemId id = AppendItem(idParent, str, image, image + 1,
507 new MyTreeItemData(str));
508
509 // and now we also set the expanded one (only for the folders)
510 if ( hasChildren )
511 {
512 SetItemImage(id, TreeCtrlIcon_FolderOpened,
513 wxTreeItemIcon_Expanded);
514 }
515
516 // remember the last child for OnEnsureVisible()
517 if ( !hasChildren && n == numChildren - 1 )
518 {
519 m_lastItem = id;
520 }
521
522 AddItemsRecursively(id, numChildren, depth - 1, n + 1);
523 }
524 }
525 //else: done!
526 }
527
528 void MyTreeCtrl::AddTestItemsToTree(size_t numChildren,
529 size_t depth)
530 {
531 wxTreeItemId rootId = AddRoot("Root",
532 TreeCtrlIcon_Folder, TreeCtrlIcon_Folder,
533 new MyTreeItemData("Root item"));
534 SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded);
535
536 AddItemsRecursively(rootId, numChildren, depth, 0);
537 }
538
539 void MyTreeCtrl::GetItemsRecursively(const wxTreeItemId& idParent, long cookie)
540 {
541 wxTreeItemId id;
542
543 if( cookie == -1 )
544 id = GetFirstChild(idParent, cookie);
545 else
546 id = GetNextChild(idParent, cookie);
547
548 if(id <= 0)
549 return;
550
551 wxString text = GetItemText(id);
552 wxLogMessage(text);
553
554 if (ItemHasChildren(id))
555 GetItemsRecursively(id,-1);
556
557 GetItemsRecursively(idParent, cookie);
558 }
559
560 void MyTreeCtrl::DoToggleIcon(const wxTreeItemId& item)
561 {
562 int image = GetItemImage(item) == TreeCtrlIcon_Folder ? TreeCtrlIcon_File
563 : TreeCtrlIcon_Folder;
564
565 SetItemImage(item, image);
566 }
567
568
569 // avoid repetition
570 #define TREE_EVENT_HANDLER(name) \
571 void MyTreeCtrl::name(wxTreeEvent& WXUNUSED(event)) \
572 { \
573 wxLogMessage(#name); \
574 }
575
576 TREE_EVENT_HANDLER(OnBeginDrag)
577 TREE_EVENT_HANDLER(OnBeginRDrag)
578 TREE_EVENT_HANDLER(OnDeleteItem)
579 TREE_EVENT_HANDLER(OnGetInfo)
580 TREE_EVENT_HANDLER(OnSetInfo)
581 TREE_EVENT_HANDLER(OnItemExpanded)
582 TREE_EVENT_HANDLER(OnItemExpanding)
583 TREE_EVENT_HANDLER(OnItemCollapsed)
584 TREE_EVENT_HANDLER(OnSelChanged)
585 TREE_EVENT_HANDLER(OnSelChanging)
586
587 #undef TREE_EVENT_HANDLER
588
589 void MyTreeCtrl::OnBeginLabelEdit(wxTreeEvent& event)
590 {
591 wxLogMessage("OnBeginLabelEdit");
592
593 // for testing, prevent this items label editing
594 wxTreeItemId itemId = event.GetItem();
595 if ( IsTestItem(itemId) )
596 {
597 wxMessageBox("You can't edit this item.");
598
599 event.Veto();
600 }
601 }
602
603 void MyTreeCtrl::OnEndLabelEdit(wxTreeEvent& event)
604 {
605 wxLogMessage("OnEndLabelEdit");
606
607 // don't allow anything except letters in the labels
608 if ( !event.GetLabel().IsWord() )
609 {
610 wxMessageBox("The label should contain only letters.");
611
612 event.Veto();
613 }
614 }
615
616 void MyTreeCtrl::OnItemCollapsing(wxTreeEvent& event)
617 {
618 wxLogMessage("OnItemCollapsing");
619
620 // for testing, prevent the user from collapsing the first child folder
621 wxTreeItemId itemId = event.GetItem();
622 if ( IsTestItem(itemId) )
623 {
624 wxMessageBox("You can't collapse this item.");
625
626 event.Veto();
627 }
628 }
629
630 void MyTreeCtrl::OnTreeKeyDown(wxTreeEvent&WXUNUSED(event))
631 {
632 wxLogMessage("OnTreeKeyDown");
633 }
634
635 void MyTreeCtrl::OnItemActivated(wxTreeEvent&WXUNUSED(event))
636 {
637 // show some info about this item
638 wxTreeItemId itemId = GetSelection();
639 MyTreeItemData *item = (MyTreeItemData *)GetItemData(itemId);
640
641 if ( item != NULL )
642 {
643 item->ShowInfo(this);
644 }
645
646 wxLogMessage("OnItemActivated");
647 }
648
649 void MyTreeCtrl::OnRMouseDClick(wxMouseEvent& event)
650 {
651 wxTreeItemId id = HitTest(event.GetPosition());
652 if ( !id )
653 wxLogMessage("No item under mouse");
654 else
655 {
656 MyTreeItemData *item = (MyTreeItemData *)GetItemData(id);
657 if ( item )
658 wxLogMessage("Item '%s' under mouse", item->GetDesc());
659 }
660 }
661
662 static inline const char *Bool2String(bool b)
663 {
664 return b ? "" : "not ";
665 }
666
667 void MyTreeItemData::ShowInfo(wxTreeCtrl *tree)
668 {
669 wxLogMessage("Item '%s': %sselected, %sexpanded, %sbold,\n"
670 "%u children (%u immediately under this item).",
671 m_desc.c_str(),
672 Bool2String(tree->IsSelected(GetId())),
673 Bool2String(tree->IsExpanded(GetId())),
674 Bool2String(tree->IsBold(GetId())),
675 tree->GetChildrenCount(GetId()),
676 tree->GetChildrenCount(GetId(), FALSE));
677 }