1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTreeLayout class
4 // Author: Julian Smart
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
24 #include "wx/deprecated/setup.h"
28 #include "wx/deprecated/treelay.h"
35 IMPLEMENT_ABSTRACT_CLASS(wxTreeLayout
, wxObject
)
37 wxTreeLayout::wxTreeLayout()
43 m_orientation
= false;
47 void wxTreeLayout::DoLayout(wxDC
& dc
, long topId
)
49 if (topId
!= wxID_ANY
)
52 long actualTopId
= GetTopNode();
53 long id
= actualTopId
;
54 while (id
!= wxID_ANY
)
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();
76 while (id
!= wxID_ANY
)
84 void wxTreeLayout::DrawBranches(wxDC
& dc
)
86 long id
= GetTopNode();
87 while (id
!= wxID_ANY
)
89 if (GetNodeParent(id
) != wxID_ANY
)
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
.GetCount();
143 if (m_orientation
== false)
148 SetNodeX(nodeId
, m_leftMargin
);
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
));
159 wxList::compatibility_iterator node
= children
.GetFirst();
162 CalcLayout((long)node
->GetData(), level
+1, dc
);
163 node
= node
->GetNext();
168 ActivateNode(nodeId
, true);
173 node
= children
.GetFirst();
176 averageY
+= GetNodeY((long)node
->GetData());
177 node
= node
->GetNext();
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
);
203 if (parentId
!= wxID_ANY
)
204 GetNodeSize(parentId
, &x
, &y
, dc
);
205 SetNodeY(nodeId
, (long)(GetNodeY(parentId
) + m_ySpacing
+ y
));
208 wxList::compatibility_iterator node
= children
.GetFirst();
211 CalcLayout((long)node
->GetData(), level
+1, dc
);
212 node
= node
->GetNext();
217 ActivateNode(nodeId
, true);
222 node
= children
.GetFirst();
225 averageX
+= GetNodeX((long)node
->GetData());
226 node
= node
->GetNext();
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
= wxT("");
272 m_nodes
[i
].m_active
= false;
273 m_nodes
[i
].m_parentId
= wxID_ANY
;
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::AddChild(const wxString
& name
, long parent
)
303 if (m_num
< (m_maxNodes
-1 ) && parent
< m_num
)
312 m_parentNode
= m_num
;
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;
327 long wxTreeLayoutStored::NameToId(const wxString
& name
)
330 for (i
= 0; i
< m_num
; i
++)
331 if (name
== m_nodes
[i
].m_name
)
336 void wxTreeLayoutStored::GetChildren(long id
, wxList
& list
)
338 long currentId
= GetTopNode();
339 while (currentId
!= wxID_ANY
)
341 if (id
== GetNodeParent(currentId
))
342 list
.Append((wxObject
*)currentId
);
343 currentId
= GetNextNode(currentId
);
347 wxStoredNode
* wxTreeLayoutStored::GetNode(long idx
) const
349 wxASSERT(idx
< m_num
);
351 return &m_nodes
[idx
];
354 long wxTreeLayoutStored::GetNodeX(long id
)
356 wxASSERT(id
< m_num
);
358 return (long)m_nodes
[id
].m_x
;
361 long wxTreeLayoutStored::GetNodeY(long id
)
363 wxASSERT(id
< m_num
);
365 return (long)m_nodes
[id
].m_y
;
368 void wxTreeLayoutStored::SetNodeX(long id
, long x
)
370 wxASSERT(id
< m_num
);
372 m_nodes
[id
].m_x
= (int)x
;
375 void wxTreeLayoutStored::SetNodeY(long id
, long y
)
377 wxASSERT(id
< m_num
);
379 m_nodes
[id
].m_y
= (int)y
;
382 void wxTreeLayoutStored::SetNodeName(long id
, const wxString
& name
)
384 wxASSERT(id
< m_num
);
386 m_nodes
[id
].m_name
= name
;
389 wxString
wxTreeLayoutStored::GetNodeName(long id
)
391 wxASSERT(id
< m_num
);
393 return m_nodes
[id
].m_name
;
396 long wxTreeLayoutStored::GetNodeParent(long id
)
400 wxASSERT(id
< m_num
);
402 return m_nodes
[id
].m_parentId
;
408 long wxTreeLayoutStored::GetNextNode(long id
)
410 wxASSERT(id
< m_num
);
412 if ((id
!= wxID_ANY
) && (id
< (m_num
- 1)))
418 void wxTreeLayoutStored::SetClientData(long id
, long clientData
)
420 wxASSERT(id
< m_num
);
422 m_nodes
[id
].m_clientData
= clientData
;
425 long wxTreeLayoutStored::GetClientData(long id
) const
427 wxASSERT(id
< m_num
);
429 return m_nodes
[id
].m_clientData
;
432 void wxTreeLayoutStored::ActivateNode(long id
, bool active
)
434 wxASSERT(id
< m_num
);
436 m_nodes
[id
].m_active
= active
;
439 bool wxTreeLayoutStored::NodeActive(long id
)
441 wxASSERT(id
< m_num
);
443 return m_nodes
[id
].m_active
;
446 wxString
wxTreeLayoutStored::HitTest(wxMouseEvent
& event
, wxDC
& dc
)
448 wxPoint pt
= event
.GetPosition();
453 for (i
= 0; i
< m_maxNodes
; i
++)
456 dc
.GetTextExtent(m_nodes
[i
].m_name
, &width
, &height
);
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)) )
461 return m_nodes
[i
].m_name
;
465 return wxString( wxT("") );