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

📄 tkscale.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (afterDecimal > 0) {	fDigits++;			/* Decimal point. */    }    if (mostSigDigit < 0) {	fDigits++;			/* Zero to left of decimal point. */    }    if (fDigits <= eDigits) {	sprintf(scalePtr->format, "%%.%df", afterDecimal);    } else {	sprintf(scalePtr->format, "%%.%de", numDigits-1);    }}/* *---------------------------------------------------------------------- * * ComputeScaleGeometry -- * *	This procedure is called to compute various geometrical *	information for a scale, such as where various things get *	displayed.  It's called when the window is reconfigured. * * Results: *	None. * * Side effects: *	Display-related numbers get changed in *scalePtr.  The *	geometry manager gets told about the window's preferred size. * *---------------------------------------------------------------------- */static voidComputeScaleGeometry(scalePtr)    register TkScale *scalePtr;		/* Information about widget. */{    char valueString[PRINT_CHARS];    int tmp, valuePixels, x, y, extraSpace;    Tk_FontMetrics fm;    /*     * Horizontal scales are simpler than vertical ones because     * all sizes are the same (the height of a line of text);     * handle them first and then quit.     */    Tk_GetFontMetrics(scalePtr->tkfont, &fm);    if (!scalePtr->vertical) {	y = scalePtr->inset;	extraSpace = 0;	if (scalePtr->labelLength != 0) {	    scalePtr->horizLabelY = y + SPACING;	    y += fm.linespace + SPACING;	    extraSpace = SPACING;	}	if (scalePtr->showValue) {	    scalePtr->horizValueY = y + SPACING;	    y += fm.linespace + SPACING;	    extraSpace = SPACING;	} else {	    scalePtr->horizValueY = y;	}	y += extraSpace;	scalePtr->horizTroughY = y;	y += scalePtr->width + 2*scalePtr->borderWidth;	if (scalePtr->tickInterval != 0) {	    scalePtr->horizTickY = y + SPACING;	    y += fm.linespace + 2*SPACING;	}	Tk_GeometryRequest(scalePtr->tkwin,		scalePtr->length + 2*scalePtr->inset, y + scalePtr->inset);	Tk_SetInternalBorder(scalePtr->tkwin, scalePtr->inset);	return;    }    /*     * Vertical scale:  compute the amount of space needed to display     * the scales value by formatting strings for the two end points;     * use whichever length is longer.     */    sprintf(valueString, scalePtr->format, scalePtr->fromValue);    valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);    sprintf(valueString, scalePtr->format, scalePtr->toValue);    tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);    if (valuePixels < tmp) {	valuePixels = tmp;    }    /*     * Assign x-locations to the elements of the scale, working from     * left to right.     */    x = scalePtr->inset;    if ((scalePtr->tickInterval != 0) && (scalePtr->showValue)) {	scalePtr->vertTickRightX = x + SPACING + valuePixels;	scalePtr->vertValueRightX = scalePtr->vertTickRightX + valuePixels		+ fm.ascent/2;	x = scalePtr->vertValueRightX + SPACING;    } else if (scalePtr->tickInterval != 0) {	scalePtr->vertTickRightX = x + SPACING + valuePixels;	scalePtr->vertValueRightX = scalePtr->vertTickRightX;	x = scalePtr->vertTickRightX + SPACING;    } else if (scalePtr->showValue) {	scalePtr->vertTickRightX = x;	scalePtr->vertValueRightX = x + SPACING + valuePixels;	x = scalePtr->vertValueRightX + SPACING;    } else {	scalePtr->vertTickRightX = x;	scalePtr->vertValueRightX = x;    }    scalePtr->vertTroughX = x;    x += 2*scalePtr->borderWidth + scalePtr->width;    if (scalePtr->labelLength == 0) {	scalePtr->vertLabelX = 0;    } else {	scalePtr->vertLabelX = x + fm.ascent/2;	x = scalePtr->vertLabelX + fm.ascent/2		+ Tk_TextWidth(scalePtr->tkfont, scalePtr->label,			scalePtr->labelLength);    }    Tk_GeometryRequest(scalePtr->tkwin, x + scalePtr->inset,	    scalePtr->length + 2*scalePtr->inset);    Tk_SetInternalBorder(scalePtr->tkwin, scalePtr->inset);}/* *-------------------------------------------------------------- * * ScaleEventProc -- * *	This procedure is invoked by the Tk dispatcher for various *	events on scales. * * Results: *	None. * * Side effects: *	When the window gets deleted, internal structures get *	cleaned up.  When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */static voidScaleEventProc(clientData, eventPtr)    ClientData clientData;	/* Information about window. */    XEvent *eventPtr;		/* Information about event. */{    TkScale *scalePtr = (TkScale *) clientData;    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);    } else if (eventPtr->type == DestroyNotify) {	if (scalePtr->tkwin != NULL) {	    scalePtr->tkwin = NULL;	    Tcl_DeleteCommandFromToken(scalePtr->interp, scalePtr->widgetCmd);	}	if (scalePtr->flags & REDRAW_ALL) {	    Tcl_CancelIdleCall(TkpDisplayScale, (ClientData) scalePtr);	}	Tcl_EventuallyFree((ClientData) scalePtr, DestroyScale);    } else if (eventPtr->type == ConfigureNotify) {	ComputeScaleGeometry(scalePtr);	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);    } else if (eventPtr->type == FocusIn) {	if (eventPtr->xfocus.detail != NotifyInferior) {	    scalePtr->flags |= GOT_FOCUS;	    if (scalePtr->highlightWidth > 0) {		TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);	    }	}    } else if (eventPtr->type == FocusOut) {	if (eventPtr->xfocus.detail != NotifyInferior) {	    scalePtr->flags &= ~GOT_FOCUS;	    if (scalePtr->highlightWidth > 0) {		TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);	    }	}    }}/* *---------------------------------------------------------------------- * * ScaleCmdDeletedProc -- * *	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 voidScaleCmdDeletedProc(clientData)    ClientData clientData;	/* Pointer to widget record for widget. */{    TkScale *scalePtr = (TkScale *) clientData;    Tk_Window tkwin = scalePtr->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) {	scalePtr->tkwin = NULL;	Tk_DestroyWindow(tkwin);    }}/* *-------------------------------------------------------------- * * TkEventuallyRedrawScale -- * *	Arrange for part or all of a scale widget to redrawn at *	the next convenient time in the future. * * Results: *	None. * * Side effects: *	If "what" is REDRAW_SLIDER then just the slider and the *	value readout will be redrawn;  if "what" is REDRAW_ALL *	then the entire widget will be redrawn. * *-------------------------------------------------------------- */voidTkEventuallyRedrawScale(scalePtr, what)    register TkScale *scalePtr;	/* Information about widget. */    int what;			/* What to redraw:  REDRAW_SLIDER				 * or REDRAW_ALL. */{    if ((what == 0) || (scalePtr->tkwin == NULL)	    || !Tk_IsMapped(scalePtr->tkwin)) {	return;    }    if ((scalePtr->flags & REDRAW_ALL) == 0) {	Tcl_DoWhenIdle(TkpDisplayScale, (ClientData) scalePtr);    }    scalePtr->flags |= what;}/* *-------------------------------------------------------------- * * TkRoundToResolution -- * *	Round a given floating-point value to the nearest multiple *	of the scale's resolution. * * Results: *	The return value is the rounded result. * * Side effects: *	None. * *-------------------------------------------------------------- */doubleTkRoundToResolution(scalePtr, value)    TkScale *scalePtr;		/* Information about scale widget. */    double value;		/* Value to round. */{    double rem, new;    if (scalePtr->resolution <= 0) {	return value;    }    new = scalePtr->resolution * floor(value/scalePtr->resolution);    rem = value - new;    if (rem < 0) {	if (rem <= -scalePtr->resolution/2) {	    new -= scalePtr->resolution;	}    } else {	if (rem >= scalePtr->resolution/2) {	    new += scalePtr->resolution;	}    }    return new;}/* *---------------------------------------------------------------------- * * ScaleVarProc -- * *	This procedure is invoked by Tcl whenever someone modifies a *	variable associated with a scale widget. * * Results: *	NULL is always returned. * * Side effects: *	The value displayed in the scale will change to match the *	variable's new value.  If the variable has a bogus value then *	it is reset to the value of the scale. * *---------------------------------------------------------------------- */    /* ARGSUSED */static char *ScaleVarProc(clientData, interp, name1, name2, flags)    ClientData clientData;	/* Information about button. */    Tcl_Interp *interp;		/* Interpreter containing variable. */    char *name1;		/* Name of variable. */    char *name2;		/* Second part of variable name. */    int flags;			/* Information about what happened. */{    register TkScale *scalePtr = (TkScale *) clientData;    char *stringValue, *end, *result;    double value;    /*     * If the variable is unset, then immediately recreate it unless     * the whole interpreter is going away.     */    if (flags & TCL_TRACE_UNSETS) {	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {	    Tcl_TraceVar(interp, scalePtr->varName,		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,		    ScaleVarProc, clientData);	    scalePtr->flags |= NEVER_SET;	    TkpSetScaleValue(scalePtr, scalePtr->value, 1, 0);	}	return (char *) NULL;    }    /*     * If we came here because we updated the variable (in TkpSetScaleValue),     * then ignore the trace.  Otherwise update the scale with the value     * of the variable.     */    if (scalePtr->flags & SETTING_VAR) {	return (char *) NULL;    }    result = NULL;    stringValue = Tcl_GetVar(interp, scalePtr->varName, TCL_GLOBAL_ONLY);    if (stringValue != NULL) {	value = strtod(stringValue, &end);	if ((end == stringValue) || (*end != 0)) {	    result = "can't assign non-numeric value to scale variable";	} else {	    scalePtr->value = TkRoundToResolution(scalePtr, value);	}	/*	 * This code is a bit tricky because it sets the scale's value before	 * calling TkpSetScaleValue.  This way, TkpSetScaleValue won't bother 	 * to set the variable again or to invoke the -command.  However, it	 * also won't redisplay the scale, so we have to ask for that	 * explicitly.	 */	TkpSetScaleValue(scalePtr, scalePtr->value, 1, 0);	TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);    }    return result;}

⌨️ 快捷键说明

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