?? wmenu.c
字號:
best=temp;
}
/* see if menu selection is non-selectable */
if(best->fmask&M_NOSEL) best=right_item(best);
/* return best record */
return(best);
}
/*---------------------------------------------------------------------------*/
/* this is a recursive function that frees a menu and all of its submenus */
static void free_menu(struct _menu_t *wmenu)
{
struct _item_t *witem;
/* free all items in menu, including sub-menus */
while(wmenu->item!=NULL) {
if(wmenu->item->child!=NULL) free_menu(wmenu->item->child);
witem=wmenu->item->prev;
free(wmenu->item);
wmenu->item=witem;
if(wmenu->item!=NULL) wmenu->item->next=NULL;
}
/* free the menu itself */
free(wmenu);
}
/*---------------------------------------------------------------------------*/
/* this function will hide the mouse cursor */
/* if mouse cursor mode is on */
static void hide_mouse_cursor(void)
{
if(_mouse&MS_CURS) mshidecur();
}
/*---------------------------------------------------------------------------*/
/* this function moves the selection bar to another menu item, */
/* automatically taking care of necessary pre/post move actions */
static struct _item_t *goto_item(struct _item_t *citem,int which)
{
struct _item_t *item;
if(which==ITM_FR) item=first_item();
else if(which==ITM_LS) item=last_item();
else item=(*funcs[which])(citem);
if(item!=citem) {
pre_move(citem);
post_move(citem=item);
}
return(citem);
}
/*---------------------------------------------------------------------------*/
/* this function will find the bottom-rightmost menu selection */
static struct _item_t *last_item(void)
{
struct _item_t *best,*temp;
int bcol;
/* initialize best record to highest record in linked list */
best=_winfo.cmenu->item;
bcol=best->wcol;
/* search backwards through linked list, testing each item */
for(temp=best->prev;temp!=NULL;temp=temp->prev) {
if( (temp->wrow>best->wrow) ||
( (temp->wrow==best->wrow) &&
(temp->wcol>bcol) ) ) {
best=temp;
bcol=best->wcol;
}
}
/* see if menu selection is non-selectable */
if(best->fmask&M_NOSEL) best=left_item(best);
/* return best record */
return(best);
}
/*---------------------------------------------------------------------------*/
/* this function will find the menu selection to the left of current */
static struct _item_t *left_item(struct _item_t *curr)
{
struct _item_t *best,*temp;
int wwidth,bpos,tpos,cpos;
/* calculate window width and current position */
wwidth=_winfo.cmenu->ecol - _winfo.cmenu->scol + 1;
cpos=(curr->wrow * wwidth) + curr->wcol;
/* initialize best record to NULL, and best position to -1 */
best=NULL;
bpos=-1;
/* search backwards through linked list, testing each item */
for(temp=_winfo.cmenu->item;temp!=NULL;temp=temp->prev) {
/* calculate position of test each item */
tpos=(temp->wrow*wwidth) + temp->wcol;
/* compare position of test item with best item, current item */
if(tpos>bpos && tpos<cpos) {
best=temp;
bpos=tpos;
}
}
/* if there wasn't a item to the left, then wrap around */
if(best==NULL)
best=last_item();
else
/* see if menu selection is non-selectable */
if(best->fmask&M_NOSEL)
best=left_item(best);
/* return best record */
return(best);
}
/*---------------------------------------------------------------------------*/
/* this function determines if the mouse cursor is on a menu item */
static struct _item_t *mouse_on_item(struct _menu_t *menu,int mcrow,int mccol)
{
int srow,scol,border,start,end;
struct _item_t *item,*found;
found = NULL;
srow = menu->srow;
scol = menu->scol;
border = menu->btype==5?0:1;
for(item=menu->item;item!=NULL;item=item->prev) {
if(mcrow==(srow+border+item->wrow)) {
start = scol+border+item->wcol;
end = start+calc_bar_width(menu,item)-1;
if(mccol>=start&&mccol<=end) {
found=item;
break;
}
}
}
return(found);
}
/*---------------------------------------------------------------------------*/
/* this function is called after a menu bar move */
static void post_move(struct _item_t *citem)
{
_winfo.cmenu->citem=citem;
_winfo.help=citem->help;
disp_item(citem,1);
call_before(citem);
}
/*---------------------------------------------------------------------------*/
static void pre_exit(WINDOW w,int close)
{
struct _menu_t *wmenu;
hide_mouse_cursor();
/* if not using current window for menu, then close it */
if(close) close_window(w);
/* if at highest menu then free the whole menu structure */
if(_winfo.cmenu==_winfo.menu) {
wmenu=_winfo.menu->prev;
if(_winfo.cmenu!=NULL) free_menu(_winfo.cmenu);
_winfo.menu=wmenu;
if(_winfo.menu!=NULL) _winfo.menu->next=NULL;
_winfo.cmenu=_winfo.menu;
}
}
/*---------------------------------------------------------------------------*/
/* this function prepares for a menu bar move */
static void pre_move(struct _item_t *citem)
{
disp_item(citem,0);
call_after(citem);
}
/*---------------------------------------------------------------------------*/
/* this function reads the mouse for input */
static int read_mouse(struct _item_t *citem)
{
register struct _item_t *item;
int bcount,bstat,mrow,mcol;
/* if free-floating mouse cursor support is on */
if(_mouse&MS_CURS) {
/* clear mouse button queue */
msbclear();
/* loop until a key is pressed */
while(!kbhit()&&_kbinfo.kbuf==NULL) {
/* call the keyboard loop function */
if(_kbinfo.kbloop!=NULL) (*_kbinfo.kbloop)();
/* if left button was pressed, and mouse cursor is on */
/* a selectable menu item, then move selection bar to */
/* that item, and select it. If mouse cursor is on */
/* a main menu item of a pull-down menu system, then */
/* stuff that item's selection character into the CXL */
/* keyboard buffer and return Esc to close the current */
/* pull-down menu. */
msbreles(0,&bstat,&bcount,&mrow,&mcol);
if(bcount) {
if((item=mouse_on_item(_winfo.cmenu,mrow,mcol))==NULL) {
if(_winfo.cmenu->menutype&M_PD) {
if(((item=mouse_on_item(_winfo.cmenu->parent,mrow,
mcol))!=NULL)&&(!(item->fmask&M_NOSEL))) {
kbput(item->schar);
return(0x011b); /* Esc */
}
}
}
else {
if(!(item->fmask&M_NOSEL)) {
if(citem!=item) {
pre_move(citem);
post_move(_winfo.cmenu->citem=citem=item);
}
return(0x1c0d); /* Enter */
}
}
}
/* if right button was pressed, simulate pressing the Esc key */
msbreles(1,&bstat,&bcount,&mrow,&mcol);
if(bcount) return(0x011b); /* Esc */
}
}
/* return zero - it means a key was pressed */
return(0);
}
/*---------------------------------------------------------------------------*/
/* this function will find the menu selection to the right of current */
static struct _item_t *right_item(struct _item_t *curr)
{
struct _item_t *best,*temp;
int wwidth,bpos,tpos,cpos;
/* calculate window width and current position */
wwidth=_winfo.cmenu->ecol - _winfo.cmenu->scol + 1;
cpos=(curr->wrow * wwidth) + curr->wcol;
/* initialize best record to NULL, and best position to 32767 */
best=NULL;
bpos=32767;
/* search backwards through linked list, testing items */
for(temp=_winfo.cmenu->item;temp!=NULL;temp=temp->prev) {
/* calculate position of test item */
tpos=(temp->wrow*wwidth) + temp->wcol;
/* compare position of test item with best item, current item */
if(tpos<bpos && tpos>cpos) {
best=temp;
bpos=tpos;
}
}
/* if there wasn't a item to the right, then wrap around */
if(best==NULL)
best=first_item();
else
/* see if menu selection is non-selectable */
if(best->fmask&M_NOSEL)
best=right_item(best);
/* return best record */
return(best);
}
/*---------------------------------------------------------------------------*/
/* this function will display the mouse */
/* cursor if mouse cursor mode is on */
static void show_mouse_cursor(void)
{
if(_mouse) {
if(_mouse&MS_CURS) {
msshowcur();
mscursor(0,0xffff,((LGREY|_LGREY)<<8));
}
}
}
/*---------------------------------------------------------------------------*/
/* this function finds the previous menu selection upwards */
static struct _item_t *up_item(struct _item_t *curr)
{
struct _item_t *best,*temp;
int brow,bcol,tcol,crow,trow,ccol,tdist,bdist;
/* initialize best record to NULL */
best = NULL;
brow = -1;
bcol = 32767;
/* calculate window column at center of current item */
crow=(int)curr->wrow;
ccol=calc_center_item(curr);
/* search backwards through linked list, testing items */
for(temp=_winfo.cmenu->item;temp!=NULL;temp=temp->prev) {
/* calculate window column at center of test item */
trow=(int)temp->wrow;
tcol=calc_center_item(temp);
if(trow<crow) {
tdist=abs(ccol-tcol);
bdist=abs(ccol-bcol);
if((trow>brow)||((trow==brow&&tdist<bdist))) {
best=temp;
brow=trow;
bcol=tcol;
}
}
}
/* if there wasn't a item to the left, then wrap around */
if(best==NULL) {
if((temp=malloc(sizeof(struct _item_t)))==NULL) {
best=curr;
}
else {
*temp=*curr;
temp->wrow=255;
best=up_item(temp);
free(temp);
}
}
else
/* see if menu selection is non-selectable */
if(best->fmask&M_NOSEL)
best=up_item(best);
/* return best record */
return(best);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -