JAL-4386 Small refactor of helper NAME to Color methods
authorBen Soares <b.soares@dundee.ac.uk>
Thu, 7 Nov 2024 12:27:40 +0000 (12:27 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Thu, 7 Nov 2024 12:27:40 +0000 (12:27 +0000)
src/jalview/util/ColorUtils.java

index ee519a7..6d55302 100644 (file)
@@ -44,11 +44,25 @@ public class ColorUtils
 
   private static Map<String, Color> myHSBSpacedColours = new HashMap<>();
 
-  public static final String ID_COLOUR_SCHEME;
+  private static String ID_COLOUR_SCHEME;
+
+  // default ranges
+  private static float defaultHmin;
+
+  private static float defaultHmax;
+
+  private static float defaultSmin;
+
+  private static float defaultSmax;
+
+  private static float defaultBmin;
+
+  private static float defaultBmax;
 
   static
   {
     ID_COLOUR_SCHEME = Cache.getDefault("ID_COLOUR_SCHEME", "NONE");
+    setDefaultHSBColourScheme(ID_COLOUR_SCHEME);
   }
 
   /**
@@ -77,7 +91,6 @@ public class ColorUtils
 
     Color color = new Color(red, green, blue);
     return color;
-
   }
 
   /**
@@ -86,7 +99,6 @@ public class ColorUtils
    */
   public static final Color getARandomColor()
   {
-
     Color col = new Color((int) (Math.random() * 255),
             (int) (Math.random() * 255), (int) (Math.random() * 255));
     return col;
@@ -406,68 +418,127 @@ public class ColorUtils
     return col;
   }
 
-  public static Color getDefaultColourFromName(String name)
+  public enum ColourScheme
   {
-    return getColourFromNameAndScheme(name, ID_COLOUR_SCHEME);
+    AVOID_RED, AVOID_GREEN, AVOID_BLUE, SATURATED, DESATURATED, GREYSCALE,
+    BRIGHT, DARK
   }
 
-  public static Color getColourFromNameAndScheme(String name,
-          String colourSchemes)
+  public static float[] getHSBRanges(String colourScheme)
   {
-    String cacheKey = name + "::" + colourSchemes;
-    if (myHSBSpacedColours.containsKey(cacheKey))
-    {
-      return myHSBSpacedColours.get(cacheKey);
-    }
     float Hmin = 0.0f;
     float Hmax = 1.0f;
     float Smin = 0.7f;
     float Smax = 1.0f;
     float Bmin = 0.7f;
     float Bmax = 1.0f;
-    for (String scheme : colourSchemes.split(","))
+    for (String scheme : colourScheme.split(","))
     {
-      switch (scheme)
+      ColourScheme cs;
+      try
+      {
+        cs = ColourScheme.valueOf(scheme);
+      } catch (IllegalArgumentException | NullPointerException e)
+      {
+        Console.warn("Did not recognise something in the colour scheme '"
+                + colourScheme + "'");
+        return new float[] { Hmin, Hmax, Smin, Smax, Bmin, Bmax };
+      }
+      switch (cs)
       {
-      case "AVOID_RED":
+      case AVOID_RED:
         Hmin = 0.15f;
         Hmax = 0.85f;
         break;
-      case "AVOID_GREEN":
+      case AVOID_GREEN:
         Hmin = 0.48f;
         Hmax = 0.18f;
         break;
-      case "AVOID_BLUE":
+      case AVOID_BLUE:
         Hmin = 0.51f;
         Hmax = 0.81f;
         break;
-      case "SATURATED":
+      case SATURATED:
         Smin = 1.0f;
         Smax = 1.0f;
         break;
-      case "PALE":
+      case DESATURATED:
         Smin = 0.2f;
         Smax = 0.7f;
         break;
-      case "GREYSCALE":
+      case GREYSCALE:
         Smin = 0.0f;
         Smax = 0.0f;
-      case "BRIGHT":
+      case BRIGHT:
         Bmin = 1.0f;
         Bmax = 0.9f;
         break;
-      case "DARK":
+      case DARK:
         Bmin = 0.2f;
         Bmax = 0.6f;
         break;
       }
     }
-    Color col = getHSBColourspacedColourFromName(name, Hmin, Hmax, Smin,
-            Smax, Bmin, Bmax);
+    return new float[] { Hmin, Hmax, Smin, Smax, Bmin, Bmax };
+  }
+
+  public static float[] setDefaultHSBColourScheme(String colourScheme)
+  {
+    ID_COLOUR_SCHEME = colourScheme;
+    float[] vals = getHSBRanges(ID_COLOUR_SCHEME);
+    if (vals.length > 5)
+    {
+      defaultHmin = vals[0];
+      defaultHmax = vals[1];
+      defaultSmin = vals[2];
+      defaultSmax = vals[3];
+      defaultBmin = vals[4];
+      defaultBmax = vals[5];
+    }
+    return vals;
+  }
+
+  private static String getHSBColourSpacedCacheKey(String name,
+          String colourScheme)
+  {
+    return name.hashCode() + "::" + colourScheme;
+  }
+
+  public static Color getDefaultColourFromName(String name)
+  {
+    Console.debug("Getting default colour from name '" + name
+            + "' and colour scheme '" + ID_COLOUR_SCHEME + "'");
+    String cacheKey = getHSBColourSpacedCacheKey(name, ID_COLOUR_SCHEME);
+    if (myHSBSpacedColours.containsKey(cacheKey))
+    {
+      return myHSBSpacedColours.get(cacheKey);
+    }
+    Color col = getHSBColourspacedColourFromName(name, defaultHmin,
+            defaultHmax, defaultSmin, defaultSmax, defaultBmin,
+            defaultBmax);
     myHSBSpacedColours.put(cacheKey, col);
     return col;
   }
 
+  public static Color getColourFromNameAndScheme(String name,
+          String colourScheme)
+  {
+    String cacheKey = getHSBColourSpacedCacheKey(name, colourScheme);
+    if (myHSBSpacedColours.containsKey(cacheKey))
+    {
+      return myHSBSpacedColours.get(cacheKey);
+    }
+    float[] vals = getHSBRanges(colourScheme);
+    Color col = null;
+    if (vals.length > 5)
+    {
+      col = getHSBColourspacedColourFromName(name, vals[0], vals[1],
+              vals[2], vals[3], vals[4], vals[5]);
+      myHSBSpacedColours.put(cacheKey, col);
+    }
+    return col;
+  }
+
   public static Color getHSBColourspacedColourFromName(String name,
           float Hmin, float Hmax, float Smin, float Smax, float Bmin,
           float Bmax)
@@ -480,11 +551,11 @@ public class ColorUtils
     // use first three bytes from MD5 rather than String.hashCode() as short
     // strings all low number hashCodes
     byte[] hash = StringUtils.getMD5Bytes(name);
-    int bl = hash.length > 0 ? hash[0] : 0;
-    int g = hash.length > 1 ? hash[1] : 0;
-    int r = hash.length > 2 ? hash[2] : 0;
+    int b = hash.length > 0 ? Byte.toUnsignedInt(hash[0]) : 0;
+    int g = hash.length > 1 ? Byte.toUnsignedInt(hash[1]) : 0;
+    int r = hash.length > 2 ? Byte.toUnsignedInt(hash[2]) : 0;
 
-    float[] hsbf = Color.RGBtoHSB(r, g, bl, null);
+    float[] hsbf = Color.RGBtoHSB(r, g, b, null);
 
     if (hsbf.length < 3)
     {
@@ -512,6 +583,9 @@ public class ColorUtils
     float s1 = Smin + (Smax - Smin) * s0;
     float b1 = Bmin + (Bmax - Bmin) * b0;
 
+    Console.debug("Setting new colour for '" + name + "' with H=" + h1
+            + ", S=" + s1 + ", B=" + b1);
+
     return Color.getHSBColor(h1, s1, b1);
   }
 }
\ No newline at end of file