Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / glui / glui_node.cpp
1 /****************************************************************************
2   
3   GLUI User Interface Toolkit
4   ---------------------------
5
6      glui_node.cpp - linked-list tree structure
7
8
9           --------------------------------------------------
10
11   Copyright (c) 1998 Paul Rademacher
12
13   WWW:    http://sourceforge.net/projects/glui/
14   Forums: http://sourceforge.net/forum/?group_id=92496
15
16   This library is free software; you can redistribute it and/or
17   modify it under the terms of the GNU Lesser General Public
18   License as published by the Free Software Foundation; either
19   version 2.1 of the License, or (at your option) any later version.
20
21   This library is distributed in the hope that it will be useful,
22   but WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   Lesser General Public License for more details.
25
26   You should have received a copy of the GNU Lesser General Public
27   License along with this library; if not, write to the Free Software
28   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
30 *****************************************************************************/
31
32 #include "GL/glui.h"
33 #include "glui_internal.h"
34
35 /********************************************* GLUI_Node::GLUI_Node() *******/
36
37 GLUI_Node::GLUI_Node()
38
39     parent_node(NULL),
40     child_head(NULL),
41     child_tail(NULL),
42     next_sibling(NULL),
43     prev_sibling(NULL)
44 {
45 }
46
47 /********************************************* GLUI_Node::first() *******/
48 /* Returns first sibling in 'this' node's sibling list                  */
49
50 GLUI_Node   *GLUI_Node::first_sibling( void )
51 {
52   if ( parent_node == NULL )  
53     return this;           /* root node has no siblings */
54   else
55     return parent_node->child_head;
56 }
57
58
59 /******************************************** GLUI_Node::next() ********/
60 /* Returns next sibling in 'this' node's sibling list                  */
61
62 GLUI_Node    *GLUI_Node::next( void )
63 {
64   return next_sibling;
65 }
66
67
68 /******************************************** GLUI_Node::prev() ********/
69 /* Returns prev sibling in 'this' node's sibling list                  */
70
71 GLUI_Node    *GLUI_Node::prev( void )
72 {
73   return prev_sibling;
74 }
75
76
77 /********************************************* GLUI_Node::last() *******/
78 /* Returns last sibling in 'this' node's sibling list                  */
79
80 GLUI_Node   *GLUI_Node::last_sibling( void )
81 {
82   if ( parent_node == NULL )
83     return this;            /* root node has no siblings */
84   else
85     return parent_node->child_tail;
86 }
87
88
89 /*************************** GLUI_Node::link_this_to_parent_last() *******/
90 /* Links as last child of parent                                         */
91
92 void   GLUI_Node::link_this_to_parent_last( GLUI_Node *new_parent )
93 {
94   if ( new_parent->child_tail == NULL ) {   /* parent has no children */
95     new_parent->child_head = this;
96     new_parent->child_tail = this;
97     this->parent_node      = new_parent;
98   }
99   else {                                 /* parent has children */
100     new_parent->child_tail->next_sibling = this;
101     this->prev_sibling                   = new_parent->child_tail;
102     new_parent->child_tail               = this;
103     this->parent_node                    = new_parent;
104   }
105 }
106
107
108 /*************************** GLUI_Node::link_this_to_parent_first() *******/
109 /* Links as first child of parent                                         */
110
111 void   GLUI_Node::link_this_to_parent_first( GLUI_Node *new_parent )
112 {
113   if ( new_parent->child_head == NULL ) {   /* parent has no children */
114     new_parent->child_head               = this;
115     new_parent->child_tail               = this;
116     this->parent_node                    = new_parent;
117   }
118   else {                                 /* parent has children */
119     new_parent->child_head->prev_sibling = this;
120     this->next_sibling                   = new_parent->child_head;
121     new_parent->child_head               = this;
122     this->parent_node                    = new_parent;
123   }
124 }
125
126 /**************************** GLUI_Node::link_this_to_sibling_next() *****/
127
128 void   GLUI_Node::link_this_to_sibling_next( GLUI_Node *sibling )
129 {
130   if ( sibling->next_sibling == NULL ) {    /* node has no next sibling */
131     sibling->next_sibling  = this;
132     this->prev_sibling     = sibling;
133
134     /* This was the parent's last child, so update that as well */
135     if ( sibling->parent_node  != NULL ) {
136       sibling->parent_node->child_tail = this;
137     }
138   }
139   else {                            /* node already has a next sibling */
140     sibling->next_sibling->prev_sibling = this;
141     this->next_sibling                  = sibling->next_sibling;
142     sibling->next_sibling               = this;
143     this->prev_sibling                  = sibling;
144   }
145
146   this->parent_node = sibling->parent_node;
147 }
148
149
150 /**************************** GLUI_Node::link_this_to_sibling_prev() *****/
151
152 void   GLUI_Node::link_this_to_sibling_prev( GLUI_Node *sibling )
153 {
154   if ( sibling->prev_sibling == NULL ) {    /* node has no prev sibling */
155     sibling->prev_sibling  = this;
156     this->next_sibling     = sibling;
157
158     /* This was the parent's first child, so update that as well */
159     if ( sibling->parent_node  != NULL ) {
160       sibling->parent_node->child_head = this;
161     }
162   }
163   else {                            /* node already has a prev sibling */
164     sibling->prev_sibling->next_sibling = this;
165     this->prev_sibling                  = sibling->prev_sibling;
166     sibling->prev_sibling               = this;
167     this->next_sibling                  = sibling;
168   }
169
170   this->parent_node = sibling->parent_node;
171 }
172
173 /**************************************** GLUI_Node::unlink() **************/
174
175 void   GLUI_Node::unlink( void )
176 {
177   /* Unlink from prev sibling */
178   if ( this->prev_sibling != NULL ) {
179     this->prev_sibling->next_sibling = this->next_sibling;
180   }
181   else {                 /* No prev sibling: this was parent's first child */
182     this->parent_node->child_head = this->next_sibling;
183   }
184
185   /* Unlink from next sibling */
186   if ( this->next_sibling != NULL ) {
187     this->next_sibling->prev_sibling = this->prev_sibling;
188   }
189   else {                /* No next sibling: this was parent's last child */
190     this->parent_node->child_tail = this->prev_sibling;
191   }
192
193   this->parent_node  = NULL;
194   this->next_sibling = NULL;
195   this->prev_sibling = NULL;
196   this->child_head   = NULL;
197   this->child_tail   = NULL;
198 }
199
200 /**************************************** GLUI_Node::dump() **************/
201
202 void GLUI_Node::dump( FILE *out, const char *name )
203 {
204     fprintf( out, "GLUI_node: %s\n", name );
205     fprintf( out, "   parent: %p     child_head: %p    child_tail: %p\n",
206         (void *) parent_node,
207         (void *) child_head,
208         (void *) child_tail );
209     fprintf( out, "   next: %p       prev: %p\n",
210         (void *) next_sibling,
211         (void *) prev_sibling );
212 }