2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: menubar.c,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $";
17 #pragma on (unreferenced)
46 int (*user_function)(void);
56 grs_bitmap * Background;
62 static int num_menus = 0;
64 static int menubar_hid;
66 #define CMENU (Menu[0].CurrentItem+1)
68 //------------------------- Show a menu item -------------------
70 void item_show( MENU * menu, int n )
72 ITEM * item = &menu->Item[n];
74 gr_set_current_canvas(NULL);
75 // If this is a seperator, then draw it.
76 if ( item->Text[0] == '-' )
78 gr_setcolor( CBLACK );
79 gr_urect( item->x, item->y+item->h/2, item->x+item->w-1, item->y+item->h/2 );
83 if ( menu->CurrentItem==n && menu->ShowBar )
85 if ( menu != &Menu[0] )
87 gr_setcolor( CBLACK );
88 gr_urect( item->x+1, item->y+1, item->x+menu->w-2, item->y+item->h-2 );
90 gr_set_fontcolor( CWHITE, CBLACK );
92 if ( menu != &Menu[0] )
95 gr_urect( item->x+1, item->y+1, item->x+menu->w-2, item->y+item->h-2 );
97 gr_set_fontcolor( CBLACK, CGREY );
100 if ( menu != &Menu[0] )
103 gr_ustring( item->x+1, item->y+1, item->Text );
105 gr_ustring( item->x+1, item->y+1, item->InactiveText );
108 gr_ustring( item->x, item->y, item->Text );
110 gr_ustring( item->x, item->y, item->InactiveText );
114 //---------------------------- Show a menu ---------------------
116 void menu_show( MENU * menu )
122 gr_set_current_canvas(NULL);
123 // Don't save background it if it's already drawn
124 if (!menu->Displayed)
126 // Save the background
127 gr_bm_ubitblt(menu->w, menu->h, 0, 0, menu->x, menu->y, &(grd_curscreen->sc_canvas.cv_bitmap), menu->Background);
129 // Draw the menu background
130 gr_setcolor( CGREY );
131 gr_urect( menu->x, menu->y, menu->x + menu->w - 1, menu->y + menu->h - 1 );
132 if ( menu != &Menu[0] )
134 gr_setcolor( CBLACK );
135 gr_ubox( menu->x, menu->y, menu->x + menu->w - 1, menu->y + menu->h - 1 );
141 for (i=0; i< menu->NumItems; i++ )
142 item_show( menu, i );
146 // Mark as displayed.
150 //-------------------------- Hide a menu -----------------------
152 void menu_hide( MENU * menu )
155 // Can't hide if it's not already drawn
156 if (!menu->Displayed) return;
160 // Restore the background
163 gr_bm_ubitblt(menu->w, menu->h, menu->x, menu->y, 0, 0, menu->Background, &(grd_curscreen->sc_canvas.cv_bitmap));
172 //------------------------- Move the menu bar ------------------
174 void menu_move_bar_to( MENU * menu, int number )
178 old_item = menu->CurrentItem;
179 menu->CurrentItem = number;
181 if (menu->Displayed && (number != old_item))
185 item_show( menu, old_item );
186 item_show( menu, number );
192 //------------------------ Match keypress to item ------------------
193 int menu_match_keypress( MENU * menu, int keypress )
199 if ((keypress & KEY_CTRLED) || (keypress & KEY_SHIFTED))
204 c = key_to_ascii(keypress);
206 for (i=0; i< menu->NumItems; i++ )
208 letter = strrchr( menu->Item[i].Text, CC_UNDERLINE );
212 if (c==tolower(*letter))
220 int menu_is_mouse_on( ITEM * item )
222 if ((Mouse.x >= item->x) &&
223 (Mouse.x < item->x + item->w ) &&
224 (Mouse.y >= item->y) &&
225 (Mouse.y <= item->y + item->h ) )
231 int menu_check_mouse_item( MENU * menu )
235 for (i=0; i<menu->NumItems; i++ )
237 if (menu_is_mouse_on( &menu->Item[i] ))
239 if (menu->Item[i].Text[0] == '-')
253 for (i=1; i<num_menus; i++)
254 menu_hide( &Menu[i] );
258 menu_show( &Menu[0] );
263 static state2_alt_down;
265 void do_state_0( int keypress )
271 if (Menu[0].Displayed==0)
272 menu_show( &Menu[0] );
274 if ( keypress & KEY_ALTED ) {
275 i = menu_match_keypress( &Menu[0], keypress );
278 Menu[0].CurrentItem = i;
281 Menu[ CMENU ].ShowBar = 1;
282 Menu[ CMENU ].Active = 1;
285 menu_show( &Menu[ CMENU ] );
286 menu_show( &Menu[0] );
290 for (i=0; i<num_menus; i++ )
291 for (j=0; j< Menu[i].NumItems; j++ )
293 if ( Menu[i].Item[j].Hotkey == keypress )
295 if (Menu[i].Item[j].user_function)
296 Menu[i].Item[j].user_function();
302 if (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] || ((keypress & 0xFF) == KEY_LALT) )
303 //if ( (keypress & 0xFF) == KEY_LALT )
307 menu_show( &Menu[0] );
311 i = menu_check_mouse_item( &Menu[0] );
313 if ( B1_PRESSED && (i > -1))
315 Menu[0].CurrentItem = i;
317 Menu[ CMENU ].ShowBar = 1;
319 Menu[ CMENU ].Active = 1;
321 menu_show( &Menu[ CMENU ] );
322 menu_show( &Menu[0] );
327 void do_state_1( int keypress )
331 if (!keyd_pressed[KEY_LALT] && !keyd_pressed[KEY_RALT] )
334 //state2_alt_down = 0;
335 //Menu[0].ShowBar = 1;
336 //Menu[0].Active = 1;
337 //menu_show( &Menu[0] );
342 i = menu_match_keypress( &Menu[0], keypress );
346 Menu[0].CurrentItem = i;
349 Menu[ CMENU ].ShowBar = 1;
350 Menu[ CMENU ].Active = 1;
353 menu_show( &Menu[ CMENU ] );
354 menu_show( &Menu[0] );
357 i = menu_check_mouse_item( &Menu[0] );
359 if ( (i == -1) && B1_JUST_RELEASED )
365 if ( B1_PRESSED && (i > -1))
367 Menu[0].CurrentItem = i;
369 Menu[ CMENU ].ShowBar = 1;
370 Menu[ CMENU ].Active = 1;
373 menu_show( &Menu[ CMENU ] );
374 menu_show( &Menu[0] );
378 void do_state_2(int keypress)
382 if (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
385 if (!keyd_pressed[KEY_LALT] && !keyd_pressed[KEY_RALT] && state2_alt_down )
399 i = Menu[0].CurrentItem-1;
400 if (i < 0 ) i = Menu[0].NumItems-1;
401 menu_move_bar_to( &Menu[0], i );
405 i = Menu[0].CurrentItem+1;
406 if (i >= Menu[0].NumItems ) i = 0;
407 menu_move_bar_to( &Menu[0], i );
414 Menu[ CMENU ].ShowBar = 1;
415 Menu[ CMENU ].Active = 1;
417 menu_show( &Menu[ 0 ] );
418 menu_show( &Menu[ CMENU ] );
422 i = menu_match_keypress( &Menu[0], keypress );
426 Menu[0].CurrentItem = i;
429 Menu[ CMENU ].ShowBar = 1;
430 Menu[ CMENU ].Active = 1;
432 menu_show( &Menu[ CMENU ] );
433 menu_show( &Menu[0] );
437 i = menu_check_mouse_item( &Menu[0] );
439 if ( (i == -1) && B1_JUST_RELEASED )
446 if ( B1_PRESSED && (i > -1))
448 Menu[0].CurrentItem = i;
451 Menu[ CMENU ].ShowBar = 1;
452 Menu[ CMENU ].Active = 1;
454 menu_show( &Menu[ CMENU ] );
455 menu_show( &Menu[0] );
465 void do_state_3( int keypress )
477 i = Menu[ CMENU ].CurrentItem;
480 if ( i >= Menu[ CMENU ].NumItems )
482 } while( Menu[CMENU].Item[i].Text[0] == '-');
483 menu_move_bar_to( &Menu[ CMENU ], i );
487 i = Menu[ CMENU ].CurrentItem;
492 i = Menu[ CMENU ].NumItems-1;
493 } while( Menu[CMENU].Item[i].Text[0] == '-');
494 menu_move_bar_to( &Menu[ CMENU ], i );
498 menu_hide( &Menu[ CMENU ] );
499 i = Menu[0].CurrentItem+1;
500 if (i >= Menu[0].NumItems ) i = 0;
501 menu_move_bar_to( &Menu[0], i );
502 Menu[CMENU].ShowBar = 1;
503 Menu[CMENU].Active = 1;
504 menu_show( &Menu[CMENU] );
508 menu_hide( &Menu[ CMENU ] );
509 i = Menu[0].CurrentItem-1;
510 if (i < 0 ) i = Menu[0].NumItems-1;
511 menu_move_bar_to( &Menu[0], i );
512 Menu[ CMENU ].ShowBar = 1;
513 Menu[CMENU].Active = 1;
514 menu_show( &Menu[ CMENU ] );
521 if (Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function)
522 Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function();
527 i = menu_match_keypress( &Menu[ CMENU ], keypress );
531 menu_move_bar_to( &Menu[ CMENU ], i );
535 if (Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function)
536 Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function();
539 i = menu_check_mouse_item( &Menu[CMENU] );
544 menu_move_bar_to( &Menu[ CMENU ], i );
545 else if ( B1_JUST_RELEASED )
547 menu_move_bar_to( &Menu[ CMENU ], i );
551 if (Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function)
552 Menu[CMENU].Item[ Menu[CMENU].CurrentItem ].user_function();
556 i = menu_check_mouse_item( &Menu[0] );
558 if ( B1_PRESSED && (i > -1))
560 if ( Menu[0].CurrentItem != i) {
561 menu_hide( &Menu[ CMENU ] );
562 menu_move_bar_to( &Menu[0], i );
563 Menu[ CMENU ].ShowBar = 1;
564 Menu[CMENU].Active = 1;
565 menu_show( &Menu[ CMENU ] );
570 if ( B1_JUST_RELEASED )
582 void menubar_do( int keypress )
584 if (menubar_hid) return;
587 do_state_0(last_keypress);
595 do_state_1(last_keypress);
598 do_state_2(last_keypress);
601 do_state_3(last_keypress);
610 void CommaParse( int n, char * dest, char * source )
612 int i = 0, j=0, cn = 0;
614 // Go to the n'th comma
616 if (source[i++] == ',' )
618 // Read all the whitespace
619 while ( source[i]==' ' || source[i]=='\t' || source[i]==13 || source[i]==10 )
622 // Read up until the next comma
623 while ( source[i] != ',' )
625 dest[j] = source[i++];
633 //translate '&' characters to the underline character
634 void ul_xlate(char *s)
636 while ((s=strchr(s,'&'))!=NULL)
641 void menubar_init( char * file )
651 num_menus = state = 0;
653 for (i=0; i < MAXMENUS; i++ )
655 Menu[i].x = Menu[i].y = Menu[i].w = Menu[i].h = 0;
657 Menu[i].CurrentItem = 0;
658 Menu[i].NumItems = 0;
659 Menu[i].Displayed = 0;
660 Menu[i].Background = 0;
661 for (j=0; j< MAXITEMS; j++ )
663 Menu[i].Item[j].x = Menu[i].Item[j].y = Menu[i].Item[j].w = Menu[i].Item[j].h = 0;
664 Menu[i].Item[j].Text = NULL;
665 Menu[i].Item[j].Hotkey = -1;
666 Menu[i].Item[j].user_function = NULL;
670 infile = fopen( file, "rt" );
674 while ( fgets( buffer, 200, infile) != NULL )
676 if ( buffer[0] == ';' ) continue;
678 //mprintf( 0, "%s\n", buffer );
680 CommaParse( 0, buf1, buffer );
682 if (menu >= MAXMENUS)
683 Error("Too many menus (%d).",menu);
685 CommaParse( 1, buf1, buffer );
687 if (item >= MAXITEMS)
688 Error("Too many items (%d) in menu %d.",item+1,menu);
690 CommaParse( 2, buf1, buffer );
695 sprintf( buf2, " %s ", buf1 );
696 Menu[menu].Item[item].Text = strdup(buf2);
698 Menu[menu].Item[item].Text = strdup(buf1);
700 Menu[menu].Item[item].InactiveText = strdup(Menu[menu].Item[item].Text);
703 for (i=0; i<=strlen(Menu[menu].Item[item].Text); i++ )
705 np = Menu[menu].Item[item].Text[i];
706 if (np != CC_UNDERLINE)
707 Menu[menu].Item[item].InactiveText[j++] = np;
710 CommaParse( 3, buf1, buffer );
711 if (buf1[0]=='{' && buf1[1] =='}')
712 Menu[menu].Item[item].Hotkey = -1;
714 i = DecodeKeyText(buf1);
716 Error("Unknown key, %s, in %s\n", buf1, file );
718 Menu[menu].Item[item].Hotkey = i;
721 CommaParse( 4, buf1, buffer );
725 Menu[menu].Item[item].user_function = func_get(buf1, &np);
727 // if (!strcmp(buf1,"do-wall-dialog")) {
728 // mprintf( 0, "Found function %s\n", buf1);
729 // mprintf( 0, "User function %s\n", Menu[menu].Item[item].user_function);
732 if (Menu[menu].Item[item].user_function==NULL)
734 Error( "Unknown function, %s, in %s\n", buf1, file );
735 //MessageBox( -2, -2, 1, buffer, "Ok" );
739 Menu[menu].Item[item].x = Menu[menu].x;
740 Menu[menu].Item[item].y = Menu[menu].y;
742 if ( Menu[menu].Item[item].Text[0] == '-' )
746 gr_get_string_size( Menu[menu].Item[item].Text, &w, &h, &aw );
754 Menu[0].Item[item].x = Menu[0].x + Menu[0].w;
756 Menu[0].Item[item].y = Menu[0].y;
758 Menu[item+1].x = Menu[0].x + Menu[0].w;
759 Menu[item+1].y = Menu[0].h - 2;
761 Menu[0].Item[item].w = w;
762 Menu[0].Item[item].h = h;
767 if ( w > Menu[menu].w )
770 for (i=0; i< Menu[menu].NumItems; i++ )
771 Menu[menu].Item[i].w = Menu[menu].w;
773 Menu[menu].Item[item].w = Menu[menu].w;
774 Menu[menu].Item[item].x = Menu[menu].x;
775 Menu[menu].Item[item].y = Menu[menu].y+Menu[menu].h;
776 Menu[menu].Item[item].h = h;
780 if ( item >= Menu[menu].NumItems )
782 Menu[menu].NumItems = item+1;
785 if ( menu >= num_menus )
795 for (i=0; i<num_menus; i++ )
796 Menu[i].Background = gr_create_bitmap(Menu[i].w, Menu[i].h );
806 menu_hide( &Menu[0] );
812 menu_show( &Menu[0] );
820 //menu_hide( &Menu[0] );
822 for (i=0; i<num_menus; i++ )
823 gr_free_bitmap( Menu[i].Background );