]>
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"
28 #include "wx/treelay.h"
35 IMPLEMENT_ABSTRACT_CLASS(wxTreeLayout
, wxObject
)
37 wxTreeLayout::wxTreeLayout()
43 m_orientation
= FALSE
;
47 void wxTreeLayout::DoLayout(wxDC
& dc
, long topId
)
52 long actualTopId
= GetTopNode();
53 long id
= actualTopId
;
58 ActivateNode(id
, FALSE
);
61 m_lastY
= m_topMargin
;
62 m_lastX
= m_leftMargin
;
63 CalcLayout(actualTopId
, 0, dc
);
66 void wxTreeLayout::Draw(wxDC
& dc
)
73 void wxTreeLayout::DrawNodes(wxDC
& dc
)
75 long id
= GetTopNode();
84 void wxTreeLayout::DrawBranches(wxDC
& dc
)
86 long id
= GetTopNode();
89 if (GetNodeParent(id
) > -1)
91 long parent
= GetNodeParent(id
);
92 if (NodeActive(parent
))
93 DrawBranch(parent
, id
, dc
);
99 void wxTreeLayout::DrawNode(long id
, wxDC
& dc
)
102 wxString
name(GetNodeName(id
));
104 wxSprintf(buf
, wxT("%s"), (const wxChar
*) name
);
106 wxSprintf(buf
, wxT("<unnamed>"));
110 dc
.GetTextExtent(buf
, &x
, &y
);
111 dc
.DrawText(buf
, GetNodeX(id
), (long)(GetNodeY(id
) - (y
/2.0)));
114 void wxTreeLayout::DrawBranch(long from
, long to
, wxDC
& dc
)
117 GetNodeSize(from
, &w
, &h
, dc
);
118 dc
.DrawLine(GetNodeX(from
)+w
, GetNodeY(from
),
119 GetNodeX(to
), GetNodeY(to
));
122 void wxTreeLayout::Initialize(void)
126 void wxTreeLayout::GetNodeSize(long id
, long *x
, long *y
, wxDC
& dc
)
128 wxString
name(GetNodeName(id
));
130 dc
.GetTextExtent(name
, x
, y
);
137 void wxTreeLayout::CalcLayout(long nodeId
, int level
, wxDC
& dc
)
140 GetChildren(nodeId
, children
);
141 int n
= children
.Number();
143 if (m_orientation
== FALSE
)
148 SetNodeX(nodeId
, m_leftMargin
);
153 long parentId
= GetNodeParent(nodeId
);
155 GetNodeSize(parentId
, &x
, &y
, dc
);
156 SetNodeX(nodeId
, (long)(GetNodeX(parentId
) + m_xSpacing
+ x
));
159 wxNode
*node
= children
.First();
162 CalcLayout((long)node
->Data(), level
+1, dc
);
168 ActivateNode(nodeId
, TRUE
);
173 node
= children
.First();
176 averageY
+= GetNodeY((long)node
->Data());
179 averageY
= averageY
/ n
;
180 SetNodeY(nodeId
, averageY
);
184 SetNodeY(nodeId
, m_lastY
);
186 GetNodeSize(nodeId
, &x
, &y
, dc
);
188 m_lastY
= m_lastY
+ y
+ m_ySpacing
;
197 SetNodeY(nodeId
, m_topMargin
);
202 long parentId
= GetNodeParent(nodeId
);
204 GetNodeSize(parentId
, &x
, &y
, dc
);
205 SetNodeY(nodeId
, (long)(GetNodeY(parentId
) + m_ySpacing
+ y
));
208 wxNode
*node
= children
.First();
211 CalcLayout((long)node
->Data(), level
+1, dc
);
217 ActivateNode(nodeId
, TRUE
);
222 node
= children
.First();
225 averageX
+= GetNodeX((long)node
->Data());
228 averageX
= averageX
/ n
;
229 SetNodeX(nodeId
, averageX
);
233 SetNodeX(nodeId
, m_lastX
);
235 GetNodeSize(nodeId
, &x
, &y
, dc
);
237 m_lastX
= m_lastX
+ x
+ m_xSpacing
;
247 IMPLEMENT_DYNAMIC_CLASS(wxTreeLayoutStored
, wxTreeLayout
)
249 wxTreeLayoutStored::wxTreeLayoutStored(int n
):wxTreeLayout()
256 wxTreeLayoutStored::~wxTreeLayoutStored(void)
262 void wxTreeLayoutStored::Initialize(int n
)
265 wxTreeLayout::Initialize();
266 if (m_nodes
) delete[] m_nodes
;
267 m_nodes
= new wxStoredNode
[m_maxNodes
];
269 for (i
= 0; i
< n
; i
++)
271 m_nodes
[i
].m_name
= "";
272 m_nodes
[i
].m_active
= FALSE
;
273 m_nodes
[i
].m_parentId
= -1;
280 long wxTreeLayoutStored::AddChild(const wxString
& name
, const wxString
& parent
)
282 if (m_num
< (m_maxNodes
-1 ))
285 if (parent
!= wxT(""))
286 i
= NameToId(parent
);
287 else m_parentNode
= m_num
;
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;
301 long wxTreeLayoutStored::NameToId(const wxString
& name
)
304 for (i
= 0; i
< m_num
; i
++)
305 if (name
== m_nodes
[i
].m_name
)
310 void wxTreeLayoutStored::GetChildren(long id
, wxList
& list
)
312 long currentId
= GetTopNode();
313 while (currentId
!= -1)
315 if (id
== GetNodeParent(currentId
))
316 list
.Append((wxObject
*)currentId
);
317 currentId
= GetNextNode(currentId
);
321 wxStoredNode
* wxTreeLayoutStored::GetNode(long idx
) const
323 wxASSERT(idx
< m_num
);
325 return &m_nodes
[idx
];
328 long wxTreeLayoutStored::GetNodeX(long id
)
330 wxASSERT(id
< m_num
);
332 return (long)m_nodes
[id
].m_x
;
335 long wxTreeLayoutStored::GetNodeY(long id
)
337 wxASSERT(id
< m_num
);
339 return (long)m_nodes
[id
].m_y
;
342 void wxTreeLayoutStored::SetNodeX(long id
, long x
)
344 wxASSERT(id
< m_num
);
346 m_nodes
[id
].m_x
= (int)x
;
349 void wxTreeLayoutStored::SetNodeY(long id
, long y
)
351 wxASSERT(id
< m_num
);
353 m_nodes
[id
].m_y
= (int)y
;
356 void wxTreeLayoutStored::SetNodeName(long id
, const wxString
& name
)
358 wxASSERT(id
< m_num
);
360 m_nodes
[id
].m_name
= name
;
363 wxString
wxTreeLayoutStored::GetNodeName(long id
)
365 wxASSERT(id
< m_num
);
367 return m_nodes
[id
].m_name
;
370 long wxTreeLayoutStored::GetNodeParent(long id
)
374 wxASSERT(id
< m_num
);
376 return m_nodes
[id
].m_parentId
;
382 long wxTreeLayoutStored::GetNextNode(long id
)
384 wxASSERT(id
< m_num
);
386 if ((id
!= -1) && (id
< (m_num
- 1)))
392 void wxTreeLayoutStored::SetClientData(long id
, long clientData
)
394 wxASSERT(id
< m_num
);
396 m_nodes
[id
].m_clientData
= clientData
;
399 long wxTreeLayoutStored::GetClientData(long id
) const
401 wxASSERT(id
< m_num
);
403 return m_nodes
[id
].m_clientData
;
406 void wxTreeLayoutStored::ActivateNode(long id
, bool active
)
408 wxASSERT(id
< m_num
);
410 m_nodes
[id
].m_active
= active
;
413 bool wxTreeLayoutStored::NodeActive(long id
)
415 wxASSERT(id
< m_num
);
417 return m_nodes
[id
].m_active
;
420 wxString
wxTreeLayoutStored::HitTest(wxMouseEvent
& event
, wxDC
& dc
)
422 wxPoint pt
= event
.GetPosition();
427 for (i
= 0; i
< m_maxNodes
; i
++)
430 dc
.GetTextExtent(m_nodes
[i
].m_name
, &width
, &height
);
432 if ( (x
>= (m_nodes
[i
].m_x
-10)) && (x
< (m_nodes
[i
].m_x
+ width
+10)) &&
433 (y
>= m_nodes
[i
].m_y
-10) && (y
< (m_nodes
[i
].m_y
+ height
+10)) )
435 return m_nodes
[i
].m_name
;