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

📄 tkmenudraw.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Results: *	None. * * Side effects: *	Fields of menu entries are changed to reflect their *	current positions, and the size of the menu window *	itself may be changed. * *-------------------------------------------------------------- */static voidComputeMenuGeometry(clientData)    ClientData clientData;		/* Structure describing menu. */{    TkMenu *menuPtr = (TkMenu *) clientData;    if (menuPtr->tkwin == NULL) {	return;    }    if (menuPtr->menuType == MENUBAR) {	TkpComputeMenubarGeometry(menuPtr);    } else {	TkpComputeStandardMenuGeometry(menuPtr);    }    if ((menuPtr->totalWidth != Tk_ReqWidth(menuPtr->tkwin)) ||	    (menuPtr->totalHeight != Tk_ReqHeight(menuPtr->tkwin))) {	Tk_GeometryRequest(menuPtr->tkwin, menuPtr->totalWidth,		menuPtr->totalHeight);    }	    /*     * Must always force a redisplay here if the window is mapped     * (even if the size didn't change, something else might have     * changed in the menu, such as a label or accelerator).  The     * resize will force a redisplay above.     */        TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);        menuPtr->menuFlags &= ~RESIZE_PENDING;}/* *---------------------------------------------------------------------- * * TkMenuSelectImageProc -- * *	This procedure is invoked by the image code whenever the manager *	for an image does something that affects the size of contents *	of an image displayed in a menu entry when it is selected. * * Results: *	None. * * Side effects: *	Arranges for the menu to get redisplayed. * *---------------------------------------------------------------------- */voidTkMenuSelectImageProc(clientData, x, y, width, height, imgWidth,	imgHeight)    ClientData clientData;		/* Pointer to widget record. */    int x, y;				/* Upper left pixel (within image)					 * that must be redisplayed. */    int width, height;			/* Dimensions of area to redisplay					 * (may be <= 0). */    int imgWidth, imgHeight;		/* New dimensions of image. */{    register TkMenuEntry *mePtr = (TkMenuEntry *) clientData;    if ((mePtr->entryFlags & ENTRY_SELECTED)	    && !(mePtr->menuPtr->menuFlags &	    REDRAW_PENDING)) {	mePtr->menuPtr->menuFlags |= REDRAW_PENDING;	Tcl_DoWhenIdle(DisplayMenu, (ClientData) mePtr->menuPtr);    }}/* *---------------------------------------------------------------------- * * DisplayMenu -- * *	This procedure is invoked to display a menu widget. * * Results: *	None. * * Side effects: *	Commands are output to X to display the menu in its *	current mode. * *---------------------------------------------------------------------- */static voidDisplayMenu(clientData)    ClientData clientData;	/* Information about widget. */{    register TkMenu *menuPtr = (TkMenu *) clientData;    register TkMenuEntry *mePtr;    register Tk_Window tkwin = menuPtr->tkwin;    int index, strictMotif;    Tk_Font tkfont = menuPtr->tkfont;    Tk_FontMetrics menuMetrics;    int width;    menuPtr->menuFlags &= ~REDRAW_PENDING;    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {	return;    }    if (menuPtr->menuType == MENUBAR) {	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), menuPtr->border,		menuPtr->borderWidth, menuPtr->borderWidth,		Tk_Width(tkwin) - 2 * menuPtr->borderWidth,		Tk_Height(tkwin) - 2 * menuPtr->borderWidth, 0,		TK_RELIEF_FLAT);    }    strictMotif = Tk_StrictMotif(menuPtr->tkwin);    /*     * See note in ComputeMenuGeometry. We don't want to be doing font metrics     * all of the time.     */    Tk_GetFontMetrics(menuPtr->tkfont, &menuMetrics);    /*     * Loop through all of the entries, drawing them one at a time.     */    for (index = 0; index < menuPtr->numEntries; index++) {	mePtr = menuPtr->entries[index];	if (menuPtr->menuType != MENUBAR) {	    if (!(mePtr->entryFlags & ENTRY_NEEDS_REDISPLAY)) {		continue;	    }	}	mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;	if (menuPtr->menuType == MENUBAR) {	    width = mePtr->width;	} else {	    if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {		width = Tk_Width(menuPtr->tkwin) - mePtr->x			- menuPtr->activeBorderWidth;	    } else {		width = mePtr->width + menuPtr->borderWidth;	    }	}	TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,		&menuMetrics, mePtr->x, mePtr->y, width, 		mePtr->height, strictMotif, 1);	if ((index > 0) && (menuPtr->menuType != MENUBAR) 		&& mePtr->columnBreak) {	    mePtr = menuPtr->entries[index - 1];	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), menuPtr->border,		mePtr->x, mePtr->y + mePtr->height, 		mePtr->width,		Tk_Height(tkwin) - mePtr->y - mePtr->height 		- menuPtr->activeBorderWidth, 0,		TK_RELIEF_FLAT);	}    }    if (menuPtr->menuType != MENUBAR) {	int x, y, height;	if (menuPtr->numEntries == 0) {	    x = y = menuPtr->borderWidth;	    width = Tk_Width(tkwin) - 2 * menuPtr->activeBorderWidth;	    height = Tk_Height(tkwin) - 2 * menuPtr->activeBorderWidth;	} else {	    mePtr = menuPtr->entries[menuPtr->numEntries - 1];	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),		menuPtr->border, mePtr->x, mePtr->y + mePtr->height,		mePtr->width, Tk_Height(tkwin) - mePtr->y - mePtr->height		- menuPtr->activeBorderWidth, 0,		TK_RELIEF_FLAT);	    x = mePtr->x + mePtr->width;	    y = mePtr->y + mePtr->height;	    width = Tk_Width(tkwin) - x - menuPtr->activeBorderWidth;	    height = Tk_Height(tkwin) - y - menuPtr->activeBorderWidth;	}	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), menuPtr->border, x, y, 		width, height, 0, TK_RELIEF_FLAT);    }    Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin),	    menuPtr->border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin),	    menuPtr->borderWidth, menuPtr->relief);}/* *-------------------------------------------------------------- * * TkMenuEventProc -- * *	This procedure is invoked by the Tk dispatcher for various *	events on menus. * * Results: *	None. * * Side effects: *	When the window gets deleted, internal structures get *	cleaned up.  When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */voidTkMenuEventProc(clientData, eventPtr)    ClientData clientData;	/* Information about window. */    XEvent *eventPtr;		/* Information about event. */{    TkMenu *menuPtr = (TkMenu *) clientData;        if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {	TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);    } else if (eventPtr->type == ConfigureNotify) {	TkEventuallyRecomputeMenu(menuPtr);	TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);    } else if (eventPtr->type == ActivateNotify) {    	if (menuPtr->menuType == TEAROFF_MENU) {    	    TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL);    	}    } else if (eventPtr->type == DestroyNotify) {	if (menuPtr->tkwin != NULL) {	    menuPtr->tkwin = NULL;	    Tcl_DeleteCommandFromToken(menuPtr->interp, menuPtr->widgetCmd);	}	if (menuPtr->menuFlags & REDRAW_PENDING) {	    Tcl_CancelIdleCall(DisplayMenu, (ClientData) menuPtr);	}	if (menuPtr->menuFlags & RESIZE_PENDING) {	    Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr);	}	TkDestroyMenu(menuPtr);    }}/* *---------------------------------------------------------------------- * * TkMenuImageProc -- * *	This procedure is invoked by the image code whenever the manager *	for an image does something that affects the size of contents *	of an image displayed in a menu entry. * * Results: *	None. * * Side effects: *	Arranges for the menu to get redisplayed. * *---------------------------------------------------------------------- */voidTkMenuImageProc(clientData, x, y, width, height, imgWidth,	imgHeight)    ClientData clientData;		/* Pointer to widget record. */    int x, y;				/* Upper left pixel (within image)					 * that must be redisplayed. */    int width, height;			/* Dimensions of area to redisplay					 * (may be <= 0). */    int imgWidth, imgHeight;		/* New dimensions of image. */{    register TkMenu *menuPtr = ((TkMenuEntry *)clientData)->menuPtr;    if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags	    & RESIZE_PENDING)) {	menuPtr->menuFlags |= RESIZE_PENDING;	Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr);    }}/* *---------------------------------------------------------------------- * * TkPostTearoffMenu -- * *	Posts a menu on the screen. Used to post tearoff menus. On Unix, *	all menus are posted this way. Adjusts the menu's position *	so that it fits on the screen, and maps and raises the menu. * * Results: *	Returns a standard Tcl Error. * * Side effects: *	The menu is posted. * *---------------------------------------------------------------------- */intTkPostTearoffMenu(interp, menuPtr, x, y)    Tcl_Interp *interp;			/* The interpreter of the menu */    TkMenu *menuPtr;			/* The menu we are posting */    int x;				/* The root X coordinate where we					 * are posting */    int y;				/* The root Y coordinate where we					 * are posting */{    int vRootX, vRootY, vRootWidth, vRootHeight;    int tmp, result;    TkActivateMenuEntry(menuPtr, -1);    TkRecomputeMenu(menuPtr);    result = TkPostCommand(menuPtr);    if (result != TCL_OK) {    	return result;    }    /*     * The post commands could have deleted the menu, which means     * we are dead and should go away.     */    if (menuPtr->tkwin == NULL) {    	return TCL_OK;    }    /*     * Adjust the position of the menu if necessary to keep it     * visible on the screen.  There are two special tricks to     * make this work right:     *     * 1. If a virtual root window manager is being used then     *    the coordinates are in the virtual root window of     *    menuPtr's parent;  since the menu uses override-redirect     *    mode it will be in the *real* root window for the screen,     *    so we have to map the coordinates from the virtual root     *    (if any) to the real root.  Can't get the virtual root     *    from the menu itself (it will never be seen by the wm)     *    so use its parent instead (it would be better to have an     *    an option that names a window to use for this...).     * 2. The menu may not have been mapped yet, so its current size     *    might be the default 1x1.  To compute how much space it     *    needs, use its requested size, not its actual size.     *     * Note that this code assumes square screen regions and all     * positive coordinates. This does not work on a Mac with     * multiple monitors. But then again, Tk has other problems     * with this.     */    Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,	&vRootWidth, &vRootHeight);    x += vRootX;    y += vRootY;    tmp = WidthOfScreen(Tk_Screen(menuPtr->tkwin))	- Tk_ReqWidth(menuPtr->tkwin);    if (x > tmp) {	x = tmp;    }    if (x < 0) {	x = 0;    }    tmp = HeightOfScreen(Tk_Screen(menuPtr->tkwin))	- Tk_ReqHeight(menuPtr->tkwin);    if (y > tmp) {	y = tmp;    }    if (y < 0) {	y = 0;    }    Tk_MoveToplevelWindow(menuPtr->tkwin, x, y);    if (!Tk_IsMapped(menuPtr->tkwin)) {	Tk_MapWindow(menuPtr->tkwin);    }    TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL);    return TCL_OK;}/* *-------------------------------------------------------------- * * TkPostSubmenu -- * *	This procedure arranges for a particular submenu (i.e. the *	menu corresponding to a given cascade entry) to be *	posted. * * Results: *	A standard Tcl return result.  Errors may occur in the *	Tcl commands generated to post and unpost submenus. * * Side effects: *	If there is already a submenu posted, it is unposted. *	The new submenu is then posted. * *-------------------------------------------------------------- */intTkPostSubmenu(interp, menuPtr, mePtr)    Tcl_Interp *interp;		/* Used for invoking sub-commands and				 * reporting errors. */    register TkMenu *menuPtr;	/* Information about menu as a whole. */    register TkMenuEntry *mePtr;	/* Info about submenu that is to be				 * posted.  NULL means make sure that				 * no submenu is posted. */{    char string[30];    int result, x, y;    if (mePtr == menuPtr->postedCascade) {	return TCL_OK;    }    if (menuPtr->postedCascade != NULL) {	/*	 * Note: when unposting a submenu, we have to redraw the entire	 * parent menu.  This is because of a combination of the following	 * things:	 * (a) the submenu partially overlaps the parent.	 * (b) the submenu specifies "save under", which causes the X	 *     server to make a copy of the information under it when it	 *     is posted.  When the submenu is unposted, the X server	 *     copies this data back and doesn't generate any Expose	 *     events for the parent.	 * (c) the parent may have redisplayed itself after the submenu	 *     was posted, in which case the saved information is no	 *     longer correct.	 * The simplest solution is just force a complete redisplay of	 * the parent.	 */	TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);	result = Tcl_VarEval(interp, menuPtr->postedCascade->name,		" unpost", (char *) NULL);	menuPtr->postedCascade = NULL;	if (result != TCL_OK) {	    return result;	}    }    if ((mePtr != NULL) && (mePtr->name != NULL)	    && Tk_IsMapped(menuPtr->tkwin)) {	/*	 * Position the cascade with its upper left corner slightly	 * below and to the left of the upper right corner of the	 * menu entry (this is an attempt to match Motif behavior).	 *	 * The menu has to redrawn so that the entry can change relief.	 */	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);	AdjustMenuCoords(menuPtr, mePtr, &x, &y, string);	result = Tcl_VarEval(interp, mePtr->name, " post ", string,		(char *) NULL);	if (result != TCL_OK) {	    return result;	}	menuPtr->postedCascade = mePtr;	TkEventuallyRedrawMenu(menuPtr, mePtr);    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * AdjustMenuCoords -- * *	Adjusts the given coordinates down and the left to give a Motif *	look. * * Results: *	None. * * Side effects: *	The menu is eventually redrawn if necessary. * *---------------------------------------------------------------------- */static voidAdjustMenuCoords(menuPtr, mePtr, xPtr, yPtr, string)    TkMenu *menuPtr;    TkMenuEntry *mePtr;    int *xPtr;    int *yPtr;    char *string;{    if (menuPtr->menuType == MENUBAR) {	*xPtr += mePtr->x;	*yPtr += mePtr->y + mePtr->height;    } else {	*xPtr += Tk_Width(menuPtr->tkwin) - menuPtr->borderWidth		- menuPtr->activeBorderWidth - 2;	*yPtr += mePtr->y	        + menuPtr->activeBorderWidth + 2;    }    sprintf(string, "%d %d", *xPtr, *yPtr);}

⌨️ 快捷键说明

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