JAL-3148 SequenceRenderer, ResidueColourFinder overloads and
[jalview.git] / src / jalview / gui / SequenceRenderer.java
index 5bb0de7..90d068b 100755 (executable)
@@ -25,30 +25,28 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.ResidueColourFinder;
 import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.schemes.ColourSchemeI;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 
-public class SequenceRenderer implements jalview.api.SequenceRenderer
+public class SequenceRenderer implements jalview.api.SequenceRendererI
 {
   final static int CHAR_TO_UPPER = 'A' - 'a';
 
-  AlignViewportI av;
+  private AlignViewportI av;
 
-  FontMetrics fm;
+  private FontMetrics fm;
 
-  boolean renderGaps = true;
+  private SequenceGroup[] allGroups = null;
 
-  SequenceGroup[] allGroups = null;
+  private Graphics graphics;
 
-  // Color resBoxColour;
+  private boolean monospacedFont;
 
-  Graphics graphics;
-
-  boolean monospacedFont;
-
-  ResidueColourFinder resColourFinder;
+  private ResidueColourFinder resColourFinder;
 
   /**
    * Creates a new SequenceRenderer object
@@ -62,12 +60,23 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
   }
 
   /**
-   * DOCUMENT ME!
+   * Constructor given a choice of colour scheme. May be used to find colours
+   * for a structure that has a viewport colour scheme other than 'by sequence'
    * 
-   * @param b
-   *          DOCUMENT ME!
+   * @param cs
+   */
+  public SequenceRenderer(AlignViewportI viewport, ColourSchemeI cs) 
+  {
+    this.av = viewport;
+    resColourFinder = new ResidueColourFinder(viewport, cs);
+  }
+
+/**
+   * Sets the Graphics context to draw on, and also guesses whether we are using a monospaced font
+   * 
+   * @param g
    */
-  public void prepare(Graphics g, boolean renderGaps)
+  public void setGraphics(Graphics g)
   {
     graphics = g;
     fm = g.getFontMetrics();
@@ -75,10 +84,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
     // If EPS graphics, stringWidth will be a double, not an int
     double dwidth = fm.getStringBounds("M", g).getWidth();
 
-    monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth() && av
-            .getCharWidth() == dwidth);
-
-    this.renderGaps = renderGaps;
+    monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth()
+            && av.getCharWidth() == dwidth);
   }
 
   /**
@@ -95,37 +102,27 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
   public Color getResidueColour(final SequenceI seq, int position,
           FeatureColourFinder finder)
   {
-    return resColourFinder.getResidueColour(av.getResidueShading(),
+    allGroups = av.getAlignment().findAllGroups(seq);
+    return resColourFinder.getResidueColour(av.getShowBoxes(),
+            av.getResidueShading(),
             allGroups, seq, position,
             finder);
   }
 
-
-
   /**
-   * DOCUMENT ME!
+   * Draws the sequence (box colour and residues) over the given range, at the
+   * specified y-offset on the Graphics context
    * 
-   * @param g
-   *          DOCUMENT ME!
    * @param seq
-   *          DOCUMENT ME!
-   * @param sg
-   *          DOCUMENT ME!
+   * @param sg  groups (if any) that the sequence is a member of (may have
+   *            distinct group colouring)
    * @param start
-   *          DOCUMENT ME!
    * @param end
-   *          DOCUMENT ME!
-   * @param x1
-   *          DOCUMENT ME!
    * @param y1
-   *          DOCUMENT ME!
-   * @param width
-   *          DOCUMENT ME!
-   * @param height
-   *          DOCUMENT ME!
+   * @param drawGaps
    */
   public void drawSequence(SequenceI seq, SequenceGroup[] sg, int start,
-          int end, int y1)
+          int end, int y1, boolean drawGaps)
   {
     allGroups = sg;
 
@@ -133,27 +130,18 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
 
     if (av.isValidCharWidth())
     {
-      drawText(seq, start, end, y1);
+      drawText(seq, start, end, y1, drawGaps);
     }
   }
 
   /**
-   * DOCUMENT ME!
+   * Draws box colours on the given sequence residue range, at the specified
+   * y-offset on the Graphics context
    * 
    * @param seq
-   *          DOCUMENT ME!
    * @param start
-   *          DOCUMENT ME!
    * @param end
-   *          DOCUMENT ME!
-   * @param x1
-   *          DOCUMENT ME!
    * @param y1
-   *          DOCUMENT ME!
-   * @param width
-   *          DOCUMENT ME!
-   * @param height
-   *          DOCUMENT ME!
    */
   public synchronized void drawBoxes(SequenceI seq, int start, int end,
           int y1)
@@ -168,8 +156,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
     int length = seq.getLength();
 
     int curStart = -1;
-    int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(), avHeight = av
-            .getCharHeight();
+    int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(),
+            avHeight = av.getCharHeight();
 
     Color tempColour = null;
 
@@ -225,24 +213,16 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
   }
 
   /**
-   * DOCUMENT ME!
+   * Draws residue letters on the given sequence residue range, at the specified
+   * y-offset on the Graphics context
    * 
    * @param seq
-   *          DOCUMENT ME!
    * @param start
-   *          DOCUMENT ME!
    * @param end
-   *          DOCUMENT ME!
-   * @param x1
-   *          DOCUMENT ME!
    * @param y1
-   *          DOCUMENT ME!
-   * @param width
-   *          DOCUMENT ME!
-   * @param height
-   *          DOCUMENT ME!
+   * @param drawGaps
    */
-  public void drawText(SequenceI seq, int start, int end, int y1)
+  public void drawText(SequenceI seq, int start, int end, int y1, boolean drawGaps)
   {
     y1 += av.getCharHeight() - av.getCharHeight() / 5; // height/5 replaces pady
     int charOffset = 0;
@@ -264,8 +244,9 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
       else
       {
         char gap = av.getGapCharacter();
-        graphics.drawString(seq.getSequenceAsString(start, end + 1)
-                .replace(gap, ' '), 0, y1);
+        graphics.drawString(
+                seq.getSequenceAsString(start, end + 1).replace(gap, ' '),
+                0, y1);
       }
     }
     else
@@ -282,7 +263,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
         getboxColour = false;
         s = seq.getCharAt(i);
 
-        if (!renderGaps && jalview.util.Comparison.isGap(s))
+        if (!drawGaps && Comparison.isGap(s))
         {
           continue;
         }
@@ -313,7 +294,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
             if (currentSequenceGroup.thresholdTextColour > 0)
             {
               if (resBoxColour.getRed() + resBoxColour.getBlue()
-                      + resBoxColour.getGreen() < currentSequenceGroup.thresholdTextColour)
+                      + resBoxColour
+                              .getGreen() < currentSequenceGroup.thresholdTextColour)
               {
                 graphics.setColor(currentSequenceGroup.textColour2);
               }
@@ -331,9 +313,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
           {
             // todo - use sequence group consensus
             s = getDisplayChar(srep, i, s, '.', currentSequenceGroup);
-
           }
-
         }
         else
         {
@@ -375,15 +355,12 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
           if (!isarep && av.getShowUnconserved())
           {
             s = getDisplayChar(srep, i, s, '.', null);
-
           }
-
         }
 
         charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
         graphics.drawString(String.valueOf(s),
                 charOffset + av.getCharWidth() * (i - start), y1);
-
       }
     }
   }
@@ -406,21 +383,25 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
     // currentSequenceGroup.getConsensus()
     char conschar = (usesrep) ? (currentGroup == null
             || position < currentGroup.getStartRes()
-            || position > currentGroup.getEndRes() ? av.getAlignment()
-            .getSeqrep().getCharAt(position)
-            : (currentGroup.getSeqrep() != null ? currentGroup.getSeqrep()
-                    .getCharAt(position) : av.getAlignment().getSeqrep()
-                    .getCharAt(position)))
+            || position > currentGroup.getEndRes()
+                    ? av.getAlignment().getSeqrep().getCharAt(position)
+                    : (currentGroup.getSeqrep() != null
+                            ? currentGroup.getSeqrep().getCharAt(position)
+                            : av.getAlignment().getSeqrep()
+                                    .getCharAt(position)))
             : (currentGroup != null && currentGroup.getConsensus() != null
                     && position >= currentGroup.getStartRes()
-                    && position <= currentGroup.getEndRes() && currentGroup
-                    .getConsensus().annotations.length > position) ? currentGroup
-                    .getConsensus().annotations[position].displayCharacter
-                    .charAt(0)
-                    : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
-                            .charAt(0);
+                    && position <= currentGroup.getEndRes()
+                    && currentGroup
+                            .getConsensus().annotations.length > position)
+                                    ? currentGroup
+                                            .getConsensus().annotations[position].displayCharacter
+                                                    .charAt(0)
+                                    : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
+                                            .charAt(0);
     if (!jalview.util.Comparison.isGap(conschar)
-            && (sequenceChar == conschar || sequenceChar + CHAR_TO_UPPER == conschar))
+            && (sequenceChar == conschar
+                    || sequenceChar + CHAR_TO_UPPER == conschar))
     {
       sequenceChar = conservedChar;
     }
@@ -445,8 +426,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
    * @param height
    *          DOCUMENT ME!
    */
-  public void drawHighlightedText(SequenceI seq, int start, int end,
-          int x1, int y1)
+  public void drawHighlightedText(SequenceI seq, int start, int end, int x1,
+          int y1)
   {
     int pady = av.getCharHeight() / 5;
     int charOffset = 0;
@@ -475,21 +456,30 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
     }
   }
 
-  public void drawCursor(SequenceI seq, int res, int x1, int y1)
+  /**
+   * Draw a sequence canvas cursor
+   * 
+   * @param g
+   *          graphics context to draw on
+   * @param s
+   *          character to draw at cursor
+   * @param x1
+   *          x position of cursor in graphics context
+   * @param y1
+   *          y position of cursor in graphics context
+   */
+  public void drawCursor(Graphics g, char s, int x1, int y1)
   {
     int pady = av.getCharHeight() / 5;
     int charOffset = 0;
-    graphics.setColor(Color.black);
-    graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
+    g.setColor(Color.black);
+    g.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
 
     if (av.isValidCharWidth())
     {
-      graphics.setColor(Color.white);
-
-      char s = seq.getCharAt(res);
-
+      g.setColor(Color.white);
       charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
-      graphics.drawString(String.valueOf(s), charOffset + x1,
+      g.drawString(String.valueOf(s), charOffset + x1,
               (y1 + av.getCharHeight()) - pady);
     }