]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/treelay.cpp
1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTreeLayout class
4 // Author: Julian Smart
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "wxtree.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
30 #include "wx/treelay.h"
37 IMPLEMENT_ABSTRACT_CLASS(wxTreeLayout
, wxObject
)
39 wxTreeLayout::wxTreeLayout()
45 m_orientation
= FALSE
;
49 void wxTreeLayout::DoLayout(wxDC
& dc
, long topId
)
54 long actualTopId
= GetTopNode();
55 long id
= actualTopId
;
60 ActivateNode(id
, FALSE
);
63 m_lastY
= m_topMargin
;
64 m_lastX
= m_leftMargin
;
65 CalcLayout(actualTopId
, 0, dc
);
68 void wxTreeLayout::Draw(wxDC
& dc
)
75 void wxTreeLayout::DrawNodes(wxDC
& dc
)
77 long id
= GetTopNode();
86 void wxTreeLayout::DrawBranches(wxDC
& dc
)
88 long id
= GetTopNode();
91 if (GetNodeParent(id
) > -1)
93 long parent
= GetNodeParent(id
);
94 if (NodeActive(parent
))
95 DrawBranch(parent
, id
, dc
);
101 void wxTreeLayout::DrawNode(long id
, wxDC
& dc
)
104 wxString
name(GetNodeName(id
));
106 wxSprintf(buf
, wxT("%s"), (const wxChar
*) name
);
108 wxSprintf(buf
, wxT("<unnamed>"));
112 dc
.GetTextExtent(buf
, &x
, &y
);
113 dc
.DrawText(buf
, GetNodeX(id
), (long)(GetNodeY(id
) - (y
/2.0)));
116 void wxTreeLayout::DrawBranch(long from
, long to
, wxDC
& dc
)
119 GetNodeSize(from
, &w
, &h
, dc
);
120 dc
.DrawLine(GetNodeX(from
)+w
, GetNodeY(from
),
121 GetNodeX(to
), GetNodeY(to
));
124 void wxTreeLayout::Initialize(void)
128 void wxTreeLayout::GetNodeSize(long id
, long *x
, long *y
, wxDC
& dc
)
130 wxString
name(GetNodeName(id
));
132 dc
.GetTextExtent(name
, x
, y
);
139 void wxTreeLayout::CalcLayout(long nodeId
, int level
, wxDC
& dc
)
142 GetChildren(nodeId
, children
);
143 int n
= children
.Number();
145 if (m_orientation
== FALSE
)
150 SetNodeX(nodeId
, m_leftMargin
);
155 long parentId
= GetNodeParent(nodeId
);
157 GetNodeSize(parentId
, &x
, &y
, dc
);
158 SetNodeX(nodeId
, (long)(GetNodeX(parentId
) + m_xSpacing
+ x
));
161 wxNode
*node
= children
.First();
164 CalcLayout((long)node
->Data(), level
+1, dc
);
170 ActivateNode(nodeId
, TRUE
);
175 node
= children
.First();
178 averageY
+= GetNodeY((long)node
->Data());
181 averageY
= averageY
/ n
;
182 SetNodeY(nodeId
, averageY
);
186 SetNodeY(nodeId
, m_lastY
);
188 GetNodeSize(nodeId
, &x
, &y
, dc
);
190 m_lastY
= m_lastY
+ y
+ m_ySpacing
;
199 SetNodeY(nodeId
, m_topMargin
);
204 long parentId
= GetNodeParent(nodeId
);
206 GetNodeSize(parentId
, &x
, &y
, dc
);
207 SetNodeY(nodeId
, (long)(GetNodeY(parentId
) + m_ySpacing
+ y
));
210 wxNode
*node
= children
.First();
213 CalcLayout((long)node
->Data(), level
+1, dc
);
219 ActivateNode(nodeId
, TRUE
);
224 node
= children
.First();
227 averageX
+= GetNodeX((long)node
->Data());
230 averageX
= averageX
/ n
;
231 SetNodeX(nodeId
, averageX
);
235 SetNodeX(nodeId
, m_lastX
);
237 GetNodeSize(nodeId
, &x
, &y
, dc
);
239 m_lastX
= m_lastX
+ x
+ m_xSpacing
;
249 IMPLEMENT_DYNAMIC_CLASS(wxTreeLayoutStored
, wxTreeLayout
)
251 wxTreeLayoutStored::wxTreeLayoutStored(int n
):wxTreeLayout()
258 wxTreeLayoutStored::~wxTreeLayoutStored(void)
264 void wxTreeLayoutStored::Initialize(int n
)
267 wxTreeLayout::Initialize();
268 if (m_nodes
) delete[] m_nodes
;
269 m_nodes
= new wxStoredNode
[m_maxNodes
];
271 for (i
= 0; i
< n
; i
++)
273 m_nodes
[i
].m_name
= "";
274 m_nodes
[i
].m_active
= FALSE
;
275 m_nodes
[i
].m_parentId
= -1;
282 long wxTreeLayoutStored::AddChild(const wxString
& name
, const wxString
& parent
)
284 if (m_num
< (m_maxNodes
-1 ))
287 if (parent
!= wxT(""))
288 i
= NameToId(parent
);
289 else m_parentNode
= m_num
;
291 m_nodes
[m_num
].m_parentId
= i
;
292 m_nodes
[m_num
].m_name
= name
;
293 m_nodes
[m_num
].m_x
= m_nodes
[m_num
].m_y
= 0;
294 m_nodes
[m_num
].m_clientData
= 0;
303 long wxTreeLayoutStored::AddChild(const wxString
& name
, long parent
)
305 if (m_num
< (m_maxNodes
-1 ) && parent
< m_num
)
314 m_parentNode
= m_num
;
317 m_nodes
[m_num
].m_parentId
= i
;
318 m_nodes
[m_num
].m_name
= name
;
319 m_nodes
[m_num
].m_x
= m_nodes
[m_num
].m_y
= 0;
320 m_nodes
[m_num
].m_clientData
= 0;
329 long wxTreeLayoutStored::NameToId(const wxString
& name
)
332 for (i
= 0; i
< m_num
; i
++)
333 if (name
== m_nodes
[i
].m_name
)
338 void wxTreeLayoutStored::GetChildren(long id
, wxList
& list
)
340 long currentId
= GetTopNode();
341 while (currentId
!= -1)
343 if (id
== GetNodeParent(currentId
))
344 list
.Append((wxObject
*)currentId
);
345 currentId
= GetNextNode(currentId
);
349 wxStoredNode
* wxTreeLayoutStored::GetNode(long idx
) const
351 wxASSERT(idx
< m_num
);
353 return &m_nodes
[idx
];
356 long wxTreeLayoutStored::GetNodeX(long id
)
358 wxASSERT(id
< m_num
);
360 return (long)m_nodes
[id
].m_x
;
363 long wxTreeLayoutStored::GetNodeY(long id
)
365 wxASSERT(id
< m_num
);
367 return (long)m_nodes
[id
].m_y
;
370 void wxTreeLayoutStored::SetNodeX(long id
, long x
)
372 wxASSERT(id
< m_num
);
374 m_nodes
[id
].m_x
= (int)x
;
377 void wxTreeLayoutStored::SetNodeY(long id
, long y
)
379 wxASSERT(id
< m_num
);
381 m_nodes
[id
].m_y
= (int)y
;
384 void wxTreeLayoutStored::SetNodeName(long id
, const wxString
& name
)
386 wxASSERT(id
< m_num
);
388 m_nodes
[id
].m_name
= name
;
391 wxString
wxTreeLayoutStored::GetNodeName(long id
)
393 wxASSERT(id
< m_num
);
395 return m_nodes
[id
].m_name
;
398 long wxTreeLayoutStored::GetNodeParent(long id
)
402 wxASSERT(id
< m_num
);
404 return m_nodes
[id
].m_parentId
;
410 long wxTreeLayoutStored::GetNextNode(long id
)
412 wxASSERT(id
< m_num
);
414 if ((id
!= -1) && (id
< (m_num
- 1)))
420 void wxTreeLayoutStored::SetClientData(long id
, long clientData
)
422 wxASSERT(id
< m_num
);
424 m_nodes
[id
].m_clientData
= clientData
;
427 long wxTreeLayoutStored::GetClientData(long id
) const
429 wxASSERT(id
< m_num
);
431 return m_nodes
[id
].m_clientData
;
434 void wxTreeLayoutStored::ActivateNode(long id
, bool active
)
436 wxASSERT(id
< m_num
);
438 m_nodes
[id
].m_active
= active
;
441 bool wxTreeLayoutStored::NodeActive(long id
)
443 wxASSERT(id
< m_num
);
445 return m_nodes
[id
].m_active
;
448 wxString
wxTreeLayoutStored::HitTest(wxMouseEvent
& event
, wxDC
& dc
)
450 wxPoint pt
= event
.GetPosition();
455 for (i
= 0; i
< m_maxNodes
; i
++)
458 dc
.GetTextExtent(m_nodes
[i
].m_name
, &width
, &height
);
460 if ( (x
>= (m_nodes
[i
].m_x
-10)) && (x
< (m_nodes
[i
].m_x
+ width
+10)) &&
461 (y
>= m_nodes
[i
].m_y
-10) && (y
< (m_nodes
[i
].m_y
+ height
+10)) )
463 return m_nodes
[i
].m_name
;