summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2019-01-05 20:55:12 (GMT)
committerfvogel <fvogelnew1@free.fr>2019-01-05 20:55:12 (GMT)
commit79864b3cecd15cecaaeeded2d301de7b1d96511c (patch)
tree1827f7cee7dd565dae2ae4386ce8d9115c1af774 /generic
parent9997531222f9a5ea6e8da18ca5eb0241f06c0c61 (diff)
downloadtk-79864b3cecd15cecaaeeded2d301de7b1d96511c.zip
tk-79864b3cecd15cecaaeeded2d301de7b1d96511c.tar.gz
tk-79864b3cecd15cecaaeeded2d301de7b1d96511c.tar.bz2
Fix [3003895fff] and [1899040fff]: TkRoundToResolution doesn't account for -from
Diffstat (limited to 'generic')
-rw-r--r--generic/tkScale.c56
-rw-r--r--generic/tkScale.h3
2 files changed, 37 insertions, 22 deletions
diff --git a/generic/tkScale.c b/generic/tkScale.c
index af45afa..547f698 100644
--- a/generic/tkScale.c
+++ b/generic/tkScale.c
@@ -611,7 +611,7 @@ ConfigureScale(
TCL_GLOBAL_ONLY);
if ((valuePtr != NULL) &&
(Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) {
- scalePtr->value = TkRoundToResolution(scalePtr, value);
+ scalePtr->value = TkRoundValueToResolution(scalePtr, value);
}
}
@@ -620,10 +620,10 @@ ConfigureScale(
* orientation and creating GCs.
*/
- scalePtr->fromValue = TkRoundToResolution(scalePtr,
+ scalePtr->fromValue = TkRoundValueToResolution(scalePtr,
scalePtr->fromValue);
- scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue);
- scalePtr->tickInterval = TkRoundToResolution(scalePtr,
+ scalePtr->toValue = TkRoundValueToResolution(scalePtr, scalePtr->toValue);
+ scalePtr->tickInterval = TkRoundIntervalToResolution(scalePtr,
scalePtr->tickInterval);
/*
@@ -1119,10 +1119,14 @@ TkEventuallyRedrawScale(
/*
*--------------------------------------------------------------
*
- * TkRoundToResolution --
+ * TkRoundValueToResolution, TkRoundIntervalToResolution --
*
* Round a given floating-point value to the nearest multiple of the
* scale's resolution.
+ * TkRoundValueToResolution rounds an absolute value based on the from
+ * value as a reference.
+ * TkRoundIntervalToResolution rounds a relative value without
+ * reference, i.e. it rounds an interval.
*
* Results:
* The return value is the rounded result.
@@ -1134,28 +1138,38 @@ TkEventuallyRedrawScale(
*/
double
-TkRoundToResolution(
+TkRoundValueToResolution(
TkScale *scalePtr, /* Information about scale widget. */
double value) /* Value to round. */
{
- double rem, rounded, tick;
+ double rem, start;
if (scalePtr->resolution <= 0) {
return value;
}
- tick = floor(value/scalePtr->resolution);
- rounded = scalePtr->resolution * tick;
- rem = value - rounded;
+ start = fmod(scalePtr->fromValue, scalePtr->resolution);
+ rem = fmod(value - start + scalePtr->resolution/2, scalePtr->resolution);
if (rem < 0) {
- if (rem <= -scalePtr->resolution/2) {
- rounded = (tick - 1.0) * scalePtr->resolution;
- }
- } else {
- if (rem >= scalePtr->resolution/2) {
- rounded = (tick + 1.0) * scalePtr->resolution;
- }
+ rem += scalePtr->resolution;
+ }
+ return value + scalePtr->resolution/2 - rem;
+}
+
+double
+TkRoundIntervalToResolution(
+ TkScale *scalePtr, /* Information about scale widget. */
+ double value) /* Value to round. */
+{
+ double rem;
+
+ if (scalePtr->resolution <= 0) {
+ return value;
+ }
+ rem = fmod(value + scalePtr->resolution/2, scalePtr->resolution);
+ if (rem < 0) {
+ rem += scalePtr->resolution;
}
- return rounded;
+ return value + scalePtr->resolution/2 - rem;
}
/*
@@ -1238,7 +1252,7 @@ ScaleVarProc(
resultStr = "can't assign non-numeric value to scale variable";
ScaleSetVariable(scalePtr);
} else {
- scalePtr->value = TkRoundToResolution(scalePtr, value);
+ scalePtr->value = TkRoundValueToResolution(scalePtr, value);
/*
* This code is a bit tricky because it sets the scale's value before
@@ -1282,7 +1296,7 @@ TkScaleSetValue(
int invokeCommand) /* Non-zero means invoked -command option to
* notify of new value, 0 means don't. */
{
- value = TkRoundToResolution(scalePtr, value);
+ value = TkRoundValueToResolution(scalePtr, value);
if ((value < scalePtr->fromValue)
^ (scalePtr->toValue < scalePtr->fromValue)) {
value = scalePtr->fromValue;
@@ -1402,7 +1416,7 @@ TkScalePixelToValue(
}
value = scalePtr->fromValue +
value * (scalePtr->toValue - scalePtr->fromValue);
- return TkRoundToResolution(scalePtr, value);
+ return TkRoundValueToResolution(scalePtr, value);
}
/*
diff --git a/generic/tkScale.h b/generic/tkScale.h
index aa0feff..6756e73 100644
--- a/generic/tkScale.h
+++ b/generic/tkScale.h
@@ -219,7 +219,8 @@ typedef struct TkScale {
*/
MODULE_SCOPE void TkEventuallyRedrawScale(TkScale *scalePtr, int what);
-MODULE_SCOPE double TkRoundToResolution(TkScale *scalePtr, double value);
+MODULE_SCOPE double TkRoundValueToResolution(TkScale *scalePtr, double value);
+MODULE_SCOPE double TkRoundIntervalToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE TkScale * TkpCreateScale(Tk_Window tkwin);
MODULE_SCOPE void TkpDestroyScale(TkScale *scalePtr);
MODULE_SCOPE void TkpDisplayScale(ClientData clientData);