Fix periodic focus bug
[wmaker-crm.git] / WINGs / tree.c
blobe5c56ea3f657bad4c6164bd04568a7bce069d733
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;
26 void
27 destroyNode(void *data)
29 WMTreeNode *aNode = (WMTreeNode*) data;
31 if (aNode->destructor) {
32 (*aNode->destructor)(aNode->data);
34 if (aNode->leaves) {
35 WMFreeArray(aNode->leaves);
37 wfree(aNode);
41 WMTreeNode*
42 WMCreateTreeNode(void *data)
44 return WMCreateTreeNodeWithDestructor(data, NULL);
48 WMTreeNode*
49 WMCreateTreeNodeWithDestructor(void *data, WMFreeDataProc *destructor)
51 WMTreeNode *aNode;
53 aNode = (WMTreeNode*) wmalloc(sizeof(W_TreeNode));
54 memset(aNode, 0, sizeof(W_TreeNode));
56 aNode->destructor = destructor;
58 aNode->data = data;
59 aNode->parent = NULL;
60 aNode->depth = 0;
61 aNode->leaves = NULL;
62 /*aNode->leaves = WMCreateArrayWithDestructor(1, destroyNode);*/
64 return aNode;
68 WMTreeNode*
69 WMInsertItemInTree(WMTreeNode *parent, int index, void *item)
71 WMTreeNode *aNode;
73 wassertrv(parent!=NULL, NULL);
75 aNode = WMCreateTreeNodeWithDestructor(item, parent->destructor);
76 aNode->parent = parent;
77 aNode->depth = parent->depth+1;
78 if (!parent->leaves) {
79 parent->leaves = WMCreateArrayWithDestructor(1, destroyNode);
81 if (index < 0) {
82 WMAddToArray(parent->leaves, aNode);
83 } else {
84 WMInsertInArray(parent->leaves, index, aNode);
87 return aNode;
91 static void
92 updateNodeDepth(WMTreeNode *aNode, int depth)
94 int i;
96 aNode->depth = depth;
98 if (aNode->leaves) {
99 for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
100 updateNodeDepth(WMGetFromArray(aNode->leaves, i), depth+1);
106 WMTreeNode*
107 WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *aNode)
109 wassertrv(parent!=NULL, NULL);
110 wassertrv(aNode!=NULL, NULL);
112 aNode->parent = parent;
113 updateNodeDepth(aNode, parent->depth+1);
114 if (!parent->leaves) {
115 parent->leaves = WMCreateArrayWithDestructor(1, destroyNode);
117 if (index < 0) {
118 WMAddToArray(parent->leaves, aNode);
119 } else {
120 WMInsertInArray(parent->leaves, index, aNode);
123 return aNode;
127 void
128 WMDestroyTreeNode(WMTreeNode *aNode)
130 wassertr(aNode!=NULL);
132 if (aNode->parent && aNode->parent->leaves) {
133 WMRemoveFromArray(aNode->parent->leaves, aNode);
134 } else {
135 destroyNode(aNode);
140 void
141 WMDeleteLeafForTreeNode(WMTreeNode *aNode, int index)
143 wassertr(aNode!=NULL);
144 wassertr(aNode->leaves!=NULL);
146 WMDeleteFromArray(aNode->leaves, index);
150 static int
151 sameData(void *item, void *data)
153 return (((WMTreeNode*)item)->data == data);
157 void
158 WMRemoveLeafForTreeNode(WMTreeNode *aNode, void *leaf)
160 int index;
162 wassertr(aNode!=NULL);
163 wassertr(aNode->leaves!=NULL);
165 index = WMFindInArray(aNode->leaves, sameData, leaf);
166 if (index != WANotFound) {
167 WMDeleteFromArray(aNode->leaves, index);
172 void*
173 WMReplaceDataForTreeNode(WMTreeNode *aNode, void *newData)
175 void *old;
177 wassertrv(aNode!=NULL, NULL);
179 old = aNode->data;
180 aNode->data = newData;
182 return old;
186 void*
187 WMGetDataForTreeNode(WMTreeNode *aNode)
189 return aNode->data;
194 WMGetTreeNodeDepth(WMTreeNode *aNode)
196 return aNode->depth;
200 WMTreeNode*
201 WMGetParentForTreeNode(WMTreeNode *aNode)
203 return aNode->parent;
207 void
208 WMSortLeavesForTreeNode(WMTreeNode *aNode, WMCompareDataProc *comparer)
210 wassertr(aNode!=NULL);
212 if (aNode->leaves) {
213 WMSortArray(aNode->leaves, comparer);
218 static void
219 sortLeavesForNode(WMTreeNode *aNode, WMCompareDataProc *comparer)
221 int i;
223 if (!aNode->leaves)
224 return;
226 WMSortArray(aNode->leaves, comparer);
227 for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
228 sortLeavesForNode(WMGetFromArray(aNode->leaves, i), comparer);
233 void
234 WMSortTree(WMTreeNode *aNode, WMCompareDataProc *comparer)
236 wassertr(aNode!=NULL);
238 sortLeavesForNode(aNode, comparer);
242 static WMTreeNode*
243 findNodeInTree(WMTreeNode *aNode, WMMatchDataProc *match, void *cdata)
245 if (match==NULL) {
246 if (aNode->data == cdata) {
247 return aNode;
249 } else {
250 if ((*match)(aNode->data, cdata)) {
251 return aNode;
255 if (aNode->leaves) {
256 WMTreeNode *leaf;
257 int i;
259 for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
260 leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i), match, cdata);
261 if (leaf) {
262 return leaf;
267 return NULL;
271 WMTreeNode*
272 WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata)
274 wassertrv(aTree!=NULL, NULL);
276 return findNodeInTree(aTree, match, cdata);