X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fschemes%2FUserColourScheme.java;h=bf62e453b4b9e6eb8cdd9aaf6df20631a33b43ff;hb=refs%2Fheads%2Fkjvdh%2Ffeatures%2Ftesting;hp=4bb54f9c93746a591ce6ff480dac1d831a8e0d89;hpb=1f690971e7ffd3c33453e9e6e97653cb3b481169;p=jalview.git diff --git a/src/jalview/schemes/UserColourScheme.java b/src/jalview/schemes/UserColourScheme.java index 4bb54f9..bf62e45 100755 --- a/src/jalview/schemes/UserColourScheme.java +++ b/src/jalview/schemes/UserColourScheme.java @@ -23,13 +23,23 @@ package jalview.schemes; import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; +import jalview.util.ColorUtils; +import jalview.util.StringUtils; import java.awt.Color; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.StringTokenizer; public class UserColourScheme extends ResidueColourScheme { + /* + * lookup (by symbol index) of lower case colours (if configured) + */ Color[] lowerCaseColours; protected String schemeName; @@ -46,37 +56,86 @@ public class UserColourScheme extends ResidueColourScheme } @Override - public ColourSchemeI applyTo(AnnotatedCollectionI sg, + public ColourSchemeI getInstance(AnnotatedCollectionI sg, Map hiddenRepSequences) { - UserColourScheme usc = new UserColourScheme(colors); - if (lowerCaseColours != null) + return new UserColourScheme(this); + } + + /** + * Copy constructor + * + * @return + */ + protected UserColourScheme(UserColourScheme from) + { + this(from.colors); + schemeName = from.schemeName; + if (from.lowerCaseColours != null) { - usc.schemeName = new String(schemeName); - usc.lowerCaseColours = new Color[lowerCaseColours.length]; - System.arraycopy(lowerCaseColours, 0, usc.lowerCaseColours, 0, - lowerCaseColours.length); + lowerCaseColours = new Color[from.lowerCaseColours.length]; + System.arraycopy(from.lowerCaseColours, 0, lowerCaseColours, 0, + from.lowerCaseColours.length); } - return usc; } + /** + * Constructor for an animino acid colour scheme. The colour specification may + * be one of + * + * + * @param colour + */ public UserColourScheme(String colour) { super(ResidueProperties.aaIndex); - Color col = getColourFromString(colour); + + if (colour.contains("=")) + { + /* + * a list of colours per residue(s) + */ + parseAppletParameter(colour); + return; + } + + Color col = ColorUtils.parseColourString(colour); if (col == null) { System.out.println("Making colour from name: " + colour); - col = createColourFromName(colour); + col = ColorUtils.createColourFromName(colour); } - colors = new Color[24]; - for (int i = 0; i < 24; i++) + setAll(col); + schemeName = colour; + } + + /** + * Sets all symbols to the specified colour + * + * @param col + */ + protected void setAll(Color col) + { + if (symbolIndex == null) + { + return; + } + int max = 0; + for (int index : symbolIndex) + { + max = Math.max(max, index); + } + colors = new Color[max + 1]; + for (int i = 0; i <= max; i++) { colors[i] = col; } - schemeName = colour; } public Color[] getColours() @@ -100,86 +159,6 @@ public class UserColourScheme extends ResidueColourScheme } /** - * Parses a string into a Color, where the accepted formats are - * - * - * @param colour - * @return the parsed colour, or null if parsing fails - */ - public static Color getColourFromString(String colour) - { - if (colour == null) - { - return null; - } - colour = colour.trim(); - - Color col = null; - try - { - int value = Integer.parseInt(colour, 16); - col = new Color(value); - } catch (NumberFormatException ex) - { - } - - if (col == null) - { - col = ColourSchemeProperty.getAWTColorFromName(colour); - } - - if (col == null) - { - try - { - String[] tokens = colour.split(","); - if (tokens.length == 3) - { - int r = Integer.parseInt(tokens[0].trim()); - int g = Integer.parseInt(tokens[1].trim()); - int b = Integer.parseInt(tokens[2].trim()); - col = new Color(r, g, b); - } - } catch (Exception ex) - { - // non-numeric token or out of 0-255 range - } - } - - return col; - } - - public static Color createColourFromName(String name) - { - int r, g, b; - - int lsize = name.length(); - int start = 0, end = lsize / 3; - - int rgbOffset = Math.abs(name.hashCode() % 10) * 15; - - r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20; - start = end; - end += lsize / 3; - if (end > lsize) - { - end = lsize; - } - - g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20; - - b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20; - - Color color = new Color(r, g, b); - - return color; - } - - /** * Parse and save residue colours specified as (for example) * *
@@ -194,10 +173,10 @@ public class UserColourScheme extends ResidueColourScheme
    * 
    * @param paramValue
    */
-  public void parseAppletParameter(String paramValue)
+  void parseAppletParameter(String paramValue)
   {
-    // TODO: need a function to generate appletParameter colour string from a
-    // UCS
+    setAll(Color.white);
+
     StringTokenizer st = new StringTokenizer(paramValue, ";");
     StringTokenizer st2;
     String token = null, colour, residues;
@@ -224,13 +203,13 @@ public class UserColourScheme extends ResidueColourScheme
           {
             if (lowerCaseColours == null)
             {
-              lowerCaseColours = new Color[23];
+              lowerCaseColours = new Color[colors.length];
             }
-            for (int i = 0; i < 23; i++)
+            for (int i = 0; i < lowerCaseColours.length; i++)
             {
               if (lowerCaseColours[i] == null)
               {
-                lowerCaseColours[i] = getColourFromString(colour);
+                lowerCaseColours[i] = ColorUtils.parseColourString(colour);
               }
             }
 
@@ -241,52 +220,23 @@ public class UserColourScheme extends ResidueColourScheme
           {
             if (lowerCaseColours == null)
             {
-              lowerCaseColours = new Color[23];
+              lowerCaseColours = new Color[colors.length];
             }
-            lowerCaseColours[colIndex] = getColourFromString(colour);
+            lowerCaseColours[colIndex] = ColorUtils
+                    .parseColourString(colour);
           }
           else
           {
-            colors[colIndex] = getColourFromString(colour);
+            colors[colIndex] = ColorUtils.parseColourString(colour);
           }
         }
       }
     } catch (Exception ex)
     {
-      System.out.println("Error parsing userDefinedColours:\n" + token
-              + "\n" + ex);
-    }
-
-  }
-
-  @Override
-  public Color findColour(char c, int j, SequenceI seq)
-  {
-    Color currentColour;
-    int index = ResidueProperties.aaIndex[c];
-
-    if ((threshold == 0) || aboveThreshold(c, j))
-    {
-      if (lowerCaseColours != null && 'a' <= c && c <= 'z')
-      {
-        currentColour = lowerCaseColours[index];
-      }
-      else
-      {
-        currentColour = colors[index];
-      }
-    }
-    else
-    {
-      currentColour = Color.white;
-    }
-
-    if (conservationColouring)
-    {
-      currentColour = applyConservation(currentColour, j);
+      System.out.println(
+              "Error parsing userDefinedColours:\n" + token + "\n" + ex);
     }
 
-    return currentColour;
   }
 
   public void setLowerCaseColours(Color[] lcolours)
@@ -313,4 +263,97 @@ public class UserColourScheme extends ResidueColourScheme
     return super.findColour(c);
   }
 
+  /**
+   * Answers the customised name of the colour scheme, if it has one, else "User
+   * Defined"
+   */
+  @Override
+  public String getSchemeName()
+  {
+    if (schemeName != null && schemeName.length() > 0)
+    {
+      return schemeName;
+    }
+    return ResidueColourScheme.USER_DEFINED;
+  }
+
+  /**
+   * Generate an applet colour parameter like A,C,D=12ffe9;Q,W=2393fd;w=9178dd
+   * 
+   * @return
+   */
+  public String toAppletParameter()
+  {
+    /*
+     * step 1: build a map from colours to the symbol(s) that have the colour
+     */
+    Map> colours = new HashMap<>();
+
+    for (char symbol = 'A'; symbol <= 'Z'; symbol++)
+    {
+      String residue = String.valueOf(symbol);
+      int index = symbolIndex[symbol];
+      Color c = colors[index];
+      if (c != null && !c.equals(Color.white))
+      {
+        if (colours.get(c) == null)
+        {
+          colours.put(c, new ArrayList());
+        }
+        colours.get(c).add(residue);
+      }
+      if (lowerCaseColours != null)
+      {
+        c = lowerCaseColours[index];
+        if (c != null && !c.equals(Color.white))
+        {
+          residue = residue.toLowerCase();
+          if (colours.get(c) == null)
+          {
+            colours.put(c, new ArrayList());
+          }
+          colours.get(c).add(residue);
+        }
+      }
+    }
+
+    /*
+     * step 2: make a list of { A,G,R=12f9d6 } residues/colour specs
+     */
+    List residueColours = new ArrayList<>();
+    for (Entry> cols : colours.entrySet())
+    {
+      boolean first = true;
+      StringBuilder sb = new StringBuilder();
+      for (String residue : cols.getValue())
+      {
+        if (!first)
+        {
+          sb.append(",");
+        }
+        sb.append(residue);
+        first = false;
+      }
+      sb.append("=");
+      /*
+       * get color as hex value, dropping the alpha (ff) part
+       */
+      String hexString = Integer.toHexString(cols.getKey().getRGB())
+              .substring(2);
+      sb.append(hexString);
+      residueColours.add(sb.toString());
+    }
+
+    /*
+     * sort and output
+     */
+    Collections.sort(residueColours);
+    return StringUtils.listToDelimitedString(residueColours, ";");
+  }
+
+  @Override
+  public boolean hasGapColour()
+  {
+    return (findColour(' ') != null);
+  }
 }