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