From ccaf00b5893d507b376b66fe9173eb3a3925c9a1 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Tue, 16 Jul 2019 17:05:45 +0100 Subject: [PATCH] JAL-2983 slider 'translated' to have a non-negative range --- src/jalview/gui/FeatureTypeSettings.java | 83 +++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/src/jalview/gui/FeatureTypeSettings.java b/src/jalview/gui/FeatureTypeSettings.java index 7456e18..73a22fa 100644 --- a/src/jalview/gui/FeatureTypeSettings.java +++ b/src/jalview/gui/FeatureTypeSettings.java @@ -142,8 +142,17 @@ public class FeatureTypeSettings extends JalviewDialog /* * scale factor for conversion between absolute min-max and slider + * slider value is true value * scale factor */ - private float scaleFactor; + private float sliderScaleFactor; + + /* + * value to subtract from slider value before conversion; + * normally zero, but >0 if min is negative + * true value = (slider value - offset) / scale factor + * slider value = true value * scale factor + offset + */ + private int sliderOffset; /* * radio button group, to select what to colour by: @@ -347,11 +356,15 @@ public class FeatureTypeSettings extends JalviewDialog * update min-max scaling if there is a range to work with, * else disable the widgets (this shouldn't happen if only * valid options are offered in the combo box) + * offset slider to have only non-negative values if necessary (JAL-2983) */ - scaleFactor = (max == min) ? 1f : 100f / (max - min); - float range = (max - min) * scaleFactor; - slider.setMinimum((int) (min * scaleFactor)); - slider.setMaximum((int) (max * scaleFactor)); + sliderScaleFactor = (max == min) ? 1f : 100f / (max - min); + float range = (max - min) * sliderScaleFactor; + int minimum = (int) (min * sliderScaleFactor); + int maximum = (int) (max * sliderScaleFactor); + sliderOffset = minimum < 0f ? -minimum : 0; + slider.setMinimum(minimum + sliderOffset); + slider.setMaximum(maximum + sliderOffset); slider.setMajorTickSpacing((int) (range / 10f)); threshline = new GraphLine((max - min) / 2f, "Threshold", @@ -364,7 +377,7 @@ public class FeatureTypeSettings extends JalviewDialog fc.isAboveThreshold() ? ABOVE_THRESHOLD_OPTION : BELOW_THRESHOLD_OPTION); slider.setEnabled(true); - slider.setValue((int) (fc.getThreshold() * scaleFactor)); + setSliderValue(fc.getThreshold()); thresholdValue.setText(String.valueOf(fc.getThreshold())); thresholdValue.setEnabled(true); thresholdIsMin.setEnabled(true); @@ -657,7 +670,7 @@ public class FeatureTypeSettings extends JalviewDialog if (!adjusting) { thresholdValue - .setText(String.valueOf(slider.getValue() / scaleFactor)); + .setText(String.format("%.3f", getSliderValue())); thresholdValue.setBackground(Color.white); // to reset red for invalid sliderValueChanged(); } @@ -1033,7 +1046,7 @@ public class FeatureTypeSettings extends JalviewDialog f = Float.max(f, this.min); f = Float.min(f, this.max); thresholdValue.setText(String.valueOf(f)); - slider.setValue((int) (f * scaleFactor)); + setSliderValue(f * sliderScaleFactor); threshline.value = f; thresholdValue.setBackground(Color.white); // ok adjusting = false; @@ -1052,7 +1065,7 @@ public class FeatureTypeSettings extends JalviewDialog */ protected void sliderValueChanged() { - threshline.value = getRoundedSliderValue(); + threshline.value = getSliderValue(); /* * repaint alignment, but not Overview or structure, @@ -1061,21 +1074,6 @@ public class FeatureTypeSettings extends JalviewDialog colourChanged(false); } - /** - * Converts the slider value to its absolute value by dividing by the - * scaleFactor. Rounding errors are squashed by forcing min/max of slider - * range to the actual min/max of feature score range - * - * @return - */ - private float getRoundedSliderValue() - { - int value = slider.getValue(); - float f = value == slider.getMaximum() ? max - : (value == slider.getMinimum() ? min : value / scaleFactor); - return f; - } - void addActionListener(ActionListener listener) { if (featureSettings != null) @@ -1757,4 +1755,41 @@ public class FeatureTypeSettings extends JalviewDialog updateFiltersTab(); } + + /** + * Answers the slider value, converted to the corresponding 'true' value by + * applying scaling + * + * @return + */ + float getSliderValue() + { + int value = slider.getValue(); + float f = (value - sliderOffset) / sliderScaleFactor; + + /* + * avoid rounding errors at min/max of range + */ + if (value == slider.getMaximum()) + { + f = max; + } + else if (value == slider.getMinimum()) + { + f = min; + } + return f; + } + + /** + * Sets the slider value, converted from the corresponding 'true' value by + * applying scaling + * + * @param f + */ + void setSliderValue(float f) + { + float v = f * sliderScaleFactor + sliderOffset; + slider.setValue((int) v); + } } -- 1.7.10.2