JAL-2983 slider 'translated' to have a non-negative range
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 16 Jul 2019 16:05:45 +0000 (17:05 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 16 Jul 2019 16:05:45 +0000 (17:05 +0100)
src/jalview/gui/FeatureTypeSettings.java

index 7456e18..73a22fa 100644 (file)
@@ -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);
+  }
 }