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