1 /****************************************************************************
3 GLUI User Interface Toolkit
4 ---------------------------
6 glui_node.cpp - linked-list tree structure
9 --------------------------------------------------
11 Copyright (c) 1998 Paul Rademacher
13 WWW: http://sourceforge.net/projects/glui/
14 Forums: http://sourceforge.net/forum/?group_id=92496
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.
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.
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
30 *****************************************************************************/
33 #include "glui_internal.h"
35 /********************************************* GLUI_Node::GLUI_Node() *******/
37 GLUI_Node::GLUI_Node()
47 /********************************************* GLUI_Node::first() *******/
48 /* Returns first sibling in 'this' node's sibling list */
50 GLUI_Node *GLUI_Node::first_sibling( void )
52 if ( parent_node == NULL )
53 return this; /* root node has no siblings */
55 return parent_node->child_head;
59 /******************************************** GLUI_Node::next() ********/
60 /* Returns next sibling in 'this' node's sibling list */
62 GLUI_Node *GLUI_Node::next( void )
68 /******************************************** GLUI_Node::prev() ********/
69 /* Returns prev sibling in 'this' node's sibling list */
71 GLUI_Node *GLUI_Node::prev( void )
77 /********************************************* GLUI_Node::last() *******/
78 /* Returns last sibling in 'this' node's sibling list */
80 GLUI_Node *GLUI_Node::last_sibling( void )
82 if ( parent_node == NULL )
83 return this; /* root node has no siblings */
85 return parent_node->child_tail;
89 /*************************** GLUI_Node::link_this_to_parent_last() *******/
90 /* Links as last child of parent */
92 void GLUI_Node::link_this_to_parent_last( GLUI_Node *new_parent )
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;
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;
108 /*************************** GLUI_Node::link_this_to_parent_first() *******/
109 /* Links as first child of parent */
111 void GLUI_Node::link_this_to_parent_first( GLUI_Node *new_parent )
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;
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;
126 /**************************** GLUI_Node::link_this_to_sibling_next() *****/
128 void GLUI_Node::link_this_to_sibling_next( GLUI_Node *sibling )
130 if ( sibling->next_sibling == NULL ) { /* node has no next sibling */
131 sibling->next_sibling = this;
132 this->prev_sibling = sibling;
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;
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;
146 this->parent_node = sibling->parent_node;
150 /**************************** GLUI_Node::link_this_to_sibling_prev() *****/
152 void GLUI_Node::link_this_to_sibling_prev( GLUI_Node *sibling )
154 if ( sibling->prev_sibling == NULL ) { /* node has no prev sibling */
155 sibling->prev_sibling = this;
156 this->next_sibling = sibling;
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;
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;
170 this->parent_node = sibling->parent_node;
173 /**************************************** GLUI_Node::unlink() **************/
175 void GLUI_Node::unlink( void )
177 /* Unlink from prev sibling */
178 if ( this->prev_sibling != NULL ) {
179 this->prev_sibling->next_sibling = this->next_sibling;
181 else { /* No prev sibling: this was parent's first child */
182 this->parent_node->child_head = this->next_sibling;
185 /* Unlink from next sibling */
186 if ( this->next_sibling != NULL ) {
187 this->next_sibling->prev_sibling = this->prev_sibling;
189 else { /* No next sibling: this was parent's last child */
190 this->parent_node->child_tail = this->prev_sibling;
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;
200 /**************************************** GLUI_Node::dump() **************/
202 void GLUI_Node::dump( FILE *out, const char *name )
204 fprintf( out, "GLUI_node: %s\n", name );
205 fprintf( out, " parent: %p child_head: %p child_tail: %p\n",
206 (void *) parent_node,
208 (void *) child_tail );
209 fprintf( out, " next: %p prev: %p\n",
210 (void *) next_sibling,
211 (void *) prev_sibling );