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 + -
显示快捷键?