summaryrefslogtreecommitdiff
path: root/tk/unix/tkUnixScale.c
diff options
context:
space:
mode:
Diffstat (limited to 'tk/unix/tkUnixScale.c')
-rw-r--r--tk/unix/tkUnixScale.c260
1 files changed, 65 insertions, 195 deletions
diff --git a/tk/unix/tkUnixScale.c b/tk/unix/tkUnixScale.c
index 6378c03b70e..a05bbbef37d 100644
--- a/tk/unix/tkUnixScale.c
+++ b/tk/unix/tkUnixScale.c
@@ -5,6 +5,7 @@
* widget.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 by Scriptics Corporation.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -56,7 +57,9 @@ TkpCreateScale(tkwin)
*
* TkpDestroyScale --
*
- * Destroy a TkScale structure.
+ * Destroy a TkScale structure. It's necessary to do this with
+ * Tcl_EventuallyFree to allow the Tcl_Preserve(scalePtr) to work
+ * as expected in TkpDisplayScale. (hobbs)
*
* Results:
* None
@@ -71,7 +74,7 @@ void
TkpDestroyScale(scalePtr)
TkScale *scalePtr;
{
- ckfree((char *) scalePtr);
+ Tcl_EventuallyFree((ClientData) scalePtr, TCL_DYNAMIC);
}
/*
@@ -107,7 +110,7 @@ DisplayVerticalScale(scalePtr, drawable, drawnAreaPtr)
{
Tk_Window tkwin = scalePtr->tkwin;
int x, y, width, height, shadowWidth;
- double tickValue;
+ double tickValue, tickInterval = scalePtr->tickInterval;
Tk_3DBorder sliderBorder;
/*
@@ -129,9 +132,22 @@ DisplayVerticalScale(scalePtr, drawable, drawnAreaPtr)
* Display the tick marks.
*/
- if (scalePtr->tickInterval != 0) {
+ if (tickInterval != 0) {
+ double ticks, maxTicks;
+
+ /*
+ * Ensure that we will only draw enough of the tick values
+ * such that they don't overlap
+ */
+ ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
+ / tickInterval);
+ maxTicks = (double) Tk_Height(tkwin)
+ / (double) scalePtr->fontHeight;
+ if (ticks > maxTicks) {
+ tickInterval *= (ticks / maxTicks);
+ }
for (tickValue = scalePtr->fromValue; ;
- tickValue += scalePtr->tickInterval) {
+ tickValue += tickInterval) {
/*
* The TkRoundToResolution call gets rid of accumulated
* round-off errors, if any.
@@ -177,7 +193,7 @@ DisplayVerticalScale(scalePtr, drawable, drawnAreaPtr)
(unsigned) scalePtr->width,
(unsigned) (Tk_Height(tkwin) - 2*scalePtr->inset
- 2*scalePtr->borderWidth));
- if (scalePtr->state == tkActiveUid) {
+ if (scalePtr->state == STATE_ACTIVE) {
sliderBorder = scalePtr->activeBorder;
} else {
sliderBorder = scalePtr->bgBorder;
@@ -185,7 +201,7 @@ DisplayVerticalScale(scalePtr, drawable, drawnAreaPtr)
width = scalePtr->width;
height = scalePtr->sliderLength/2;
x = scalePtr->vertTroughX + scalePtr->borderWidth;
- y = TkpValueToPixel(scalePtr, scalePtr->value) - height;
+ y = TkScaleValueToPixel(scalePtr, scalePtr->value) - height;
shadowWidth = scalePtr->borderWidth/2;
if (shadowWidth == 0) {
shadowWidth = 1;
@@ -210,8 +226,9 @@ DisplayVerticalScale(scalePtr, drawable, drawnAreaPtr)
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);
+ scalePtr->tkfont, scalePtr->label,
+ scalePtr->labelLength, scalePtr->vertLabelX,
+ scalePtr->inset + (3*fm.ascent)/2);
}
}
@@ -252,7 +269,7 @@ DisplayVerticalValue(scalePtr, drawable, value, rightEdge)
Tk_FontMetrics fm;
Tk_GetFontMetrics(scalePtr->tkfont, &fm);
- y = TkpValueToPixel(scalePtr, value) + fm.ascent/2;
+ y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
sprintf(valueString, scalePtr->format, value);
length = strlen(valueString);
width = Tk_TextWidth(scalePtr->tkfont, valueString, length);
@@ -305,7 +322,7 @@ DisplayHorizontalScale(scalePtr, drawable, drawnAreaPtr)
{
register Tk_Window tkwin = scalePtr->tkwin;
int x, y, width, height, shadowWidth;
- double tickValue;
+ double tickValue, tickInterval = scalePtr->tickInterval;
Tk_3DBorder sliderBorder;
/*
@@ -327,9 +344,25 @@ DisplayHorizontalScale(scalePtr, drawable, drawnAreaPtr)
* Display the tick marks.
*/
- if (scalePtr->tickInterval != 0) {
+ if (tickInterval != 0) {
+ char valueString[PRINT_CHARS];
+ double ticks, maxTicks;
+
+ /*
+ * Ensure that we will only draw enough of the tick values
+ * such that they don't overlap. We base this off the width that
+ * fromValue would take. Not exact, but better than no constraint.
+ */
+ ticks = fabs((scalePtr->toValue - scalePtr->fromValue)
+ / tickInterval);
+ sprintf(valueString, scalePtr->format, scalePtr->fromValue);
+ maxTicks = (double) Tk_Width(tkwin)
+ / (double) Tk_TextWidth(scalePtr->tkfont, valueString, -1);
+ if (ticks > maxTicks) {
+ tickInterval *= (ticks / maxTicks);
+ }
for (tickValue = scalePtr->fromValue; ;
- tickValue += scalePtr->tickInterval) {
+ tickValue += tickInterval) {
/*
* The TkRoundToResolution call gets rid of accumulated
* round-off errors, if any.
@@ -376,14 +409,14 @@ DisplayHorizontalScale(scalePtr, drawable, drawnAreaPtr)
(unsigned) (Tk_Width(tkwin) - 2*scalePtr->inset
- 2*scalePtr->borderWidth),
(unsigned) scalePtr->width);
- if (scalePtr->state == tkActiveUid) {
+ if (scalePtr->state == STATE_ACTIVE) {
sliderBorder = scalePtr->activeBorder;
} else {
sliderBorder = scalePtr->bgBorder;
}
width = scalePtr->sliderLength/2;
height = scalePtr->width;
- x = TkpValueToPixel(scalePtr, scalePtr->value) - width;
+ x = TkScaleValueToPixel(scalePtr, scalePtr->value) - width;
y += scalePtr->borderWidth;
shadowWidth = scalePtr->borderWidth/2;
if (shadowWidth == 0) {
@@ -409,8 +442,9 @@ DisplayHorizontalScale(scalePtr, drawable, drawnAreaPtr)
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);
+ scalePtr->tkfont, scalePtr->label,
+ scalePtr->labelLength, scalePtr->inset + fm.ascent/2,
+ scalePtr->horizLabelY + fm.ascent);
}
}
@@ -450,7 +484,7 @@ DisplayHorizontalValue(scalePtr, drawable, value, top)
char valueString[PRINT_CHARS];
Tk_FontMetrics fm;
- x = TkpValueToPixel(scalePtr, value);
+ x = TkScaleValueToPixel(scalePtr, value);
Tk_GetFontMetrics(scalePtr->tkfont, &fm);
y = top + fm.ascent;
sprintf(valueString, scalePtr->format, value);
@@ -502,6 +536,7 @@ TkpDisplayScale(clientData)
char string[PRINT_CHARS];
XRectangle drawnArea;
+ scalePtr->flags &= ~REDRAW_PENDING;
if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
goto done;
}
@@ -509,23 +544,22 @@ TkpDisplayScale(clientData)
/*
* Invoke the scale's command if needed.
*/
-
Tcl_Preserve((ClientData) scalePtr);
- Tcl_Preserve((ClientData) interp);
if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
+ Tcl_Preserve((ClientData) interp);
sprintf(string, scalePtr->format, scalePtr->value);
- result = Tcl_VarEval(interp, scalePtr->command, " ", string,
- (char *) NULL);
+ result = Tcl_VarEval(interp, scalePtr->command, " ", string,
+ (char *) NULL);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp, "\n (command executed by scale)");
Tcl_BackgroundError(interp);
}
+ Tcl_Release((ClientData) interp);
}
- Tcl_Release((ClientData) interp);
scalePtr->flags &= ~INVOKE_COMMAND;
- if (scalePtr->tkwin == NULL) {
+ if (scalePtr->flags & SCALE_DELETED) {
Tcl_Release((ClientData) scalePtr);
- return;
+ goto done;
}
Tcl_Release((ClientData) scalePtr);
@@ -549,7 +583,7 @@ TkpDisplayScale(clientData)
* different.
*/
- if (scalePtr->vertical) {
+ if (scalePtr->orient == ORIENT_VERTICAL) {
DisplayVerticalScale(scalePtr, pixmap, &drawnArea);
} else {
DisplayHorizontalScale(scalePtr, pixmap, &drawnArea);
@@ -575,7 +609,8 @@ TkpDisplayScale(clientData)
if (scalePtr->flags & GOT_FOCUS) {
gc = Tk_GCForColor(scalePtr->highlightColorPtr, pixmap);
} else {
- gc = Tk_GCForColor(scalePtr->highlightBgColorPtr, pixmap);
+ gc = Tk_GCForColor(
+ Tk_3DBorderColor(scalePtr->highlightBorder), pixmap);
}
Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth, pixmap);
}
@@ -621,7 +656,7 @@ TkpScaleElement(scalePtr, x, y)
{
int sliderFirst;
- if (scalePtr->vertical) {
+ if (scalePtr->orient == ORIENT_VERTICAL) {
if ((x < scalePtr->vertTroughX)
|| (x >= (scalePtr->vertTroughX + 2*scalePtr->borderWidth +
scalePtr->width))) {
@@ -631,7 +666,7 @@ TkpScaleElement(scalePtr, x, y)
|| (y >= (Tk_Height(scalePtr->tkwin) - scalePtr->inset))) {
return OTHER;
}
- sliderFirst = TkpValueToPixel(scalePtr, scalePtr->value)
+ sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
- scalePtr->sliderLength/2;
if (y < sliderFirst) {
return TROUGH1;
@@ -651,7 +686,7 @@ TkpScaleElement(scalePtr, x, y)
|| (x >= (Tk_Width(scalePtr->tkwin) - scalePtr->inset))) {
return OTHER;
}
- sliderFirst = TkpValueToPixel(scalePtr, scalePtr->value)
+ sliderFirst = TkScaleValueToPixel(scalePtr, scalePtr->value)
- scalePtr->sliderLength/2;
if (x < sliderFirst) {
return TROUGH1;
@@ -661,168 +696,3 @@ TkpScaleElement(scalePtr, x, y)
}
return TROUGH2;
}
-
-/*
- *--------------------------------------------------------------
- *
- * TkpSetScaleValue --
- *
- * This procedure changes the value of a scale and invokes
- * a Tcl command to reflect the current position of a scale
- *
- * Results:
- * None.
- *
- * Side effects:
- * A Tcl command is invoked, and an additional error-processing
- * command may also be invoked. The scale's slider is redrawn.
- *
- *--------------------------------------------------------------
- */
-
-void
-TkpSetScaleValue(scalePtr, value, setVar, invokeCommand)
- register TkScale *scalePtr; /* Info about widget. */
- double value; /* New value for scale. Gets adjusted
- * if it's off the scale. */
- int setVar; /* Non-zero means reflect new value through
- * to associated variable, if any. */
- int invokeCommand; /* Non-zero means invoked -command option
- * to notify of new value, 0 means don't. */
-{
- char string[PRINT_CHARS];
-
- value = TkRoundToResolution(scalePtr, value);
- if ((value < scalePtr->fromValue)
- ^ (scalePtr->toValue < scalePtr->fromValue)) {
- value = scalePtr->fromValue;
- }
- if ((value > scalePtr->toValue)
- ^ (scalePtr->toValue < scalePtr->fromValue)) {
- value = scalePtr->toValue;
- }
- if (scalePtr->flags & NEVER_SET) {
- scalePtr->flags &= ~NEVER_SET;
- } else if (scalePtr->value == value) {
- return;
- }
- scalePtr->value = value;
- if (invokeCommand) {
- scalePtr->flags |= INVOKE_COMMAND;
- }
- TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);
-
- if (setVar && (scalePtr->varName != NULL)) {
- sprintf(string, scalePtr->format, scalePtr->value);
- scalePtr->flags |= SETTING_VAR;
- Tcl_SetVar(scalePtr->interp, scalePtr->varName, string,
- TCL_GLOBAL_ONLY);
- scalePtr->flags &= ~SETTING_VAR;
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpPixelToValue --
- *
- * Given a pixel within a scale window, return the scale
- * reading corresponding to that pixel.
- *
- * Results:
- * A double-precision scale reading. If the value is outside
- * the legal range for the scale then it's rounded to the nearest
- * end of the scale.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-double
-TkpPixelToValue(scalePtr, x, y)
- register TkScale *scalePtr; /* Information about widget. */
- int x, y; /* Coordinates of point within
- * window. */
-{
- double value, pixelRange;
-
- if (scalePtr->vertical) {
- pixelRange = Tk_Height(scalePtr->tkwin) - scalePtr->sliderLength
- - 2*scalePtr->inset - 2*scalePtr->borderWidth;
- value = y;
- } else {
- pixelRange = Tk_Width(scalePtr->tkwin) - scalePtr->sliderLength
- - 2*scalePtr->inset - 2*scalePtr->borderWidth;
- value = x;
- }
-
- if (pixelRange <= 0) {
- /*
- * Not enough room for the slider to actually slide: just return
- * the scale's current value.
- */
-
- return scalePtr->value;
- }
- value -= scalePtr->sliderLength/2 + scalePtr->inset
- + scalePtr->borderWidth;
- value /= pixelRange;
- if (value < 0) {
- value = 0;
- }
- if (value > 1) {
- value = 1;
- }
- value = scalePtr->fromValue +
- value * (scalePtr->toValue - scalePtr->fromValue);
- return TkRoundToResolution(scalePtr, value);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpValueToPixel --
- *
- * Given a reading of the scale, return the x-coordinate or
- * y-coordinate corresponding to that reading, depending on
- * whether the scale is vertical or horizontal, respectively.
- *
- * Results:
- * An integer value giving the pixel location corresponding
- * to reading. The value is restricted to lie within the
- * defined range for the scale.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TkpValueToPixel(scalePtr, value)
- register TkScale *scalePtr; /* Information about widget. */
- double value; /* Reading of the widget. */
-{
- int y, pixelRange;
- double valueRange;
-
- valueRange = scalePtr->toValue - scalePtr->fromValue;
- pixelRange = (scalePtr->vertical ? Tk_Height(scalePtr->tkwin)
- : Tk_Width(scalePtr->tkwin)) - scalePtr->sliderLength
- - 2*scalePtr->inset - 2*scalePtr->borderWidth;
- if (valueRange == 0) {
- y = 0;
- } else {
- y = (int) ((value - scalePtr->fromValue) * pixelRange
- / valueRange + 0.5);
- if (y < 0) {
- y = 0;
- } else if (y > pixelRange) {
- y = pixelRange;
- }
- }
- y += scalePtr->sliderLength/2 + scalePtr->inset + scalePtr->borderWidth;
- return y;
-}