📄 menu.c
字号:
/*---------------------------------------------------------------------- File : menu.c Contents: simplified menu definition for Athena widgets Author : Christian Borgelt History : 11.04.1998 file created 16.04.1998 first version completed 17.06.2000 bug in function mn_resize fixed (negative width)----------------------------------------------------------------------*/#include "menu.h"#include <stdio.h>#include <stdlib.h>#include <X11/StringDefs.h>#include <X11/Xaw/Box.h>#include <X11/Xaw/Form.h>#include <X11/Xaw/Label.h>#include <X11/Xaw/MenuButton.h>#include <X11/Xaw/SimpleMenu.h>#include <X11/Xaw/SmeBSB.h>#include <X11/Xaw/SmeLine.h>/*---------------------------------------------------------------------- Preprocessor Definitions----------------------------------------------------------------------*/#define BS_TITLES 8 /* block size for menu titles vector */#define BS_ITEMS 8 /* block size for menu items vector *//*---------------------------------------------------------------------- Functions----------------------------------------------------------------------*/MENU* mn_create (Widget parent){ /* --- create a menu --- */ MENU *menu; /* created menu */ Arg args[10]; /* widget argument list */ int n; /* argument counter */ menu = (MENU*)calloc(1, sizeof(MENU)); if (!menu) return NULL; /* allocate memory */ menu->parent = parent; /* and note parent widget */ n = 0; /* build argument list */ XtSetArg(args[n], XtNborderWidth, 0); n++; XtSetArg(args[n], XtNhSpace, 0); n++; XtSetArg(args[n], XtNvSpace, 0); n++; XtSetArg(args[n], XtNorientation, XtEhorizontal); n++; XtSetArg(args[n], XtNleft, XtChainLeft); n++; XtSetArg(args[n], XtNtop, XtChainTop); n++; XtSetArg(args[n], XtNright, XtChainLeft); n++; XtSetArg(args[n], XtNbottom, XtChainTop); n++; XtSetArg(args[n], XtNresizable, True); n++; menu->menubar = XtCreateManagedWidget("menuBar", boxWidgetClass, parent, args, n); if (!menu->menubar) { mn_delete(menu); return NULL; } return menu; /* create menu bar and return menu */} /* mn_create() *//*--------------------------------------------------------------------*/void mn_delete (MENU *menu){ /* --- delete a menu */ XtDestroyWidget(menu->menubar); /* destroy all menu widgets */ if (menu->titles) free(menu->titles); if (menu->items) free(menu->items); free(menu); /* deallocate memory */} /* mn_delete() *//*--------------------------------------------------------------------*/int mn_addtitle (MENU *menu, const char *name, int flags, XtCallbackProc proc, XtPointer data){ /* --- add a menu title */ MNTITLE *tmp; /* new menu titles vector, buffer */ int vsz; /* new menu titles vector size */ Widget title, pane; /* created menu title and item pane */ Arg args[8]; /* widget argument list */ int n; /* argument counter */ Dimension wd; /* width of menu title */ if (menu->filler) return -1; /* check whether menu is complete */ /* --- add the filler title --- */ if (!name) { /* if no title name given */ n = 0; /* build argument list */ XtSetArg(args[n], XtNlabel, ""); n++; XtSetArg(args[n], XtNborderWidth, 0); n++; XtSetArg(args[n], XtNjustify, XtJustifyRight); n++; XtSetArg(args[n], XtNleft, XtChainLeft); n++; XtSetArg(args[n], XtNright, XtChainRight); n++; XtSetArg(args[n], XtNresize, False); n++; XtSetArg(args[n], XtNresizable, True); n++; menu->filler = XtCreateManagedWidget("filler", labelWidgetClass, menu->menubar, args, n); if (!menu->filler) return -1; XtVaGetValues(menu->filler, XtNheight, &menu->height, NULL); return 0; /* create a filler title */ } /* and abort the function */ /* --- add a menu title --- */ vsz = menu->titlevsz; /* get the size of the title vector */ if (menu->titlecnt >= vsz) { /* if the menu titles vector is full, */ vsz += BS_TITLES; /* enlarge menu titles vector */ tmp = (MNTITLE*)realloc(menu->titles, vsz *sizeof(MNTITLE)); if (!tmp) return -1; /* allocate a (new) vector */ menu->titles = tmp; menu->titlevsz = vsz; } /* set new vector and its size */ n = 0; /* build argument list */ XtSetArg(args[n], XtNmenuName, name); n++; XtSetArg(args[n], XtNborderWidth, 0); n++; title = XtCreateManagedWidget(name, menuButtonWidgetClass, menu->menubar, args, n); if (!title) return -1; /* create a menu title */ pane = XtCreatePopupShell(name, simpleMenuWidgetClass, title, NULL, 0); /* create a menu for the items */ if (!pane) { XtDestroyWidget(title); return -1; } if (proc) /* set menu callback function */ XtAddCallback(pane, XtNpopupCallback, proc, data); XtVaGetValues(title, XtNwidth, &wd, NULL); menu->mnwd += wd; /* add title width to menu width */ tmp = menu->titles +menu->titlecnt++; tmp->title = title; /* note the menu title */ tmp->pane = pane; /* and the menu pane widget */ tmp->flags = flags; /* and the title flags */ return 0; /* return `ok' */} /* mn_addtitle() *//*--------------------------------------------------------------------*/int mn_additem (MENU *menu, const char *name, int flags, XtCallbackProc proc, XtPointer data){ /* --- add a menu item */ MNITEM *tmp; /* new menu items vector, buffer */ int vsz; /* new menu items vector size */ Widget pane; /* item pane to add to */ Widget item; /* created menu item */ if (menu->titlecnt <= 0) return -1; pane = menu->titles[menu->titlecnt-1].pane; vsz = menu->itemvsz; /* get the size of the title vector */ if (menu->itemcnt >= vsz) { /* if the menu items vector is full, */ vsz += BS_ITEMS; /* enlarge menu items vector */ tmp = (MNITEM*)realloc(menu->items, vsz *sizeof(MNITEM)); if (!tmp) return -1; /* allocate a (new) vector */ menu->items = tmp; menu->itemvsz = vsz; } /* set new vector and its size */ /* --- add a separator --- */ if (!name) { /* if no item name is given */ item = XtCreateManagedWidget("_line_", smeLineObjectClass, pane, NULL, 0); if (!item) return -1; } /* create a separating line */ else { /* if an item name is given */ item = XtCreateManagedWidget(name, smeBSBObjectClass, pane, NULL, 0); if (!item) return -1; /* create a menu item */ if (proc) /* set item callback function */ XtAddCallback(item, XtNcallback, proc, data); XtInstallAccelerators(menu->parent, item); XtInstallAccelerators(pane, item); } /* install item accelerators */ tmp = menu->items +menu->itemcnt++; tmp->item = item; /* note the item widget */ tmp->flags = flags; /* and the item flags */ return 0; /* return `ok' */} /* mn_additem *//*--------------------------------------------------------------------*/void mn_visible (MENU *menu, int type, int flags){ /* --- enable/disable menu titles */ int i; /* loop variable */ MNTITLE *mnt; /* to traverse menu titles */ MNITEM *mni; /* to traverse menu items */ Dimension wd, mnwd = 0; /* width of menu titles */ if (type & MN_MENU) { /* if to show/hide menu bar */ if (flags) XtManageChild(menu->menubar); else XtUnmanageChild(menu->menubar); } /* manage/unmanage menu bar widget */ if (type & MN_TITLES) { /* if to show/hide menu titles */ if (menu->filler) XtUnmanageChild(menu->filler); mnt = menu->titles; /* traverse menu titles */ for (i = menu->titlecnt; --i >= 0; mnt++) { if ( mnt->flags /* if to hide this menu title */ && !(mnt->flags & flags)) XtUnmanageChild(mnt->title); else { /* if to show this menu title */ XtManageChild(mnt->title); XtVaGetValues(mnt->title, XtNwidth, &wd, NULL); mnwd += wd; /* manage the menu title widget, */ } /* get the title width and thus */ } /* determine the menu width */ menu->mnwd = mnwd; /* and note it afterwards */ mn_resize(menu, menu->width); if (menu->filler) XtManageChild(menu->filler); } /* set the filler width */ if (type & MN_ITEMS) { /* if to show/hide menu items */ mni = menu->items; /* traverse menu items */ for (i = menu->itemcnt; --i >= 0; mni++) { if ( mni->flags /* if to hide this menu item */ && !(mni->flags & flags)) XtUnmanageChild(mni->item); else /* if to show this menu item */ XtManageChild(mni->item); } /* manage the menu item widget */ }} /* mn_visible() *//*--------------------------------------------------------------------*/void mn_enable (MENU *menu, int type, int flags){ /* --- enable/disable menu titles */ int i; /* loop variable */ MNTITLE *mnt; /* to traverse menu titles */ MNITEM *mni; /* to traverse menu items */ if (type & MN_MENU) /* if to enable/disable menu bar */ XtSetSensitive(menu->menubar, flags); if (type & MN_TITLES) { /* if to show/hide menu titles */ mnt = menu->titles; /* traverse menu titles */ for (i = menu->titlecnt; --i >= 0; mnt++) XtSetSensitive(mnt->title, (mnt->flags == 0) || (mnt->flags & flags)); } /* enable and disable menu titles */ if (type & MN_ITEMS) { /* if to show/hide menu items */ mni = menu->items; /* traverse menu items */ for (i = menu->itemcnt; --i >= 0; mni++) XtSetSensitive(mni->item, (mni->flags == 0) || (mni->flags & flags)); } /* enable and disable menu items */} /* mn_enable() *//*--------------------------------------------------------------------*/int mn_info (MENU *menu, const char *text){ /* --- set text of filler widget */ if (!menu->filler) return -1; /* check existence of filler */ XtVaSetValues(menu->filler, XtNlabel, text, NULL); mn_resize(menu, menu->width); /* set label and filler width */ return 0; /* return `ok' */} /* mn_info() *//*--------------------------------------------------------------------*/int mn_resize (MENU *menu, Dimension width){ /* --- resize menu bar */ if (!menu->filler) return -1; /* check existence of filler */ menu->width = width; /* note new menu width */ width = (width > menu->mnwd) ? (width -menu->mnwd) : 0; if (width <= 0) width = 1; /* compute the filler size */ XtVaSetValues(menu->filler, XtNwidth, width, NULL); return 0; /* set filler size and return `ok' */} /* mn_resize() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -