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

📄 tklistbox.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
 * *---------------------------------------------------------------------- */static voidListboxComputeGeometry(listPtr, fontChanged, maxIsStale, updateGrid)    Listbox *listPtr;		/* Listbox whose geometry is to be				 * recomputed. */    int fontChanged;		/* Non-zero means the font may have changed				 * so per-element width information also				 * has to be computed. */    int maxIsStale;		/* Non-zero means the "maxWidth" field may				 * no longer be up-to-date and must				 * be recomputed.  If fontChanged is 1 then				 * this must be 1. */    int updateGrid;		/* Non-zero means call Tk_SetGrid or				 * Tk_UnsetGrid to update gridding for				 * the window. */{    register Element *elPtr;    int width, height, pixelWidth, pixelHeight;    Tk_FontMetrics fm;    if (fontChanged  || maxIsStale) {	listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1);	if (listPtr->xScrollUnit == 0) {	    listPtr->xScrollUnit = 1;	}	listPtr->maxWidth = 0;	for (elPtr = listPtr->firstPtr; elPtr != NULL; elPtr = elPtr->nextPtr) {	    if (fontChanged) {		elPtr->pixelWidth = Tk_TextWidth(listPtr->tkfont,			elPtr->text, elPtr->textLength);		elPtr->lBearing = 0;	    }	    if (elPtr->pixelWidth > listPtr->maxWidth) {		listPtr->maxWidth = elPtr->pixelWidth;	    }	}    }    Tk_GetFontMetrics(listPtr->tkfont, &fm);    listPtr->lineHeight = fm.linespace + 1 + 2*listPtr->selBorderWidth;    width = listPtr->width;    if (width <= 0) {	width = (listPtr->maxWidth + listPtr->xScrollUnit - 1)		/listPtr->xScrollUnit;	if (width < 1) {	    width = 1;	}    }    pixelWidth = width*listPtr->xScrollUnit + 2*listPtr->inset	    + 2*listPtr->selBorderWidth;    height = listPtr->height;    if (listPtr->height <= 0) {	height = listPtr->numElements;	if (height < 1) {	    height = 1;	}    }    pixelHeight = height*listPtr->lineHeight + 2*listPtr->inset;    Tk_GeometryRequest(listPtr->tkwin, pixelWidth, pixelHeight);    Tk_SetInternalBorder(listPtr->tkwin, listPtr->inset);    if (updateGrid) {	if (listPtr->setGrid) {	    Tk_SetGrid(listPtr->tkwin, width, height, listPtr->xScrollUnit,		    listPtr->lineHeight);	} else {	    Tk_UnsetGrid(listPtr->tkwin);	}    }}/* *---------------------------------------------------------------------- * * InsertEls -- * *	Add new elements to a listbox widget. * * Results: *	None. * * Side effects: *	New information gets added to listPtr;  it will be redisplayed *	soon, but not immediately. * *---------------------------------------------------------------------- */static voidInsertEls(listPtr, index, argc, argv)    register Listbox *listPtr;	/* Listbox that is to get the new				 * elements. */    int index;			/* Add the new elements before this				 * element. */    int argc;			/* Number of new elements to add. */    char **argv;		/* New elements (one per entry). */{    register Element *prevPtr, *newPtr;    int length, i, oldMaxWidth;    /*     * Find the element before which the new ones will be inserted.     */    if (index <= 0) {	index = 0;    }    if (index > listPtr->numElements) {	index = listPtr->numElements;    }    if (index == 0) {	prevPtr = NULL;    } else if (index == listPtr->numElements) {          prevPtr = listPtr->lastPtr;    } else {	for (prevPtr = listPtr->firstPtr, i = index - 1; i > 0; i--) {	    prevPtr = prevPtr->nextPtr;	}    }    /*     * For each new element, create a record, initialize it, and link     * it into the list of elements.     */    oldMaxWidth = listPtr->maxWidth;    for (i = argc ; i > 0; i--, argv++, prevPtr = newPtr) {	length = strlen(*argv);	newPtr = (Element *) ckalloc(ElementSize(length));	newPtr->textLength = length;	strcpy(newPtr->text, *argv);	newPtr->pixelWidth = Tk_TextWidth(listPtr->tkfont, newPtr->text,		newPtr->textLength);	newPtr->lBearing = 0;	if (newPtr->pixelWidth > listPtr->maxWidth) {	    listPtr->maxWidth = newPtr->pixelWidth;	}	newPtr->selected = 0;	if (prevPtr == NULL) {	    newPtr->nextPtr = listPtr->firstPtr;	    listPtr->firstPtr = newPtr;	} else {	    newPtr->nextPtr = prevPtr->nextPtr;	    prevPtr->nextPtr = newPtr;	}    }    if ((prevPtr != NULL) && (prevPtr->nextPtr == NULL)) {	listPtr->lastPtr = prevPtr;    }    listPtr->numElements += argc;    /*     * Update the selection and other indexes to account for the     * renumbering that has just occurred.  Then arrange for the new     * information to be displayed.     */    if (index <= listPtr->selectAnchor) {	listPtr->selectAnchor += argc;    }    if (index < listPtr->topIndex) {	listPtr->topIndex += argc;    }    if (index <= listPtr->active) {	listPtr->active += argc;	if ((listPtr->active >= listPtr->numElements)		&& (listPtr->numElements > 0)) {	    listPtr->active = listPtr->numElements-1;	}    }    listPtr->flags |= UPDATE_V_SCROLLBAR;    if (listPtr->maxWidth != oldMaxWidth) {	listPtr->flags |= UPDATE_H_SCROLLBAR;    }    ListboxComputeGeometry(listPtr, 0, 0, 0);    ListboxRedrawRange(listPtr, index, listPtr->numElements-1);}/* *---------------------------------------------------------------------- * * DeleteEls -- * *	Remove one or more elements from a listbox widget. * * Results: *	None. * * Side effects: *	Memory gets freed, the listbox gets modified and (eventually) *	redisplayed. * *---------------------------------------------------------------------- */static voidDeleteEls(listPtr, first, last)    register Listbox *listPtr;	/* Listbox widget to modify. */    int first;			/* Index of first element to delete. */    int last;			/* Index of last element to delete. */{    register Element *prevPtr, *elPtr;    int count, i, widthChanged;    /*     * Adjust the range to fit within the existing elements of the     * listbox, and make sure there's something to delete.     */    if (first < 0) {	first = 0;    }    if (last >= listPtr->numElements) {	last = listPtr->numElements-1;    }    count = last + 1 - first;    if (count <= 0) {	return;    }    /*     * Find the element just before the ones to delete.     */    if (first == 0) {	prevPtr = NULL;    } else {	for (i = first-1, prevPtr = listPtr->firstPtr; i > 0; i--) {	    prevPtr = prevPtr->nextPtr;	}    }    /*     * Delete the requested number of elements.     */    widthChanged = 0;    for (i = count; i > 0; i--) {	if (prevPtr == NULL) {	    elPtr = listPtr->firstPtr;	    listPtr->firstPtr = elPtr->nextPtr;	    if (listPtr->firstPtr == NULL) {		listPtr->lastPtr = NULL;	    }	} else {	    elPtr = prevPtr->nextPtr;	    prevPtr->nextPtr = elPtr->nextPtr;	    if (prevPtr->nextPtr == NULL) {		listPtr->lastPtr = prevPtr;	    }	}	if (elPtr->pixelWidth == listPtr->maxWidth) {	    widthChanged = 1;	}	if (elPtr->selected) {	    listPtr->numSelected -= 1;	}	ckfree((char *) elPtr);    }    listPtr->numElements -= count;    /*     * Update the selection and viewing information to reflect the change     * in the element numbering, and redisplay to slide information up over     * the elements that were deleted.     */    if (first <= listPtr->selectAnchor) {	listPtr->selectAnchor -= count;	if (listPtr->selectAnchor < first) {	    listPtr->selectAnchor = first;	}    }    if (first <= listPtr->topIndex) {	listPtr->topIndex -= count;	if (listPtr->topIndex < first) {	    listPtr->topIndex = first;	}    }    if (listPtr->topIndex > (listPtr->numElements - listPtr->fullLines)) {	listPtr->topIndex = listPtr->numElements - listPtr->fullLines;	if (listPtr->topIndex < 0) {	    listPtr->topIndex = 0;	}    }    if (listPtr->active > last) {	listPtr->active -= count;    } else if (listPtr->active >= first) {	listPtr->active = first;	if ((listPtr->active >= listPtr->numElements)		&& (listPtr->numElements > 0)) {	    listPtr->active = listPtr->numElements-1;	}    }    listPtr->flags |= UPDATE_V_SCROLLBAR;    ListboxComputeGeometry(listPtr, 0, widthChanged, 0);    if (widthChanged) {	listPtr->flags |= UPDATE_H_SCROLLBAR;    }    ListboxRedrawRange(listPtr, first, listPtr->numElements-1);}/* *-------------------------------------------------------------- * * ListboxEventProc -- * *	This procedure is invoked by the Tk dispatcher for various *	events on listboxes. * * Results: *	None. * * Side effects: *	When the window gets deleted, internal structures get *	cleaned up.  When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */static voidListboxEventProc(clientData, eventPtr)    ClientData clientData;	/* Information about window. */    XEvent *eventPtr;		/* Information about event. */{    Listbox *listPtr = (Listbox *) clientData;    if (eventPtr->type == Expose) {	ListboxRedrawRange(listPtr,		NearestListboxElement(listPtr, eventPtr->xexpose.y),		NearestListboxElement(listPtr, eventPtr->xexpose.y		+ eventPtr->xexpose.height));    } else if (eventPtr->type == DestroyNotify) {	if (listPtr->tkwin != NULL) {	    if (listPtr->setGrid) {		Tk_UnsetGrid(listPtr->tkwin);	    }	    listPtr->tkwin = NULL;	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);	}	if (listPtr->flags & REDRAW_PENDING) {	    Tcl_CancelIdleCall(DisplayListbox, (ClientData) listPtr);	}	Tcl_EventuallyFree((ClientData) listPtr, DestroyListbox);    } else if (eventPtr->type == ConfigureNotify) {	int vertSpace;	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;	listPtr->fullLines = vertSpace / listPtr->lineHeight;	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {	    listPtr->partialLine = 1;	} else {	    listPtr->partialLine = 0;	}	listPtr->flags |= UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR;	ChangeListboxView(listPtr, listPtr->topIndex);	ChangeListboxOffset(listPtr, listPtr->xOffset);	/*	 * Redraw the whole listbox.  It's hard to tell what needs	 * to be redrawn (e.g. if the listbox has shrunk then we	 * may only need to redraw the borders), so just redraw	 * everything for safety.	 */	ListboxRedrawRange(listPtr, 0, listPtr->numElements-1);    } else if (eventPtr->type == FocusIn) {	if (eventPtr->xfocus.detail != NotifyInferior) {	    listPtr->flags |= GOT_FOCUS;	    ListboxRedrawRange(listPtr, 0, listPtr->numElements-1);	}    } else if (eventPtr->type == FocusOut) {	if (eventPtr->xfocus.detail != NotifyInferior) {	    listPtr->flags &= ~GOT_FOCUS;	    ListboxRedrawRange(listPtr, 0, listPtr->numElements-1);	}    }}/* *---------------------------------------------------------------------- * * ListboxCmdDeletedProc -- * *	This procedure is invoked when a widget command is deleted.  If *	the widget isn't already in the process of being destroyed, *	this command destroys it. * * Results: *	None. * * Side effects: *	The widget is destroyed. * *---------------------------------------------------------------------- */static voidListboxCmdDeletedProc(clientData)    ClientData clientData;	/* Pointer to widget record for widget. */{    Listbox *listPtr = (Listbox *) clientData;    Tk_Window tkwin = listPtr->tkwin;    /*     * This procedure could be invoked either because the window was     * destroyed and the command was then deleted (in which case tkwin     * is NULL) or because the command was deleted, and then this procedure     * destroys the widget.     */    if (tkwin != NULL) {	if (listPtr->setGrid) {	    Tk_UnsetGrid(listPtr->tkwin);	}	listPtr->tkwin = NULL;	Tk_DestroyWindow(tkwin);    }}/* *-------------------------------------------------------------- * * GetListboxIndex -- * *	Parse an index into a listbox and return either its value *	or an error.

⌨️ 快捷键说明

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