]>
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>
29 #include <wx/treelay.h>
36 IMPLEMENT_ABSTRACT_CLASS(wxTreeLayout
, wxObject
)
38 wxTreeLayout::wxTreeLayout()
44 m_orientation
= FALSE
;
48 void wxTreeLayout::DoLayout(wxDC
& dc
, long topId
)
53 long actualTopId
= GetTopNode();
54 long id
= actualTopId
;
59 ActivateNode(id
, FALSE
);
62 m_lastY
= m_topMargin
;
63 m_lastX
= m_leftMargin
;
64 CalcLayout(actualTopId
, 0, dc
);
67 void wxTreeLayout::Draw(wxDC
& dc
)
74 void wxTreeLayout::DrawNodes(wxDC
& dc
)
76 long id
= GetTopNode();
85 void wxTreeLayout::DrawBranches(wxDC
& dc
)
87 long id
= GetTopNode();
90 if (GetNodeParent(id
) > -1)
92 long parent
= GetNodeParent(id
);
93 if (NodeActive(parent
))
94 DrawBranch(parent
, id
, dc
);
100 void wxTreeLayout::DrawNode(long id
, wxDC
& dc
)
103 wxString
name(GetNodeName(id
));
105 sprintf(buf
, "%s", (const char*) name
);
107 sprintf(buf
, "<unnamed>");
111 dc
.GetTextExtent(buf
, &x
, &y
);
112 dc
.DrawText(buf
, GetNodeX(id
), (long)(GetNodeY(id
) - (y
/2.0)));
115 void wxTreeLayout::DrawBranch(long from
, long to
, wxDC
& dc
)
118 GetNodeSize(from
, &w
, &h
, dc
);
119 dc
.DrawLine(GetNodeX(from
)+w
, GetNodeY(from
),
120 GetNodeX(to
), GetNodeY(to
));
123 void wxTreeLayout::Initialize(void)
127 void wxTreeLayout::GetNodeSize(long id
, long *x
, long *y
, wxDC
& dc
)
129 wxString
name(GetNodeName(id
));
131 dc
.GetTextExtent(name
, x
, y
);
138 void wxTreeLayout::CalcLayout(long nodeId
, int level
, wxDC
& dc
)
141 GetChildren(nodeId
, children
);
142 int n
= children
.Number();
144 if (m_orientation
== FALSE
)
149 SetNodeX(nodeId
, m_leftMargin
);
154 long parentId
= GetNodeParent(nodeId
);
156 GetNodeSize(parentId
, &x
, &y
, dc
);
157 SetNodeX(nodeId
, (long)(GetNodeX(parentId
) + m_xSpacing
+ x
));
160 wxNode
*node
= children
.First();
163 CalcLayout((long)node
->Data(), level
+1, dc
);
169 ActivateNode(nodeId
, TRUE
);
174 node
= children
.First();
177 averageY
+= GetNodeY((long)node
->Data());
180 averageY
= averageY
/ n
;
181 SetNodeY(nodeId
, averageY
);
185 SetNodeY(nodeId
, m_lastY
);
187 GetNodeSize(nodeId
, &x
, &y
, dc
);
189 m_lastY
= m_lastY
+ y
+ m_ySpacing
;
198 SetNodeY(nodeId
, m_topMargin
);
203 long parentId
= GetNodeParent(nodeId
);
205 GetNodeSize(parentId
, &x
, &y
, dc
);
206 SetNodeY(nodeId
, (long)(GetNodeY(parentId
) + m_ySpacing
+ y
));
209 wxNode
*node
= children
.First();
212 CalcLayout((long)node
->Data(), level
+1, dc
);
218 ActivateNode(nodeId
, TRUE
);
223 node
= children
.First();
226 averageX
+= GetNodeX((long)node
->Data());
229 averageX
= averageX
/ n
;
230 SetNodeX(nodeId
, averageX
);
234 SetNodeX(nodeId
, m_lastX
);
236 GetNodeSize(nodeId
, &x
, &y
, dc
);
238 m_lastX
= m_lastX
+ x
+ m_xSpacing
;
248 IMPLEMENT_DYNAMIC_CLASS(wxTreeLayoutStored
, wxTreeLayout
)
250 wxTreeLayoutStored::wxTreeLayoutStored(int n
):wxTreeLayout()
257 wxTreeLayoutStored::~wxTreeLayoutStored(void)
263 void wxTreeLayoutStored::Initialize(int n
)
266 wxTreeLayout::Initialize();
267 if (m_nodes
) delete[] m_nodes
;
268 m_nodes
= new wxStoredNode
[m_maxNodes
];
270 for (i
= 0; i
< n
; i
++)
272 m_nodes
[i
].m_name
= "";
273 m_nodes
[i
].m_active
= FALSE
;
274 m_nodes
[i
].m_parentId
= -1;
281 long wxTreeLayoutStored::AddChild(const wxString
& name
, const wxString
& parent
)
283 if (m_num
< (m_maxNodes
-1 ))
287 i
= NameToId(parent
);
288 else m_parentNode
= m_num
;
290 m_nodes
[m_num
].m_parentId
= i
;
291 m_nodes
[m_num
].m_name
= name
;
292 m_nodes
[m_num
].m_x
= m_nodes
[m_num
].m_y
= 0;
293 m_nodes
[m_num
].m_clientData
= 0;
302 long wxTreeLayoutStored::NameToId(const wxString
& name
)
305 for (i
= 0; i
< m_num
; i
++)
306 if (name
== m_nodes
[i
].m_name
)
311 void wxTreeLayoutStored::GetChildren(long id
, wxList
& list
)
313 long currentId
= GetTopNode();
314 while (currentId
!= -1)
316 if (id
== GetNodeParent(currentId
))
317 list
.Append((wxObject
*)currentId
);
318 currentId
= GetNextNode(currentId
);
322 wxStoredNode
* wxTreeLayoutStored::GetNode(long idx
) const
324 wxASSERT(idx
< m_num
);
326 return &m_nodes
[idx
];
329 long wxTreeLayoutStored::GetNodeX(long id
)
331 wxASSERT(id
< m_num
);
333 return (long)m_nodes
[id
].m_x
;
336 long wxTreeLayoutStored::GetNodeY(long id
)
338 wxASSERT(id
< m_num
);
340 return (long)m_nodes
[id
].m_y
;
343 void wxTreeLayoutStored::SetNodeX(long id
, long x
)
345 wxASSERT(id
< m_num
);
347 m_nodes
[id
].m_x
= (int)x
;
350 void wxTreeLayoutStored::SetNodeY(long id
, long y
)
352 wxASSERT(id
< m_num
);
354 m_nodes
[id
].m_y
= (int)y
;
357 void wxTreeLayoutStored::SetNodeName(long id
, const wxString
& name
)
359 wxASSERT(id
< m_num
);
361 m_nodes
[id
].m_name
= name
;
364 wxString
wxTreeLayoutStored::GetNodeName(long id
)
366 wxASSERT(id
< m_num
);
368 return m_nodes
[id
].m_name
;
371 long wxTreeLayoutStored::GetNodeParent(long id
)
375 wxASSERT(id
< m_num
);
377 return m_nodes
[id
].m_parentId
;
383 long wxTreeLayoutStored::GetNextNode(long id
)
385 wxASSERT(id
< m_num
);
387 if ((id
!= -1) && (id
< (m_num
- 1)))
393 void wxTreeLayoutStored::SetClientData(long id
, long clientData
)
395 wxASSERT(id
< m_num
);
397 m_nodes
[id
].m_clientData
= clientData
;
400 long wxTreeLayoutStored::GetClientData(long id
) const
402 wxASSERT(id
< m_num
);
404 return m_nodes
[id
].m_clientData
;
407 void wxTreeLayoutStored::ActivateNode(long id
, bool active
)
409 wxASSERT(id
< m_num
);
411 m_nodes
[id
].m_active
= active
;
414 bool wxTreeLayoutStored::NodeActive(long id
)
416 wxASSERT(id
< m_num
);
418 return m_nodes
[id
].m_active
;
421 wxString
wxTreeLayoutStored::HitTest(wxMouseEvent
& event
, wxDC
& dc
)
423 wxPoint pt
= event
.GetPosition();
428 for (i
= 0; i
< m_maxNodes
; i
++)
430 wxStoredNode
* item
= &m_nodes
[i
];
433 dc
.GetTextExtent(m_nodes
[i
].m_name
, &width
, &height
);
435 if ( (x
>= (m_nodes
[i
].m_x
-10)) && (x
< (m_nodes
[i
].m_x
+ width
+10)) &&
436 (y
>= m_nodes
[i
].m_y
-10) && (y
< (m_nodes
[i
].m_y
+ height
+10)) )
438 return m_nodes
[i
].m_name
;