JAL-2664 Initial change to drawing hidden regions in overview
authorkiramt <k.mourao@dundee.ac.uk>
Mon, 14 Aug 2017 08:43:47 +0000 (09:43 +0100)
committerkiramt <k.mourao@dundee.ac.uk>
Mon, 14 Aug 2017 08:43:47 +0000 (09:43 +0100)
src/jalview/renderer/OverviewRenderer.java

index 46490cd..07a8631 100644 (file)
@@ -29,8 +29,10 @@ import jalview.renderer.seqfeatures.FeatureColourFinder;
 import jalview.renderer.seqfeatures.FeatureRenderer;
 import jalview.viewmodel.OverviewDimensions;
 
+import java.awt.AlphaComposite;
 import java.awt.Color;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
 
 public class OverviewRenderer
@@ -79,21 +81,23 @@ public class OverviewRenderer
     int seqIndex = 0;
     int pixelRow = 0;
 
+    BufferedImage hiddenImage = buildHiddenImage(rows, cols,
+            miniMe.getWidth(), miniMe.getHeight());
+
     for (int alignmentRow : rows)
     {
       if (redraw)
       {
         break;
       }
-
+    
       // get details of this alignment row
-      boolean hidden = rows.isHidden(alignmentRow);
       SequenceI seq = rows.getSequence(alignmentRow);
-
+    
       // calculate where this row extends to in pixels
       int endRow = Math.min(Math.round((seqIndex + 1) * pixelsPerSeq) - 1,
               miniMe.getHeight() - 1);
-
+    
       int colIndex = 0;
       int pixelCol = 0;
       for (int alignmentCol : cols)
@@ -102,22 +106,21 @@ public class OverviewRenderer
         {
           break;
         }
-
+    
         // calculate where this column extends to in pixels
         int endCol = Math.min(
                 Math.round((colIndex + 1) * pixelsPerCol) - 1,
                 miniMe.getWidth() - 1);
-
+    
         // don't do expensive colour determination if we're not going to use it
         // NB this is important to avoid performance issues in the overview
         // panel
         if (pixelCol <= endCol)
         {
-          // determine the colour based on the sequence and column position
           rgbcolor = getColumnColourFromSequence(seq,
-                  hidden || cols.isHidden(alignmentCol), alignmentCol,
+                  alignmentCol,
                   finder);
-
+    
           // fill in the appropriate number of pixels
           for (int row = pixelRow; row <= endRow; ++row)
           {
@@ -126,7 +129,7 @@ public class OverviewRenderer
               miniMe.setRGB(col, row, rgbcolor);
             }
           }
-
+    
           pixelCol = endCol + 1;
         }
         colIndex++;
@@ -134,14 +137,15 @@ public class OverviewRenderer
       pixelRow = endRow + 1;
       seqIndex++;
     }
-    return miniMe;
+
+    return applyMask(hiddenImage, miniMe);
   }
 
   /*
    * Find the colour of a sequence at a specified column position
    */
   private int getColumnColourFromSequence(jalview.datamodel.SequenceI seq,
-          boolean isHidden, int lastcol, FeatureColourFinder fcfinder)
+          int lastcol, FeatureColourFinder fcfinder)
   {
     Color color = Color.white;
 
@@ -150,12 +154,92 @@ public class OverviewRenderer
       color = sr.getResidueColour(seq, lastcol, fcfinder);
     }
 
-    if (isHidden)
+    return color.getRGB();
+  }
+
+  private BufferedImage applyMask(BufferedImage mask, BufferedImage image)
+  {
+    Graphics2D g = (Graphics2D) image.getGraphics();
+    g.setComposite(
+            AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
+    g.drawImage(mask, 0, 0, image.getWidth(), image.getHeight(), null);
+    return image;
+  }
+
+  /*
+   * Build a masking image of hidden columns and rows to be applied on top
+   * of the main overview image.
+   */
+  private BufferedImage buildHiddenImage(AlignmentRowsCollectionI rows,
+          AlignmentColsCollectionI cols, int width, int height)
+  {
+    // new masking image
+    BufferedImage hiddenImage = new BufferedImage(width, height,
+            BufferedImage.TYPE_INT_ARGB);
+
+    int colIndex = 0;
+    int pixelCol = 0;
+
+    Color hidden = Color.DARK_GRAY;
+
+    Graphics2D g2d = (Graphics2D) hiddenImage.getGraphics();
+
+    // set background to transparent
+    g2d.setComposite(AlphaComposite.Clear);
+    g2d.fillRect(0, 0, width, height);
+
+    // set next colour to opaque
+    g2d.setComposite(AlphaComposite.Src);
+
+    for (int alignmentCol : cols)
     {
-      color = color.darker().darker();
+      if (redraw)
+      {
+        break;
+      }
+
+      // calculate where this column extends to in pixels
+      int endCol = Math.min(Math.round((colIndex + 1) * pixelsPerCol) - 1,
+              hiddenImage.getWidth() - 1);
+
+      if (pixelCol <= endCol)
+      {
+        // determine the colour based on the sequence and column position
+        if (cols.isHidden(alignmentCol))
+        {
+          g2d.setColor(hidden);
+          g2d.fillRect(pixelCol, 0, endCol - pixelCol + 1, height);
+        }
+
+        pixelCol = endCol + 1;
+      }
+      colIndex++;
+
     }
 
-    return color.getRGB();
+    int seqIndex = 0;
+    int pixelRow = 0;
+    for (int alignmentRow : rows)
+    {
+      if (redraw)
+      {
+        break;
+      }
+
+      // calculate where this row extends to in pixels
+      int endRow = Math.min(Math.round((seqIndex + 1) * pixelsPerSeq) - 1,
+              miniMe.getHeight() - 1);
+
+      // get details of this alignment row
+      if (rows.isHidden(alignmentRow))
+      {
+        g2d.fillRect(0, pixelRow, width, endRow - pixelRow + 1);
+      }
+      pixelRow = endRow + 1;
+      seqIndex++;
+    }
+
+    return hiddenImage;
   }
 
   /**