Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / glui / glui_treepanel.cpp
1 #include "GL/glui.h"
2
3
4 /****************************** GLUI_TreePanel::GLUI_TreePanel() *********/
5
6 GLUI_TreePanel::GLUI_TreePanel(GLUI_Node *parent, const char *name, 
7                                bool open, int inset)
8 {
9   common_init();
10
11   set_name( name );
12   user_id    = -1;
13         
14   if ( !open ) {
15     is_open = false;
16     h = GLUI_DEFAULT_CONTROL_HEIGHT + 7;
17   }
18
19   parent->add_control( this );
20 }
21
22 /****************************** GLUI_TreePanel::set_color() *********/
23
24 void GLUI_TreePanel::set_color(float r, float g, float b) 
25 {
26   red = r;
27   green = g;
28   blue = b;
29   redraw();
30 }
31
32 /************************ GLUI_TreePanel::set_level_color() *********/
33
34 void GLUI_TreePanel::set_level_color(float r, float g, float b) 
35 {
36   lred = r;
37   lgreen = g;
38   lblue = b;
39   redraw();
40 }
41
42 /****************************** GLUI_TreePanel::ab() *********/
43
44 /* Adds branch to curr_root */
45 GLUI_Tree *GLUI_TreePanel::ab(const char *name, GLUI_Tree *root) 
46 {
47   GLUI_Tree *temp;
48
49   
50   if (root != NULL) {
51     resetToRoot(root);
52   }
53
54   temp = new GLUI_Tree(curr_root, name);
55   initNode(temp);
56   formatNode(temp);
57
58   curr_root = temp;
59   curr_branch = NULL; /* Currently at leaf */
60
61   if (temp->dynamicCastGLUI_Tree())
62     ((GLUI_Tree *)temp)->set_current(true);
63   //refresh();
64   //  glui->deactivate_current_control();
65   //glui->activate_control( temp, GLUI_ACTIVATE_TAB );
66   return temp;
67
68 }
69
70 /****************************** GLUI_TreePanel::fb() *********/
71
72 /* Goes up one level, resets curr_root and curr_branch to parents*/
73 void GLUI_TreePanel::fb(GLUI_Tree *branch) 
74 {
75   if (((GLUI_Panel *)branch) == ((GLUI_Panel *)this))
76     return;
77
78   if (((GLUI_Panel *)curr_branch) == ((GLUI_Panel *)this)) {
79     resetToRoot();
80     return;
81   }
82   if (((GLUI_Panel *)curr_root) == ((GLUI_Panel *)this)) {
83     resetToRoot();
84     return;
85   }
86
87   if (branch != NULL) {
88
89           if ( branch->dynamicCastGLUI_Tree() )
90       ((GLUI_Tree *)branch)->set_current(false);
91
92     curr_branch = (GLUI_Tree *)branch->next();
93     curr_root = (GLUI_Panel *)branch->parent();
94
95     if (curr_branch == NULL && (curr_root->collapsed_node).first_child() != NULL)
96       curr_branch = (GLUI_Tree *)(curr_root->collapsed_node).first_child();
97
98
99         if ( curr_root->dynamicCastGLUI_Tree() )
100       ((GLUI_Tree *)curr_root)->set_current(true);
101
102   } else {
103     if (curr_root != NULL) { /* up one parent */
104
105       if (curr_root->dynamicCastGLUI_Tree())
106         ((GLUI_Tree *)curr_root)->set_current(false);
107
108       curr_branch = (GLUI_Tree *) curr_root->next();
109       curr_root = (GLUI_Panel *) curr_root->parent();
110
111       if (curr_branch == NULL && (curr_root->collapsed_node).first_child() != NULL)
112         curr_branch = (GLUI_Tree *)(curr_root->collapsed_node).first_child();
113
114       if (curr_root->dynamicCastGLUI_Tree())
115         ((GLUI_Tree *)curr_root)->set_current(true);
116
117     }
118
119   }
120   //refresh();
121 }
122
123
124 /****************************** GLUI_TreePanel::refresh() *********/
125
126 void GLUI_TreePanel::refresh() 
127 {
128   glui->deactivate_current_control();
129   glui->activate_control( curr_root, GLUI_ACTIVATE_TAB );
130
131   redraw();
132 }
133
134 /****************************** GLUI_TreePanel::initNode() *********/
135
136 void GLUI_TreePanel::initNode(GLUI_Tree *temp) 
137 {
138   if (temp == NULL)
139     return;
140   int level = temp->get_level();
141   int child_number = 1;
142
143   GLUI_Tree *ptree = temp->parent()->dynamicCastGLUI_Tree();
144   if (ptree) {
145     level = ptree->get_level() + 1;
146     GLUI_Tree *prevTree = temp->prev()->dynamicCastGLUI_Tree();
147     if (prevTree) {
148       child_number = prevTree->get_child_number() + 1;
149     }
150   } else if (temp->dynamicCastGLUI_Tree() && 
151              temp->parent()->dynamicCastGLUI_TreePanel()) {
152     child_number = ++root_children;
153   }
154   temp->set_id(uniqueID());     // -1 if unset
155   temp->set_level(level);
156   temp->set_child_number(child_number);
157 }
158
159 /****************************** GLUI_TreePanel::formatNode() *********/
160
161 void GLUI_TreePanel::formatNode(GLUI_Tree *temp) 
162 {
163   if (temp == NULL)
164     return;
165   int level = temp->get_level();
166   int child_number = temp->get_child_number();
167   GLUI_String level_name="";
168   GLUI_String full_name="";
169
170   temp->level_name == "";
171
172   if (format & GLUI_TREEPANEL_DISPLAY_HIERARCHY) {
173     if (format & GLUI_TREEPANEL_HIERARCHY_LEVEL_ONLY) {
174       glui_format_str(level_name, "%d", level);
175     }
176     if (format & GLUI_TREEPANEL_HIERARCHY_NUMERICDOT) {
177       if ( temp->parent()->dynamicCastGLUI_Tree() )
178         glui_format_str(level_name, "%s.%d", 
179                         ((GLUI_Tree *)(temp->parent()))->level_name.c_str(), 
180                         child_number);
181       else
182         glui_format_str(level_name, "%d", child_number);
183     }
184   }
185
186   temp->set_level_color(lred, lgreen, lblue);
187   temp->set_format(format);
188   temp->level_name = level_name;
189
190   if (format & GLUI_TREEPANEL_ALTERNATE_COLOR) {
191     switch (level%8) {
192     case (7): temp->set_color(.5,.5,.5); break;
193     case (6): temp->set_color(.3,.5,.5); break;
194     case (5): temp->set_color(.5,.3,.5); break;
195     case (4): temp->set_color(.3,.3,.5); break;
196     case (3): temp->set_color(.5,.5,.3); break;
197     case (2): temp->set_color(.3,.5,.3); break;
198     case (1): temp->set_color(.5,.3,.3); break;
199     default: temp->set_color(.3,.3,.3);
200     }
201   } else {
202     temp->set_color(red,green,blue);
203   }
204
205   if (format & GLUI_TREEPANEL_DISABLE_BAR) {
206     temp->disable_bar();
207   } else {
208     if (format & GLUI_TREEPANEL_DISABLE_DEEPEST_BAR) {
209       temp->disable_bar();
210       if ( curr_root->dynamicCastGLUI_Tree() )
211         ((GLUI_Tree *)curr_root)->enable_bar();
212     } else
213       if (format & GLUI_TREEPANEL_CONNECT_CHILDREN_ONLY) {
214         temp->disable_bar();
215         if (temp->prev() && temp->prev()->dynamicCastGLUI_Tree() ) 
216         {
217           ((GLUI_Tree *)temp->prev())->enable_bar();
218         }
219       }
220   }
221 }
222
223 /****************************** GLUI_TreePanel::update_all() *********/
224
225 void GLUI_TreePanel::update_all() 
226 {
227   printf("GLUI_TreePanel::update_all() doesn't work yet. - JVK\n");
228   return;
229   GLUI_Panel *saved_root = curr_root;
230   GLUI_Tree *saved_branch = curr_branch;
231   root_children = 0;
232   resetToRoot(this);
233   if (curr_branch && curr_branch->dynamicCastGLUI_Tree())
234     formatNode((GLUI_Tree *)curr_branch);
235   next();
236   while (curr_root && curr_branch != this->first_child()) {
237           if (curr_branch && curr_branch->dynamicCastGLUI_Tree()) {
238       formatNode((GLUI_Tree *)curr_branch);
239     }
240     next();
241   } 
242   curr_root = saved_root;
243   curr_branch = saved_branch;
244 }
245
246 /****************************** GLUI_TreePanel::expand_all() *********/
247
248 void            GLUI_TreePanel::expand_all() 
249 {
250   GLUI_Panel *saved_root = curr_root;
251   GLUI_Tree *saved_branch = curr_branch;
252
253   resetToRoot(this);
254   if (curr_root->dynamicCastGLUI_Tree())
255     ((GLUI_Tree*)curr_root)->open();
256   next();
257   while (curr_root != NULL && curr_branch != this->first_child()) {
258     if (curr_root->dynamicCastGLUI_Tree())
259       ((GLUI_Tree*)curr_root)->open();
260     next();
261   }
262
263   curr_root = saved_root;
264   curr_branch = saved_branch;
265 }
266
267 /****************************** GLUI_TreePanel::collapse_all() *********/
268
269 void            GLUI_TreePanel::collapse_all() 
270 {
271   GLUI_Panel *saved_root = curr_root;
272   GLUI_Tree *saved_branch = curr_branch;
273
274   resetToRoot(this);
275   next();
276   while (curr_root != NULL && curr_branch != this->first_child()) {
277     if (curr_root->dynamicCastGLUI_Tree() && 
278               curr_branch == NULL) { /* we want to close everything leaf-first */
279       ((GLUI_Tree*)curr_root)->close();
280       /* Rather than simply next(), we need to manually move the
281          curr_root because this node has been moved to the 
282          collapsed_node list */
283       curr_branch = (GLUI_Tree *)curr_root->next();
284       curr_root = (GLUI_Panel *)curr_root->parent();
285     } else
286       next();
287   }
288
289   curr_root = saved_root;
290   curr_branch = saved_branch;
291
292 }
293
294 /****************************** GLUI_TreePanel::db() *********/
295
296 /* Deletes the curr_root */
297 void GLUI_TreePanel::db(GLUI_Tree *root) 
298 {
299   GLUI_Tree  *temp_branch;
300   GLUI_Panel *temp_root;
301
302   if (((GLUI_Control *)root) == ((GLUI_Control *)this))
303     return;
304
305   if (root != NULL) {
306     curr_root = (GLUI_Tree *)root;
307     curr_branch = NULL;
308   }
309
310   if (curr_root == NULL || ((GLUI_Panel *)curr_root) == ((GLUI_Panel *)this)) {
311     resetToRoot();
312     return;
313   }
314
315
316   temp_branch = (GLUI_Tree *)curr_root->next();              /* Next branch, if any */
317   temp_root   = (GLUI_Panel *)curr_root->parent();      /* new root */
318   curr_root->unlink();
319   delete curr_root;
320   curr_branch = (GLUI_Tree *) temp_branch;
321   curr_root   = (GLUI_Panel *) temp_root;
322   if (curr_root->dynamicCastGLUI_Tree())
323     ((GLUI_Tree *)curr_root)->open();
324
325   if ((format & GLUI_TREEPANEL_DISABLE_DEEPEST_BAR) == GLUI_TREEPANEL_DISABLE_DEEPEST_BAR) {
326     if (curr_root->dynamicCastGLUI_Tree() && ((GLUI_Tree *)curr_root->next()) == NULL)
327       ((GLUI_Tree *)curr_root)->disable_bar();
328   }
329   //refresh();
330 }
331
332 /****************************** GLUI_TreePanel::descendBranch() *********/
333
334 /* Finds the very last branch of curr_root, resets vars */
335 void            GLUI_TreePanel::descendBranch(GLUI_Panel *root) {
336   if (root)
337     resetToRoot(root);
338   else
339     resetToRoot(curr_root);
340   if (curr_branch != NULL && curr_branch != ((GLUI_Panel *)this)) {
341     if (curr_root->dynamicCastGLUI_Tree())
342       ((GLUI_Tree *)curr_root)->set_current(false);
343     descendBranch(curr_branch); 
344   } 
345 }
346
347 /****************************** GLUI_TreePanel::next() *********/
348
349 void GLUI_TreePanel::next() 
350 {
351   if (curr_root == NULL)
352     resetToRoot(this);
353
354   if (curr_branch == NULL && (curr_root->collapsed_node).first_child() != NULL)
355     curr_branch = (GLUI_Tree *)(curr_root->collapsed_node).first_child();
356
357
358   if (curr_branch != NULL && curr_branch != ((GLUI_Panel *)this)) {     /* Descend into branch */
359     if (curr_root->dynamicCastGLUI_Tree())
360       ((GLUI_Tree *)curr_root)->set_current(false);
361     resetToRoot(curr_branch);
362   } else if (curr_branch == NULL) {
363     fb(NULL);  /* Backup and move on */
364   }
365 }
366
367 /****************************** GLUI_TreePanel::resetToRoot() *********/
368
369 /* Resets curr_root and curr branch to TreePanel and lastChild */
370 void GLUI_TreePanel::resetToRoot(GLUI_Panel *new_root) 
371 {
372   GLUI_Panel *root = this;
373   if (new_root != NULL)
374     root = new_root;
375   curr_root = root;
376   if (curr_root->dynamicCastGLUI_Tree())
377     ((GLUI_Tree *)curr_root)->set_current(true);
378   curr_branch = (GLUI_Tree *)root->first_child();
379
380   /* since Trees are collapsable, we need to check the collapsed nodes
381      in case the curr_root is collapsed */
382   if (curr_branch == NULL && (root->collapsed_node).first_child() != NULL) {
383     curr_branch = (GLUI_Tree *)(root->collapsed_node).first_child();
384   }
385   while (curr_branch && curr_branch->dynamicCastGLUI_Tree()) {
386     curr_branch=(GLUI_Tree *)curr_branch->next();
387   }
388 }