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

📄 wmenu.c

📁 详细介绍了一篇关于pci开发的接口芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
                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 + -