1 /****************************************************************************
2 
3   A simple GLUT program using the GLUI User Interface Library
4 
5   This program sets up a checkbox and a spinner, both with live variables.
6   No callbacks are used.
7 
8   -----------------------------------------------------------------------
9   9/17/04 John Kew - Natural Selection, Inc. (jkew@natural-selection.com)
10   9/9/98 Paul Rademacher (rademach@cs.unc.edu)
11 
12 ****************************************************************************/
13 
14 #include <string.h>
15 #include <GL/glui.h>
16 
17 /** These are the live variables passed into GLUI ***/
18 int main_window;
19 int num_display  = 0;
20 int num_format  = 0;
21 int enable_textbox = 0;
22 GLUI_StaticText  *text;
23 GLUI_List        *hah;
24 GLUI_TextBox     *moo;
25 GLUI             *tree;
26 GLUI_TreePanel   *tp;
27 GLUI_FileBrowser *fb;
28 GLUI_EditText    *bedit;
29 
30 const char general[] =
31   "GLUI 2.3 Widgets\n"
32   "\n"
33   "A number of widgets have been introduced in GLUI 2.3\n"
34   "\n"
35   "  * GLUI_Scrollbar   - A scrollbar slider widget\n"
36   "  * GLUI_TextBox     - A multi-line text widget\n"
37   "  * GLUI_List        - A static choice list\n"
38   "  * GLUI_FileBrowser - A simple filebrowser based on GLUI_List\n"
39   "  * GLUI_Tree        - Hierarchical tree widget\n"
40   "  * GLUI_TreePanel   - Manager for the tree widget\n";
41 
42 const char scroll[] =
43   "Scrollbar Widget\n"
44   "\n"
45   "The GLUI_Scrollbar can be used more or less like a GLUI_Spinner.\n"
46   "It can be horizontal or vertical, and have float or int values.\n"
47   "\n"
48   "The set_int_limits and set_float_limits functions work properly even\n"
49   "if the min and max values are reversed.  In this way you can choose\n"
50   "whether the left/right or top/bottom is the minimum value.  \n"
51   "\n"
52   "For instance, with set_int_limits(0, 100) you get a normal slider with\n"
53   "0 corresponding to the left (bottom) end, and 100 corresponding to the\n"
54   "right (top) end.\n"
55   "\n"
56   "By calling set_int_limits(100,0) instead, the right (top) end becomes 0,\n"
57   "and the left (bottom) end is 100.\n";
58 
59 const char tree_txt[] = "Tree Widget";
60 
61 const char commandline[] =
62   "CommandLine Widget\n"
63   "\n"
64   "The GLUI_CommandLine is a GLUI_EditText with some special functionality\n"
65   "useful for implementing a simple command-line style input widget.\n"
66   "The main feature is that it maintains a command history buffer so that\n"
67   "users can recall previous commands.\n";
68 
69 const char gstring[] =
70   "GLUI_String\n"
71   "\n"
72   "The GLUI string class used to be wrapper class around \n"
73   "a fixed 300 char buffer.\n"
74   "Now GLUI_String is just a typedef for std::string.\n"
75   "\n"
76   "One new function has been introduced, which is a sprintf() equivalent\n"
77   "for std::string/GLUI_String.\n"
78   "\n"
79   "  glui_format_str(GLUI_String& str, const char *format_str, ...);\n"
80   "\n"
81   "Other than the fact that it takes a GLUI_String as the first argument,\n"
82   "it works just like sprintf().\n";
83 
84 const char list[] =
85   "List Widget\n"
86   "\n"
87   "As seen on the left side of this window.";
88 
89 const char filebrowser[] =
90   "FileBrowserWidget\n"
91   "\n"
92   "As seen in the lower left corner of this window.\n"
93   "\n"
94   "The GLUI_FileBrowser is a subclass of GLUI_List and provides,\n"
95   "a simple file browsing and selecting interface under Windows and Unix.\n"
96   "\n"
97   "Go ahead and give it a try!  Navigate and select files by double-clicking.\n"
98   "If you pick a text file it will be displayed in this GLUI_TextBox.\n";
99 
100 const char text_box[] =
101   "TextBox w/ optional Scrollbar\n"
102   "\n"
103   "A TextBox is a multiline editing box that supports basic navigation, \n"
104   "formatting, and editing capabilities. These are text block selection, \n"
105   "tabs, new lines, arrow key navigation, as well as an optional scrollbar. \n"
106   "The scrollbar is actually a distinct widget and can exist by itself, or \n"
107   "be associated with objects that have a specified callback routine.\n"
108   "\n"
109   "new GLUI_TextBox\n"
110   "Adds a new textbox to a GLUI window, optionally nested within another \n"
111   "rollout or panel.\n"
112   "\n"
113   "Usage:\n"
114   "new GLUI_TextBox(GLUI_Node *glui_or_panel, char *live_var=NULL,\n"
115   "  int scroll = false,\n"
116   "  int id=-1,\n"
117   "  GLUI_Update_CB callback=NULL );\n"
118   "\n"
119   "  panel    - Name of panel to place the TextBox in.\n"
120   "  live_var - Currently unimplemented, this might be used\n"
121   "             in future iterations.\n"
122   "  scroll   - set to \"true\" if you want a scrollbar on the left side\n"
123   "  id       - If callback is defined, it will be passed this integer\n"
124   "             when the value is modified.\n"
125   "  callback - Pointer to callback function of type (*)(int)\n"
126   "\n"
127   "Notes:\n"
128   "The scrollbar widget uses a different callback scheme to communicate with \n"
129   "the textbox. Any object wishing to utilize a scrollbar in some way should \n"
130   "implement a static function in the object with the signature:\n"
131   "\n"
132   "(*)(GLUI_Control *, int)\n"
133   "\n"
134   "Where the first parameter is the object the scrollbar is associated with \n"
135   "and the second is the int_val passed into the object by the scrollbar.\n"
136   "Refer to glui_textbox.cpp and glui_scrollbar.cpp for implementation details.\n"
137   "\n"
138   "Wishlist:\n"
139   "* Word Wrap\n"
140   "* Optimized Drawing (Update only lines that change, etc.)\n"
141   "* Multicolour text\n"
142   "* Current word selection\n"
143   "* copy/paste\n";
144 
145 /*Bugs:\n\
146  * fewer Mouse Drag calls  with large texts\n\
147  * Insertion Pt sometimes drawn on wrong line.\n\
148  * The scrollbar tab does not exactly match mouse position.\n\
149  * Two tabs cannot be placed next to each other in a string without a space between them.\n\
150  * Occasional horizontal drawing overruns.\n\
151  * set_text seems to like being called after all the windows are open for large amounts of text. If you try it with a string longer than 195 characters it seems to trucate it to 195.\n\
152  \n\
153  ";
154 */
155 
156 /***************************************** myGlutDisplay() *****************/
157 
control_cb(int control)158 void control_cb(int control) {
159   int item;
160   GLUI_String text;
161   std::string file_name;
162   FILE  *file;
163   char c;
164   int i;
165   int format;
166   glutPostRedisplay();
167   item = hah->get_current_item();
168 
169   if (control == 7) {
170     i = 0;
171     file_name = "";
172     file_name = fb->get_file();
173     file = fopen(file_name.c_str(),"r");
174     if (file == NULL)
175       printf("Error opening file\n");
176     else {
177       do {
178         c = getc(file);
179         text += c;
180         i++;
181       } while (c != EOF);
182       fclose(file);
183     }
184 
185     moo->set_text(text.c_str());
186   }
187 
188 
189   if ( control == 1 ) {
190     tree->hide();
191     if (item==0) {
192       moo->set_text(general);
193     }
194     if (item==1) {
195       moo->set_text(text_box);
196     }
197     if (item==2) {
198       moo->set_text(scroll);
199     }
200     if (item==3) {
201       moo->set_text(gstring);
202     }
203     if (item==4) {
204       moo->set_text(commandline);
205     }
206     if (item==5) {
207       tree->show();
208       moo->set_text(tree_txt);
209     }
210     if (item==6) {
211       moo->set_text(list);
212     }
213     if (item==7) {
214       moo->set_text(filebrowser);
215     }
216   }
217   if ( control == 2) {
218     tp->ab("foo");
219   }
220   if ( control == 3) {
221       tp->db();
222   }
223   if ( control == 4) {
224     tp->fb();
225   }
226   if ( control == 5) {
227       tp->resetToRoot();
228   }
229   if ( control == 6) {
230       tp->descendBranch();
231   }
232   if ( control == 8) {
233       tp->next();
234   }
235   if ( control == 9) {
236       tp->expand_all();
237   }
238   if ( control == 10) {
239       tp->collapse_all();
240   }
241   if ( control == 11) {
242     format = 0;
243     format = GLUI_TREEPANEL_ALTERNATE_COLOR |
244       GLUI_TREEPANEL_CONNECT_CHILDREN_ONLY;
245 
246     if (num_display)
247       format = format | GLUI_TREEPANEL_DISPLAY_HIERARCHY;
248     if (num_format)
249       format = format | GLUI_TREEPANEL_HIERARCHY_NUMERICDOT;
250     else
251       format = format | GLUI_TREEPANEL_HIERARCHY_LEVEL_ONLY;
252     tp->set_format(format);
253     tp->update_all();
254   }
255   if (control == 12) {
256     if (enable_textbox) {
257       moo->enable();
258     } else {
259       moo->disable();
260     }
261   }
262 }
263 
264 //void out_of_memory() {
265 //  printf("Out of memory!\n\n");
266 //}
267 
268 /**************************************** main() ********************/
269 
main(int argc,char * argv[])270 int main(int argc, char* argv[])
271 {
272   glutInit(&argc, argv);
273 
274   GLUI *edit = GLUI_Master.create_glui("Help on GLUI Widgets", 0);
275   main_window = edit->get_glut_window_id();
276   GLUI_Panel *ep = new GLUI_Panel(edit,"",true);
277   new GLUI_StaticText(ep,"Widget Information:");
278   hah = new GLUI_List(ep,true,1,control_cb);
279   hah->add_item(0,"GLUI 2.3");
280   hah->add_item(1,"TextBox");
281   hah->add_item(2,"Scrollbar");
282   hah->add_item(3,"GLUI_String");
283   hah->add_item(4,"CommandLine");
284   hah->add_item(5,"Tree");
285   hah->add_item(6,"List");
286   hah->add_item(7,"FileBrowser");
287   new GLUI_StaticText(ep,"Open Text File:");
288   fb = new GLUI_FileBrowser(ep, "", false, 7, control_cb);
289   fb->set_h(180);
290   hah->set_h(180);
291   new GLUI_Column(ep,false);
292 
293   moo = new GLUI_TextBox(ep,true);
294   moo->set_text(general);
295   moo->set_h(400);
296   moo->set_w(410);
297   moo->disable();
298   enable_textbox=0;
299   new GLUI_Checkbox(ep, "Enable text box:",&enable_textbox,12,control_cb);
300 
301   tree = GLUI_Master.create_glui("Tree Test", 0);
302   ep = new GLUI_Panel(tree, "Tree Controls");
303   bedit = new GLUI_EditText(ep, "New Branch Name:");
304   new GLUI_Checkbox(ep, "Display Numbers", &num_display);
305   new GLUI_StaticText(ep, "Number format:");
306   GLUI_RadioGroup *rg = new GLUI_RadioGroup(ep, &num_format);
307   new GLUI_RadioButton(rg, "Level Only");
308   new GLUI_RadioButton(rg, "Hierarchal");
309   new GLUI_Button(ep, "Update Format", 11, control_cb);
310   new GLUI_Column(ep);
311   new GLUI_Button(ep, "Add Branch", 2, control_cb);
312   new GLUI_Button(ep, "Del Branch", 3, control_cb);
313   new GLUI_Button(ep, "Up Branch", 4, control_cb);
314   new GLUI_Button(ep, "Goto Root", 5, control_cb);
315   new GLUI_Column(ep);
316   new GLUI_Button(ep, "Descend to Leaf", 6, control_cb);
317   new GLUI_Button(ep, "Next Branch", 8, control_cb);
318   new GLUI_Button(ep, "Expand All", 9, control_cb);
319   new GLUI_Button(ep, "Collapse All", 10, control_cb);
320   tp = new GLUI_TreePanel(tree,"Tree Test");
321   tp->set_format(GLUI_TREEPANEL_ALTERNATE_COLOR |
322                  GLUI_TREEPANEL_CONNECT_CHILDREN_ONLY |
323                  GLUI_TREEPANEL_DISPLAY_HIERARCHY |
324                  GLUI_TREEPANEL_HIERARCHY_NUMERICDOT);
325   tp->set_level_color(1,1,1);
326   tp->ab("foo you");
327   tree->hide();
328 
329   edit->set_main_gfx_window(main_window);
330   tree->set_main_gfx_window(main_window);
331 
332   glutMainLoop();
333   return 0;
334 }
335 
336 
337 
338