⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 LTris a tetris clone for Linux
💻 C
字号:
/***************************************************************************                          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"#ifdef SOUND#include "audio.h"#endifList *menus = 0; /* list of menus used to delete them later */extern Font *mfont, *mhfont, *mcfont;extern int gap_height; /* gap size between items */extern Menu *cur_menu;extern int motion, motion_x, motion_y; /* mouse motion event */#ifdef SOUNDextern Sound_Chunk *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 ){    Menu *menu = calloc( 1, sizeof( Menu ) );    /* name */    menu->name = strdup( name );    /* 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 */    list_add( menus, menu );    /* create caption */    menu_add( menu, item_create_separator( name ) );    ((Item*)menu->items->head.next->item)->font = mcfont;    menu_add( menu, item_create_separator( "" ) );    /* 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 * mhfont->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 = mhfont->height;            y += gap_height + mhfont->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 );}/*====================================================================Update alpha of items and modify items according to event (if any)====================================================================*/int menu_update( Menu *menu, SDL_Event *event, int ms ){    int result = ACTION_NONE;    Item *item, *old_item;    int item_used;    void (*callback)(void);    /* update alpha of all items */    list_reset( menu->items );    while ( ( item = list_next( menu->items ) ) )        item_update_alpha( item, ms );    /* 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:			case SDLK_RETURN:	//kdhong                        /* 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:			      case SDLK_SPACE: // kdhong..                        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 SOUND                            sound_play( wav_menu_click );#endif                            if ( callback ) (callback)();                        }                        break;                    case SDLK_RIGHT:                        if ( !menu->cur_item ) break;                        item_used = 1;                        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 SOUND                        if ( item_used )                            sound_play( wav_menu_click );#endif                        break;                    case SDLK_LEFT:                        if ( !menu->cur_item ) break;                        item_used = 1;                        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 SOUND                        if ( item_used )                            sound_play( wav_menu_click );#endif                        break;                    case SDLK_UP:                        menu_up( menu );                        hint_set( menu->cur_item->hint );#ifdef SOUND                        sound_play( wav_menu_click );#endif                        break;                    case SDLK_DOWN:                        menu_down( menu );                        hint_set( menu->cur_item->hint );#ifdef SOUND                        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 SOUND                            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 == LEFT_BUTTON )                            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 SOUND                    sound_play( wav_menu_click );#endif                    if ( callback ) (callback)();                }                break;        }    /* mouse motion is handled by event_filter so check motion */    if ( motion ) {        /* 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, motion_x, motion_y ) ) {                menu_select_item( menu, item );                if ( old_item != menu->cur_item ) {#ifdef SOUND                    sound_play( wav_menu_motion );#endif                }                break;            }        if ( menu->cur_item )             hint_set( menu->cur_item->hint );        else            hint_set( 0 );    }    return result;}/*====================================================================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 ){    List_Entry *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 ){    List_Entry *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 );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -