uimenu.c

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

C
967
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "uidef.h"
#include "uimenu.h"
#include "uibox.h"
#include "uishift.h"
#include "uigchar.h"

#define         TABCHAR                 '\t'
#define         TITLE_OFFSET            2
#define         BETWEEN_TITLES          2

static          int                     BetweenTitles = BETWEEN_TITLES;

extern          EVENT                   Event;

static          VBARMENU                MenuList;
static          VBARMENU*               Menu;

static          DESCMENU                Describe[ MAX_MENUS ];
static          int                     NumMenus        = 0;

static          UI_WINDOW               BarWin;

static          EVENT                   menu_list[]      = {
                EV_FIRST_EDIT_CHAR, EV_LAST_EDIT_CHAR,
                EV_ALT_Q, EV_ALT_M,
                EV_SCROLL_PRESS, EV_CAPS_RELEASE,
                EV_NO_EVENT,
                EV_MOUSE_PRESS,
                EV_MOUSE_DRAG,
                EV_MOUSE_RELEASE,
                EV_ESCAPE,
                EV_RETURN,
                EV_CURSOR_LEFT,
                EV_CURSOR_RIGHT,
                EV_CURSOR_DOWN,
                EV_ALT_PRESS,
                EV_ALT_RELEASE,
                EV_FUNC(10),
                EV_NO_EVENT
};

static          char*                   alt             =
        "qwertyuiop\0\0\0\0asdfghjkl\0\0\0\0\0zxcvbnm";

static          bool                    InitMenuPopupPending = FALSE;

extern void uisetbetweentitles( int between )
{
    BetweenTitles = between;
}

extern char uialtchar( EVENT ev )
/*******************************/
{
    if( ( ev >= EV_ALT_Q ) && ( ev <= EV_ALT_M ) ) {
        return( alt[ ev - EV_ALT_Q ] );
    } else {
        return( '\0' );
    }
}


static void mstring( BUFFER *bptr, ORD row, ORD col, ATTR attr,
                                   char __FAR *string, int len )
/**************************************************************/
{
    SAREA       area;

    bstring( bptr, row, col, attr, string, len );
    area.row = row;
    area.col = col;
    area.height = 1;
    area.width = len;
    physupdate( &area );
}

static void mfill( BUFFER *bptr, ORD row, ORD col, ATTR attr,
                               char ch, int len, int height )
/***********************************************************/
{
    SAREA       area;

    area.row = row;
    area.col = col;
    area.width = len;
    area.height = height;
    while( height != 0 ) {
        bfill( bptr, row, col, attr, ch, len );
        ++row;
        --height;
    }
    physupdate( &area );
}

static void menutitle( int menu, bool current )
/*********************************************/
{
    register    DESCMENU*               desc;
    register    MENUITEM*               mptr;
    register    ATTR                    attr;
    register    ATTR                    chattr;

    desc = &Describe[ menu - 1 ];
    mptr = &Menu->titles[ menu - 1 ];
    if( MENUGRAYED(*mptr) ) {
        if( current ) {
            attr = UIData->attrs[ ATTR_CURR_INACTIVE ];
        } else {
            attr = UIData->attrs[ ATTR_INACTIVE ];
        }
        chattr = attr;
    } else {
        if( Menu->active ){
            if( current ){
                attr = UIData->attrs[ ATTR_CURR_ACTIVE ];
                chattr = UIData->attrs[ ATTR_HOT_CURR ];
            } else {
                attr = UIData->attrs[ ATTR_ACTIVE ];
                chattr = UIData->attrs[ ATTR_HOT ];
            }
        } else {
            attr = UIData->attrs[ ATTR_ACTIVE ];
            chattr = UIData->attrs[ ATTR_HOT_QUIET ];
        }
    }
    mstring( &UIData->screen, MENU_GET_ROW( desc ), desc->titlecol + TITLE_OFFSET,
             attr, mptr->name, desc->titlewidth );
    mstring( &UIData->screen, MENU_GET_ROW( desc ),
             desc->titlecol + TITLE_OFFSET + ( mptr->flags & ITEM_CHAR_OFFSET ),
             chattr, &mptr->name[ ( mptr->flags & ITEM_CHAR_OFFSET ) ], 1 );
}

void global uidisplayitem( MENUITEM *menu, DESCMENU *desc, int item, bool curr )
/******************************************************************************/
{
    bool                    active;
    ORD                     choffset;
    int                     len;
    char                    ch;
    char*                   tab_loc;
    int                     tab_len;
    ORD                     start_col;
    char*                   str;
    ATTR                    attr;
    ATTR                    chattr;
    int                     str_len;

    active = !MENUGRAYED(*menu) && uiinlist( menu->event );
    if( active ) {
        if( curr ) {
            attr = UIData->attrs[ ATTR_CURR_ACTIVE ];
            chattr = UIData->attrs[ ATTR_HOT_CURR ];
        } else {
            attr = UIData->attrs[ ATTR_ACTIVE ];
            chattr = UIData->attrs[ ATTR_HOT ];
        }
    } else {
        if( curr ) {
            attr = UIData->attrs[ ATTR_CURR_INACTIVE ];
        } else {
            attr = UIData->attrs[ ATTR_INACTIVE ];
        }
        chattr = attr;
    }
    if( item > 0 ) {
        len = desc->area.width - 2;
        str = menu->name;
        if( MENUSEPARATOR( *menu ) ) {
            ch = UiGChar[ UI_SBOX_LEFT_TACK ];
            mstring( &UIData->screen,
                    (ORD) desc->area.row + item,
                    (ORD) desc->area.col,
                     UIData->attrs[ATTR_MENU], &ch, 1 );
            mfill( &UIData->screen,
                    (ORD) desc->area.row + item,
                    (ORD) desc->area.col + 1,
                    UIData->attrs[ATTR_MENU],
                    UiGChar[ UI_SBOX_HORIZ_LINE ],
                    len, 1 );
            ch = UiGChar[ UI_SBOX_RIGHT_TACK ];
            mstring( &UIData->screen,
                    (ORD) desc->area.row + item,
                    (ORD) desc->area.col + len + 1,
                    UIData->attrs[ATTR_MENU], &ch, 1 );
        } else {
            if( len < 0 ) {
                len = 0;
            }
            choffset = ( menu->flags & ITEM_CHAR_OFFSET );
            mfill( &UIData->screen,                     /* blank line */
                    (ORD) desc->area.row + item,
                    (ORD) desc->area.col + 1,
                    attr, ' ', len, 1 );
            if( desc->flags & MENU_HAS_CHECK ) {
                start_col = desc->area.col + 1;
                len--;
            } else {
                start_col = desc->area.col;
            }
            if( menu->flags & ITEM_CHECKED ) {
                mfill( &UIData->screen,                 /* checkmark */
                       (ORD) desc->area.row + item,
                       (ORD) start_col,
                       attr, UiGChar[ UI_CHECK_MARK], 1, 1 );
            }
            if( menu->popup != NULL ) {
                mfill( &UIData->screen,                 /* > for popup */
                       (ORD) desc->area.row + item,
                       (ORD) start_col + len,
                       attr, UiGChar[ UI_POPUP_MARK], 1, 1 );
            }
            if( desc->flags & MENU_HAS_POPUP ) {
                len--;
            }
            if( str != NULL ) {
                tab_loc = strchr( str, TABCHAR );
                if( tab_loc != NULL ) {
                    tab_loc++;
                    if( tab_loc != NULL ) {
                        tab_len = strlen( tab_loc ) + 1;
                    } else {
                        tab_len = 0;
                    }
                } else {
                    tab_len = 0;
                }
                str_len = strlen( str ) - tab_len;
                if( desc->flags & MENU_HAS_TAB ) {
                    if( str_len > TAB_OFFSET( desc ) ) {
                        str_len = TAB_OFFSET( desc ) - 1;
                    }
                }
                /* text */
                mstring( &UIData->screen, (ORD) desc->area.row + item,
                         (ORD) start_col + 2, attr, str, str_len );
                if( tab_loc != NULL ) {
                    mstring( &UIData->screen,           /* tabbed text */
                             (ORD) desc->area.row + item,
                             (ORD) start_col + TAB_OFFSET( desc ) + 2,
                             attr, tab_loc, tab_len );
                }
                mstring( &UIData->screen,               /* short cut key */
                         (ORD) desc->area.row + item,
                         (ORD) start_col + choffset + 2,
                         chattr, &str[choffset], 1 );
            }
        }
    }
}


extern void uidrawmenu( MENUITEM *menu, DESCMENU *desc, int curr )
{
    register    int             item;

    forbid_refresh();
    if( desc->area.height > 0 ) {
        drawbox( &UIData->screen, desc->area, (char *)&UiGChar[ UI_SBOX_TOP_LEFT ],
                 UIData->attrs[ATTR_MENU], FALSE );
        for( item = 1 ; item < desc->area.height - 1 ; ++item ) {
            uidisplayitem( &menu[ item - 1 ], desc, item, item == curr );
        }
    }
    permit_refresh();
}

void global uiclosepopup( UI_WINDOW *window )
{
    closewindow( window );
    window->update = NULL;
}

void global uiopenpopup( DESCMENU *desc, UI_WINDOW *window )
{
    window->area = desc->area;
    window->priority = P_DIALOGUE;
    window->update = NULL;
    window->parm = NULL;
    openwindow( window );
}

static int process_char( int ch, DESCMENU **desc, int *menu, int *select )
{
    register    int                     index;
    register    MENUITEM*               itemptr;
    register    int                     handled;
    register    int                     hotchar;

⌨️ 快捷键说明

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