menu.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,035 行 · 第 1/2 页

C
1,035
字号
    buff[0] = 0;
    MenuItem( buff );

    cinfo = InfoHead;
    cnt = 1;
    while( cinfo != NULL && cnt < 10 ) {
        MySprintf( buff,"\"&%d %s\" edit %s", cnt,
                cinfo->CurrentFile->name, cinfo->CurrentFile->name );
        MenuItem( buff );
        cinfo = cinfo->next;
        cnt++;
    }
    if( cinfo != NULL ) {
        strcpy( buff, "\"&More Windows ...\" files" );
        MenuItem( buff );
    }
    initMenuList( cmenu );
    currMenu = NULL;

} /* addFileList */

/*
 * removeFileList - remove files from a menu
 */
static void removeFileList( menu *cmenu )
{
    menu_item   *citem,*nitem;
    int         i;

    i = 0;
    citem = cmenu->itemhead;
    while( i < cmenu->orig_itemcnt ) {
        citem = citem->next;
        i++;
    }
    while( citem != NULL ) {
        nitem = citem->next;
        DeleteLLItem( (ss**)&cmenu->itemhead, (ss**)&cmenu->itemtail, (ss*)citem );
        MemFree( citem );
        citem = nitem;
        cmenu->itemcnt--;
    }
    cmenu->maxwidth = cmenu->orig_maxwidth;
    initMenuList( cmenu );

} /* removeFileList */

#define START_OFFSET  1

/*
 * InitMenu - initialize control bar window
 */
int InitMenu( void )
{
    int         i,ws;
    char        disp[MAX_STR];
    char        tmp[MAX_STR];
    menu        *cmenu;

    if( !EditFlags.WindowsStarted ) {
        return( ERR_NO_ERR );
    }
    if( MenuWindow >= 0 ) {
        CloseAWindow( MenuWindow );
        MenuWindow = -1;
    }
    if( !EditFlags.Menus ) {
        return( ERR_NO_ERR );
    }
    menubarw_info.y1 = 0;
    menubarw_info.y2 = 0;
    menubarw_info.x1 = 0;
    menubarw_info.x2 = WindMaxWidth-1;
    i = NewWindow2( &MenuWindow, &menubarw_info );
    if( i ) {
        EditFlags.Menus = FALSE;
        return( i );
    }

    memset( disp,' ', sizeof( disp ) - 1 );
    disp[START_OFFSET] = 0;
    for( cmenu=menuHead; cmenu != NULL; cmenu=cmenu->next ) {
        MySprintf(tmp,"%s  ",cmenu->str );
        strcat(disp,tmp );
    }
    disp[ strlen( disp ) ] = ' ';
    if( EditFlags.CurrentStatus ) {
        disp[ CurrentStatusColumn-1 ] = 0;
        // disp[ CurrentStatusColumn-7 ] = 0;
        // strcat( disp, "Mode:" );
    }
    DisplayLineInWindow( MenuWindow, 1, disp );

    ws = 0;
    for( cmenu=menuHead; cmenu != NULL; cmenu=cmenu->next ) {
        SetCharInWindowWithColor( MenuWindow,1, ws+START_OFFSET+1+
                cmenu->hioff,cmenu->hi, &menubarw_info.hilight );
        ws += cmenu->slen+2;
    }

    return( ERR_NO_ERR );

} /* InitMenu */

void FiniMenu( void ){
    menu        *cmenu;
    menu        *oldmenu;
    int         i;

    for( cmenu=menuHead; cmenu != NULL; ) {
        oldmenu = cmenu;
        cmenu = cmenu->next;
        freeMenu( oldmenu );
    }
    for( i=0; i<MAX_FLOAT_MENUS; i++ ){
        if( floatMenus[i] != NULL ){
            freeMenu( floatMenus[i] );
        }
    }
    freeMenu( windowGadgetMenu );
}

/*
 * lightMenu - light up control name
 */
static void lightMenu( int sel, int ws ,int on)
{
    char        ch;
    int         i;
    menu        *cmenu;
    type_style  s;

    if( sel >= menuCnt ) {
        return;
    }

    ws++;

    cmenu = menuHead;
    for( i=0;i<sel;i++ ) {
        cmenu = cmenu->next;
    }

    for( i=0; i<cmenu->slen; i++ ) {
        if( i == cmenu->hioff && !on ) {
            ch = cmenu->hi;
            s = menubarw_info.hilight;
        } else {
            ch = cmenu->str[i];
            s = menubarw_info.text;
            if( on ) {
                s.foreground = menubarw_info.hilight.foreground;
            }
        }
        SetCharInWindowWithColor( MenuWindow,1, ws+i,ch, &s );
    }

} /* lightMenu */

/*
 * getMenuPtrFromId - given an id, find the menu in the list
 */
static menu *getMenuPtrFromId( int id )
{
    int         i=0;
    menu        *cmenu;
    for( cmenu=menuHead; cmenu != NULL; cmenu=cmenu->next ) {
        if( id == i ) {
            break;
        }
        i++;
    }
    return( cmenu );

} /* getMenuPtrFromId */

static int currentID;
/*
 * processMenu - process selected menu
 */
static int processMenu( int sel, menu *cmenu, int xpos, int ypos, int rxwid )
{
    int         i,ws;
    char        result[80];
    int         resint,allowrl,*arl;
    selectitem  si;
    menu        *tmenu;
    menu_item   *cmi;
    char        cmd[MAX_INPUT_LINE];
    int         x1,y1,x2,y2;
    int         diff;
    int         xwid;
    int         rc;

    xwid = rxwid;
    if( xwid < 0 ) {
        xwid = 0;
    }

    while( TRUE ) {

        if( cmenu->has_file_list ) {
            addFileList( cmenu );
        }

        /*
         * get coordinates of menu
         */
        currentID = sel;
        if( xpos < 0 ) {
            ws = START_OFFSET;
            tmenu = menuHead;
            while( tmenu != cmenu ) {
                ws += tmenu->slen+2;
                tmenu = tmenu->next;
            }
            x1 = ws;
            arl = &allowrl;
        } else {
            ws = xpos;
            x1 = ws;
            arl = NULL;
        }
        x2 = x1+cmenu->maxwidth+1;
        y1 = ypos;
        y2 = y1 + (int) cmenu->itemcnt+1;

        /*
         * make sure menu will be valid!
         */
        if( x2-x1+1 > WindMaxWidth || y2-y1+1 > WindMaxHeight ) {
            return( ERR_WIND_INVALID );;
        }
        if( xpos < 0 ) {
            if( x2 >= WindMaxWidth ) {
                diff = x2-WindMaxWidth;
                x2 -= diff;
                x1 -= diff;
            }
        } else {
            if( y2 >= WindMaxHeight ) {
                diff = y2-y1;
                y2 = y1;
                y1 -= diff;
                if( xwid > 0 || rxwid == -1 ) {
                    y1 -= 2;
                    y2 -= 2;
                }
            }
            if( x2 >= WindMaxWidth ) {
                diff = x2-x1;
                x2 = x1-xwid;
                x1 -= (diff+xwid);
            }
        }
        menuw_info.x1 = x1;
        menuw_info.x2 = x2;
        menuw_info.y1 = y1;
        menuw_info.y2 = y2;

        /*
         * go get a selected item from the menu
         */
        memset( &si, 0, sizeof( si ) );
        allowrl=0;
        si.is_menu = TRUE;
        si.wi = &menuw_info;
        si.list = cmenu->list;
        si.maxlist = (int) cmenu->itemcnt;
        si.result = result;
        si.allowrl = arl;
        si.hilite = (char **) cmenu->hilist;
        si.cln = 1;
        si.eiw = -1;

        if( xpos < 0 ) {
            lightMenu( sel, ws, TRUE );
        }
        CurrentMenuNumber = sel+1;
        i = SelectItem( &si );
        if( xpos < 0 ) {
            lightMenu( sel, ws, FALSE );
        }
        if( i ) {
            if( cmenu->has_file_list ) {
                removeFileList( cmenu );
            }
            return( i );
        }
        if( !allowrl ) {
            break;
        }

        sel += allowrl;
        if( sel < 0 ) {
            sel = menuCnt-1;
        }
        if( sel >= menuCnt ) {
            sel = 0;
        }
        if( cmenu->has_file_list ) {
            removeFileList( cmenu );
        }
        cmenu = getMenuPtrFromId( sel );

    }

    resint = si.num;
    if( resint < 0 ) {
        if( cmenu->has_file_list ) {
            removeFileList( cmenu );
        }
        return( ERR_NO_ERR );
    }

    cmi = cmenu->itemhead;
    for( i=0;i<resint;i++ ) {
        cmi = cmi->next;
    }
    strcpy( cmd, cmi->cmd );
    rc = RunCommandLine( cmd );
    if( cmenu->has_file_list ) {
        removeFileList( cmenu );
    }
    return( rc );

} /* processMenu */

/*
 * DoMenu - process some kind of control request
 */
int DoMenu( void )
{
    int         i;
    int         sel= -1;
    char        key;
    menu        *cmenu;

    /*
     * get which command to run
     */
    if( !EditFlags.Menus ) {
        return( ERR_NO_ERR );
    }
    key = LastEvent - (char) VI_KEY( ALT_A ) + (char) 'A';
    i = 0;
    for( cmenu=menuHead; cmenu != NULL; cmenu=cmenu->next ) {
        if( key == cmenu->hi ) {
            sel=i;
            break;
        }
        i++;
    }
    if( sel < 0 ) {
        return( ERR_NO_ERR );
    }
    return( processMenu( sel, cmenu, -1, 1, 0 ) );

} /* DoMenu */

/*
 * DoWindowGadgetMenu - handle menu for each file
 */
int DoWindowGadgetMenu( void )
{
    int         rc;

    if( windowGadgetMenu == NULL ) {
        return( ERR_NO_ERR );
    }
    rc = processMenu( -1, windowGadgetMenu,
        WindowAuxInfo( CurrentWindow, WIND_INFO_X1 ),
        WindowAuxInfo( CurrentWindow, WIND_INFO_Y1 )+1, -1 );
    return( rc );

} /* DoWindowGadgetMenu */

/*
 * DoFloatMenu - handle floating menus
 */
int DoFloatMenu( int id, int slen, int x1, int y1 )
{
    int         rc;

    if( id < 0 || id >= MAX_FLOAT_MENUS ) {
        return( ERR_INVALID_MENU );
    }
    if( floatMenus[id] == NULL ) {
        return( ERR_INVALID_MENU );
    }
    rc = processMenu( -1, floatMenus[id], x1, y1, slen );
    return( rc );

} /* DoFloatMenu */

/*
 * ActivateFloatMenu - activate floating menu
 */
int ActivateFloatMenu( char *data )
{
    char        str[MAX_STR];
    int         id,slen,x1,y1;

    /*
     * get input syntax :
     * FLOATMENU id slen x1 y1
     */
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    id = atoi( str );
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    slen = atoi( str );
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    x1 = atoi( str );
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    y1 = atoi( str );
    return( DoFloatMenu( id, slen, x1, y1 ) );

} /* ActivateFloatMenu */

/*
 * GetCurrentMenuId - get id of currently displayed menu
 */
int GetCurrentMenuId( void )
{
    return( currentID );

} /* GetCurrentMenuId*/

/*
 * SetToMenuId - set to specified menu id (mouse did it)
 */
int SetToMenuId( int id )
{
    menu        *cmenu;

    cmenu = getMenuPtrFromId( id );
    if( cmenu != NULL ) {
        return( processMenu( id, cmenu, -1, 1, 0 ) );
    }
    return( ERR_NO_ERR );

} /* SetToMenuId */

/*
 * GetMenuIdFromCoord - given x coordinate, determine menu item
 */
int GetMenuIdFromCoord( int x )
{
    int         i;
    int         ws;
    menu        *cmenu;

    ws = START_OFFSET;
    i = 0;
    for( cmenu=menuHead; cmenu != NULL; cmenu=cmenu->next ) {
        if( x >= ws && x < ws + cmenu->slen ) {
            return( i );
        }
        ws += cmenu->slen+2;
        i++;
    }
    return( -1 );

} /* GetMenuIdFromCoord */

/*
 * IsMenuHotKey - test if a specified character is a main menu hot key
 */
int IsMenuHotKey( int ch )
{
    menu        *curr;

    curr = menuHead;
    while( curr != NULL ) {
        if( curr->hi == ch ) {
            return( TRUE );
        }
        curr = curr->next;
    }
    return( FALSE );

} /* IsMenuHotKey */

/*
 * MenuItemFileList - add the Window List menu item
 */
int MenuItemFileList( void )
{
    if( currMenu == NULL ) {
        return( ERR_INVALID_MENU );
    }
    currMenu->has_file_list = TRUE;
    return( ERR_NO_ERR );

} /* MenuItemFileList */

/*
 * MenuItemLastFiles - add the Last File List menu item
 */
int MenuItemLastFiles( void )
{
    if( currMenu == NULL ) {
        return( ERR_INVALID_MENU );
    }
    currMenu->has_last_files = TRUE;
    return( ERR_NO_ERR );

} /* MenuItemLastFiles */

⌨️ 快捷键说明

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