Added initial LBreakout2 sources, already slightly modified - it does not work yet!
This commit is contained in:
430
project/jni/application/lbreakout2/client/menu.c
Normal file
430
project/jni/application/lbreakout2/client/menu.c
Normal file
@@ -0,0 +1,430 @@
|
||||
/***************************************************************************
|
||||
menu.c - description
|
||||
-------------------
|
||||
begin : Thu Sep 20 2001
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "manager.h"
|
||||
|
||||
List *menus = 0; /* list of menus used to delete them later */
|
||||
extern StkFont *mfont, *mhfont, *mcfont;
|
||||
extern int gap_height; /* gap size between items */
|
||||
extern Menu *cur_menu;
|
||||
#ifdef AUDIO_ENABLED
|
||||
extern StkSound *wav_menu_motion, *wav_menu_click;
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Create menu.
|
||||
====================================================================
|
||||
*/
|
||||
Menu *menu_create( char *name, int layout, int x, int y, int w, int h, int border, int add_to_list )
|
||||
{
|
||||
Menu *menu = calloc( 1, sizeof( Menu ) );
|
||||
/* name */
|
||||
if ( name )
|
||||
menu->name = strdup( name );
|
||||
else
|
||||
menu->name = strdup( "none" );
|
||||
/* layout */
|
||||
menu->layout = layout;
|
||||
menu->x = x + border; menu->y = y + border;
|
||||
menu->w = w - border * 2; menu->h = h - border * 2;
|
||||
/* items are cleared normally */
|
||||
menu->items = list_create( LIST_AUTO_DELETE, item_delete );
|
||||
/* add menu to list menus */
|
||||
if ( add_to_list )
|
||||
list_add( menus, menu );
|
||||
/* create caption */
|
||||
if ( name ) {
|
||||
menu_add( menu, item_create_separator( name ) );
|
||||
((Item*)menu->items->head->next->item)->font = mcfont;
|
||||
menu_add( menu, item_create_separator( "" ) );
|
||||
}
|
||||
/* default fonts */
|
||||
menu->font = mfont;
|
||||
menu->hfont = mhfont;
|
||||
menu->cfont = mcfont;
|
||||
/* return menu */
|
||||
return menu;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete menu and all submenus starting with root menu
|
||||
====================================================================
|
||||
*/
|
||||
void menu_delete( void *pmenu )
|
||||
{
|
||||
Menu *menu = (Menu*)pmenu;
|
||||
if ( !menu ) return;
|
||||
list_delete( menu->items );
|
||||
if ( menu->name ) free( menu->name );
|
||||
free( menu );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Add item to menu.
|
||||
====================================================================
|
||||
*/
|
||||
void menu_add( Menu *menu, Item *item )
|
||||
{
|
||||
list_add( menu->items, item );
|
||||
if ( item->type == ITEM_LINK && (Menu*)item->link != menu )
|
||||
((Menu*)item->link)->parent = menu;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Adjust position and size of all entries according to layout.
|
||||
====================================================================
|
||||
*/
|
||||
void menu_adjust( Menu *menu )
|
||||
{
|
||||
int height, x, y;
|
||||
Item *item;
|
||||
if ( menu->layout == MENU_LAYOUT_CENTERED ) {
|
||||
/* get full height of all items + gaps */
|
||||
height = menu->items->count * menu->hfont->height +
|
||||
( menu->items->count - 1 ) * gap_height;
|
||||
/* get positions of items */
|
||||
y = menu->y + ( menu->h - height ) / 2;
|
||||
x = menu->x;
|
||||
/* set position */
|
||||
list_reset( menu->items );
|
||||
while( ( item = list_next( menu->items ) ) ) {
|
||||
item->x = x; item->y = y;
|
||||
item->w = menu->w; item->h = menu->hfont->height;
|
||||
y += gap_height + menu->hfont->height;
|
||||
item_adjust( item ); /* adjust alignment */
|
||||
}
|
||||
return;
|
||||
}
|
||||
fprintf( stderr, "menu_adjust: layout %i not supported\n", menu->layout );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Select menu: clear current item and set extern variable cur_menu
|
||||
====================================================================
|
||||
*/
|
||||
void menu_select( Menu *menu )
|
||||
{
|
||||
if ( cur_menu ) menu_unselect_cur_item( cur_menu );
|
||||
cur_menu = menu;
|
||||
menu->cur_item = 0;
|
||||
hint_set( 0 );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Show/hide all items
|
||||
====================================================================
|
||||
*/
|
||||
void menu_hide( Menu *menu )
|
||||
{
|
||||
Item *item;
|
||||
list_reset( menu->items );
|
||||
while ( ( item = list_next( menu->items ) ) )
|
||||
item_hide( item );
|
||||
}
|
||||
void menu_show( Menu *menu )
|
||||
{
|
||||
Item *item;
|
||||
list_reset( menu->items );
|
||||
while ( ( item = list_next( menu->items ) ) )
|
||||
item_show( item );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
modify items according to event (if any)
|
||||
====================================================================
|
||||
*/
|
||||
int menu_handle_event( Menu *menu, SDL_Event *event )
|
||||
{
|
||||
int result = ACTION_NONE;
|
||||
Item *item, *old_item;
|
||||
int item_used;
|
||||
int x, y, xoff, yoff;
|
||||
void (*callback)(void);
|
||||
/* if value::grab is set do only except keyup events */
|
||||
if ( menu->cur_item && menu->cur_item->type == ITEM_KEY && menu->cur_item->value->grab ) {
|
||||
if ( event && event->type == SDL_KEYDOWN )
|
||||
value_set_key( menu->cur_item->value, event->key.keysym.sym );
|
||||
return result;
|
||||
}
|
||||
/* if other event occured check */
|
||||
if ( event )
|
||||
switch ( event->type ) {
|
||||
case SDL_KEYDOWN:
|
||||
switch ( event->key.keysym.sym ) {
|
||||
case SDLK_ESCAPE:
|
||||
/* if ESCAPE is pressed go up to last menu or leave */
|
||||
if ( strequal( "Back", ((Item*)menu->items->tail->prev->item)->name ) )
|
||||
menu_select( ((Item*)menu->items->tail->prev->item)->link );
|
||||
else
|
||||
if ( strequal( "Quit", ((Item*)menu->items->tail->prev->item)->name ) )
|
||||
result = ACTION_QUIT;
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
if ( !menu->cur_item ) break;
|
||||
item_used = 1;
|
||||
/* callback */
|
||||
callback = menu->cur_item->callback;
|
||||
/* action */
|
||||
switch ( menu->cur_item->type ) {
|
||||
case ITEM_ACTION: result = menu->cur_item->item_id; break;
|
||||
case ITEM_LINK: menu_select( menu->cur_item->link ); break;
|
||||
case ITEM_KEY: value_grab( menu->cur_item->value ); break;
|
||||
case ITEM_SWITCH:
|
||||
case ITEM_SWITCH_X:
|
||||
case ITEM_RANGE:
|
||||
value_inc( menu->cur_item->value );
|
||||
break;
|
||||
default: item_used = 0; break;
|
||||
}
|
||||
if ( item_used ) {
|
||||
#ifdef AUDIO_ENABLED
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
if ( callback ) (callback)();
|
||||
}
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
if ( !menu->cur_item ) break;
|
||||
item_used = 1;
|
||||
/* callback */
|
||||
callback = menu->cur_item->callback;
|
||||
/* action */
|
||||
switch ( menu->cur_item->type ) {
|
||||
case ITEM_SWITCH:
|
||||
case ITEM_SWITCH_X:
|
||||
case ITEM_RANGE:
|
||||
value_inc( menu->cur_item->value );
|
||||
break;
|
||||
default: item_used = 0; break;
|
||||
}
|
||||
#ifdef AUDIO_ENABLED
|
||||
if ( item_used ) {
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
if ( callback ) (callback)();
|
||||
}
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
if ( !menu->cur_item ) break;
|
||||
item_used = 1;
|
||||
/* callback */
|
||||
callback = menu->cur_item->callback;
|
||||
/* action */
|
||||
switch ( menu->cur_item->type ) {
|
||||
case ITEM_SWITCH:
|
||||
case ITEM_SWITCH_X:
|
||||
case ITEM_RANGE:
|
||||
value_dec( menu->cur_item->value );
|
||||
break;
|
||||
default: item_used = 0; break;
|
||||
}
|
||||
#ifdef AUDIO_ENABLED
|
||||
if ( item_used ) {
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
if ( callback ) (callback)();
|
||||
}
|
||||
break;
|
||||
case SDLK_UP:
|
||||
menu_up( menu );
|
||||
hint_set( menu->cur_item->hint );
|
||||
#ifdef AUDIO_ENABLED
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
menu_down( menu );
|
||||
hint_set( menu->cur_item->hint );
|
||||
#ifdef AUDIO_ENABLED
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
/* if type is edit: edit! */
|
||||
if ( menu->cur_item && menu->cur_item->type == ITEM_EDIT ) {
|
||||
value_edit( menu->cur_item->value, event->key.keysym.sym, event->key.keysym.unicode );
|
||||
#ifdef AUDIO_ENABLED
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if ( !menu->cur_item ) break;
|
||||
item_used = 1;
|
||||
callback = menu->cur_item->callback;
|
||||
switch ( menu->cur_item->type ) {
|
||||
case ITEM_ACTION: result = menu->cur_item->item_id; break;
|
||||
case ITEM_LINK: menu_select( menu->cur_item->link ); break;
|
||||
case ITEM_SWITCH:
|
||||
case ITEM_SWITCH_X:
|
||||
case ITEM_RANGE:
|
||||
if ( event->button.button == STK_BUTTON_LEFT )
|
||||
value_inc( menu->cur_item->value );
|
||||
else
|
||||
value_dec( menu->cur_item->value );
|
||||
break;
|
||||
case ITEM_KEY: value_grab( menu->cur_item->value ); break;
|
||||
default: item_used = 0; break;
|
||||
}
|
||||
if ( item_used ) {
|
||||
#ifdef AUDIO_ENABLED
|
||||
stk_sound_play( wav_menu_click );
|
||||
#endif
|
||||
if ( callback ) (callback)();
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* mouse motion is handled directly */
|
||||
SDL_GetRelativeMouseState( &xoff, &yoff );
|
||||
if ( xoff != 0 || yoff != 0 ) {
|
||||
SDL_GetMouseState( &x, &y );
|
||||
/* select item mouse pointer is on */
|
||||
old_item = menu->cur_item;
|
||||
menu_unselect_cur_item( menu );
|
||||
list_reset( menu->items );
|
||||
while( ( item = list_next( menu->items ) ) )
|
||||
if ( item_focus( item, x, y ) ) {
|
||||
menu_select_item( menu, item );
|
||||
if ( old_item != menu->cur_item ) {
|
||||
#ifdef AUDIO_ENABLED
|
||||
stk_sound_play( wav_menu_motion );
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( menu->cur_item )
|
||||
hint_set( menu->cur_item->hint );
|
||||
else
|
||||
hint_set( 0 );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Update alpha of items
|
||||
====================================================================
|
||||
*/
|
||||
void menu_update( Menu *menu, int ms )
|
||||
{
|
||||
Item *item;
|
||||
/* update alpha of all items */
|
||||
list_reset( menu->items );
|
||||
while ( ( item = list_next( menu->items ) ) )
|
||||
item_update_alpha( item, ms );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Select/unselect item: update menu::cur_item und item::highlight
|
||||
====================================================================
|
||||
*/
|
||||
void menu_unselect_cur_item( Menu *menu )
|
||||
{
|
||||
if ( menu->cur_item ) menu->cur_item->highlighted = 0;
|
||||
menu->cur_item = 0;
|
||||
}
|
||||
void menu_select_item( Menu *menu, Item *item )
|
||||
{
|
||||
menu->cur_item = item;
|
||||
menu->cur_item->highlighted = 1;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Go one valid menu item up or down.
|
||||
====================================================================
|
||||
*/
|
||||
void menu_up( Menu *menu )
|
||||
{
|
||||
ListEntry *entry;
|
||||
Item *item;
|
||||
int valid = 0;
|
||||
/* no selection so far: select first item after caption */
|
||||
if ( !menu->cur_item ) {
|
||||
menu_select_item( menu, list_get( menu->items, 2 ) );
|
||||
return;
|
||||
}
|
||||
/* get entry -- MUST exist so don't check */
|
||||
entry = list_entry( menu->items, menu->cur_item );
|
||||
/* get next entry */
|
||||
do {
|
||||
entry = entry->prev;
|
||||
if ( entry == menu->items->head )
|
||||
entry = menu->items->tail->prev;
|
||||
item = (Item*)entry->item;
|
||||
if ( item->type == ITEM_SEPARATOR ) continue;
|
||||
valid = 1;
|
||||
} while ( !valid );
|
||||
/* set as current */
|
||||
menu_unselect_cur_item( menu );
|
||||
menu_select_item( menu, entry->item );
|
||||
}
|
||||
void menu_down( Menu *menu )
|
||||
{
|
||||
ListEntry *entry;
|
||||
Item *item;
|
||||
int valid = 0;
|
||||
/* no selection so far: select first item after caption */
|
||||
if ( !menu->cur_item ) {
|
||||
menu_select_item( menu, list_get( menu->items, 2 ) );
|
||||
return;
|
||||
}
|
||||
/* get entry -- MUST exist so don't check */
|
||||
entry = list_entry( menu->items, menu->cur_item );
|
||||
/* get next entry */
|
||||
do {
|
||||
entry = entry->next;
|
||||
if ( entry == menu->items->tail )
|
||||
entry = menu->items->head->next;
|
||||
item = (Item*)entry->item;
|
||||
if ( item->type == ITEM_SEPARATOR ) continue;
|
||||
valid = 1;
|
||||
} while ( !valid );
|
||||
/* set as current */
|
||||
menu_unselect_cur_item( menu );
|
||||
menu_select_item( menu, entry->item );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Set fonts of menu and items.
|
||||
====================================================================
|
||||
*/
|
||||
void menu_set_fonts(
|
||||
Menu *menu, StkFont *cfont, StkFont *font, StkFont *hfont )
|
||||
{
|
||||
Item *item;
|
||||
menu->cfont = cfont; menu->font = font; menu->hfont = hfont;
|
||||
list_reset( menu->items );
|
||||
while ( ( item = list_next( menu->items ) ) ) {
|
||||
item->font = font;
|
||||
item->hfont = hfont;
|
||||
}
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Set background of menu and items.
|
||||
====================================================================
|
||||
*/
|
||||
void menu_set_bkgnd( Menu *menu, SDL_Surface *bkgnd )
|
||||
{
|
||||
Item *item;
|
||||
list_reset( menu->items );
|
||||
while ( ( item = list_next( menu->items ) ) )
|
||||
item->bkgnd = bkgnd;
|
||||
}
|
||||
Reference in New Issue
Block a user