updates to the tree code
[wmaker-crm.git] / WINGs / tree.c
blobdd2a9d015e8450d3346a387d191f7060bab36c45
4 #include <string.h>
6 #include "WUtil.h"
9 typedef struct W_TreeNode {
10 void *data;
12 /*unsigned int uflags:16;*/
14 WMArray *leaves;
16 int depth;
18 struct W_TreeNode *parent;
20 WMFreeDataProc *destructor;
21 } W_TreeNode;
25 void
26 destroyNode(void *data)
28 WMTreeNode *node = (WMTreeNode*) data;
30 if (node->destructor) {
31 (*node->destructor)(node->data);
33 if (node->leaves) {
34 WMFreeArray(node->leaves);
36 wfree(node);
40 WMTreeNode*
41 WMCreateTreeNode(void *data)
43 return WMCreateTreeNodeWithDestructor(data, NULL);
47 WMTreeNode*
48 WMCreateTreeNodeWithDestructor(void *data, WMFreeDataProc *destructor)
50 WMTreeNode *node;
52 node = (WMTreeNode*) wmalloc(sizeof(W_TreeNode));
53 memset(node, 0, sizeof(W_TreeNode));
55 node->destructor = destructor;
57 node->data = data;
58 node->parent = NULL;
59 node->depth = 0;
60 node->leaves = WMCreateArrayWithDestructor(1, destroyNode);
62 return node;
66 WMTreeNode*
67 WMInsertItemInTree(WMTreeNode *parent, int index, void *item)
69 WMTreeNode *node;
71 wassertrv(parent!=NULL, NULL);
73 node = WMCreateTreeNodeWithDestructor(item, parent->destructor);
74 node->parent = parent;
75 node->depth = parent->depth+1;
76 if (index < 0 || index > WMGetArrayItemCount(parent->leaves)) {
77 WMAddToArray(parent->leaves, node);
78 } else {
79 WMInsertInArray(parent->leaves, index, node);
82 return node;
86 WMTreeNode*
87 WMAddItemToTree(WMTreeNode *parent, void *item)
89 WMTreeNode *node;
91 wassertrv(parent!=NULL, NULL);
93 node = WMCreateTreeNodeWithDestructor(item, parent->destructor);
94 node->parent = parent;
95 node->depth = parent->depth+1;
96 WMAddToArray(parent->leaves, node);
98 return node;
102 static void
103 updateNodeDepth(WMTreeNode *node, int depth)
105 int i;
107 node->depth = depth;
108 for (i=0; i<WMGetArrayItemCount(node->leaves); i++) {
109 updateNodeDepth(WMGetFromArray(node->leaves, i), depth+1);
114 WMTreeNode*
115 WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *node)
117 wassertrv(parent!=NULL, NULL);
118 wassertrv(node!=NULL, NULL);
120 node->parent = parent;
121 updateNodeDepth(node, parent->depth+1);
122 if (index < 0 || index > WMGetArrayItemCount(parent->leaves)) {
123 WMAddToArray(parent->leaves, node);
124 } else {
125 WMInsertInArray(parent->leaves, index, node);
128 return node;
132 WMTreeNode*
133 WMAddNodeToTree(WMTreeNode *parent, WMTreeNode *node)
135 wassertrv(parent!=NULL, NULL);
136 wassertrv(node!=NULL, NULL);
138 node->parent = parent;
139 updateNodeDepth(node, parent->depth+1);
140 WMAddToArray(parent->leaves, node);
142 return node;
147 WMGetTreeNodeDepth(WMTreeNode *node)
149 return node->depth;
153 void
154 WMDestroyTreeNode(WMTreeNode *node)
156 destroyNode(node);
160 void*
161 WMGetDataForTreeNode(WMTreeNode *node)
163 return node->data;
167 WMTreeNode*
168 WMGetParentForTreeNode(WMTreeNode *node)
170 return node->parent;
174 void
175 WMSortLeavesForTreeNode(WMTreeNode *node, WMCompareDataProc *comparer)
177 wassertr(node!=NULL);
179 WMSortArray(node->leaves, comparer);
183 static void
184 sortLeavesForNode(WMTreeNode *node, WMCompareDataProc *comparer)
186 int i;
188 WMSortArray(node->leaves, comparer);
189 for (i=0; i<WMGetArrayItemCount(node->leaves); i++) {
190 sortLeavesForNode(WMGetFromArray(node->leaves, i), comparer);
195 void
196 WMSortTree(WMTreeNode *root, WMCompareDataProc *comparer)
198 wassertr(root!=NULL);
200 sortLeavesForNode(root, comparer);