]> git.saurik.com Git - wxWidgets.git/blob - samples/treectrl/treetest.cpp
wxTreeCtrl::Delete() bug corrected, sample expanded to test it
[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 // under Windows the icons are in the .rc file
29 #ifndef __WXMSW__
30 #include "icon1.xpm"
31 #include "icon2.xpm"
32 #include "mondrian.xpm"
33 #endif
34
35 #include "wx/log.h"
36
37 #include "wx/imaglist.h"
38 #include "wx/treectrl.h"
39
40 #include "treetest.h"
41
42 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
43 EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
44 EVT_MENU(TreeTest_About, MyFrame::OnAbout)
45 EVT_MENU(TreeTest_Dump, MyFrame::OnDump)
46 EVT_MENU(TreeTest_Delete, MyFrame::OnDelete)
47 EVT_MENU(TreeTest_DeleteAll, MyFrame::OnDeleteAll)
48 EVT_MENU(TreeTest_Recreate, MyFrame::OnRecreate)
49 END_EVENT_TABLE()
50
51 BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
52 EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginDrag)
53 EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginRDrag)
54 EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnBeginLabelEdit)
55 EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnEndLabelEdit)
56 EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, MyTreeCtrl::OnDeleteItem)
57 EVT_TREE_GET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnGetInfo)
58 EVT_TREE_SET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnSetInfo)
59 EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanded)
60 EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanding)
61 EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsed)
62 EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsing)
63 EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, MyTreeCtrl::OnSelChanged)
64 EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, MyTreeCtrl::OnSelChanging)
65 EVT_CHAR(MyTreeCtrl::OnKeyDown)
66 END_EVENT_TABLE()
67
68 IMPLEMENT_APP(MyApp)
69
70 // `Main program' equivalent, creating windows and returning main app frame
71 bool MyApp::OnInit()
72 {
73 // Create the main frame window
74 MyFrame *frame = new MyFrame("wxTreeCtrl Test", 50, 50, 450, 340);
75
76 // Show the frame
77 frame->Show(TRUE);
78 SetTopWindow(frame);
79
80 return TRUE;
81 }
82
83
84 // My frame constructor
85 MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
86 : wxFrame((wxFrame *)NULL, -1, title, wxPoint(x, y), wxSize(w, h))
87 {
88 // This reduces flicker effects - even better would be to define
89 // OnEraseBackground to do nothing. When the tree control's scrollbars are
90 // show or hidden, the frame is sent a background erase event.
91 SetBackgroundColour(wxColour(255, 255, 255));
92
93 // Give it an icon
94 SetIcon(wxICON(mondrian));
95
96 // Make a menubar
97 wxMenu *file_menu = new wxMenu;
98
99 file_menu->Append(TreeTest_Dump, "D&ump tree items");
100 file_menu->Append(TreeTest_Delete, "&Delete this item");
101 file_menu->Append(TreeTest_DeleteAll, "Delete &all items");
102 file_menu->Append(TreeTest_Recreate, "&Recreate the tree");
103 file_menu->AppendSeparator();
104 file_menu->Append(TreeTest_About, "&About...");
105 file_menu->AppendSeparator();
106 file_menu->Append(TreeTest_Quit, "E&xit");
107
108 wxMenuBar *menu_bar = new wxMenuBar;
109 menu_bar->Append(file_menu, "&File");
110 SetMenuBar(menu_bar);
111
112 // Make a panel with a message
113 m_treeCtrl = new MyTreeCtrl(this, TreeTest_Ctrl,
114 wxDefaultPosition, wxDefaultSize,
115 wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
116 wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "",
117 wxDefaultPosition, wxDefaultSize,
118 wxTE_MULTILINE | wxSUNKEN_BORDER);
119
120 wxLayoutConstraints *c = new wxLayoutConstraints;
121 c->top.SameAs(this, wxTop);
122 c->left.SameAs(this, wxLeft);
123 c->right.SameAs(this, wxRight);
124 c->height.PercentOf(this, wxHeight, 66);
125 m_treeCtrl->SetConstraints(c);
126
127 c = new wxLayoutConstraints;
128 c->top.Below(m_treeCtrl);
129 c->left.SameAs(this, wxLeft);
130 c->right.SameAs(this, wxRight);
131 c->bottom.SameAs(this, wxBottom);
132 textCtrl->SetConstraints(c);
133 SetAutoLayout(TRUE);
134
135 // create a status bar with 3 panes
136 CreateStatusBar(3);
137 SetStatusText("", 0);
138
139 // set our text control as the log target
140 wxLogTextCtrl *logWindow = new wxLogTextCtrl(textCtrl);
141 delete wxLog::SetActiveTarget(logWindow);
142 }
143
144 MyFrame::~MyFrame()
145 {
146 delete wxLog::SetActiveTarget(NULL);
147 }
148
149 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
150 {
151 Close(TRUE);
152 }
153
154 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
155 {
156 wxMessageDialog dialog(this,
157 "Tree test sample\n"
158 "Julian Smart (c) 1997",
159 "About tree test", wxOK);
160
161 dialog.ShowModal();
162 }
163
164 void MyFrame::OnDump(wxCommandEvent& WXUNUSED(event))
165 {
166 wxTreeItemId root = m_treeCtrl->GetSelection();
167 m_treeCtrl->GetItemsRecursively(root, -1);
168 }
169
170 void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
171 {
172 wxTreeItemId item = m_treeCtrl->GetSelection();
173 m_treeCtrl->Delete(item);
174 }
175
176 void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event))
177 {
178 m_treeCtrl->DeleteAllItems();
179 }
180
181 void MyFrame::OnRecreate(wxCommandEvent& event)
182 {
183 OnDeleteAll(event);
184 m_treeCtrl->AddTestItemsToTree(3, 2);
185 }
186
187 // MyTreeCtrl implementation
188 MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
189 const wxPoint& pos, const wxSize& size,
190 long style)
191 : wxTreeCtrl(parent, id, pos, size, style)
192 {
193 // Make an image list containing small icons
194 m_imageListNormal = new wxImageList(16, 16, TRUE);
195
196 // should correspond to TreeCtrlIcon_xxx enum
197 m_imageListNormal->Add(wxICON(icon2));
198 m_imageListNormal->Add(wxICON(icon1));
199
200 SetImageList(m_imageListNormal);
201
202 // Add some items to the tree
203 AddTestItemsToTree(3, 2);
204 }
205
206 MyTreeCtrl::~MyTreeCtrl()
207 {
208 delete m_imageListNormal;
209 }
210
211 void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent,
212 size_t numChildren,
213 size_t depth,
214 size_t folder)
215 {
216 if ( depth > 0 )
217 {
218 wxString str;
219 for ( size_t n = 0; n < numChildren; n++ )
220 {
221 // at depth 1 elements won't have any more children
222 if (depth == 1)
223 str.Printf("%s child %d.%d", "File", folder, n + 1);
224 else
225 str.Printf("%s child %d","Folder", n + 1);
226
227 int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
228 wxTreeItemId id = AppendItem(idParent, str, image, image,
229 new MyTreeItemData(str));
230 AddItemsRecursively(id, numChildren, depth - 1,n+1);
231 }
232 }
233 //else: done!
234 }
235
236 void MyTreeCtrl::AddTestItemsToTree(size_t numChildren,
237 size_t depth)
238 {
239 wxTreeItemId rootId = AddRoot("Root",
240 TreeCtrlIcon_Folder, TreeCtrlIcon_Folder,
241 new MyTreeItemData("Root item"));
242
243 AddItemsRecursively(rootId, numChildren, depth,0);
244 }
245
246 void MyTreeCtrl::GetItemsRecursively(const wxTreeItemId& idParent, long cookie)
247 {
248 wxTreeItemId id;
249
250 if( cookie == -1 )
251 id = GetFirstChild(idParent, cookie);
252 else
253 id = GetNextChild(idParent, cookie);
254
255 if(id <= 0)
256 return;
257
258 wxString text=GetItemText(id);
259 wxLogMessage(text);
260
261 if (ItemHasChildren(id))
262 GetItemsRecursively(id,-1);
263
264 GetItemsRecursively(idParent, cookie);
265 }
266
267
268 // avoid repetition
269 #define TREE_EVENT_HANDLER(name) \
270 void MyTreeCtrl::name(wxTreeEvent& WXUNUSED(event)) \
271 { \
272 wxLogMessage(#name); \
273 }
274
275 TREE_EVENT_HANDLER(OnBeginDrag)
276 TREE_EVENT_HANDLER(OnBeginRDrag)
277 TREE_EVENT_HANDLER(OnBeginLabelEdit)
278 TREE_EVENT_HANDLER(OnEndLabelEdit)
279 TREE_EVENT_HANDLER(OnDeleteItem)
280 TREE_EVENT_HANDLER(OnGetInfo)
281 TREE_EVENT_HANDLER(OnSetInfo)
282 TREE_EVENT_HANDLER(OnItemExpanded)
283 TREE_EVENT_HANDLER(OnItemExpanding)
284 TREE_EVENT_HANDLER(OnItemCollapsed)
285 TREE_EVENT_HANDLER(OnSelChanged)
286 TREE_EVENT_HANDLER(OnSelChanging)
287
288 #undef TREE_EVENT_HANDLER
289
290 void MyTreeCtrl::OnItemCollapsing(wxTreeEvent& event)
291 {
292 wxLogMessage("OnItemCollapsing");
293
294 // for testing, prevent the user from collapsing the root item
295 wxTreeItemId itemId = event.GetItem();
296 if ( !GetParent(itemId).IsOk() )
297 {
298 wxMessageBox("You can't collapse the root item.");
299
300 event.Veto();
301 }
302 }
303
304 void MyTreeCtrl::OnKeyDown(wxTreeEvent& WXUNUSED(event))
305 {
306 // show some info about this item
307 wxTreeItemId itemId = GetSelection();
308 MyTreeItemData *item = (MyTreeItemData *)GetItemData(itemId);
309
310 if ( item != NULL )
311 {
312 item->ShowInfo(this);
313 }
314
315 wxLogMessage("OnKeyDown");
316 }
317
318 static inline const char *Bool2String(bool b)
319 {
320 return b ? "" : "not ";
321 }
322
323 void MyTreeItemData::ShowInfo(wxTreeCtrl *tree)
324 {
325 wxLogMessage("Item '%s': %sselected, %sexpanded, "
326 "%u children (%u immediately under this item).",
327 m_desc.c_str(),
328 Bool2String(tree->IsSelected(GetId())),
329 Bool2String(tree->IsExpanded(GetId())),
330 tree->GetChildrenCount(GetId()),
331 tree->GetChildrenCount(GetId(), FALSE));
332 }