1 #include "menu.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <GL/gl.h>
7 #include "options.h"
8 #include "sys_stuff.h"
9
10
menu_new(void (* callback)(int,void *))11 menuType * menu_new( void (* callback)( int, void * ) )
12 {
13 menuType * menu;
14
15 DPRINTF("menu_new:\n");
16
17 menu = malloc(sizeof(menuType));
18 menu->nr = 0;
19 menu->select_id = -1;
20 menu->p_select_id = &(menu->select_id);
21 menu->select_index = 0;
22 menu->textedit_mode = 0;
23 menu->callback = callback;
24 menu->parent = (menuType *)0;
25 return menu;
26 }
27
28
menu_add_submenu(menuType * menu,char * text,menuType * submenu,int show_subsetting)29 void menu_add_submenu( menuType * menu, char * text, menuType * submenu, int show_subsetting )
30 {
31 DPRINTF("menu_add_submenu:\n");
32 if(menu->nr<MAX_MENU_ENTRY_NUM){
33 menu->entry[menu->nr].type = ENTRY_TYPE_SUBMENU;
34 strcpy( menu->entry[menu->nr].text, text);
35 menu->entry[menu->nr].settingtext[0] = 0;
36 menu->entry[menu->nr].submenu = submenu;
37 menu->entry[menu->nr].text_obj = (textObj *)0;
38 // menu->entry[menu->nr].settingtext_obj = (textObj *)0;
39 menu->entry[menu->nr].fontname = options_menu_fontname;
40 menu->entry[menu->nr].fontsize = 32;
41 menu->entry[menu->nr].show_subsetting = show_subsetting;
42 menu->entry[menu->nr].arg = (void *) 0;
43 if(submenu!=(menuType *)0){
44 submenu->callback = menu->callback;
45 submenu->p_select_id = menu->p_select_id;
46 submenu->parent = menu;
47 submenu->parent_entry = &(menu->entry[menu->nr]);
48 }
49 menu->nr++;
50 } else {
51 printf("menu_add_submenu: too many menu entries - ignoring this entry\n");
52 }
53 }
54
55
menu_add_entry(menuType * menu,char * text,int id)56 void menu_add_entry( menuType * menu, char * text, int id )
57 {
58 DPRINTF("menu_add_entry:\n");
59 if(menu->nr<MAX_MENU_ENTRY_NUM){
60 menu->entry[menu->nr].type = ENTRY_TYPE_ID;
61 strcpy( menu->entry[menu->nr].text, text );
62 menu->entry[menu->nr].settingtext[0] = 0;
63 menu->entry[menu->nr].id = id;
64 menu->entry[menu->nr].text_obj = (textObj *)0;
65 // menu->entry[menu->nr].settingtext_obj = (textObj *)0;
66 menu->entry[menu->nr].fontname = options_menu_fontname;
67 menu->entry[menu->nr].fontsize = 32;
68 menu->entry[menu->nr].arg = (void *) 0;
69 menu->nr++;
70 } else {
71 printf("menu_add_entry: too many menu entries - ignoring this entry\n");
72 }
73 }
74
75
menu_add_arg_entry(menuType * menu,char * text,int id,void * arg)76 void menu_add_arg_entry( menuType * menu, char * text, int id, void * arg )
77 {
78 DPRINTF("menu_add_arg_entry:\n");
79 if(menu->nr<MAX_MENU_ENTRY_NUM){
80 menu->entry[menu->nr].type = ENTRY_TYPE_ID;
81 strcpy( menu->entry[menu->nr].text, text );
82 menu->entry[menu->nr].settingtext[0] = 0;
83 menu->entry[menu->nr].id = id;
84 menu->entry[menu->nr].text_obj = (textObj *)0;
85 // menu->entry[menu->nr].settingtext_obj = (textObj *)0;
86 menu->entry[menu->nr].fontname = options_menu_fontname;
87 menu->entry[menu->nr].fontsize = 32;
88 menu->entry[menu->nr].arg = arg;
89 menu->nr++;
90 } else {
91 printf("menu_add_arg_entry: too many menu entries - ignoring this entry\n");
92 }
93 }
94
95
menu_add_textfield(menuType * menu,char * text,int id,int fixedlen)96 void menu_add_textfield( menuType * menu, char * text, int id, int fixedlen )
97 {
98 DPRINTF("menu_add_arg_entry:\n");
99 if(menu->nr<MAX_MENU_ENTRY_NUM){
100 menu->entry[menu->nr].type = ENTRY_TYPE_TEXTFIELD;
101 strcpy( menu->entry[menu->nr].text, text );
102 menu->entry[menu->nr].settingtext[0] = 0;
103 menu->entry[menu->nr].id = id;
104 menu->entry[menu->nr].text_obj = (textObj *)0;
105 // menu->entry[menu->nr].settingtext_obj = (textObj *)0;
106 menu->entry[menu->nr].fontname = options_menu_fontname;
107 menu->entry[menu->nr].fontsize = 32;
108 menu->entry[menu->nr].arg = (void *)0;
109 menu->entry[menu->nr].fixedlen = fixedlen;
110 menu->nr++;
111 } else {
112 printf("menu_add_textfield: too many menu entries - ignoring this entry\n");
113 }
114 }
115
116
menu_add_exit(menuType * menu,char * text)117 void menu_add_exit( menuType * menu, char * text )
118 {
119 DPRINTF("menu_add_exit:\n");
120 if(menu->nr<MAX_MENU_ENTRY_NUM){
121 menu->entry[menu->nr].type = ENTRY_TYPE_EXIT;
122 strcpy( menu->entry[menu->nr].text, text );
123 menu->entry[menu->nr].settingtext[0] = 0;
124 menu->entry[menu->nr].text_obj = (textObj *)0;
125 // menu->entry[menu->nr].settingtext_obj = (textObj *)0;
126 menu->entry[menu->nr].fontname = options_menu_fontname;
127 menu->entry[menu->nr].fontsize = 32;
128 menu->entry[menu->nr].arg = (void *) 0;
129 menu->nr++;
130 } else {
131 printf("menu_add_exit: too many menu entries - ignoring this entry\n");
132 }
133 }
134
135
menu_entry_set_text(menuEntry * entry,char * text)136 void menu_entry_set_text( menuEntry * entry, char * text )
137 {
138 char str[256];
139 strcpy( entry->text, text );
140 if( entry->text_obj != (textObj *)0 ){
141 if( entry->show_subsetting && entry->settingtext[0]!=0 ){
142 sprintf(str,"%s : %s",entry->text,entry->settingtext);
143 textObj_setText( entry->text_obj, str );
144 // textObj_setText( entry->text_obj, text );
145 } else {
146 textObj_setText( entry->text_obj, text );
147 }
148 }
149 }
150
151
menu_entry_set_settingtext(menuEntry * entry,char * text)152 void menu_entry_set_settingtext( menuEntry * entry, char * text )
153 {
154 char str[256];
155 strcpy( entry->settingtext, text );
156 if( entry->text_obj != (textObj *)0 ){
157 if( entry->show_subsetting && entry->settingtext[0]!=0 ){
158 sprintf(str,"%s : %s",entry->text,entry->settingtext);
159 textObj_setText( entry->text_obj, str );
160 /* sprintf(str," : %s",entry->settingtext);
161 if( entry->settingtext_obj != (textObj *)0 ){
162 textObj_setText( entry->settingtext_obj, str );
163 } else {
164 entry->settingtext_obj=textObj_new( str, entry->fontname, entry->fontsize );
165 }*/
166 } else {
167 textObj_setText( entry->text_obj, text );
168 }
169 }
170 }
171
172
menu_create_textobj(menuEntry * entry)173 static void menu_create_textobj( menuEntry * entry )
174 {
175 char str[256];
176 if( entry->text_obj == (textObj *)0 ){
177 if( entry->show_subsetting && entry->settingtext[0]!=0 ){
178 sprintf(str,"%s : %s",entry->text,entry->settingtext);
179 entry->text_obj = textObj_new( str, entry->fontname, entry->fontsize );
180 /* entry->text_obj = textObj_new( entry->text, entry->fontname, entry->fontsize );
181 sprintf(str," : %s",entry->settingtext);
182 entry->settingtext_obj = textObj_new( str, entry->fontname, entry->fontsize );*/
183 } else {
184 entry->text_obj = textObj_new( entry->text, entry->fontname, entry->fontsize );
185 }
186 // textObj_toggle3D(entry->text_obj);
187 }
188 }
189
menu_select_by_coord(menuType * menu,int x,int y)190 void menu_select_by_coord( menuType * menu, int x, int y )
191 /* selects the menupoint under the pos x,y */
192 {
193 int i,x1,y1,x2,y2, all_height;
194
195 if(!menu->textedit_mode){
196 all_height=0;
197 for(i=0;i<menu->nr;i++){
198 all_height+=menu->entry[i].fontsize;
199 }
200
201 for(i=0;i<menu->nr;i++){
202 // fprintf( stderr, "menu->entry[i].text_obj = %d\n", menu->entry[i].text_obj );
203 if( menu->entry[i].text_obj == (textObj *)0 ){
204 menu_create_textobj( &(menu->entry[i]) );
205 }
206 x1 = -menu->entry[i].text_obj->quad_w/2;
207 y1 = all_height/2-i*menu->entry[i].fontsize-menu->entry[i].text_obj->quad_h/2;
208 x2 = +menu->entry[i].text_obj->quad_w/2;
209 y2 = all_height/2-i*menu->entry[i].fontsize+menu->entry[i].text_obj->quad_h/2;
210 if( x<=x2 && x>=x1 && y<=y2 && y>=y1 ){
211 menu->select_index=i;
212 *(menu->p_select_id)=menu->entry[i].id;
213 }
214 }
215 }
216 }
217
218
menu_select_next(menuType * menu)219 void menu_select_next( menuType * menu )
220 /* selects the next menupoint in the current submenu */
221 {
222 if(!menu->textedit_mode){
223 (menu->select_index)++;
224 if( menu->select_index >= menu->nr ) menu->select_index=0;
225 *(menu->p_select_id) = menu->entry[menu->select_index].id;
226 }
227 }
228
menu_select_prev(menuType * menu)229 void menu_select_prev( menuType * menu )
230 /* selects the previous menupoint in the current submenu */
231 {
232 if(!menu->textedit_mode){
233 (menu->select_index)--;
234 if( menu->select_index < 0 ) menu->select_index=(menu->nr)-1;
235 *(menu->p_select_id) = menu->entry[menu->select_index].id;
236 }
237 }
238
menu_choose(menuType ** menu)239 void menu_choose(menuType ** menu)
240 {
241 DPRINTF("menu_choose:\n");
242 if( (*menu)->entry[(*menu)->select_index].type==ENTRY_TYPE_SUBMENU ) {
243
244 DPRINTF("menu_choose: switch submenu\n");
245 // menu_texObj_cleanup(menu);
246 (*menu)=(*menu)->entry[(*menu)->select_index].submenu;
247
248 } else if( (*menu)->entry[(*menu)->select_index].type==ENTRY_TYPE_ID ) {
249
250 DPRINTF("menu_choose: id=%d\n",(*menu)->entry[(*menu)->select_index].id);
251 if( (*menu)->parent_entry != 0 ){
252 if( (*menu)->parent_entry->show_subsetting ){
253 menu_entry_set_settingtext( (*menu)->parent_entry, (*menu)->entry[(*menu)->select_index].text );
254 }
255 }
256 (*menu)->callback( (*menu)->entry[(*menu)->select_index].id,
257 (*menu)->entry[(*menu)->select_index].arg );
258 menu_exit(menu);
259
260 } else if( (*menu)->entry[(*menu)->select_index].type==ENTRY_TYPE_TEXTFIELD ) {
261 DPRINTF("menu_choose: ENTRY_TYPE_TEXTFIELD\n");
262 if(!(*menu)->textedit_mode){
263 DPRINTF("menu_choose: ENTRY_TYPE_TEXTFIELD - !textedit_mode\n");
264 (*menu)->textedit_mode=1;
265 } else {
266 DPRINTF("menu_choose: ENTRY_TYPE_TEXTFIELD - textedit_mode\n");
267 (*menu)->textedit_mode=0;
268 strcpy((*menu)->entry[(*menu)->select_index].text,
269 (*menu)->entry[(*menu)->select_index].text_obj->str);
270 /* give the entered string as arg */
271 (*menu)->entry[(*menu)->select_index].arg = (void *)&((*menu)->entry[(*menu)->select_index].text[(*menu)->entry[(*menu)->select_index].fixedlen]);
272 DPRINTF("printing arg:\n");
273 DPRINTF("%s\n",(char *)((*menu)->entry[(*menu)->select_index].arg));
274 (*menu)->callback( (*menu)->entry[(*menu)->select_index].id,
275 (*menu)->entry[(*menu)->select_index].arg );
276 }
277 } else if( (*menu)->entry[(*menu)->select_index].type==ENTRY_TYPE_EXIT ) {
278
279 menu_exit(menu);
280
281 }
282 }
283
284
menu_exit(menuType ** menu)285 void menu_exit(menuType ** menu)
286 {
287 DPRINTF("menu_exit:\n");
288 if(!(*menu)->textedit_mode){
289 /* if( (*menu)->parent != (menuType *)0 ){*/
290 DPRINTF("menu_exit: switch to parent\n");
291 menu_texObj_cleanup(*menu);
292 *menu=(*menu)->parent;
293 DPRINTF("menu_exit: switch to parent - end\n");
294 /* } else {
295 fprintf(stderr,"menu_exit: cleanup only\n");
296 menu_texObj_cleanup(*menu);
297 }*/
298 } else {
299 textObj_setText( (*menu)->entry[(*menu)->select_index].text_obj, (*menu)->entry[(*menu)->select_index].text );
300 (*menu)->textedit_mode=0;
301 }
302 }
303
304
305
menu_text_keystroke(menuType * menu,int key)306 void menu_text_keystroke( menuType * menu, int key )
307 {
308 if(menu->textedit_mode){
309 switch(key){
310 case 8:
311 if(strlen(menu->entry[menu->select_index].text_obj->str) > menu->entry[menu->select_index].fixedlen)
312 textObj_delete_last( menu->entry[menu->select_index].text_obj );
313 break;
314 default:
315 if (isprint(key))
316 textObj_append_char( menu->entry[menu->select_index].text_obj, key );
317 break;
318 }
319 }
320 }
321
322
323
menu_draw_entry(menuEntry * entry)324 static void menu_draw_entry( menuEntry * entry )
325 {
326 if( entry->text_obj == (textObj *)0 ){
327 menu_create_textobj( entry );
328 }
329 textObj_draw_centered(entry->text_obj);
330 /* if( entry->show_subsetting ){
331 textObj_draw_bound(entry->text_obj, HBOUND_RIGHT, VBOUND_CENTER );
332 if(entry->settingtext_obj != (textObj *)0 ){
333 textObj_draw_bound(entry->settingtext_obj, HBOUND_LEFT, VBOUND_CENTER );
334 }
335 } else {
336 textObj_draw_bound(entry->text_obj, HBOUND_CENTER, VBOUND_CENTER );
337 }*/
338 }
339
menu_draw(menuType * menu)340 void menu_draw( menuType * menu )
341 {
342 int i,all_height;
343
344 // fprintf(stderr,"menu_draw:\n");
345
346 // fprintf(stderr,"menu_draw: calc total height\n");
347 all_height=0;
348 for(i=0;i<menu->nr;i++){
349 all_height+=menu->entry[i].fontsize;
350 }
351
352 // fprintf(stderr,"menu_draw: draw\n");
353 glPushMatrix();
354 glTranslatef(0,all_height/2,0);
355 // for(i=0;i<1/*menu->nr*/;i++){
356 for(i=0;i<menu->nr;i++){
357 /* hilight the entry with id=*p_select_id */
358 // fprintf(stderr,"menu_draw: draw entry#%d\n",i);
359 if( i==menu->select_index ){ /* selected menu entry */
360 if(menu->textedit_mode){ /* if textedit-field */
361 glColor3f(1.0,0.0,0.0);
362 menu_draw_entry(&(menu->entry[i]));
363 } else {
364 glPushMatrix();
365 glScalef(1.1,1.1,1.0);
366 glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_COLOR );
367 glColor3f(1.0,1.0,1.0);
368 glTranslatef(2,2,0);
369 menu_draw_entry(&(menu->entry[i]));
370 glTranslatef(-4,0,0);
371 menu_draw_entry(&(menu->entry[i]));
372 glTranslatef(0,-4,0);
373 menu_draw_entry(&(menu->entry[i]));
374 glTranslatef(4,0,0);
375 menu_draw_entry(&(menu->entry[i]));
376 glTranslatef(-2,2,0);
377 glBlendFunc(GL_ONE,GL_ONE);
378 glColor3f(1.0,1.0,0.0);
379 menu_draw_entry(&(menu->entry[i]));
380 glPopMatrix();
381 }
382 } else { /* normal menu entry */
383 glPushMatrix();
384 glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR);
385 glColor3f(1.0,1.0,1.0);
386 glTranslatef(2,2,0);
387 menu_draw_entry(&(menu->entry[i]));
388 glTranslatef(-4,0,0);
389 menu_draw_entry(&(menu->entry[i]));
390 glTranslatef(0,-4,0);
391 menu_draw_entry(&(menu->entry[i]));
392 glTranslatef(4,0,0);
393 menu_draw_entry(&(menu->entry[i]));
394 glTranslatef(-2,2,0);
395 glBlendFunc(GL_ONE,GL_ONE);
396 glColor3f(1.0,1.0,1.0);
397 menu_draw_entry(&(menu->entry[i]));
398 glPopMatrix();
399 }
400
401 glTranslatef(0,-menu->entry[i].fontsize,0);
402 }
403 glPopMatrix();
404 // fprintf(stderr,"menu_draw: end\n");
405 }
406
407
menu_texObj_cleanup(menuType * menu)408 void menu_texObj_cleanup(menuType * menu)
409 /* releases the gl-lists and the allocated textures */
410 {
411 int i;
412
413 DPRINTF("menu_texObj_cleanup:\n");
414 if( menu != (menuType *)0 ){
415 for ( i=0 ; i<menu->nr ; i++ ) {
416 DPRINTF("menu_texObj_cleanup: i=%d (%s)\n",i,menu->entry[i].text);
417
418 if( menu->entry[i].text_obj != (textObj *)0 )
419 textObj_delete(menu->entry[i].text_obj);
420 DPRINTF("menu_texObj_cleanup: 1\n");
421 // if( menu->entry[i].settingtext_obj != (textObj *)0 )
422 // textObj_delete(menu->entry[i].settingtext_obj);
423
424 if( menu->entry[i].type == ENTRY_TYPE_SUBMENU ){
425 DPRINTF("menu_texObj_cleanup: menu_texObj_cleanup\n");
426 menu_texObj_cleanup(menu->entry[i].submenu);
427 }
428 DPRINTF("menu_texObj_cleanup: 2\n");
429
430 if( menu->entry[i].text_obj != (textObj *)0 )
431 free(menu->entry[i].text_obj);
432
433 DPRINTF("menu_texObj_cleanup: 3\n");
434 menu->entry[i].text_obj = (textObj *)0;
435 DPRINTF("menu_texObj_cleanup: 4\n");
436 }
437 }
438 }
439