]> git.saurik.com Git - wxWidgets.git/blame - samples/treectrl/treetest.cpp
removed test wxYield
[wxWidgets.git] / samples / treectrl / treetest.cpp
CommitLineData
457814b5
JS
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
3a5a2f56 9// Licence: wxWindows license
457814b5
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
3a5a2f56
VZ
13 #pragma implementation
14 #pragma interface
457814b5
JS
15#endif
16
17// For compilers that support precompilation, includes "wx/wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
3a5a2f56 21 #pragma hdrstop
457814b5
JS
22#endif
23
24#ifndef WX_PRECOMP
3a5a2f56 25 #include "wx/wx.h"
457814b5
JS
26#endif
27
3a5a2f56
VZ
28#include "wx/log.h"
29
91b8de8d 30#include "wx/image.h"
3a5a2f56 31#include "wx/imaglist.h"
457814b5
JS
32#include "wx/treectrl.h"
33
cf724bce
RR
34#include "math.h"
35
74b31181 36#ifdef __WXMSW__
8dc99046
VZ
37 // comment out this line to test multiple selection even under MSW (where
38 // it looks ugly - but works)
89124b1a 39 #define NO_MULTIPLE_SELECTION
74b31181 40#endif
91b8de8d 41
8dc99046
VZ
42#define NO_VARIABLE_HEIGHT
43
9dfbf520
VZ
44#include "treetest.h"
45
91b8de8d
RR
46// under Windows the icons are in the .rc file
47#ifndef __WXMSW__
91b8de8d 48 #include "icon1.xpm"
91b8de8d 49 #include "icon2.xpm"
74b31181
VZ
50 #include "icon3.xpm"
51 #include "icon4.xpm"
8dc99046 52 #include "icon5.xpm"
91b8de8d
RR
53 #include "mondrian.xpm"
54#endif
55
e1ee62bd
VZ
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; \
5f939e78
VZ
63 }
64
457814b5 65BEGIN_EVENT_TABLE(MyFrame, wxFrame)
5f939e78
VZ
66 EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
67 EVT_MENU(TreeTest_About, MyFrame::OnAbout)
68 EVT_MENU(TreeTest_Dump, MyFrame::OnDump)
9dfbf520
VZ
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
5f939e78 74 EVT_MENU(TreeTest_Rename, MyFrame::OnRename)
5fd11f09
RR
75 EVT_MENU(TreeTest_Count, MyFrame::OnCount)
76 EVT_MENU(TreeTest_CountRec, MyFrame::OnCountRec)
5f939e78
VZ
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)
75c74ca0 88 EVT_MENU(TreeTest_InsertItem, MyFrame::OnInsertItem)
cf724bce
RR
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)
9dfbf520 93 EVT_MENU(TreeTest_ToggleIcon, MyFrame::OnToggleIcon)
457814b5
JS
94END_EVENT_TABLE()
95
96BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
5f939e78
VZ
97 EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginDrag)
98 EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginRDrag)
5888ef1e 99 EVT_TREE_END_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnEndDrag)
5f939e78
VZ
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)
74b31181 103#if 0 // there are so many of those that logging them causes flicker
5f939e78 104 EVT_TREE_GET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnGetInfo)
74b31181 105#endif
5f939e78
VZ
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)
457814b5
JS
116END_EVENT_TABLE()
117
118IMPLEMENT_APP(MyApp)
119
c89a6106 120bool MyApp::OnInit()
457814b5 121{
5f939e78
VZ
122 // Create the main frame window
123 MyFrame *frame = new MyFrame("wxTreeCtrl Test", 50, 50, 450, 340);
457814b5 124
5f939e78
VZ
125 // Show the frame
126 frame->Show(TRUE);
127 SetTopWindow(frame);
457814b5 128
5f939e78 129 return TRUE;
3a5a2f56 130}
457814b5 131
457814b5 132
3a5a2f56
VZ
133// My frame constructor
134MyFrame::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{
5f939e78
VZ
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");
75c74ca0 158 tree_menu->Append(TreeTest_InsertItem, "&Insert a new item");
5f939e78
VZ
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();
5fd11f09
RR
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();
5f939e78
VZ
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");
cf724bce
RR
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");
5f939e78 176
91b8de8d 177 item_menu->Append(TreeTest_Dump, "&Dump item children");
5f939e78 178 item_menu->Append(TreeTest_Rename, "&Rename item...");
91b8de8d 179
5f939e78
VZ
180 item_menu->AppendSeparator();
181 item_menu->Append(TreeTest_Bold, "Make item &bold");
182 item_menu->Append(TreeTest_UnBold, "Make item &not bold");
9dfbf520
VZ
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
5f939e78
VZ
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,
5ea47806
VZ
201 wxTR_HAS_BUTTONS |
202 wxTR_EDIT_LABELS |
89124b1a 203#ifndef NO_MULTIPLE_SELECTION
74b31181 204 wxTR_MULTIPLE |
89124b1a
RR
205#endif
206#ifndef NO_VARIABLE_HEIGHT
74b31181 207 wxTR_HAS_VARIABLE_ROW_HEIGHT |
89124b1a 208#endif
74b31181 209 wxSUNKEN_BORDER);
31405c01
VZ
210
211 m_treeCtrl->SetBackgroundColour(wxColour(204, 205, 79));
212
5f939e78
VZ
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);
3a5a2f56 235
a367b9b3 236#ifdef __WXMOTIF__
5f939e78
VZ
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);
a367b9b3 240#else
5f939e78
VZ
241 // set our text control as the log target
242 wxLogTextCtrl *logWindow = new wxLogTextCtrl(textCtrl);
243 delete wxLog::SetActiveTarget(logWindow);
a367b9b3 244#endif
457814b5
JS
245}
246
c89a6106 247MyFrame::~MyFrame()
457814b5 248{
5f939e78 249 delete wxLog::SetActiveTarget(NULL);
457814b5
JS
250}
251
3a5a2f56 252void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
457814b5 253{
5f939e78 254 Close(TRUE);
457814b5
JS
255}
256
3a5a2f56 257void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
457814b5 258{
5f939e78 259 wxMessageBox("Tree test sample\n"
5ea47806 260 "(c) Julian Smart 1997, Vadim Zeitlin 1998",
5f939e78
VZ
261 "About tree test",
262 wxOK | wxICON_INFORMATION, this);
e1ee62bd
VZ
263}
264
265void MyFrame::OnRename(wxCommandEvent& WXUNUSED(event))
266{
5f939e78 267 wxTreeItemId item = m_treeCtrl->GetSelection();
e1ee62bd 268
5f939e78 269 CHECK_ITEM( item );
e1ee62bd 270
5ea47806
VZ
271 // old code - now we edit in place
272#if 0
5f939e78
VZ
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 }
5ea47806
VZ
280#endif // 0
281
282 // TODO demonstrate creating a custom edit control...
283 (void)m_treeCtrl->EditLabel(item);
e1ee62bd
VZ
284}
285
5fd11f09
RR
286void 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 );
75c74ca0 293
247e5b16 294 wxLogMessage(wxT("%d children"), i);
5fd11f09
RR
295}
296
297void 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 );
75c74ca0 304
247e5b16 305 wxLogMessage(wxT("%d children"), i);
5fd11f09
RR
306}
307
e1ee62bd
VZ
308void MyFrame::DoSort(bool reverse)
309{
5f939e78 310 wxTreeItemId item = m_treeCtrl->GetSelection();
e1ee62bd 311
5f939e78 312 CHECK_ITEM( item );
457814b5 313
5f939e78 314 m_treeCtrl->DoSortChildren(item, reverse);
457814b5
JS
315}
316
4832f7c0
VZ
317void MyFrame::OnDump(wxCommandEvent& WXUNUSED(event))
318{
5f939e78 319 wxTreeItemId root = m_treeCtrl->GetSelection();
e1ee62bd 320
5f939e78 321 CHECK_ITEM( root );
e1ee62bd 322
5f939e78 323 m_treeCtrl->GetItemsRecursively(root, -1);
4832f7c0
VZ
324}
325
9dfbf520
VZ
326#ifndef NO_MULTIPLE_SELECTION
327
91b8de8d
RR
328void MyFrame::OnDumpSelected(wxCommandEvent& WXUNUSED(event))
329{
9dfbf520 330 wxArrayTreeItemIds array;
91b8de8d 331
9dfbf520 332 size_t count = m_treeCtrl->GetSelections(array);
247e5b16 333 wxLogMessage(wxT("%u items selected"), count);
91b8de8d 334
9dfbf520
VZ
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
341void MyFrame::OnSelect(wxCommandEvent& event)
342{
343 m_treeCtrl->SelectItem(m_treeCtrl->GetSelection());
344}
345
346void MyFrame::OnUnselect(wxCommandEvent& event)
347{
348 m_treeCtrl->UnselectAll();
91b8de8d
RR
349}
350
9dfbf520
VZ
351#endif // NO_MULTIPLE_SELECTION
352
add28c55
VZ
353void MyFrame::DoSetBold(bool bold)
354{
5f939e78 355 wxTreeItemId item = m_treeCtrl->GetSelection();
e1ee62bd 356
5f939e78 357 CHECK_ITEM( item );
e1ee62bd 358
5f939e78 359 m_treeCtrl->SetItemBold(item, bold);
add28c55
VZ
360}
361
ff5bf259
VZ
362void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
363{
5f939e78 364 wxTreeItemId item = m_treeCtrl->GetSelection();
e1ee62bd 365
5f939e78 366 CHECK_ITEM( item );
e1ee62bd 367
5f939e78 368 m_treeCtrl->Delete(item);
ff5bf259
VZ
369}
370
372edb9d
VZ
371void MyFrame::OnDeleteChildren(wxCommandEvent& WXUNUSED(event))
372{
5f939e78 373 wxTreeItemId item = m_treeCtrl->GetSelection();
e1ee62bd 374
5f939e78 375 CHECK_ITEM( item );
e1ee62bd 376
5f939e78 377 m_treeCtrl->DeleteChildren(item);
372edb9d
VZ
378}
379
ff5bf259
VZ
380void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event))
381{
5f939e78 382 m_treeCtrl->DeleteAllItems();
ff5bf259
VZ
383}
384
385void MyFrame::OnRecreate(wxCommandEvent& event)
386{
5f939e78
VZ
387 OnDeleteAll(event);
388 m_treeCtrl->AddTestItemsToTree(3, 2);
ff5bf259
VZ
389}
390
dd3646fd
VZ
391void MyFrame::OnCollapseAndReset(wxCommandEvent& event)
392{
5f939e78 393 m_treeCtrl->CollapseAndReset(m_treeCtrl->GetRootItem());
dd3646fd
VZ
394}
395
f65635b5
VZ
396void MyFrame::OnEnsureVisible(wxCommandEvent& event)
397{
398 m_treeCtrl->DoEnsureVisible();
399}
400
75c74ca0
VZ
401void MyFrame::OnInsertItem(wxCommandEvent& WXUNUSED(event))
402{
403 m_treeCtrl->InsertItem(m_treeCtrl->GetRootItem(), 1, "2nd item");
404}
405
5f939e78
VZ
406void 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(),
112c5086
RR
414 text /*,
415 MyTreeCtrl::TreeCtrlIcon_File */ );
5f939e78
VZ
416}
417
cf724bce
RR
418void 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
425void 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
432void 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
439void 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
9dfbf520
VZ
446void 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
3a5a2f56 455// MyTreeCtrl implementation
23fd5130
VZ
456IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl)
457
3a5a2f56
VZ
458MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
459 const wxPoint& pos, const wxSize& size,
460 long style)
461 : wxTreeCtrl(parent, id, pos, size, style)
457814b5 462{
9ce29a28
SB
463#ifndef NO_VARIABLE_HEIGHT
464#if wxUSE_LIBJPEG
9dfbf520 465 wxImage::AddHandler(new wxJPEGHandler);
91b8de8d
RR
466 wxImage image;
467
468 image.LoadFile(wxString("horse.jpg"), wxBITMAP_TYPE_JPEG );
9ce29a28 469#endif
91b8de8d
RR
470#endif
471
5f939e78 472 m_reverseSort = FALSE;
e1ee62bd 473
5f939e78
VZ
474 // Make an image list containing small icons
475 m_imageListNormal = new wxImageList(16, 16, TRUE);
457814b5 476
5f939e78 477 // should correspond to TreeCtrlIcon_xxx enum
f60d0f94 478#if defined(__WXMSW__) && defined(__WIN16__)
5f939e78
VZ
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
9ce29a28 481# ifndef NO_VARIABLE_HEIGHT
91b8de8d
RR
482 m_imageListNormal->Add(image.ConvertToBitmap());
483# else
5f939e78 484 m_imageListNormal->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE));
91b8de8d 485# endif
5f939e78 486 m_imageListNormal->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE));
74b31181
VZ
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));
f60d0f94 490#else
9ce29a28 491# ifndef NO_VARIABLE_HEIGHT
91b8de8d
RR
492 m_imageListNormal->Add(image.ConvertToBitmap());
493# else
5f939e78 494 m_imageListNormal->Add(wxICON(icon1));
91b8de8d 495# endif
5f939e78 496 m_imageListNormal->Add(wxICON(icon2));
74b31181
VZ
497 m_imageListNormal->Add(wxICON(icon3));
498 m_imageListNormal->Add(wxICON(icon4));
499 m_imageListNormal->Add(wxICON(icon5));
f60d0f94 500#endif
457814b5 501
5f939e78 502 SetImageList(m_imageListNormal);
457814b5 503
5f939e78
VZ
504 // Add some items to the tree
505 AddTestItemsToTree(3, 2);
457814b5
JS
506}
507
3a5a2f56 508MyTreeCtrl::~MyTreeCtrl()
457814b5 509{
5f939e78 510 delete m_imageListNormal;
457814b5
JS
511}
512
e1ee62bd
VZ
513int MyTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
514 const wxTreeItemId& item2)
515{
5f939e78
VZ
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 }
e1ee62bd
VZ
525}
526
3a5a2f56
VZ
527void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent,
528 size_t numChildren,
4832f7c0
VZ
529 size_t depth,
530 size_t folder)
457814b5 531{
f65635b5 532 if ( depth > 0 )
3a5a2f56 533 {
74b31181
VZ
534 bool hasChildren = depth > 1;
535
f65635b5
VZ
536 wxString str;
537 for ( size_t n = 0; n < numChildren; n++ )
538 {
539 // at depth 1 elements won't have any more children
74b31181 540 if ( hasChildren )
f65635b5 541 str.Printf("%s child %d", "Folder", n + 1);
74b31181
VZ
542 else
543 str.Printf("%s child %d.%d", "File", folder, n + 1);
f65635b5 544
74b31181
VZ
545 // here we pass to AppendItem() normal and selected item images (we
546 // suppose that selected image follows the normal one in the enum)
9dfbf520 547 int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
74b31181 548 wxTreeItemId id = AppendItem(idParent, str, image, image + 1,
f65635b5
VZ
549 new MyTreeItemData(str));
550
74b31181
VZ
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
f65635b5 558 // remember the last child for OnEnsureVisible()
74b31181 559 if ( !hasChildren && n == numChildren - 1 )
f65635b5
VZ
560 {
561 m_lastItem = id;
562 }
563
564 AddItemsRecursively(id, numChildren, depth - 1, n + 1);
565 }
3a5a2f56 566 }
f65635b5 567 //else: done!
457814b5
JS
568}
569
3a5a2f56
VZ
570void MyTreeCtrl::AddTestItemsToTree(size_t numChildren,
571 size_t depth)
457814b5 572{
5f939e78
VZ
573 wxTreeItemId rootId = AddRoot("Root",
574 TreeCtrlIcon_Folder, TreeCtrlIcon_Folder,
575 new MyTreeItemData("Root item"));
74b31181 576 SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded);
457814b5 577
5f939e78 578 AddItemsRecursively(rootId, numChildren, depth, 0);
9ec64fa7
VZ
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);
4832f7c0
VZ
591}
592
593void MyTreeCtrl::GetItemsRecursively(const wxTreeItemId& idParent, long cookie)
594{
5f939e78 595 wxTreeItemId id;
4832f7c0 596
5f939e78
VZ
597 if( cookie == -1 )
598 id = GetFirstChild(idParent, cookie);
599 else
600 id = GetNextChild(idParent, cookie);
4832f7c0 601
5f939e78
VZ
602 if(id <= 0)
603 return;
4832f7c0 604
9dfbf520 605 wxString text = GetItemText(id);
5f939e78 606 wxLogMessage(text);
4832f7c0 607
5f939e78
VZ
608 if (ItemHasChildren(id))
609 GetItemsRecursively(id,-1);
4832f7c0 610
5f939e78 611 GetItemsRecursively(idParent, cookie);
457814b5
JS
612}
613
9dfbf520
VZ
614void 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
4832f7c0 622
3a5a2f56 623// avoid repetition
5f939e78
VZ
624#define TREE_EVENT_HANDLER(name) \
625void MyTreeCtrl::name(wxTreeEvent& WXUNUSED(event)) \
626{ \
627 wxLogMessage(#name); \
628}
457814b5 629
3a5a2f56 630TREE_EVENT_HANDLER(OnBeginRDrag)
3a5a2f56
VZ
631TREE_EVENT_HANDLER(OnDeleteItem)
632TREE_EVENT_HANDLER(OnGetInfo)
633TREE_EVENT_HANDLER(OnSetInfo)
634TREE_EVENT_HANDLER(OnItemExpanded)
635TREE_EVENT_HANDLER(OnItemExpanding)
636TREE_EVENT_HANDLER(OnItemCollapsed)
637TREE_EVENT_HANDLER(OnSelChanged)
638TREE_EVENT_HANDLER(OnSelChanging)
639
640#undef TREE_EVENT_HANDLER
641
5888ef1e
VZ
642void 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
660void 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
5ea47806
VZ
694void 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
708void 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
3a5a2f56 721void MyTreeCtrl::OnItemCollapsing(wxTreeEvent& event)
457814b5 722{
5f939e78 723 wxLogMessage("OnItemCollapsing");
f135ff73 724
5f939e78
VZ
725 // for testing, prevent the user from collapsing the first child folder
726 wxTreeItemId itemId = event.GetItem();
5ea47806 727 if ( IsTestItem(itemId) )
5f939e78
VZ
728 {
729 wxMessageBox("You can't collapse this item.");
457814b5 730
5f939e78
VZ
731 event.Veto();
732 }
457814b5
JS
733}
734
6daa0637 735void MyTreeCtrl::OnTreeKeyDown(wxTreeEvent&WXUNUSED(event))
435fe83e 736{
5f939e78 737 wxLogMessage("OnTreeKeyDown");
435fe83e
RR
738}
739
740void MyTreeCtrl::OnItemActivated(wxTreeEvent&WXUNUSED(event))
457814b5 741{
5f939e78
VZ
742 // show some info about this item
743 wxTreeItemId itemId = GetSelection();
744 MyTreeItemData *item = (MyTreeItemData *)GetItemData(itemId);
457814b5 745
5f939e78
VZ
746 if ( item != NULL )
747 {
748 item->ShowInfo(this);
749 }
457814b5 750
5f939e78
VZ
751 wxLogMessage("OnItemActivated");
752}
753
754void 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 }
457814b5
JS
765}
766
3a5a2f56 767static inline const char *Bool2String(bool b)
457814b5 768{
5f939e78 769 return b ? "" : "not ";
457814b5
JS
770}
771
9769e589 772void MyTreeItemData::ShowInfo(wxTreeCtrl *tree)
457814b5 773{
5f939e78
VZ
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));
457814b5 782}