]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/deprecated/treelay.cpp
Include wx/stattext.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / contrib / src / deprecated / treelay.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: treelay.h
3 // Purpose: wxTreeLayout class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 7/4/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/dc.h"
21 #include "wx/event.h"
22 #endif
23
24 #include "wx/deprecated/setup.h"
25
26 #if wxUSE_TREELAYOUT
27
28 #include "wx/deprecated/treelay.h"
29
30 /*
31 * Abstract tree
32 *
33 */
34
35 IMPLEMENT_ABSTRACT_CLASS(wxTreeLayout, wxObject)
36
37 wxTreeLayout::wxTreeLayout()
38 {
39 m_xSpacing = 16;
40 m_ySpacing = 20;
41 m_topMargin = 5;
42 m_leftMargin = 5;
43 m_orientation = false;
44 m_parentNode = 0;
45 }
46
47 void wxTreeLayout::DoLayout(wxDC& dc, long topId)
48 {
49 if (topId != wxID_ANY)
50 SetTopNode(topId);
51
52 long actualTopId = GetTopNode();
53 long id = actualTopId;
54 while (id != wxID_ANY)
55 {
56 SetNodeX(id, 0);
57 SetNodeY(id, 0);
58 ActivateNode(id, false);
59 id = GetNextNode(id);
60 }
61 m_lastY = m_topMargin;
62 m_lastX = m_leftMargin;
63 CalcLayout(actualTopId, 0, dc);
64 }
65
66 void wxTreeLayout::Draw(wxDC& dc)
67 {
68 dc.Clear();
69 DrawBranches(dc);
70 DrawNodes(dc);
71 }
72
73 void wxTreeLayout::DrawNodes(wxDC& dc)
74 {
75 long id = GetTopNode();
76 while (id != wxID_ANY)
77 {
78 if (NodeActive(id))
79 DrawNode(id, dc);
80 id = GetNextNode(id);
81 }
82 }
83
84 void wxTreeLayout::DrawBranches(wxDC& dc)
85 {
86 long id = GetTopNode();
87 while (id != wxID_ANY)
88 {
89 if (GetNodeParent(id) != wxID_ANY)
90 {
91 long parent = GetNodeParent(id);
92 if (NodeActive(parent))
93 DrawBranch(parent, id, dc);
94 }
95 id = GetNextNode(id);
96 }
97 }
98
99 void wxTreeLayout::DrawNode(long id, wxDC& dc)
100 {
101 wxChar buf[80];
102 wxString name(GetNodeName(id));
103 if (name != wxT(""))
104 wxSprintf(buf, wxT("%s"), (const wxChar*) name);
105 else
106 wxSprintf(buf, wxT("<unnamed>"));
107
108 long x = 80;
109 long y = 20;
110 dc.GetTextExtent(buf, &x, &y);
111 dc.DrawText(buf, GetNodeX(id), (long)(GetNodeY(id) - (y/2.0)));
112 }
113
114 void wxTreeLayout::DrawBranch(long from, long to, wxDC& dc)
115 {
116 long w, h;
117 GetNodeSize(from, &w, &h, dc);
118 dc.DrawLine(GetNodeX(from)+w, GetNodeY(from),
119 GetNodeX(to), GetNodeY(to));
120 }
121
122 void wxTreeLayout::Initialize(void)
123 {
124 }
125
126 void wxTreeLayout::GetNodeSize(long id, long *x, long *y, wxDC& dc)
127 {
128 wxString name(GetNodeName(id));
129 if (name != wxT(""))
130 dc.GetTextExtent(name, x, y);
131 else
132 {
133 *x = 70; *y = 20;
134 }
135 }
136
137 void wxTreeLayout::CalcLayout(long nodeId, int level, wxDC& dc)
138 {
139 wxList children;
140 GetChildren(nodeId, children);
141 int n = children.GetCount();
142
143 if (m_orientation == false)
144 {
145 // Left to right
146 // X Calculations
147 if (level == 0)
148 SetNodeX(nodeId, m_leftMargin);
149 else
150 {
151 long x = 0;
152 long y = 0;
153 long parentId = GetNodeParent(nodeId);
154 if (parentId != wxID_ANY)
155 GetNodeSize(parentId, &x, &y, dc);
156 SetNodeX(nodeId, (long)(GetNodeX(parentId) + m_xSpacing + x));
157 }
158
159 wxList::compatibility_iterator node = children.GetFirst();
160 while (node)
161 {
162 CalcLayout((long)node->GetData(), level+1, dc);
163 node = node->GetNext();
164 }
165
166 // Y Calculations
167 long averageY;
168 ActivateNode(nodeId, true);
169
170 if (n > 0)
171 {
172 averageY = 0;
173 node = children.GetFirst();
174 while (node)
175 {
176 averageY += GetNodeY((long)node->GetData());
177 node = node->GetNext();
178 }
179 averageY = averageY / n;
180 SetNodeY(nodeId, averageY);
181 }
182 else
183 {
184 SetNodeY(nodeId, m_lastY);
185 long x, y;
186 GetNodeSize(nodeId, &x, &y, dc);
187
188 m_lastY = m_lastY + y + m_ySpacing;
189 }
190 }
191 else
192 {
193 // Top to bottom
194
195 // Y Calculations
196 if (level == 0)
197 SetNodeY(nodeId, m_topMargin);
198 else
199 {
200 long x = 0;
201 long y = 0;
202 long parentId = GetNodeParent(nodeId);
203 if (parentId != wxID_ANY)
204 GetNodeSize(parentId, &x, &y, dc);
205 SetNodeY(nodeId, (long)(GetNodeY(parentId) + m_ySpacing + y));
206 }
207
208 wxList::compatibility_iterator node = children.GetFirst();
209 while (node)
210 {
211 CalcLayout((long)node->GetData(), level+1, dc);
212 node = node->GetNext();
213 }
214
215 // X Calculations
216 long averageX;
217 ActivateNode(nodeId, true);
218
219 if (n > 0)
220 {
221 averageX = 0;
222 node = children.GetFirst();
223 while (node)
224 {
225 averageX += GetNodeX((long)node->GetData());
226 node = node->GetNext();
227 }
228 averageX = averageX / n;
229 SetNodeX(nodeId, averageX);
230 }
231 else
232 {
233 SetNodeX(nodeId, m_lastX);
234 long x, y;
235 GetNodeSize(nodeId, &x, &y, dc);
236
237 m_lastX = m_lastX + x + m_xSpacing;
238 }
239 }
240 }
241
242 /*
243 * Tree with storage
244 *
245 */
246
247 IMPLEMENT_DYNAMIC_CLASS(wxTreeLayoutStored, wxTreeLayout)
248
249 wxTreeLayoutStored::wxTreeLayoutStored(int n):wxTreeLayout()
250 {
251 m_nodes = NULL;
252 m_maxNodes = 0;
253 Initialize(n);
254 }
255
256 wxTreeLayoutStored::~wxTreeLayoutStored(void)
257 {
258 if (m_nodes)
259 delete[] m_nodes;
260 }
261
262 void wxTreeLayoutStored::Initialize(int n)
263 {
264 m_maxNodes = n;
265 wxTreeLayout::Initialize();
266 if (m_nodes) delete[] m_nodes;
267 m_nodes = new wxStoredNode[m_maxNodes];
268 int i;
269 for (i = 0; i < n; i++)
270 {
271 m_nodes[i].m_name = wxT("");
272 m_nodes[i].m_active = false;
273 m_nodes[i].m_parentId = wxID_ANY;
274 m_nodes[i].m_x = 0;
275 m_nodes[i].m_y = 0;
276 }
277 m_num = 0;
278 }
279
280 long wxTreeLayoutStored::AddChild(const wxString& name, const wxString& parent)
281 {
282 if (m_num < (m_maxNodes -1 ))
283 {
284 long i = -1;
285 if (parent != wxT(""))
286 i = NameToId(parent);
287 else m_parentNode = m_num;
288
289 m_nodes[m_num].m_parentId = i;
290 m_nodes[m_num].m_name = name;
291 m_nodes[m_num].m_x = m_nodes[m_num].m_y = 0;
292 m_nodes[m_num].m_clientData = 0;
293 m_num ++;
294
295 return (m_num - 1);
296 }
297 else
298 return -1;
299 }
300
301 long wxTreeLayoutStored::AddChild(const wxString& name, long parent)
302 {
303 if (m_num < (m_maxNodes -1 ) && parent < m_num)
304 {
305 long i = -1;
306 if (parent != -1)
307 {
308 i = parent;
309 }
310 else
311 {
312 m_parentNode = m_num;
313 }
314
315 m_nodes[m_num].m_parentId = i;
316 m_nodes[m_num].m_name = name;
317 m_nodes[m_num].m_x = m_nodes[m_num].m_y = 0;
318 m_nodes[m_num].m_clientData = 0;
319 m_num ++;
320
321 return (m_num - 1);
322 }
323 else
324 return -1;
325 }
326
327 long wxTreeLayoutStored::NameToId(const wxString& name)
328 {
329 long i;
330 for (i = 0; i < m_num; i++)
331 if (name == m_nodes[i].m_name)
332 return i;
333 return -1;
334 }
335
336 void wxTreeLayoutStored::GetChildren(long id, wxList& list)
337 {
338 long currentId = GetTopNode();
339 while (currentId != wxID_ANY)
340 {
341 if (id == GetNodeParent(currentId))
342 list.Append((wxObject *)currentId);
343 currentId = GetNextNode(currentId);
344 }
345 }
346
347 wxStoredNode* wxTreeLayoutStored::GetNode(long idx) const
348 {
349 wxASSERT(idx < m_num);
350
351 return &m_nodes[idx];
352 };
353
354 long wxTreeLayoutStored::GetNodeX(long id)
355 {
356 wxASSERT(id < m_num);
357
358 return (long)m_nodes[id].m_x;
359 }
360
361 long wxTreeLayoutStored::GetNodeY(long id)
362 {
363 wxASSERT(id < m_num);
364
365 return (long)m_nodes[id].m_y;
366 }
367
368 void wxTreeLayoutStored::SetNodeX(long id, long x)
369 {
370 wxASSERT(id < m_num);
371
372 m_nodes[id].m_x = (int)x;
373 }
374
375 void wxTreeLayoutStored::SetNodeY(long id, long y)
376 {
377 wxASSERT(id < m_num);
378
379 m_nodes[id].m_y = (int)y;
380 }
381
382 void wxTreeLayoutStored::SetNodeName(long id, const wxString& name)
383 {
384 wxASSERT(id < m_num);
385
386 m_nodes[id].m_name = name;
387 }
388
389 wxString wxTreeLayoutStored::GetNodeName(long id)
390 {
391 wxASSERT(id < m_num);
392
393 return m_nodes[id].m_name;
394 }
395
396 long wxTreeLayoutStored::GetNodeParent(long id)
397 {
398 if (id != wxID_ANY)
399 {
400 wxASSERT(id < m_num);
401
402 return m_nodes[id].m_parentId;
403 }
404 else
405 return wxNOT_FOUND;
406 }
407
408 long wxTreeLayoutStored::GetNextNode(long id)
409 {
410 wxASSERT(id < m_num);
411
412 if ((id != wxID_ANY) && (id < (m_num - 1)))
413 return id + 1;
414 else
415 return wxNOT_FOUND;
416 }
417
418 void wxTreeLayoutStored::SetClientData(long id, long clientData)
419 {
420 wxASSERT(id < m_num);
421
422 m_nodes[id].m_clientData = clientData;
423 }
424
425 long wxTreeLayoutStored::GetClientData(long id) const
426 {
427 wxASSERT(id < m_num);
428
429 return m_nodes[id].m_clientData;
430 }
431
432 void wxTreeLayoutStored::ActivateNode(long id, bool active)
433 {
434 wxASSERT(id < m_num);
435
436 m_nodes[id].m_active = active;
437 }
438
439 bool wxTreeLayoutStored::NodeActive(long id)
440 {
441 wxASSERT(id < m_num);
442
443 return m_nodes[id].m_active;
444 }
445
446 wxString wxTreeLayoutStored::HitTest(wxMouseEvent& event, wxDC& dc)
447 {
448 wxPoint pt = event.GetPosition();
449 wxCoord x = pt.x;
450 wxCoord y = pt.y;
451
452 int i;
453 for (i = 0; i < m_maxNodes; i++)
454 {
455 long width, height;
456 dc.GetTextExtent(m_nodes[i].m_name, &width, &height);
457
458 if ( (x >= (m_nodes[i].m_x-10)) && (x < (m_nodes[i].m_x + width+10)) &&
459 (y >= m_nodes[i].m_y-10) && (y < (m_nodes[i].m_y + height+10)) )
460 {
461 return m_nodes[i].m_name;
462 }
463 }
464
465 return wxString( wxT("") );
466 }
467
468 #endif
469 // wxUSE_TREELAYOUT