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

📄 tkunixmenubu.c

📁 NS2网络仿真软件是目前最为流行的网络仿真模拟软件
💻 C
字号:
/*  * tkUnixMenubu.c -- * *	This file implements the Unix specific portion of the *	menubutton widget. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkUnixMenubu.c,v 1.6.4.1 2003/11/17 23:29:36 hobbs Exp $ */#include "tkMenubutton.h"/* * The structure below defines menubutton class behavior by means of * procedures that can be invoked from generic window code. */Tk_ClassProcs tkpMenubuttonClass = {    sizeof(Tk_ClassProcs),	/* size */    TkMenuButtonWorldChanged,	/* worldChangedProc */};/* *---------------------------------------------------------------------- * * TkpCreateMenuButton -- * *	Allocate a new TkMenuButton structure. * * Results: *	Returns a newly allocated TkMenuButton structure. * * Side effects: *	Registers an event handler for the widget. * *---------------------------------------------------------------------- */TkMenuButton *TkpCreateMenuButton(tkwin)    Tk_Window tkwin;{    return (TkMenuButton *)ckalloc(sizeof(TkMenuButton));}/* *---------------------------------------------------------------------- * * TkpDisplayMenuButton -- * *	This procedure is invoked to display a menubutton widget. * * Results: *	None. * * Side effects: *	Commands are output to X to display the menubutton in its *	current mode. * *---------------------------------------------------------------------- */voidTkpDisplayMenuButton(clientData)    ClientData clientData;	/* Information about widget. */{    register TkMenuButton *mbPtr = (TkMenuButton *) clientData;    GC gc;    Tk_3DBorder border;    Pixmap pixmap;    int x = 0;			/* Initialization needed only to stop				 * compiler warning. */    int y = 0;    register Tk_Window tkwin = mbPtr->tkwin;    int width=0, height=0, fullWidth=0, fullHeight=0;    int textXOffset, textYOffset;    int imageWidth, imageHeight;    int imageXOffset, imageYOffset; /* image information that will be used to				     * restrict disabled pixmap as well */    int haveImage = 0, haveText = 0;    mbPtr->flags &= ~REDRAW_PENDING;    if ((mbPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {	return;    }    if ((mbPtr->state == STATE_DISABLED) && (mbPtr->disabledFg != NULL)) {	gc = mbPtr->disabledGC;	border = mbPtr->normalBorder;    } else if ((mbPtr->state == STATE_ACTIVE)	       && !Tk_StrictMotif(mbPtr->tkwin)) {	gc = mbPtr->activeTextGC;	border = mbPtr->activeBorder;    } else {	gc = mbPtr->normalTextGC;	border = mbPtr->normalBorder;    }    if (mbPtr->image != None) {	Tk_SizeOfImage(mbPtr->image, &width, &height);	haveImage = 1;    } else if (mbPtr->bitmap != None) {	Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);	haveImage = 1;    }    imageWidth  = width;    imageHeight = height;    haveText = (mbPtr->textWidth != 0 && mbPtr->textHeight != 0);    /*     * In order to avoid screen flashes, this procedure redraws     * the menu button in a pixmap, then copies the pixmap to the     * screen in a single operation.  This means that there's no     * point in time where the on-sreen image has been cleared.     */    pixmap = Tk_GetPixmap(mbPtr->display, Tk_WindowId(tkwin),	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));    Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin),	    Tk_Height(tkwin), 0, TK_RELIEF_FLAT);    imageXOffset = 0;    imageYOffset = 0;    textXOffset = 0;    textYOffset = 0;    fullWidth = 0;    fullHeight = 0;    if (mbPtr->compound != COMPOUND_NONE && haveImage && haveText) {        switch ((enum compound) mbPtr->compound) {            case COMPOUND_TOP:            case COMPOUND_BOTTOM: {                /* Image is above or below text */                if (mbPtr->compound == COMPOUND_TOP) {                    textYOffset = height + mbPtr->padY;                } else {                    imageYOffset = mbPtr->textHeight + mbPtr->padY;                }                fullHeight = height + mbPtr->textHeight + mbPtr->padY;                fullWidth = (width > mbPtr->textWidth ? width :                        mbPtr->textWidth);                textXOffset = (fullWidth - mbPtr->textWidth)/2;                imageXOffset = (fullWidth - width)/2;                break;            }            case COMPOUND_LEFT:            case COMPOUND_RIGHT: {                /* Image is left or right of text */                if (mbPtr->compound == COMPOUND_LEFT) {                    textXOffset = width + mbPtr->padX;                } else {                    imageXOffset = mbPtr->textWidth + mbPtr->padX;                }                fullWidth = mbPtr->textWidth + mbPtr->padX + width;                fullHeight = (height > mbPtr->textHeight ? height :                        mbPtr->textHeight);                textYOffset = (fullHeight - mbPtr->textHeight)/2;                imageYOffset = (fullHeight - height)/2;                break;            }            case COMPOUND_CENTER: {                /* Image and text are superimposed */                fullWidth = (width > mbPtr->textWidth ? width :                        mbPtr->textWidth);                fullHeight = (height > mbPtr->textHeight ? height :                        mbPtr->textHeight);                textXOffset = (fullWidth - mbPtr->textWidth)/2;                imageXOffset = (fullWidth - width)/2;                textYOffset = (fullHeight - mbPtr->textHeight)/2;                imageYOffset = (fullHeight - height)/2;                break;            }            case COMPOUND_NONE: {break;}        }        TkComputeAnchor(mbPtr->anchor, tkwin, 0, 0,		mbPtr->indicatorWidth + fullWidth, fullHeight, &x, &y);	imageXOffset += x;	imageYOffset += y;	if (mbPtr->image != NULL) {	    Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap,		    imageXOffset, imageYOffset);	} else if (mbPtr->bitmap != None) {	    XSetClipOrigin(mbPtr->display, gc, imageXOffset, imageYOffset);	    XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap,		    gc, 0, 0, (unsigned) width, (unsigned) height, 		    imageXOffset, imageYOffset, 1);	    XSetClipOrigin(mbPtr->display, gc, 0, 0);	}	Tk_DrawTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,		x + textXOffset, y + textYOffset, 0, -1);	Tk_UnderlineTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,		x + textXOffset, y + textYOffset, mbPtr->underline);    } else if (haveImage) {	TkComputeAnchor(mbPtr->anchor, tkwin, 0, 0,		width + mbPtr->indicatorWidth, height, &x, &y);	imageXOffset += x;	imageYOffset += y;	if (mbPtr->image != NULL) {	    Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap,		    imageXOffset, imageYOffset);	} else if (mbPtr->bitmap != None) {	    XSetClipOrigin(mbPtr->display, gc, x, y);	    XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap,		    gc, 0, 0, (unsigned) width, (unsigned) height, 		    x, y, 1);	    XSetClipOrigin(mbPtr->display, gc, 0, 0);	}    } else {	TkComputeAnchor(mbPtr->anchor, tkwin, mbPtr->padX, mbPtr->padY,		mbPtr->textWidth + mbPtr->indicatorWidth,		mbPtr->textHeight, &x, &y);	Tk_DrawTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout, 		x + textXOffset, y + textYOffset, 0, -1);	Tk_UnderlineTextLayout(mbPtr->display, pixmap, gc,		mbPtr->textLayout, x + textXOffset, y + textYOffset,		mbPtr->underline);    }    /*     * If the menu button is disabled with a stipple rather than a special     * foreground color, generate the stippled effect.     */    if ((mbPtr->state == STATE_DISABLED)             && ((mbPtr->disabledFg == NULL) || (mbPtr->image != NULL))) {	/*	 * Stipple the whole button if no disabledFg was specified,	 * otherwise restrict stippling only to displayed image	 */	if (mbPtr->disabledFg == NULL) {	    XFillRectangle(mbPtr->display, pixmap, mbPtr->stippleGC,		    mbPtr->inset, mbPtr->inset,		    (unsigned) (Tk_Width(tkwin) - 2*mbPtr->inset),		    (unsigned) (Tk_Height(tkwin) - 2*mbPtr->inset));	} else {	    XFillRectangle(mbPtr->display, pixmap, mbPtr->stippleGC,		    imageXOffset, imageYOffset,		    (unsigned) imageWidth, (unsigned) imageHeight);	}    }    /*     * Draw the cascade indicator for the menu button on the     * right side of the window, if desired.     */    if (mbPtr->indicatorOn) {	int borderWidth;	borderWidth = (mbPtr->indicatorHeight+1)/3;	if (borderWidth < 1) {	    borderWidth = 1;	}	/*y += mbPtr->textHeight / 2;*/	Tk_Fill3DRectangle(tkwin, pixmap, border,		Tk_Width(tkwin) - mbPtr->inset - mbPtr->indicatorWidth		+ mbPtr->indicatorHeight,		((int) (Tk_Height(tkwin) - mbPtr->indicatorHeight))/2,		mbPtr->indicatorWidth - 2*mbPtr->indicatorHeight,		mbPtr->indicatorHeight, borderWidth, TK_RELIEF_RAISED);    }    /*     * Draw the border and traversal highlight last.  This way, if the     * menu button's contents overflow onto the border they'll be covered     * up by the border.     */    if (mbPtr->relief != TK_RELIEF_FLAT) {	Tk_Draw3DRectangle(tkwin, pixmap, border,		mbPtr->highlightWidth, mbPtr->highlightWidth,		Tk_Width(tkwin) - 2*mbPtr->highlightWidth,		Tk_Height(tkwin) - 2*mbPtr->highlightWidth,		mbPtr->borderWidth, mbPtr->relief);    }    if (mbPtr->highlightWidth != 0) {	GC gc;	if (mbPtr->flags & GOT_FOCUS) {	    gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap);	} else {	    gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap);	}	Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap);    }    /*     * Copy the information from the off-screen pixmap onto the screen,     * then delete the pixmap.     */    XCopyArea(mbPtr->display, pixmap, Tk_WindowId(tkwin),	    mbPtr->normalTextGC, 0, 0, (unsigned) Tk_Width(tkwin),	    (unsigned) Tk_Height(tkwin), 0, 0);    Tk_FreePixmap(mbPtr->display, pixmap);}/* *---------------------------------------------------------------------- * * TkpDestroyMenuButton -- * *	Free data structures associated with the menubutton control. * * Results: *	None. * * Side effects: *	Restores the default control state. * *---------------------------------------------------------------------- */voidTkpDestroyMenuButton(mbPtr)    TkMenuButton *mbPtr;{}/* *---------------------------------------------------------------------- * * TkpComputeMenuButtonGeometry -- * *	After changes in a menu button's text or bitmap, this procedure *	recomputes the menu button's geometry and passes this information *	along to the geometry manager for the window. * * Results: *	None. * * Side effects: *	The menu button's window may change size. * *---------------------------------------------------------------------- */voidTkpComputeMenuButtonGeometry(mbPtr)    TkMenuButton *mbPtr;	/* Widget record for menu button. */{    int width, height, mm, pixels;    int  avgWidth, txtWidth, txtHeight;    int haveImage = 0, haveText = 0;    Tk_FontMetrics fm;    mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth;    width = 0;    height = 0;    txtWidth = 0;    txtHeight = 0;    avgWidth = 0;    if (mbPtr->image != None) {	Tk_SizeOfImage(mbPtr->image, &width, &height);	haveImage = 1;    } else if (mbPtr->bitmap != None) {	Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);	haveImage = 1;    }    if (haveImage == 0 || mbPtr->compound != COMPOUND_NONE) {	Tk_FreeTextLayout(mbPtr->textLayout);	mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,		-1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,		&mbPtr->textHeight);	txtWidth = mbPtr->textWidth;	txtHeight = mbPtr->textHeight;        avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);        Tk_GetFontMetrics(mbPtr->tkfont, &fm);        haveText = (txtWidth != 0 && txtHeight != 0);    }    /*     * If the menubutton is compound (ie, it shows both an image and text),     * the new geometry is a combination of the image and text geometry.     * We only honor the compound bit if the menubutton has both text and     * an image, because otherwise it is not really a compound menubutton.     */    if (mbPtr->compound != COMPOUND_NONE && haveImage && haveText) {        switch ((enum compound) mbPtr->compound) {            case COMPOUND_TOP:            case COMPOUND_BOTTOM: {                /* Image is above or below text */                height += txtHeight + mbPtr->padY;                width = (width > txtWidth ? width : txtWidth);                break;            }            case COMPOUND_LEFT:            case COMPOUND_RIGHT: {                /* Image is left or right of text */                width += txtWidth + mbPtr->padX;                height = (height > txtHeight ? height : txtHeight);                break;            }            case COMPOUND_CENTER: {                /* Image and text are superimposed */                width = (width > txtWidth ? width : txtWidth);                height = (height > txtHeight ? height : txtHeight);                break;            }            case COMPOUND_NONE: {break;}        }        if (mbPtr->width > 0) {            width = mbPtr->width;        }        if (mbPtr->height > 0) {            height = mbPtr->height;        }        width += 2*mbPtr->padX;        height += 2*mbPtr->padY;    } else {	if (haveImage) {            if (mbPtr->width > 0) {                width = mbPtr->width;            }            if (mbPtr->height > 0) {                height = mbPtr->height;            }	} else {	    width = txtWidth;	    height = txtHeight;            if (mbPtr->width > 0) {                width = mbPtr->width * avgWidth;            }            if (mbPtr->height > 0) {                height = mbPtr->height * fm.linespace;            }	}    }    if (! haveImage) {        width += 2*mbPtr->padX;        height += 2*mbPtr->padY;    }    if (mbPtr->indicatorOn) {        mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin));        pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin));        mbPtr->indicatorHeight= (INDICATOR_HEIGHT * pixels)/(10*mm);        mbPtr->indicatorWidth = (INDICATOR_WIDTH * pixels)/(10*mm)    	    + 2*mbPtr->indicatorHeight;        width += mbPtr->indicatorWidth;    } else {        mbPtr->indicatorHeight = 0;        mbPtr->indicatorWidth = 0;    }    Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset),	    (int) (height + 2*mbPtr->inset));    Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset);}

⌨️ 快捷键说明

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