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