Merge remote-tracking branch 'origin/develop' into
authorkiramt <k.mourao@dundee.ac.uk>
Wed, 22 Mar 2017 14:47:23 +0000 (14:47 +0000)
committerkiramt <k.mourao@dundee.ac.uk>
Wed, 22 Mar 2017 14:47:23 +0000 (14:47 +0000)
features/JAL-2388OverviewWindow

Conflicts:
src/jalview/gui/OverviewPanel.java

1  2 
src/jalview/gui/OverviewCanvas.java
src/jalview/gui/OverviewPanel.java
src/jalview/viewmodel/AlignmentViewport.java

index 7d42e5e,0000000..6a7e56c
mode 100644,000000..100644
--- /dev/null
@@@ -1,243 -1,0 +1,233 @@@
 +package jalview.gui;
 +
 +import jalview.api.AlignViewportI;
 +import jalview.datamodel.SequenceI;
 +import jalview.renderer.AnnotationRenderer;
++import jalview.renderer.seqfeatures.FeatureColourFinder;
 +import jalview.viewmodel.OverviewDimensions;
 +
 +import java.awt.Color;
 +import java.awt.Dimension;
 +import java.awt.Graphics;
 +import java.awt.image.BufferedImage;
 +
 +import javax.swing.JComponent;
 +
 +public class OverviewCanvas extends JComponent
 +{
 +  private static final Color TRANS_GREY = new Color(100, 100, 100, 25);
 +
 +  private BufferedImage miniMe;
 +
 +  private BufferedImage lastMiniMe = null;
 +
 +  public boolean updating = false;
 +
 +  // This is set true if the user resizes whilst
 +  // the overview is being calculated
 +  public volatile boolean updateAgain = false;
 +
 +  // Can set different properties in this seqCanvas than
 +  // main visible SeqCanvas
 +  private SequenceRenderer sr;
 +
 +  private jalview.renderer.seqfeatures.FeatureRenderer fr;
 +
 +  private final AnnotationRenderer renderer = new AnnotationRenderer();
 +
 +  OverviewDimensions od;
 +
 +  OverviewPanel op;
 +
 +  AlignViewport av;
 +
 +  AlignmentPanel ap;
 +
 +  public OverviewCanvas(OverviewDimensions overviewDims,
 +          AlignViewportI alignvp, AlignmentPanel alignp, OverviewPanel overp)
 +  {
 +    od = overviewDims;
 +    av = alignp.av;
 +    ap = alignp;
 +    op = overp;
 +
 +    sr = new SequenceRenderer(av);
 +    sr.renderGaps = false;
 +    sr.forOverview = true;
 +    fr = new FeatureRenderer(ap);
 +  }
 +
 +  public void draw(boolean showSequenceFeatures, boolean showAnnotation)
 +  {
 +    miniMe = null;
 +
 +    if (showSequenceFeatures)
 +    {
 +      fr.transferSettings(ap.getSeqPanel().seqCanvas.getFeatureRenderer());
 +    }
 +
 +    // why do we need to set preferred size again? was set in
 +    // updateOverviewImage
 +    setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
 +
 +    miniMe = new BufferedImage(od.getWidth(), od.getHeight(),
 +            BufferedImage.TYPE_INT_RGB);
 +
 +    Graphics mg = miniMe.getGraphics();
 +    mg.setColor(Color.orange);
 +    mg.fillRect(0, 0, od.getWidth(), miniMe.getHeight());
 +
 +    // calculate sampleCol and sampleRow
 +    // alignment width is max number of residues/bases
 +    // alignment height is number of sequences
 +    int alwidth = av.getAlignment().getWidth();
 +    int alheight = av.getAlignment().getAbsoluteHeight();
 +
 +    // sampleCol or sampleRow is the width/height allocated to each residue
 +    // in particular, sometimes we may need more than one row/col of the
 +    // BufferedImage allocated
 +    // sampleCol is how much of a residue to assign to each pixel
 +    // sampleRow is how many sequences to assign to each pixel
 +    float sampleCol = alwidth / (float) od.getWidth();
 +    float sampleRow = alheight / (float) od.getSequencesHeight();
 +
 +    buildImage(sampleRow, sampleCol);
 +
 +    if (showAnnotation)
 +    {
 +      renderer.updateFromAlignViewport(av);
 +      for (int col = 0; col < od.getWidth() && !updateAgain; col++)
 +      {
 +        mg.translate(col, od.getSequencesHeight());
 +        renderer.drawGraph(mg, av.getAlignmentConservationAnnotation(),
 +                av.getAlignmentConservationAnnotation().annotations,
 +                (int) (sampleCol) + 1, od.getGraphHeight(),
 +                (int) (col * sampleCol), (int) (col * sampleCol) + 1);
 +        mg.translate(-col, -od.getSequencesHeight());
 +
 +      }
 +    }
 +    System.gc();
 +
 +    updating = false;
 +
 +    if (updateAgain)
 +    {
 +      updateAgain = false;
 +      op.updateOverviewImage();
 +    }
 +    else
 +    {
 +      lastMiniMe = miniMe;
 +    }
 +  }
 +
 +  @Override
 +  public void paintComponent(Graphics g)
 +  {
 +    if (updating || updateAgain)
 +    {
 +      if (lastMiniMe == null)
 +      {
 +        g.setColor(Color.white);
 +        g.fillRect(0, 0, getWidth(), getHeight());
 +      }
 +      else
 +      {
 +        g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
 +      }
 +      g.setColor(TRANS_GREY);
 +      g.fillRect(0, 0, getWidth(), getHeight());
 +    }
 +    else if (lastMiniMe != null)
 +    {
 +      g.drawImage(lastMiniMe, 0, 0, this);
 +      if (lastMiniMe != miniMe)
 +      {
 +        g.setColor(TRANS_GREY);
 +        g.fillRect(0, 0, getWidth(), getHeight());
 +      }
 +    }
 +
 +    g.setColor(Color.red);
 +    od.drawBox(g);
 +  }
 +
 +  /*
 +   * Build the overview panel image
 +   */
 +  private void buildImage(float sampleRow, float sampleCol)
 +  {
 +    int lastcol = -1;
 +    int lastrow = -1;
-     int color = Color.white.getRGB();
++    int rgbcolor = Color.white.getRGB();
 +
 +    SequenceI seq = null;
++    FeatureColourFinder finder = new FeatureColourFinder(fr);
 +
 +    final boolean hasHiddenCols = av.hasHiddenColumns();
 +    boolean hiddenRow = false;
 +    // get hidden row and hidden column map once at beginning.
 +    // clone featureRenderer settings to avoid race conditions... if state is
 +    // updated just need to refresh again
 +    for (int row = 0; row < od.getSequencesHeight() && !updateAgain; row++)
 +    {
 +      boolean doCopy = true;
 +      int currentrow = (int) (row * sampleRow);
 +      if (currentrow != lastrow)
 +      {
 +        doCopy = false;
 +
 +        lastrow = currentrow;
 +
 +        // get the sequence which would be at alignment index 'lastrow' if no
 +        // rows were hidden, and determine whether it is hidden or not
 +        hiddenRow = av.getAlignment().isHidden(lastrow);
 +        seq = av.getAlignment().getSequenceAtAbsoluteIndex(lastrow);
 +      }
 +
 +      for (int col = 0; col < od.getWidth() && !updateAgain; col++)
 +      {
 +        if (doCopy)
 +        {
-           color = miniMe.getRGB(col, row - 1);
++          rgbcolor = miniMe.getRGB(col, row - 1);
 +        }
 +        else if ((int) (col * sampleCol) != lastcol
 +                || (int) (row * sampleRow) != lastrow)
 +        {
 +          lastcol = (int) (col * sampleCol);
-           color = getColumnColourFromSequence(seq, hiddenRow,
-                   hasHiddenCols, lastcol);
++          rgbcolor = getColumnColourFromSequence(seq, hiddenRow,
++                  hasHiddenCols, lastcol, finder);
 +        }
 +        // else we just use the color we already have , so don't need to set it
 +
-         miniMe.setRGB(col, row, color);
++        miniMe.setRGB(col, row, rgbcolor);
 +      }
 +    }
 +  }
 +
 +  /*
 +   * Find the colour of a sequence at a specified column position
 +   */
 +  private int getColumnColourFromSequence(jalview.datamodel.SequenceI seq,
-           boolean hiddenRow, boolean hasHiddenCols, int lastcol)
++          boolean hiddenRow, boolean hasHiddenCols, int lastcol,
++          FeatureColourFinder finder)
 +  {
-     int color;
++    Color color = Color.white;
 +
-     if (seq == null)
++    if ((seq != null) && (seq.getLength() > lastcol))
 +    {
-       color = Color.white.getRGB();
-     }
-     else if (seq.getLength() > lastcol)
-     {
-       color = sr.getResidueBoxColour(seq, lastcol).getRGB();
-       if (av.isShowSequenceFeatures())
-       {
-         color = fr.findFeatureColour(color, seq, lastcol);
-       }
-     }
-     else
-     {
-       color = Color.white.getRGB();
++      color = sr.getResidueColour(seq, lastcol, finder);
 +    }
 +
 +    if (hiddenRow
 +            || (hasHiddenCols && !av.getColumnSelection()
 +                    .isVisible(lastcol)))
 +    {
-       color = new Color(color).darker().darker().getRGB();
++      color = color.darker().darker();
 +    }
 +
-     return color;
++    return color.getRGB();
 +  }
 +
 +}
@@@ -59,13 -83,17 +59,15 @@@ public class OverviewPanel extends JPan
    {
      this.av = alPanel.av;
      this.ap = alPanel;
 -    setLayout(null);
 -
 -    sr = new SequenceRenderer(av);
 -    sr.renderGaps = false;
 -    sr.forOverview = true;
 -    fr = new FeatureRenderer(ap);
  
-     od = new OverviewDimensions(av.getRanges(), av.isShowAnnotation());
+     od = new OverviewDimensions(av.getRanges(),
+             (av.isShowAnnotation() && av
+                     .getAlignmentConservationAnnotation() != null));
  
 +    oviewCanvas = new OverviewCanvas(od, av, ap, this);
 +    setLayout(new BorderLayout());
 +    add(oviewCanvas, BorderLayout.CENTER);
 +
      addComponentListener(new ComponentAdapter()
      {
        @Override
    @Override
    public void run()
    {
-     oviewCanvas.draw(av.isShowSequenceFeatures(), av.isShowAnnotation());
 -    miniMe = null;
 -
 -    if (av.isShowSequenceFeatures())
 -    {
 -      fr.transferSettings(ap.getSeqPanel().seqCanvas.getFeatureRenderer());
 -    }
 -
 -    // why do we need to set preferred size again? was set in
 -    // updateOverviewImage
 -    setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
 -
 -    miniMe = new BufferedImage(od.getWidth(), od.getHeight(),
 -            BufferedImage.TYPE_INT_RGB);
 -
 -    Graphics mg = miniMe.getGraphics();
 -    mg.setColor(Color.orange);
 -    mg.fillRect(0, 0, od.getWidth(), miniMe.getHeight());
 -
 -    // calculate sampleCol and sampleRow
 -    // alignment width is max number of residues/bases
 -    // alignment height is number of sequences
 -    int alwidth = av.getAlignment().getWidth();
 -    int alheight = av.getAlignment().getAbsoluteHeight();
 -
 -    // sampleCol or sampleRow is the width/height allocated to each residue
 -    // in particular, sometimes we may need more than one row/col of the
 -    // BufferedImage allocated
 -    // sampleCol is how much of a residue to assign to each pixel
 -    // sampleRow is how many sequences to assign to each pixel
 -    float sampleCol = alwidth / (float) od.getWidth();
 -    float sampleRow = alheight / (float) od.getSequencesHeight();
 -
 -    buildImage(sampleRow, sampleCol);
 -
 -    // check for conservation annotation to make sure overview works for DNA too
 -    if (av.isShowAnnotation()
 -            && (av.getAlignmentConservationAnnotation() != null))
 -    {
 -      renderer.updateFromAlignViewport(av);
 -      for (int col = 0; col < od.getWidth() && !resizeAgain; col++)
 -      {
 -        mg.translate(col, od.getSequencesHeight());
 -        renderer.drawGraph(mg, av.getAlignmentConservationAnnotation(),
 -                av.getAlignmentConservationAnnotation().annotations,
 -                (int) (sampleCol) + 1, od.getGraphHeight(),
 -                (int) (col * sampleCol), (int) (col * sampleCol) + 1);
 -        mg.translate(-col, -od.getSequencesHeight());
 -
 -      }
 -    }
 -    System.gc();
 -
 -    resizing = false;
 -
 -    if (resizeAgain)
 -    {
 -      resizeAgain = false;
 -      updateOverviewImage();
 -    }
 -    else
 -    {
 -      lastMiniMe = miniMe;
 -    }
 -
++    oviewCanvas.draw(av.isShowSequenceFeatures(),
++            (av.isShowAnnotation() && av
++                    .getAlignmentConservationAnnotation() != null));
      setBoxPosition();
    }