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

📄 tkunixbutton.c

📁 linux系统下的音频通信
💻 C
字号:
/*  * tkUnixButton.c -- * *	This file implements the Unix specific portion of the button *	widgets. * * Copyright (c) 1996 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. * * SCCS: @(#) tkUnixButton.c 1.4 97/06/06 11:21:40 */#include "tkButton.h"/* * Declaration of Unix specific button structure. */typedef struct UnixButton {    TkButton info;		/* Generic button info. */} UnixButton;/* * The class procedure table for the button widgets. */TkClassProcs tkpButtonProcs = {     NULL,			/* createProc. */    TkButtonWorldChanged,	/* geometryProc. */    NULL			/* modalProc. */};/* *---------------------------------------------------------------------- * * TkpCreateButton -- * *	Allocate a new TkButton structure. * * Results: *	Returns a newly allocated TkButton structure. * * Side effects: *	Registers an event handler for the widget. * *---------------------------------------------------------------------- */TkButton *TkpCreateButton(tkwin)    Tk_Window tkwin;{    UnixButton *butPtr = (UnixButton *)ckalloc(sizeof(UnixButton));    return (TkButton *) butPtr;}/* *---------------------------------------------------------------------- * * TkpDisplayButton -- * *	This procedure is invoked to display a button widget.  It is *	normally invoked as an idle handler. * * Results: *	None. * * Side effects: *	Commands are output to X to display the button in its *	current mode.  The REDRAW_PENDING flag is cleared. * *---------------------------------------------------------------------- */voidTkpDisplayButton(clientData)    ClientData clientData;	/* Information about widget. */{    register TkButton *butPtr = (TkButton *) clientData;    GC gc;    Tk_3DBorder border;    Pixmap pixmap;    int x = 0;			/* Initialization only needed to stop				 * compiler warning. */    int y, relief;    register Tk_Window tkwin = butPtr->tkwin;    int width, height;    int offset;			/* 0 means this is a label widget.  1 means				 * it is a flavor of button, so we offset				 * the text to make the button appear to				 * move up and down as the relief changes. */    butPtr->flags &= ~REDRAW_PENDING;    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {	return;    }    border = butPtr->normalBorder;    if ((butPtr->state == tkDisabledUid) && (butPtr->disabledFg != NULL)) {	gc = butPtr->disabledGC;    } else if ((butPtr->state == tkActiveUid)	    && !Tk_StrictMotif(butPtr->tkwin)) {	gc = butPtr->activeTextGC;	border = butPtr->activeBorder;    } else {	gc = butPtr->normalTextGC;    }    if ((butPtr->flags & SELECTED) && (butPtr->state != tkActiveUid)	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {	border = butPtr->selectBorder;    }    /*     * Override the relief specified for the button if this is a     * checkbutton or radiobutton and there's no indicator.     */    relief = butPtr->relief;    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {	relief = (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN		: TK_RELIEF_RAISED;    }    offset = (butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin);    /*     * In order to avoid screen flashes, this procedure redraws     * the 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(butPtr->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);    /*     * Display image or bitmap or text for button.     */    if (butPtr->image != None) {	Tk_SizeOfImage(butPtr->image, &width, &height);	imageOrBitmap:	TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,		butPtr->indicatorSpace + width, height, &x, &y);	x += butPtr->indicatorSpace;	x += offset;	y += offset;	if (relief == TK_RELIEF_RAISED) {	    x -= offset;	    y -= offset;	} else if (relief == TK_RELIEF_SUNKEN) {	    x += offset;	    y += offset;	}	if (butPtr->image != NULL) {	    if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {		Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap,			x, y);	    } else {		Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,			x, y);	    }	} else {	    XSetClipOrigin(butPtr->display, gc, x, y);	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,		    (unsigned int) width, (unsigned int) height, x, y, 1);	    XSetClipOrigin(butPtr->display, gc, 0, 0);	}	y += height/2;    } else if (butPtr->bitmap != None) {	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);	goto imageOrBitmap;    } else {	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,		butPtr->indicatorSpace + butPtr->textWidth, butPtr->textHeight,		&x, &y);	x += butPtr->indicatorSpace;	x += offset;	y += offset;	if (relief == TK_RELIEF_RAISED) {	    x -= offset;	    y -= offset;	} else if (relief == TK_RELIEF_SUNKEN) {	    x += offset;	    y += offset;	}	Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,		x, y, 0, -1);	Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,		butPtr->textLayout, x, y, butPtr->underline);	y += butPtr->textHeight/2;    }    /*     * Draw the indicator for check buttons and radio buttons.  At this     * point x and y refer to the top-left corner of the text or image     * or bitmap.     */    if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {	int dim;	dim = butPtr->indicatorDiameter;	x -= butPtr->indicatorSpace;	y -= dim/2;	if (dim > 2*butPtr->borderWidth) {	    Tk_Draw3DRectangle(tkwin, pixmap, border, x, y, dim, dim,		    butPtr->borderWidth, 		    (butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN :		    TK_RELIEF_RAISED);	    x += butPtr->borderWidth;	    y += butPtr->borderWidth;	    dim -= 2*butPtr->borderWidth;	    if (butPtr->flags & SELECTED) {		GC gc;		gc = Tk_3DBorderGC(tkwin,(butPtr->selectBorder != NULL)			? butPtr->selectBorder : butPtr->normalBorder,			TK_3D_FLAT_GC);		XFillRectangle(butPtr->display, pixmap, gc, x, y,			(unsigned int) dim, (unsigned int) dim);	    } else {		Tk_Fill3DRectangle(tkwin, pixmap, butPtr->normalBorder, x, y,			dim, dim, butPtr->borderWidth, TK_RELIEF_FLAT);	    }	}    } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) {	XPoint points[4];	int radius;	radius = butPtr->indicatorDiameter/2;	points[0].x = x - butPtr->indicatorSpace;	points[0].y = y;	points[1].x = points[0].x + radius;	points[1].y = points[0].y + radius;	points[2].x = points[1].x + radius;	points[2].y = points[0].y;	points[3].x = points[1].x;	points[3].y = points[0].y - radius;	if (butPtr->flags & SELECTED) {	    GC gc;	    gc = Tk_3DBorderGC(tkwin, (butPtr->selectBorder != NULL)		    ? butPtr->selectBorder : butPtr->normalBorder,		    TK_3D_FLAT_GC);	    XFillPolygon(butPtr->display, pixmap, gc, points, 4, Convex,		    CoordModeOrigin);	} else {	    Tk_Fill3DPolygon(tkwin, pixmap, butPtr->normalBorder, points,		    4, butPtr->borderWidth, TK_RELIEF_FLAT);	}	Tk_Draw3DPolygon(tkwin, pixmap, border, points, 4, butPtr->borderWidth,		(butPtr->flags & SELECTED) ? TK_RELIEF_SUNKEN :		TK_RELIEF_RAISED);    }    /*     * If the button is disabled with a stipple rather than a special     * foreground color, generate the stippled effect.  If the widget     * is selected and we use a different background color when selected,     * must temporarily modify the GC.     */    if ((butPtr->state == tkDisabledUid)	    && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {	if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn		&& (butPtr->selectBorder != NULL)) {	    XSetForeground(butPtr->display, butPtr->disabledGC,		    Tk_3DBorderColor(butPtr->selectBorder)->pixel);	}	XFillRectangle(butPtr->display, pixmap, butPtr->disabledGC,		butPtr->inset, butPtr->inset,		(unsigned) (Tk_Width(tkwin) - 2*butPtr->inset),		(unsigned) (Tk_Height(tkwin) - 2*butPtr->inset));	if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn		&& (butPtr->selectBorder != NULL)) {	    XSetForeground(butPtr->display, butPtr->disabledGC,		    Tk_3DBorderColor(butPtr->normalBorder)->pixel);	}    }    /*     * Draw the border and traversal highlight last.  This way, if the     * button's contents overflow they'll be covered up by the border.     * This code is complicated by the possible combinations of focus     * highlight and default rings.  We draw the focus and highlight rings     * using the highlight border and highlight foreground color.     */    if (relief != TK_RELIEF_FLAT) {	int inset = butPtr->highlightWidth;	if (butPtr->defaultState == tkActiveUid) {	    /*	     * Draw the default ring with 2 pixels of space between the	     * default ring and the button and the default ring and the	     * focus ring.  Note that we need to explicitly draw the space	     * in the highlightBorder color to ensure that we overwrite any	     * overflow text and/or a different button background color.	     */	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,		    inset, Tk_Width(tkwin) - 2*inset,		    Tk_Height(tkwin) - 2*inset, 2, TK_RELIEF_FLAT);	    inset += 2;	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,		    inset, Tk_Width(tkwin) - 2*inset,		    Tk_Height(tkwin) - 2*inset, 1, TK_RELIEF_SUNKEN);	    inset++;	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,		    inset, Tk_Width(tkwin) - 2*inset,		    Tk_Height(tkwin) - 2*inset, 2, TK_RELIEF_FLAT);	    inset += 2;	} else if (butPtr->defaultState == tkNormalUid) {	    /*	     * Leave room for the default ring and write over any text or	     * background color.	     */	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0,		    0, Tk_Width(tkwin),		    Tk_Height(tkwin), 5, TK_RELIEF_FLAT);	    inset += 5;	}	/*	 * Draw the button border.	 */	Tk_Draw3DRectangle(tkwin, pixmap, border, inset, inset,		Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,		butPtr->borderWidth, relief);    }    if (butPtr->highlightWidth != 0) {	GC gc;	if (butPtr->flags & GOT_FOCUS) {	    gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);	} else {	    gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder),		    pixmap);	}	/*	 * Make sure the focus ring shrink-wraps the actual button, not the	 * padding space left for a default ring.	 */	if (butPtr->defaultState == tkNormalUid) {	    TkDrawInsetFocusHighlight(tkwin, gc, butPtr->highlightWidth,		    pixmap, 5);	} else {	    Tk_DrawFocusHighlight(tkwin, gc, butPtr->highlightWidth, pixmap);	}    }    /*     * Copy the information from the off-screen pixmap onto the screen,     * then delete the pixmap.     */    XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin),	    butPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin),	    (unsigned) Tk_Height(tkwin), 0, 0);    Tk_FreePixmap(butPtr->display, pixmap);}/* *---------------------------------------------------------------------- * * TkpComputeButtonGeometry -- * *	After changes in a button's text or bitmap, this procedure *	recomputes the button's geometry and passes this information *	along to the geometry manager for the window. * * Results: *	None. * * Side effects: *	The button's window may change size. * *---------------------------------------------------------------------- */voidTkpComputeButtonGeometry(butPtr)    register TkButton *butPtr;	/* Button whose geometry may have changed. */{    int width, height, avgWidth;    Tk_FontMetrics fm;    if (butPtr->highlightWidth < 0) {	butPtr->highlightWidth = 0;    }    butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;    /*     * Leave room for the default ring if needed.     */    if (butPtr->defaultState != tkDisabledUid) {	butPtr->inset += 5;    }    butPtr->indicatorSpace = 0;    if (butPtr->image != NULL) {	Tk_SizeOfImage(butPtr->image, &width, &height);	imageOrBitmap:	if (butPtr->width > 0) {	    width = butPtr->width;	}	if (butPtr->height > 0) {	    height = butPtr->height;	}	if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {	    butPtr->indicatorSpace = height;	    if (butPtr->type == TYPE_CHECK_BUTTON) {		butPtr->indicatorDiameter = (65*height)/100;	    } else {		butPtr->indicatorDiameter = (75*height)/100;	    }	}    } else if (butPtr->bitmap != None) {	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);	goto imageOrBitmap;    } else {	Tk_FreeTextLayout(butPtr->textLayout);	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,		butPtr->text, -1, butPtr->wrapLength, butPtr->justify, 0,		&butPtr->textWidth, &butPtr->textHeight);	width = butPtr->textWidth;	height = butPtr->textHeight;	avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);	Tk_GetFontMetrics(butPtr->tkfont, &fm);	if (butPtr->width > 0) {	    width = butPtr->width * avgWidth;	}	if (butPtr->height > 0) {	    height = butPtr->height * fm.linespace;	}	if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {	    butPtr->indicatorDiameter = fm.linespace;	    if (butPtr->type == TYPE_CHECK_BUTTON) {		butPtr->indicatorDiameter = (80*butPtr->indicatorDiameter)/100;	    }	    butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;	}    }    /*     * When issuing the geometry request, add extra space for the indicator,     * if any, and for the border and padding, plus two extra pixels so the     * display can be offset by 1 pixel in either direction for the raised     * or lowered effect.     */    if ((butPtr->image == NULL) && (butPtr->bitmap == None)) {	width += 2*butPtr->padX;	height += 2*butPtr->padY;    }    if ((butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin)) {	width += 2;	height += 2;    }    Tk_GeometryRequest(butPtr->tkwin, (int) (width + butPtr->indicatorSpace	    + 2*butPtr->inset), (int) (height + 2*butPtr->inset));    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);}

⌨️ 快捷键说明

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