]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxtree/src/wxtree.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>
34 IMPLEMENT_ABSTRACT_CLASS(wxTreeLayout
, wxObject
)
36 wxTreeLayout::wxTreeLayout()
42 m_orientation
= FALSE
;
46 void wxTreeLayout::DoLayout(wxDC
& dc
, long topId
)
51 long actualTopId
= GetTopNode();
52 long id
= actualTopId
;
57 ActivateNode(id
, FALSE
);
60 m_lastY
= m_topMargin
;
61 m_lastX
= m_leftMargin
;
62 CalcLayout(actualTopId
, 0, dc
);
65 void wxTreeLayout::Draw(wxDC
& dc
)
72 void wxTreeLayout::DrawNodes(wxDC
& dc
)
74 long id
= GetTopNode();
83 void wxTreeLayout::DrawBranches(wxDC
& dc
)
85 long id
= GetTopNode();
88 if (GetNodeParent(id
) > -1)
90 long parent
= GetNodeParent(id
);
91 if (NodeActive(parent
))
92 DrawBranch(parent
, id
, dc
);
98 void wxTreeLayout::DrawNode(long id
, wxDC
& dc
)
101 wxString
name(GetNodeName(id
));
103 sprintf(buf
, "%s", (const char*) name
);
105 sprintf(buf
, "<unnamed>");
109 dc
.GetTextExtent(buf
, &x
, &y
);
110 dc
.DrawText(buf
, GetNodeX(id
), (long)(GetNodeY(id
) - (y
/2.0)));
113 void wxTreeLayout::DrawBranch(long from
, long to
, wxDC
& dc
)
116 GetNodeSize(from
, &w
, &h
, dc
);
117 dc
.DrawLine(GetNodeX(from
)+w
, GetNodeY(from
),
118 GetNodeX(to
), GetNodeY(to
));
121 void wxTreeLayout::Initialize(void)
125 void wxTreeLayout::GetNodeSize(long id
, long *x
, long *y
, wxDC
& dc
)
127 wxString
name(GetNodeName(id
));
129 dc
.GetTextExtent(name
, x
, y
);
136 void wxTreeLayout::CalcLayout(long nodeId
, int level
, wxDC
& dc
)
139 GetChildren(nodeId
, children
);
140 int n
= children
.Number();
142 if (m_orientation
== FALSE
)
147 SetNodeX(nodeId
, m_leftMargin
);
152 long parentId
= GetNodeParent(nodeId
);
154 GetNodeSize(parentId
, &x
, &y
, dc
);
155 SetNodeX(nodeId
, (long)(GetNodeX(parentId
) + m_xSpacing
+ x
));
158 wxNode
*node
= children
.First();
161 CalcLayout((long)node
->Data(), level
+1, dc
);
167 ActivateNode(nodeId
, TRUE
);
172 node
= children
.First();
175 averageY
+= GetNodeY((long)node
->Data());
178 averageY
= averageY
/ n
;
179 SetNodeY(nodeId
, averageY
);
183 SetNodeY(nodeId
, m_lastY
);
185 GetNodeSize(nodeId
, &x
, &y
, dc
);
187 m_lastY
= m_lastY
+ y
+ m_ySpacing
;
196 SetNodeY(nodeId
, m_topMargin
);
201 long parentId
= GetNodeParent(nodeId
);
203 GetNodeSize(parentId
, &x
, &y
, dc
);
204 SetNodeY(nodeId
, (long)(GetNodeY(parentId
) + m_ySpacing
+ y
));
207 wxNode
*node
= children
.First();
210 CalcLayout((long)node
->Data(), level
+1, dc
);
216 ActivateNode(nodeId
, TRUE
);
221 node
= children
.First();
224 averageX
+= GetNodeX((long)node
->Data());
227 averageX
= averageX
/ n
;
228 SetNodeX(nodeId
, averageX
);
232 SetNodeX(nodeId
, m_lastX
);
234 GetNodeSize(nodeId
, &x
, &y
, dc
);
236 m_lastX
= m_lastX
+ x
+ m_xSpacing
;
246 IMPLEMENT_DYNAMIC_CLASS(wxStoredTree
, wxTreeLayout
)
248 wxStoredTree::wxStoredTree(int n
):wxTreeLayout()
255 wxStoredTree::~wxStoredTree(void)
261 void wxStoredTree::Initialize(int n
)
264 wxTreeLayout::Initialize();
265 if (m_nodes
) delete[] m_nodes
;
266 m_nodes
= new wxStoredNode
[m_maxNodes
];
268 for (i
= 0; i
< n
; i
++)
270 m_nodes
[i
].m_name
= "";
271 m_nodes
[i
].m_active
= FALSE
;
272 m_nodes
[i
].m_parentId
= -1;
279 long wxStoredTree::AddChild(const wxString
& name
, const wxString
& parent
)
281 if (m_num
< (m_maxNodes
-1 ))
285 i
= NameToId(parent
);
286 else m_parentNode
= m_num
;
288 m_nodes
[m_num
].m_parentId
= i
;
289 m_nodes
[m_num
].m_name
= name
;
290 m_nodes
[m_num
].m_x
= m_nodes
[m_num
].m_y
= 0;
291 m_nodes
[m_num
].m_clientData
= 0;
300 long wxStoredTree::NameToId(const wxString
& name
)
303 for (i
= 0; i
< m_num
; i
++)
304 if (name
== m_nodes
[i
].m_name
)
309 void wxStoredTree::GetChildren(long id
, wxList
& list
)
311 long currentId
= GetTopNode();
312 while (currentId
!= -1)
314 if (id
== GetNodeParent(currentId
))
315 list
.Append((wxObject
*)currentId
);
316 currentId
= GetNextNode(currentId
);
320 wxStoredNode
* wxStoredTree::GetNode(long idx
) const
322 wxASSERT(idx
< m_num
);
324 return &m_nodes
[idx
];
327 long wxStoredTree::GetNodeX(long id
)
329 wxASSERT(id
< m_num
);
331 return (long)m_nodes
[id
].m_x
;
334 long wxStoredTree::GetNodeY(long id
)
336 wxASSERT(id
< m_num
);
338 return (long)m_nodes
[id
].m_y
;
341 void wxStoredTree::SetNodeX(long id
, long x
)
343 wxASSERT(id
< m_num
);
345 m_nodes
[id
].m_x
= (int)x
;
348 void wxStoredTree::SetNodeY(long id
, long y
)
350 wxASSERT(id
< m_num
);
352 m_nodes
[id
].m_y
= (int)y
;
355 void wxStoredTree::SetNodeName(long id
, const wxString
& name
)
357 wxASSERT(id
< m_num
);
359 m_nodes
[id
].m_name
= name
;
362 wxString
wxStoredTree::GetNodeName(long id
)
364 wxASSERT(id
< m_num
);
366 return m_nodes
[id
].m_name
;
369 long wxStoredTree::GetNodeParent(long id
)
373 wxASSERT(id
< m_num
);
375 return m_nodes
[id
].m_parentId
;
381 long wxStoredTree::GetNextNode(long id
)
383 wxASSERT(id
< m_num
);
385 if ((id
!= -1) && (id
< (m_num
- 1)))
391 void wxStoredTree::SetClientData(long id
, long clientData
)
393 wxASSERT(id
< m_num
);
395 m_nodes
[id
].m_clientData
= clientData
;
398 long wxStoredTree::GetClientData(long id
) const
400 wxASSERT(id
< m_num
);
402 return m_nodes
[id
].m_clientData
;
405 void wxStoredTree::ActivateNode(long id
, bool active
)
407 wxASSERT(id
< m_num
);
409 m_nodes
[id
].m_active
= active
;
412 bool wxStoredTree::NodeActive(long id
)
414 wxASSERT(id
< m_num
);
416 return m_nodes
[id
].m_active
;
419 wxString
wxStoredTree::HitTest(wxMouseEvent
& event
, wxDC
& dc
)
422 event
.Position(&x
, &y
);
425 for (i
= 0; i
< m_maxNodes
; i
++)
427 wxStoredNode
* item
= &m_nodes
[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
;