📄 tkunixscale.c
字号:
/* * tkUnixScale.c -- * * This file implements the X specific portion of the scrollbar * widget. * * 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: @(#) tkUnixScale.c 1.5 96/07/31 14:22:29 */#include "tkScale.h"#include "tkInt.h"/* * Forward declarations for procedures defined later in this file: */static void DisplayHorizontalScale _ANSI_ARGS_((TkScale *scalePtr, Drawable drawable, XRectangle *drawnAreaPtr));static void DisplayHorizontalValue _ANSI_ARGS_((TkScale *scalePtr, Drawable drawable, double value, int top));static void DisplayVerticalScale _ANSI_ARGS_((TkScale *scalePtr, Drawable drawable, XRectangle *drawnAreaPtr));static void DisplayVerticalValue _ANSI_ARGS_((TkScale *scalePtr, Drawable drawable, double value, int rightEdge));/* *---------------------------------------------------------------------- * * TkpCreateScale -- * * Allocate a new TkScale structure. * * Results: * Returns a newly allocated TkScale structure. * * Side effects: * None. * *---------------------------------------------------------------------- */TkScale *TkpCreateScale(tkwin) Tk_Window tkwin;{ return (TkScale *) ckalloc(sizeof(TkScale));}/* *---------------------------------------------------------------------- * * TkpDestroyScale -- * * Destroy a TkScale structure. * * Results: * None * * Side effects: * Memory is freed. * *---------------------------------------------------------------------- */voidTkpDestroyScale(scalePtr) TkScale *scalePtr;{ ckfree((char *) scalePtr);}/* *-------------------------------------------------------------- * * DisplayVerticalScale -- * * This procedure redraws the contents of a vertical scale * window. It is invoked as a do-when-idle handler, so it only * runs when there's nothing else for the application to do. * * Results: * There is no return value. If only a part of the scale needs * to be redrawn, then drawnAreaPtr is modified to reflect the * area that was actually modified. * * Side effects: * Information appears on the screen. * *-------------------------------------------------------------- */static voidDisplayVerticalScale(scalePtr, drawable, drawnAreaPtr) TkScale *scalePtr; /* Widget record for scale. */ Drawable drawable; /* Where to display scale (window * or pixmap). */ XRectangle *drawnAreaPtr; /* Initally contains area of window; * if only a part of the scale is * redrawn, gets modified to reflect * the part of the window that was * redrawn. */{ Tk_Window tkwin = scalePtr->tkwin; int x, y, width, height, shadowWidth; double tickValue; Tk_3DBorder sliderBorder; /* * Display the information from left to right across the window. */ if (!(scalePtr->flags & REDRAW_OTHER)) { drawnAreaPtr->x = scalePtr->vertTickRightX; drawnAreaPtr->y = scalePtr->inset; drawnAreaPtr->width = scalePtr->vertTroughX + scalePtr->width + 2*scalePtr->borderWidth - scalePtr->vertTickRightX; drawnAreaPtr->height -= 2*scalePtr->inset; } Tk_Fill3DRectangle(tkwin, drawable, scalePtr->bgBorder, drawnAreaPtr->x, drawnAreaPtr->y, drawnAreaPtr->width, drawnAreaPtr->height, 0, TK_RELIEF_FLAT); if (scalePtr->flags & REDRAW_OTHER) { /* * Display the tick marks. */ if (scalePtr->tickInterval != 0) { for (tickValue = scalePtr->fromValue; ; tickValue += scalePtr->tickInterval) { /* * The TkRoundToResolution call gets rid of accumulated * round-off errors, if any. */ tickValue = TkRoundToResolution(scalePtr, tickValue); if (scalePtr->toValue >= scalePtr->fromValue) { if (tickValue > scalePtr->toValue) { break; } } else { if (tickValue < scalePtr->toValue) { break; } } DisplayVerticalValue(scalePtr, drawable, tickValue, scalePtr->vertTickRightX); } } } /* * Display the value, if it is desired. */ if (scalePtr->showValue) { DisplayVerticalValue(scalePtr, drawable, scalePtr->value, scalePtr->vertValueRightX); } /* * Display the trough and the slider. */ Tk_Draw3DRectangle(tkwin, drawable, scalePtr->bgBorder, scalePtr->vertTroughX, scalePtr->inset, scalePtr->width + 2*scalePtr->borderWidth, Tk_Height(tkwin) - 2*scalePtr->inset, scalePtr->borderWidth, TK_RELIEF_SUNKEN); XFillRectangle(scalePtr->display, drawable, scalePtr->troughGC, scalePtr->vertTroughX + scalePtr->borderWidth, scalePtr->inset + scalePtr->borderWidth, (unsigned) scalePtr->width, (unsigned) (Tk_Height(tkwin) - 2*scalePtr->inset - 2*scalePtr->borderWidth)); if (scalePtr->state == tkActiveUid) { sliderBorder = scalePtr->activeBorder; } else { sliderBorder = scalePtr->bgBorder; } width = scalePtr->width; height = scalePtr->sliderLength/2; x = scalePtr->vertTroughX + scalePtr->borderWidth; y = TkpValueToPixel(scalePtr, scalePtr->value) - height; shadowWidth = scalePtr->borderWidth/2; if (shadowWidth == 0) { shadowWidth = 1; } Tk_Draw3DRectangle(tkwin, drawable, sliderBorder, x, y, width, 2*height, shadowWidth, scalePtr->sliderRelief); x += shadowWidth; y += shadowWidth; width -= 2*shadowWidth; height -= shadowWidth; Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y, width, height, shadowWidth, scalePtr->sliderRelief); Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y+height, width, height, shadowWidth, scalePtr->sliderRelief); /* * Draw the label to the right of the scale. */ if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) { Tk_FontMetrics fm; Tk_GetFontMetrics(scalePtr->tkfont, &fm); Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC, scalePtr->tkfont, scalePtr->label, scalePtr->labelLength, scalePtr->vertLabelX, scalePtr->inset + (3*fm.ascent)/2); }}/* *---------------------------------------------------------------------- * * DisplayVerticalValue -- * * This procedure is called to display values (scale readings) * for vertically-oriented scales. * * Results: * None. * * Side effects: * The numerical value corresponding to value is displayed with * its right edge at "rightEdge", and at a vertical position in * the scale that corresponds to "value". * *---------------------------------------------------------------------- */static voidDisplayVerticalValue(scalePtr, drawable, value, rightEdge) register TkScale *scalePtr; /* Information about widget in which to * display value. */ Drawable drawable; /* Pixmap or window in which to draw * the value. */ double value; /* Y-coordinate of number to display, * specified in application coords, not * in pixels (we'll compute pixels). */ int rightEdge; /* X-coordinate of right edge of text, * specified in pixels. */{ register Tk_Window tkwin = scalePtr->tkwin; int y, width, length; char valueString[PRINT_CHARS]; Tk_FontMetrics fm; Tk_GetFontMetrics(scalePtr->tkfont, &fm); y = TkpValueToPixel(scalePtr, value) + fm.ascent/2; sprintf(valueString, scalePtr->format, value); length = strlen(valueString); width = Tk_TextWidth(scalePtr->tkfont, valueString, length); /* * Adjust the y-coordinate if necessary to keep the text entirely * inside the window. */ if ((y - fm.ascent) < (scalePtr->inset + SPACING)) { y = scalePtr->inset + SPACING + fm.ascent; } if ((y + fm.descent) > (Tk_Height(tkwin) - scalePtr->inset - SPACING)) { y = Tk_Height(tkwin) - scalePtr->inset - SPACING - fm.descent; } Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC, scalePtr->tkfont, valueString, length, rightEdge - width, y);}/* *-------------------------------------------------------------- * * DisplayHorizontalScale -- * * This procedure redraws the contents of a horizontal scale * window. It is invoked as a do-when-idle handler, so it only * runs when there's nothing else for the application to do. * * Results: * There is no return value. If only a part of the scale needs * to be redrawn, then drawnAreaPtr is modified to reflect the * area that was actually modified. * * Side effects: * Information appears on the screen. * *-------------------------------------------------------------- */static voidDisplayHorizontalScale(scalePtr, drawable, drawnAreaPtr) TkScale *scalePtr; /* Widget record for scale. */ Drawable drawable; /* Where to display scale (window * or pixmap). */ XRectangle *drawnAreaPtr; /* Initally contains area of window; * if only a part of the scale is * redrawn, gets modified to reflect * the part of the window that was * redrawn. */{ register Tk_Window tkwin = scalePtr->tkwin; int x, y, width, height, shadowWidth; double tickValue; Tk_3DBorder sliderBorder; /* * Display the information from bottom to top across the window. */ if (!(scalePtr->flags & REDRAW_OTHER)) { drawnAreaPtr->x = scalePtr->inset; drawnAreaPtr->y = scalePtr->horizValueY; drawnAreaPtr->width -= 2*scalePtr->inset; drawnAreaPtr->height = scalePtr->horizTroughY + scalePtr->width + 2*scalePtr->borderWidth - scalePtr->horizValueY; } Tk_Fill3DRectangle(tkwin, drawable, scalePtr->bgBorder, drawnAreaPtr->x, drawnAreaPtr->y, drawnAreaPtr->width, drawnAreaPtr->height, 0, TK_RELIEF_FLAT); if (scalePtr->flags & REDRAW_OTHER) { /* * Display the tick marks. */ if (scalePtr->tickInterval != 0) { for (tickValue = scalePtr->fromValue; ; tickValue += scalePtr->tickInterval) { /* * The TkRoundToResolution call gets rid of accumulated * round-off errors, if any. */ tickValue = TkRoundToResolution(scalePtr, tickValue); if (scalePtr->toValue >= scalePtr->fromValue) { if (tickValue > scalePtr->toValue) { break; } } else { if (tickValue < scalePtr->toValue) { break; } } DisplayHorizontalValue(scalePtr, drawable, tickValue, scalePtr->horizTickY); } } } /* * Display the value, if it is desired. */ if (scalePtr->showValue) { DisplayHorizontalValue(scalePtr, drawable, scalePtr->value, scalePtr->horizValueY); } /* * Display the trough and the slider. */ y = scalePtr->horizTroughY; Tk_Draw3DRectangle(tkwin, drawable, scalePtr->bgBorder, scalePtr->inset, y, Tk_Width(tkwin) - 2*scalePtr->inset, scalePtr->width + 2*scalePtr->borderWidth, scalePtr->borderWidth, TK_RELIEF_SUNKEN); XFillRectangle(scalePtr->display, drawable, scalePtr->troughGC, scalePtr->inset + scalePtr->borderWidth, y + scalePtr->borderWidth, (unsigned) (Tk_Width(tkwin) - 2*scalePtr->inset - 2*scalePtr->borderWidth), (unsigned) scalePtr->width); if (scalePtr->state == tkActiveUid) { sliderBorder = scalePtr->activeBorder; } else { sliderBorder = scalePtr->bgBorder; } width = scalePtr->sliderLength/2; height = scalePtr->width; x = TkpValueToPixel(scalePtr, scalePtr->value) - width; y += scalePtr->borderWidth; shadowWidth = scalePtr->borderWidth/2; if (shadowWidth == 0) { shadowWidth = 1; } Tk_Draw3DRectangle(tkwin, drawable, sliderBorder, x, y, 2*width, height, shadowWidth, scalePtr->sliderRelief); x += shadowWidth; y += shadowWidth; width -= shadowWidth; height -= 2*shadowWidth; Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x, y, width, height, shadowWidth, scalePtr->sliderRelief); Tk_Fill3DRectangle(tkwin, drawable, sliderBorder, x+width, y, width, height, shadowWidth, scalePtr->sliderRelief); /* * Draw the label at the top of the scale. */ if ((scalePtr->flags & REDRAW_OTHER) && (scalePtr->labelLength != 0)) { Tk_FontMetrics fm; Tk_GetFontMetrics(scalePtr->tkfont, &fm); Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC, scalePtr->tkfont, scalePtr->label, scalePtr->labelLength, scalePtr->inset + fm.ascent/2, scalePtr->horizLabelY + fm.ascent); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -