use qsort and file_sort_func instead of file_sort
[btb/d2x.git] / ui / menubar.c
1 /* $Id: menubar.c,v 1.8 2005-02-27 03:55:46 chris Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef RCS
16 static char rcsid[] = "$Id: menubar.c,v 1.8 2005-02-27 03:55:46 chris Exp $";
17 #endif
18
19 #ifdef HAVE_CONFIG_H
20 #include "conf.h"
21 #endif
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #include "u_mem.h"
28 #include "fix.h"
29 #include "pstypes.h"
30 #include "gr.h"
31 #include "ui.h"
32 #include "key.h"
33 #include "cfile.h"
34
35 #include "mono.h"
36
37 #include "func.h"
38
39 #include "error.h"
40
41
42 #define MAXMENUS 30
43 #define MAXITEMS 32
44
45 typedef struct {
46         short                   x, y, w, h;
47         char                            *Text;
48         char                            *InactiveText;
49         short                   Hotkey;
50         int                     (*user_function)(void);
51 } ITEM;
52
53 typedef struct {
54         short                   x, y, w, h;
55         short                           ShowBar;
56         short                           CurrentItem;
57         short                           NumItems;
58         short                           Displayed;
59         short                           Active;
60         grs_bitmap *    Background;
61         ITEM                            Item[MAXITEMS];
62 } MENU;
63
64 MENU Menu[MAXMENUS];
65
66 static int num_menus = 0;
67 static int state;
68 static int menubar_hid;
69
70 #define CMENU (Menu[0].CurrentItem+1)
71
72 //------------------------- Show a menu item -------------------
73
74 void item_show( MENU * menu, int n )
75 {
76         ITEM * item = &menu->Item[n];
77         
78         gr_set_current_canvas(NULL);
79         // If this is a seperator, then draw it.
80         if ( item->Text[0] == '-'  )
81         {
82                 gr_setcolor( CBLACK );
83                 gr_urect( item->x, item->y+item->h/2, item->x+item->w-1, item->y+item->h/2 );
84                 return;
85         }       
86
87         if ( menu->CurrentItem==n && menu->ShowBar )
88         {
89                 if ( menu != &Menu[0] )
90                 {
91                         gr_setcolor( CBLACK );
92                         gr_urect( item->x+1, item->y+1, item->x+menu->w-2, item->y+item->h-2 );
93                 }
94                 gr_set_fontcolor( CWHITE, CBLACK );
95         }else {
96                 if ( menu != &Menu[0] )
97                 {
98                         gr_setcolor( CGREY );
99                         gr_urect( item->x+1, item->y+1, item->x+menu->w-2, item->y+item->h-2 );
100                 }
101                 gr_set_fontcolor( CBLACK, CGREY );
102         }
103
104         if ( menu != &Menu[0] )
105         {
106                 if ( menu->Active)
107                         gr_ustring( item->x+1, item->y+1, item->Text );
108                 else
109                         gr_ustring( item->x+1, item->y+1, item->InactiveText );
110         } else {
111                 if ( menu->Active)
112                         gr_ustring( item->x, item->y, item->Text );
113                 else
114                         gr_ustring( item->x, item->y, item->InactiveText );
115         }
116 }
117
118 //---------------------------- Show a menu ---------------------
119
120 void menu_show( MENU * menu )
121 {
122         int i;
123
124         ui_mouse_hide();
125
126         gr_set_current_canvas(NULL);
127         // Don't save background it if it's already drawn
128         if (!menu->Displayed) 
129         {
130                 // Save the background
131                 gr_bm_ubitblt(menu->w, menu->h, 0, 0, menu->x, menu->y, &(grd_curscreen->sc_canvas.cv_bitmap), menu->Background);
132
133                 // Draw the menu background
134                 gr_setcolor( CGREY );
135                 gr_urect( menu->x, menu->y, menu->x + menu->w - 1, menu->y + menu->h - 1 );
136                 if ( menu != &Menu[0] )
137                 {
138                         gr_setcolor( CBLACK );
139                         gr_ubox( menu->x, menu->y, menu->x + menu->w - 1, menu->y + menu->h - 1 );
140                 }
141         }
142                 
143         // Draw the items
144         
145         for (i=0; i< menu->NumItems; i++ )
146                 item_show( menu, i );
147
148         ui_mouse_show();
149         
150         // Mark as displayed.
151         menu->Displayed = 1;
152 }
153
154 //-------------------------- Hide a menu -----------------------
155
156 void menu_hide( MENU * menu )
157 {
158
159         // Can't hide if it's not already drawn
160         if (!menu->Displayed) return;
161
162         menu->Active = 0;
163                 
164         // Restore the background
165         ui_mouse_hide();
166
167         gr_bm_ubitblt(menu->w, menu->h, menu->x, menu->y, 0, 0, menu->Background, &(grd_curscreen->sc_canvas.cv_bitmap));
168
169         ui_mouse_show();
170         
171         // Mark as hidden.
172         menu->Displayed = 0;
173 }
174
175
176 //------------------------- Move the menu bar ------------------
177
178 void menu_move_bar_to( MENU * menu, int number )
179 {
180         int old_item;
181
182         old_item = menu->CurrentItem;
183         menu->CurrentItem = number;
184         
185         if (menu->Displayed && (number != old_item))
186         {
187                 ui_mouse_hide();
188
189                 item_show( menu, old_item );
190                 item_show( menu, number );
191
192                 ui_mouse_show();
193         }
194 }
195
196 //------------------------ Match keypress to item ------------------
197 int menu_match_keypress( MENU * menu, int keypress )
198 {
199         int i;
200         char c;
201         char *letter;
202
203         if ((keypress & KEY_CTRLED) || (keypress & KEY_SHIFTED))
204                 return -1;
205         
206         keypress &= 0xFF;
207
208         c = key_to_ascii(keypress);
209                         
210         for (i=0; i< menu->NumItems; i++ )
211         {
212                 letter = strrchr( menu->Item[i].Text, CC_UNDERLINE );
213                 if (letter)
214                 {
215                         letter++;
216                         if (c==tolower(*letter))
217                                 return i;
218                 }
219         }
220         return -1;
221 }
222
223
224 int menu_is_mouse_on( ITEM * item )
225 {
226         if ((Mouse.x >= item->x) &&
227                 (Mouse.x < item->x + item->w ) &&
228                 (Mouse.y >= item->y) &&
229                 (Mouse.y <= item->y + item->h ) )
230                 return 1;
231         else
232                 return 0;
233 }
234
235 int menu_check_mouse_item( MENU * menu )
236 {
237         int i;
238         
239         for (i=0; i<menu->NumItems; i++ )
240         {
241                 if (menu_is_mouse_on( &menu->Item[i] ))
242                 {
243                         if (menu->Item[i].Text[0] == '-')
244                                 return -1;
245                         else
246                                 return i;
247                 }
248         }
249         return -1;
250 }
251
252
253 void menu_hide_all()
254 {
255         int i;
256
257         for (i=1; i<num_menus; i++) 
258                 menu_hide( &Menu[i] );
259         
260         Menu[0].ShowBar = 0;
261         Menu[0].Active = 0;
262         menu_show( &Menu[0] );
263
264 }
265
266
267 static int state2_alt_down;
268
269 void do_state_0( int keypress )
270 {
271         int i, j;
272         
273         Menu[0].Active = 0;
274         Menu[0].ShowBar = 0;
275         if (Menu[0].Displayed==0)
276                 menu_show( &Menu[0] );
277
278         if ( keypress & KEY_ALTED )     {
279                 i = menu_match_keypress( &Menu[0], keypress );
280                 if (i > -1 )
281                 {
282                         Menu[0].CurrentItem = i;
283                         Menu[0].Active = 0;
284                         state = 3;      
285                         Menu[ CMENU ].ShowBar = 1;
286                         Menu[ CMENU ].Active = 1;
287                         Menu[0].ShowBar = 1;
288         
289                         menu_show( &Menu[ CMENU ] );
290                         menu_show( &Menu[0] );
291                 }
292         }
293         
294         for (i=0; i<num_menus; i++ )
295                 for (j=0; j< Menu[i].NumItems; j++ )
296                 {
297                         if ( Menu[i].Item[j].Hotkey == keypress )
298                         {
299                                 if (Menu[i].Item[j].user_function)
300                                         Menu[i].Item[j].user_function();
301                                 last_keypress = 0;
302                                 return;
303                         }
304                 }
305                 
306         if (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] || ((keypress & 0xFF) == KEY_LALT) )
307         //if ( (keypress & 0xFF) == KEY_LALT )
308         {
309                 state = 1;
310                 Menu[0].Active = 1;
311                 menu_show( &Menu[0] );
312                 return;
313         }
314
315         i = menu_check_mouse_item( &Menu[0] );
316
317         if ( B1_PRESSED && (i > -1))
318         {
319                 Menu[0].CurrentItem = i;
320                 state = 3;      
321                 Menu[ CMENU ].ShowBar = 1;
322                 Menu[0].ShowBar = 1;
323                 Menu[ CMENU ].Active = 1;
324                 Menu[0].Active = 0;
325                 menu_show( &Menu[ CMENU ] );
326                 menu_show( &Menu[0] );
327                 return;
328         }
329 }
330
331 void do_state_1( int keypress )
332 {
333         int i;
334
335         if (!keyd_pressed[KEY_LALT] && !keyd_pressed[KEY_RALT] )
336         {
337                 //state = 2;
338                 //state2_alt_down = 0;
339                 //Menu[0].ShowBar = 1;
340                 //Menu[0].Active = 1;
341                 //menu_show( &Menu[0] );
342                 state = 0;
343                 menu_hide_all();
344         }
345
346         i = menu_match_keypress( &Menu[0], keypress );
347         
348         if (i > -1 )
349         {
350                 Menu[0].CurrentItem = i;
351                 Menu[0].Active = 0;
352                 state = 3;      
353                 Menu[ CMENU ].ShowBar = 1;
354                 Menu[ CMENU ].Active = 1;
355                 Menu[0].ShowBar = 1;
356
357                 menu_show( &Menu[ CMENU ] );
358                 menu_show( &Menu[0] );
359         }
360
361         i = menu_check_mouse_item( &Menu[0] );
362
363         if ( (i == -1) && B1_JUST_RELEASED )
364         {
365                 state = 0;
366                 menu_hide_all();
367         }
368
369         if ( B1_PRESSED && (i > -1))
370         {
371                 Menu[0].CurrentItem = i;
372                 state = 3;      
373                 Menu[ CMENU ].ShowBar = 1;
374                 Menu[ CMENU ].Active = 1;
375                 Menu[0].ShowBar = 1;
376                 Menu[0].Active = 0;
377                 menu_show( &Menu[ CMENU ] );
378                 menu_show( &Menu[0] );
379         }
380 }
381
382 void do_state_2(int keypress)
383 {
384         int i;
385
386         if (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
387                 state2_alt_down = 1;
388
389         if (!keyd_pressed[KEY_LALT] && !keyd_pressed[KEY_RALT] && state2_alt_down )
390         {
391                 state = 0;
392                 menu_hide_all();
393         }                       
394
395         switch( keypress )
396         {
397         case KEY_ESC:
398                 state = 0;
399                 menu_hide_all();
400                 break;
401         case KEY_LEFT:
402         case KEY_PAD4:
403                 i = Menu[0].CurrentItem-1;
404                 if (i < 0 ) i = Menu[0].NumItems-1;
405                 menu_move_bar_to( &Menu[0], i );
406                 break;
407         case KEY_RIGHT:
408         case KEY_PAD6:
409                 i = Menu[0].CurrentItem+1;
410                 if (i >= Menu[0].NumItems ) i = 0;
411                 menu_move_bar_to( &Menu[0], i );
412                 break;
413         case KEY_ENTER:
414         case KEY_PADENTER:
415         case KEY_DOWN:
416         case KEY_PAD2:
417                 state = 3;      
418                 Menu[ CMENU ].ShowBar = 1;
419                 Menu[ CMENU ].Active = 1;
420                 Menu[0].Active = 0;
421                 menu_show( &Menu[ 0 ] );
422                 menu_show( &Menu[ CMENU ] );
423                 break;
424         
425         default:
426                 i = menu_match_keypress( &Menu[0], keypress );
427         
428                 if (i > -1 )
429                 {
430                         Menu[0].CurrentItem = i;
431                         Menu[0].Active = 0;
432                         state = 3;      
433                         Menu[ CMENU ].ShowBar = 1;
434                         Menu[ CMENU ].Active = 1;
435                         Menu[0].ShowBar = 1;
436                         menu_show( &Menu[ CMENU ] );
437                         menu_show( &Menu[0] );
438                         break;
439                 }
440
441                 i = menu_check_mouse_item( &Menu[0] );
442
443                 if ( (i == -1) && B1_JUST_RELEASED )
444                 {
445                         state = 0;
446                         menu_hide_all();
447                         break;
448                 }
449
450                 if ( B1_PRESSED && (i > -1))
451                 {
452                         Menu[0].CurrentItem = i;
453                         Menu[0].Active = 0;
454                         state = 3;      
455                         Menu[ CMENU ].ShowBar = 1;
456                         Menu[ CMENU ].Active = 1;
457                         Menu[0].ShowBar = 1;
458                         menu_show( &Menu[ CMENU ] );
459                         menu_show( &Menu[0] );
460                         break;
461                 }
462
463
464         }
465 }
466
467
468
469 void do_state_3( int keypress )
470 {
471         int i;
472         
473         switch( keypress )
474         {
475         case KEY_ESC:
476                 state = 0;
477                 menu_hide_all();
478                 break;
479         case KEY_DOWN:
480         case KEY_PAD2:
481                 i = Menu[ CMENU ].CurrentItem;
482                 do {
483                         i++;            
484                         if ( i >= Menu[ CMENU ].NumItems )
485                                 i = 0;
486                 } while( Menu[CMENU].Item[i].Text[0] == '-');
487                 menu_move_bar_to( &Menu[ CMENU ], i );
488                 break;
489         case KEY_UP:
490         case KEY_PAD8:
491                 i = Menu[ CMENU ].CurrentItem;
492                 do 
493                 {
494                         i--;
495                         if ( i < 0 )
496                                 i = Menu[ CMENU ].NumItems-1;
497                 } while( Menu[CMENU].Item[i].Text[0] == '-');
498                 menu_move_bar_to( &Menu[ CMENU ], i );
499                 break;
500         case KEY_RIGHT:
501         case KEY_PAD6:
502                 menu_hide( &Menu[ CMENU ] );
503                 i = Menu[0].CurrentItem+1;
504                 if (i >= Menu[0].NumItems ) i = 0;
505                 menu_move_bar_to( &Menu[0], i );
506                 Menu[CMENU].ShowBar = 1;
507                 Menu[CMENU].Active = 1;
508                 menu_show( &Menu[CMENU] );
509                 break;
510         case KEY_LEFT:
511         case KEY_PAD4:
512                 menu_hide( &Menu[ CMENU ] );
513                 i = Menu[0].CurrentItem-1;
514                 if (i < 0 ) i = Menu[0].NumItems-1;
515                 menu_move_bar_to( &Menu[0], i );
516                 Menu[ CMENU ].ShowBar = 1;
517                 Menu[CMENU].Active = 1;
518                 menu_show( &Menu[ CMENU ] );
519                 break;
520         case KEY_ENTER:
521         case KEY_PADENTER:
522                 state = 0;
523                 menu_hide_all();
524
525                 if (Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function)
526                         Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function();
527                 
528                 break;
529                 
530         default:
531                 i = menu_match_keypress( &Menu[ CMENU ], keypress );
532
533                 if (i > -1 )
534                 {
535                         menu_move_bar_to( &Menu[ CMENU ], i );
536                         state = 0;
537                         menu_hide_all();
538                                                         
539                         if (Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function)
540                                 Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function();
541                         break;
542                 }
543                 i = menu_check_mouse_item( &Menu[CMENU] );
544                         
545                 if (i > -1 )
546                 {
547                         if ( B1_PRESSED )
548                                 menu_move_bar_to( &Menu[ CMENU ], i );
549                         else if ( B1_JUST_RELEASED )
550                         {
551                                 menu_move_bar_to( &Menu[ CMENU ], i );
552                                 state = 0;
553                                 menu_hide_all();
554                                                                 
555                                 if (Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function)
556                                         Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function();
557                                 break;
558                         }
559                 } else {
560                         i = menu_check_mouse_item( &Menu[0] );
561
562                         if ( B1_PRESSED && (i > -1))
563                         {
564                                 if ( Menu[0].CurrentItem != i)  {
565                                         menu_hide( &Menu[ CMENU ] );
566                                         menu_move_bar_to( &Menu[0], i );
567                                         Menu[ CMENU ].ShowBar = 1;
568                                         Menu[CMENU].Active = 1;
569                                         menu_show( &Menu[ CMENU ] );
570                                         break;
571                                 }
572                         }
573
574                         if ( B1_JUST_RELEASED )
575                         {
576                                 state = 0;
577                                 menu_hide_all();
578                                 break;
579                         }
580
581                 }
582
583         }
584 }
585         
586 void menubar_do( int keypress )
587 {
588         if (menubar_hid) return;
589                 
590         keypress = keypress;
591         do_state_0(last_keypress);
592         
593         while (state > 0 )
594         {
595                 ui_mega_process();
596                 switch(state)
597                 {
598                 case 1:
599                         do_state_1(last_keypress);
600                         break;
601                 case 2:
602                         do_state_2(last_keypress);
603                         break;
604                 case 3:
605                         do_state_3(last_keypress);                      
606                         break;
607                 default:
608                         state = 0;
609                 }
610                 last_keypress  = 0;
611
612                 gr_update();
613         }
614 }
615
616 void CommaParse( int n, char * dest, char * source )
617 {
618         int i = 0, j=0, cn = 0;
619
620         // Go to the n'th comma
621         while (cn < n )
622                 if (source[i++] == ',' )
623                         cn++;
624         // Read all the whitespace
625         while ( source[i]==' ' || source[i]=='\t' || source[i]==13 || source[i]==10 )
626                 i++;
627
628         // Read up until the next comma
629         while ( source[i] != ',' )
630         {
631                 dest[j] = source[i++];
632                 j++;            
633         }
634
635         // Null-terminate       
636         dest[j++] = 0;
637 }
638
639 //translate '&' characters to the underline character
640 void ul_xlate(char *s)
641 {
642         while ((s=strchr(s,'&'))!=NULL)
643                 *s = CC_UNDERLINE;
644 }
645
646
647 void menubar_init( char * file )
648 {
649         int i,j, np;
650         int aw, w, h;
651         CFILE * infile;
652         char buffer[200];
653         char buf1[200];
654         char buf2[200];
655         int menu, item;
656                 
657         num_menus = state = 0;
658
659         for (i=0; i < MAXMENUS; i++ )
660         {
661                 Menu[i].x = Menu[i].y = Menu[i].w = Menu[i].h = 0;
662                 Menu[i].ShowBar = 0;
663                 Menu[i].CurrentItem = 0;
664                 Menu[i].NumItems = 0;
665                 Menu[i].Displayed = 0;
666                 Menu[i].Background = 0;
667                 for (j=0; j< MAXITEMS; j++ )
668                 {
669                         Menu[i].Item[j].x = Menu[i].Item[j].y = Menu[i].Item[j].w = Menu[i].Item[j].h = 0;
670                         Menu[i].Item[j].Text = NULL;
671                         Menu[i].Item[j].Hotkey = -1;
672                         Menu[i].Item[j].user_function = NULL;
673                 }
674         }
675                 
676         infile = cfopen( file, "rt" );
677
678         if (!infile) return;
679                 
680         while ( cfgets( buffer, 200, infile) != NULL )
681         {
682                 if ( buffer[0] == ';' ) continue;
683                 
684                 //mprintf( 0, "%s\n", buffer );
685                                 
686                 CommaParse( 0, buf1, buffer );
687                 menu = atoi( buf1 );
688                 if (menu >= MAXMENUS)
689                         Error("Too many menus (%d).",menu);
690
691                 CommaParse( 1, buf1, buffer );
692                 item = atoi(buf1 );
693                 if (item >= MAXITEMS)
694                         Error("Too many items (%d) in menu %d.",item+1,menu);
695
696                 CommaParse( 2, buf1, buffer );
697                 ul_xlate(buf1);
698
699                 if (buf1[0] != '-' )
700                 {
701                         sprintf( buf2, " %s ", buf1 );
702                         Menu[menu].Item[item].Text = d_strdup(buf2);
703                 } else 
704                         Menu[menu].Item[item].Text = d_strdup(buf1);
705                 
706                 Menu[menu].Item[item].InactiveText = d_strdup(Menu[menu].Item[item].Text);
707                 
708                 j= 0;
709                 for (i=0; i<=strlen(Menu[menu].Item[item].Text); i++ )
710                 {
711                         np = Menu[menu].Item[item].Text[i];
712                         if (np != CC_UNDERLINE) 
713                                 Menu[menu].Item[item].InactiveText[j++] = np;
714                 }
715
716                 CommaParse( 3, buf1, buffer );
717                 if (buf1[0]=='{' && buf1[1] =='}')
718                         Menu[menu].Item[item].Hotkey = -1;
719                 else                    {
720                         i = DecodeKeyText(buf1);
721                         if (i<1) {
722                                 Error("Unknown key, %s, in %s\n", buf1, file );
723                         } else {
724                                 Menu[menu].Item[item].Hotkey = i;
725                         }
726                 }
727                 CommaParse( 4, buf1, buffer );
728
729                 if (strlen(buf1))
730                 {
731                         Menu[menu].Item[item].user_function = func_get(buf1, &np);
732
733 //                      if (!strcmp(buf1,"do-wall-dialog")) {
734 //                              mprintf( 0, "Found function %s\n", buf1);
735 //                              mprintf( 0, "User function %s\n", Menu[menu].Item[item].user_function);
736 //                      }
737                                 
738                         if (Menu[menu].Item[item].user_function==NULL)
739                         {
740                                 Error( "Unknown function, %s, in %s\n", buf1, file );
741                                 //MessageBox( -2, -2, 1, buffer, "Ok" );
742                         }
743                 }
744                                 
745                 Menu[menu].Item[item].x = Menu[menu].x;
746                 Menu[menu].Item[item].y = Menu[menu].y;
747
748                 if ( Menu[menu].Item[item].Text[0] == '-' )
749                 {
750                         w = 1; h = 3;
751                 } else {
752                         gr_get_string_size( Menu[menu].Item[item].Text, &w, &h, &aw );
753                         w += 2;
754                         h += 2;
755                 }
756                                                                 
757                 if (menu==0)    {
758                         Menu[0].h = h;
759
760                         Menu[0].Item[item].x = Menu[0].x + Menu[0].w;
761
762                         Menu[0].Item[item].y = Menu[0].y;
763                         
764                         Menu[item+1].x = Menu[0].x + Menu[0].w;
765                         Menu[item+1].y = Menu[0].h - 2;
766
767                         Menu[0].Item[item].w = w;
768                         Menu[0].Item[item].h = h;
769
770                         Menu[0].w += w;
771
772                 }else   {
773                         if ( w > Menu[menu].w )
774                         {
775                                 Menu[menu].w = w;
776                                 for (i=0; i< Menu[menu].NumItems; i++ )
777                                         Menu[menu].Item[i].w = Menu[menu].w;
778                         }
779                         Menu[menu].Item[item].w = Menu[menu].w;
780                         Menu[menu].Item[item].x = Menu[menu].x;
781                         Menu[menu].Item[item].y = Menu[menu].y+Menu[menu].h;
782                         Menu[menu].Item[item].h = h;
783                         Menu[menu].h += h;
784                 }
785         
786                 if ( item >= Menu[menu].NumItems )
787                 {
788                         Menu[menu].NumItems = item+1;
789                 }
790
791                 if ( menu >= num_menus )
792                         num_menus = menu+1;
793
794         }
795
796         Menu[0].w = 700;
797                         
798         cfclose( infile );
799
800         
801         for (i=0; i<num_menus; i++ )
802                 Menu[i].Background = gr_create_bitmap(Menu[i].w, Menu[i].h );
803
804         menubar_hid = 1;
805 }
806
807 void menubar_hide()
808 {
809         menubar_hid = 1;
810         state = 0;
811         menu_hide_all();
812         menu_hide( &Menu[0] );
813 }
814
815 void menubar_show()
816 {
817         menubar_hid = 0;
818         menu_show( &Menu[0] );
819 }
820
821 void menubar_close()
822 {
823         int i;
824
825         //menu_hide_all();
826         //menu_hide( &Menu[0] );
827         
828         for (i=0; i<num_menus; i++ )
829                 gr_free_bitmap( Menu[i].Background );
830
831 }