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