Merge remote-tracking branch 'origin/releases/Release_2_10_2b1_Branch'
authorkiramt <k.mourao@dundee.ac.uk>
Mon, 28 Aug 2017 11:15:35 +0000 (12:15 +0100)
committerkiramt <k.mourao@dundee.ac.uk>
Mon, 28 Aug 2017 11:15:35 +0000 (12:15 +0100)
into bug/JAL-2665-2.10.2b

Conflicts:
src/jalview/gui/SeqCanvas.java

1  2 
src/jalview/datamodel/SequenceGroup.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java

Simple merge
@@@ -941,212 -811,111 +943,212 @@@ public class SeqCanvas extends JCompone
  
      if (group != null)
      {
 +      g.setStroke(new BasicStroke());
 +      g.setColor(group.getOutlineColour());
 +      
        do
        {
 -        int oldY = -1;
 -        int i = 0;
 -        boolean inGroup = false;
 -        int top = -1;
 -        int bottom = -1;
 +        drawPartialGroupOutline(g, group, startRes, endRes, startSeq,
 +                endSeq, offset);
-         
++
 +        groupIndex++;
  
 -        for (i = startSeq; i <= endSeq; i++)
 +        g.setStroke(new BasicStroke());
 +
 +        if (groupIndex >= av.getAlignment().getGroups().size())
          {
 -          sx = (group.getStartRes() - startRes) * charWidth;
 -          sy = offset + ((i - startSeq) * charHeight);
 -          ex = (((group.getEndRes() + 1) - group.getStartRes()) * charWidth)
 -                  - 1;
 +          break;
 +        }
  
 -          if (sx + ex < 0 || sx > visWidth)
 -          {
 -            continue;
 -          }
 +        group = av.getAlignment().getGroups().get(groupIndex);
  
 -          if ((sx <= (endRes - startRes) * charWidth)
 -                  && group.getSequences(null)
 -                          .contains(av.getAlignment().getSequenceAt(i)))
 -          {
 -            if ((bottom == -1) && !group.getSequences(null)
 -                    .contains(av.getAlignment().getSequenceAt(i + 1)))
 -            {
 -              bottom = sy + charHeight;
 -            }
 -
 -            if (!inGroup)
 -            {
 -              if (((top == -1) && (i == 0)) || !group.getSequences(null)
 -                      .contains(av.getAlignment().getSequenceAt(i - 1)))
 -              {
 -                top = sy;
 -              }
 -
 -              oldY = sy;
 -              inGroup = true;
 -
 -              if (group == av.getSelectionGroup())
 -              {
 -                g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
 -                        BasicStroke.JOIN_ROUND, 3f, new float[]
 -                        { 5f, 3f }, 0f));
 -                g.setColor(Color.RED);
 -              }
 -              else
 -              {
 -                g.setStroke(new BasicStroke());
 -                g.setColor(group.getOutlineColour());
 -              }
 -            }
 -          }
 -          else
 +      } while (groupIndex < av.getAlignment().getGroups().size());
 +
 +    }
 +
 +  }
 +
 +
 +  /*
 +   * Draw the selection group as a separate image and overlay
 +   */
 +  private BufferedImage drawSelectionGroup(int startRes, int endRes,
 +          int startSeq, int endSeq)
 +  {
 +    // get a new image of the correct size
 +    BufferedImage selectionImage = setupImage();
 +
 +    if (selectionImage == null)
 +    {
 +      return null;
 +    }
 +
 +    SequenceGroup group = av.getSelectionGroup();
 +    if (group == null)
 +    {
 +      // nothing to draw
 +      return null;
 +    }
 +
 +    // set up drawing colour
 +    Graphics2D g = (Graphics2D) selectionImage.getGraphics();
 +
 +    // set background to transparent
 +    g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
 +    g.fillRect(0, 0, selectionImage.getWidth(), selectionImage.getHeight());
 +
 +    // set up foreground to draw red dashed line
 +    g.setComposite(AlphaComposite.Src);
 +    g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
 +            BasicStroke.JOIN_ROUND, 3f, new float[]
 +    { 5f, 3f }, 0f));
 +    g.setColor(Color.RED);
 +
 +    if (!av.getWrapAlignment())
 +    {
 +      drawUnwrappedSelection(g, group, startRes, endRes, startSeq, endSeq,
 +              0);
 +    }
 +    else
 +    {
 +      drawWrappedSelection(g, group, getWidth(), getHeight(),
 +              av.getRanges().getStartRes());
 +    }
 +
 +    g.dispose();
 +    return selectionImage;
 +  }
 +
 +  /*
 +   * Draw a selection group over an unwrapped alignment
 +   * @param g graphics object to draw with
 +   * @param group selection group
 +   * @param startRes start residue of area to draw
 +   * @param endRes end residue of area to draw
 +   * @param startSeq start sequence of area to draw
 +   * @param endSeq end sequence of area to draw
 +   * @param offset vertical offset (used when called from wrapped alignment code)
 +   */
 +  private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
 +          int startRes, int endRes, int startSeq, int endSeq, int offset)
 +  {
 +    if (!av.hasHiddenColumns())
 +    {
 +      drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
 +              offset);
 +    }
 +    else
 +    {
 +      // package into blocks of visible columns
 +      int screenY = 0;
 +      int blockStart = startRes;
 +      int blockEnd = endRes;
 +
 +      for (int[] region : av.getAlignment().getHiddenColumns()
 +              .getHiddenColumnsCopy())
 +      {
 +        int hideStart = region[0];
 +        int hideEnd = region[1];
 +
 +        if (hideStart <= blockStart)
 +        {
 +          blockStart += (hideEnd - hideStart) + 1;
 +          continue;
 +        }
 +
 +        blockEnd = hideStart - 1;
 +
 +        g.translate(screenY * charWidth, 0);
 +        drawPartialGroupOutline(g, group,
 +                blockStart, blockEnd, startSeq, endSeq, offset);
 +
 +        g.translate(-screenY * charWidth, 0);
 +        screenY += blockEnd - blockStart + 1;
 +        blockStart = hideEnd + 1;
 +
 +        if (screenY > (endRes - startRes))
 +        {
 +          // already rendered last block
 +          break;
 +        }
 +      }
 +
 +      if (screenY <= (endRes - startRes))
 +      {
 +        // remaining visible region to render
 +        blockEnd = blockStart + (endRes - startRes) - screenY;
 +        g.translate(screenY * charWidth, 0);
 +        drawPartialGroupOutline(g, group,
 +                blockStart, blockEnd, startSeq, endSeq, offset);
 +        
 +        g.translate(-screenY * charWidth, 0);
 +      }
 +    }
 +  }
 +
 +  /*
 +   * Draw the selection group as a separate image and overlay
 +   */
 +  private void drawPartialGroupOutline(Graphics2D g, SequenceGroup group,
 +          int startRes, int endRes, int startSeq, int endSeq,
 +          int verticalOffset)
 +  {
 +    int visWidth = (endRes - startRes + 1) * charWidth;
 +
 +    int oldY = -1;
 +    int i = 0;
 +    boolean inGroup = false;
 +    int top = -1;
 +    int bottom = -1;
 +
 +    int sx = -1;
 +    int sy = -1;
 +    int xwidth = -1;
 +
 +    for (i = startSeq; i <= endSeq; i++)
 +    {
 +      // position of start residue of group relative to startRes, in pixels
 +      sx = (group.getStartRes() - startRes) * charWidth;
 +
 +      // width of group in pixels
 +      xwidth = (((group.getEndRes() + 1) - group.getStartRes()) * charWidth)
 +              - 1;
 +
 +      sy = verticalOffset + (i - startSeq) * charHeight;
 +
 +      if (sx + xwidth < 0 || sx > visWidth)
 +      {
 +        continue;
 +      }
 +
 +      if ((sx <= (endRes - startRes) * charWidth)
 +              && group.getSequences(null)
 +                      .contains(av.getAlignment().getSequenceAt(i)))
 +      {
 +        if ((bottom == -1) && !group.getSequences(null)
 +                .contains(av.getAlignment().getSequenceAt(i + 1)))
 +        {
 +          bottom = sy + charHeight;
 +        }
 +
 +        if (!inGroup)
 +        {
 +          if (((top == -1) && (i == 0)) || !group.getSequences(null)
 +                  .contains(av.getAlignment().getSequenceAt(i - 1)))
            {
 -            if (inGroup)
 -            {
 -              if (sx >= 0 && sx < visWidth)
 -              {
 -                g.drawLine(sx, oldY, sx, sy);
 -              }
 -
 -              if (sx + ex < visWidth)
 -              {
 -                g.drawLine(sx + ex, oldY, sx + ex, sy);
 -              }
 -
 -              if (sx < 0)
 -              {
 -                ex += sx;
 -                sx = 0;
 -              }
 -
 -              if (sx + ex > visWidth)
 -              {
 -                ex = visWidth;
 -              }
 -
 -              else if (sx + ex >= (endRes - startRes + 1) * charWidth)
 -              {
 -                ex = (endRes - startRes + 1) * charWidth;
 -              }
 -
 -              if (top != -1)
 -              {
 -                g.drawLine(sx, top, sx + ex, top);
 -                top = -1;
 -              }
 -
 -              if (bottom != -1)
 -              {
 -                g.drawLine(sx, bottom, sx + ex, bottom);
 -                bottom = -1;
 -              }
 -
 -              inGroup = false;
 -            }
 +            top = sy;
            }
 -        }
  
 +          oldY = sy;
 +          inGroup = true;
 +        }
 +      }
 +      else
 +      {
          if (inGroup)
          {
 -          sy = offset + ((i - startSeq) * charHeight);
 +          // if start position is visible, draw vertical line to left of
 +          // group
            if (sx >= 0 && sx < visWidth)
            {
              g.drawLine(sx, oldY, sx, sy);
Simple merge