Merge remote-tracking branch 'origin/develop' into imp/JAL-2774
authorkiramt <k.mourao@dundee.ac.uk>
Tue, 31 Oct 2017 13:59:31 +0000 (13:59 +0000)
committerkiramt <k.mourao@dundee.ac.uk>
Tue, 31 Oct 2017 13:59:31 +0000 (13:59 +0000)
Conflicts:
src/jalview/gui/SeqCanvas.java

1  2 
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/ScalePanel.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqCanvas.java
src/jalview/viewmodel/ViewportRanges.java
test/jalview/viewmodel/ViewportRangesTest.java

Simple merge
Simple merge
Simple merge
@@@ -1499,63 -1658,298 +1499,64 @@@ public class SeqCanvas extends JCompone
      {
        fastPaint = true;
        repaint();
 -      return;
      }
 -
 -    int scrollX = 0;
 -    if (eventName.equals(ViewportRanges.STARTRES))
 +    else if (av.getWrapAlignment())
      {
-       if (eventName.equals(ViewportRanges.STARTRES))
 -      // Make sure we're not trying to draw a panel
 -      // larger than the visible window
 -      ViewportRanges vpRanges = av.getRanges();
 -      scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
 -      int range = vpRanges.getViewportWidth();
 -      if (scrollX > range)
 -      {
 -        scrollX = range;
 -      }
 -      else if (scrollX < -range)
++      if (eventName.equals(ViewportRanges.STARTRES)
++              || eventName.equals(ViewportRanges.STARTRESANDSEQ))
        {
 -        scrollX = -range;
 +        repaint();
        }
      }
 -
 -    // Both scrolling and resizing change viewport ranges: scrolling changes
 -    // both start and end points, but resize only changes end values.
 -    // Here we only want to fastpaint on a scroll, with resize using a normal
 -    // paint, so scroll events are identified as changes to the horizontal or
 -    // vertical start value.
 -
 -    // scroll - startres and endres both change
 -    if (eventName.equals(ViewportRanges.STARTRES))
 +    else
      {
 -      if (av.getWrapAlignment())
 -      {
 -        fastPaintWrapped(scrollX);
 -      }
 -      else
 +      int scrollX = 0;
 +      if (eventName.equals(ViewportRanges.STARTRES)
 +              || eventName.equals(ViewportRanges.STARTRESANDSEQ))
        {
 -        fastPaint(scrollX, 0);
 -      }
 -    }
 -    else if (eventName.equals(ViewportRanges.STARTSEQ))
 -    {
 -      // scroll
 -      fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
 -    }
 -  }
 -
 -  /**
 -   * Does a minimal update of the image for a scroll movement. This method
 -   * handles scroll movements of up to one width of the wrapped alignment (one
 -   * click in the vertical scrollbar). Larger movements (for example after a
 -   * scroll to highlight a mapped position) trigger a full redraw instead.
 -   * 
 -   * @param scrollX
 -   *          number of positions scrolled (right if positive, left if negative)
 -   */
 -  protected void fastPaintWrapped(int scrollX)
 -  {
 -    ViewportRanges ranges = av.getRanges();
 -
 -    if (Math.abs(scrollX) > ranges.getViewportWidth())
 -    {
 -      /*
 -       * shift of more than one view width is 
 -       * overcomplicated to handle in this method
 -       */
 -      fastPaint = false;
 -      repaint();
 -      return;
 -    }
 -
 -    if (fastpainting || gg == null)
 -    {
 -      return;
 -    }
 -
 -    fastPaint = true;
 -    fastpainting = true;
 -
 -    try
 -    {
 -      calculateWrappedGeometry(getWidth(), getHeight());
 -
 -      /*
 -       * relocate the regions of the alignment that are still visible
 -       */
 -      shiftWrappedAlignment(-scrollX);
 +        // Make sure we're not trying to draw a panel
 +        // larger than the visible window
 +        if (eventName.equals(ViewportRanges.STARTRES))
 +        {
 +          scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
 +        }
 +        else
 +        {
 +          scrollX = ((int[]) evt.getNewValue())[0]
 +                  - ((int[]) evt.getOldValue())[0];
 +        }
 +        ViewportRanges vpRanges = av.getRanges();
  
 -      /*
 -       * add new columns (sequence, annotation)
 -       * - at top left if scrollX < 0 
 -       * - at right of last two widths if scrollX > 0
 -       */
 -      if (scrollX < 0)
 -      {
 -        int startRes = ranges.getStartRes();
 -        drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes, startRes
 -                - scrollX - 1, getHeight());
 +        int range = vpRanges.getEndRes() - vpRanges.getStartRes();
 +        if (scrollX > range)
 +        {
 +          scrollX = range;
 +        }
 +        else if (scrollX < -range)
 +        {
 +          scrollX = -range;
 +        }
        }
 -      else
 +
 +      // Both scrolling and resizing change viewport ranges: scrolling changes
 +      // both start and end points, but resize only changes end values.
 +      // Here we only want to fastpaint on a scroll, with resize using a normal
 +      // paint, so scroll events are identified as changes to the horizontal or
 +      // vertical start value.
 +      if (eventName.equals(ViewportRanges.STARTRES))
        {
 -        fastPaintWrappedAddRight(scrollX);
 +        // scroll - startres and endres both change
 +        fastPaint(scrollX, 0);
        }
 -
 -      /*
 -       * draw all scales (if  shown) and hidden column markers
 -       */
 -      drawWrappedDecorators(gg, ranges.getStartRes());
 -
 -      repaint();
 -    } finally
 -    {
 -      fastpainting = false;
 -    }
 -  }
 -
 -  /**
 -   * Draws the specified number of columns at the 'end' (bottom right) of a
 -   * wrapped alignment view, including sequences and annotations if shown, but
 -   * not scales. Also draws the same number of columns at the right hand end of
 -   * the second last width shown, if the last width is not full height (so
 -   * cannot simply be copied from the graphics image).
 -   * 
 -   * @param columns
 -   */
 -  protected void fastPaintWrappedAddRight(int columns)
 -  {
 -    if (columns == 0)
 -    {
 -      return;
 -    }
 -
 -    ViewportRanges ranges = av.getRanges();
 -    int viewportWidth = ranges.getViewportWidth();
 -    int charWidth = av.getCharWidth();
 -
 -    /**
 -     * draw full height alignment in the second last row, last columns, if the
 -     * last row was not full height
 -     */
 -    int visibleWidths = wrappedVisibleWidths;
 -    int canvasHeight = getHeight();
 -    boolean lastWidthPartHeight = (wrappedVisibleWidths * wrappedRepeatHeightPx) > canvasHeight;
 -
 -    if (lastWidthPartHeight)
 -    {
 -      int widthsAbove = Math.max(0, visibleWidths - 2);
 -      int ypos = wrappedRepeatHeightPx * widthsAbove
 -              + wrappedSpaceAboveAlignment;
 -      int endRes = ranges.getEndRes();
 -      endRes += widthsAbove * viewportWidth;
 -      int startRes = endRes - columns;
 -      int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth)
 -              * charWidth;
 -
 -      /*
 -       * white fill first to erase annotations
 -       */
 -      gg.translate(xOffset, 0);
 -      gg.setColor(Color.white);
 -      gg.fillRect(labelWidthWest, ypos,
 -              (endRes - startRes + 1) * charWidth, wrappedRepeatHeightPx);
 -      gg.translate(-xOffset, 0);
 -
 -      drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
 -    }
 -
 -    /*
 -     * draw newly visible columns in last wrapped width (none if we
 -     * have reached the end of the alignment)
 -     * y-offset for drawing last width is height of widths above,
 -     * plus one gap row
 -     */
 -    int widthsAbove = visibleWidths - 1;
 -    int ypos = wrappedRepeatHeightPx * widthsAbove
 -            + wrappedSpaceAboveAlignment;
 -    int endRes = ranges.getEndRes();
 -    endRes += widthsAbove * viewportWidth;
 -    int startRes = endRes - columns + 1;
 -
 -    /*
 -     * white fill first to erase annotations
 -     */
 -    int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth)
 -            * charWidth;
 -    gg.translate(xOffset, 0);
 -    gg.setColor(Color.white);
 -    int width = viewportWidth * charWidth - xOffset;
 -    gg.fillRect(labelWidthWest, ypos, width, wrappedRepeatHeightPx);
 -    gg.translate(-xOffset, 0);
 -
 -    gg.setFont(av.getFont());
 -    gg.setColor(Color.black);
 -
 -    if (startRes < ranges.getVisibleAlignmentWidth())
 -    {
 -      drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
 -    }
 -
 -    /*
 -     * and finally, white fill any space below the visible alignment
 -     */
 -    int heightBelow = canvasHeight - visibleWidths * wrappedRepeatHeightPx;
 -    if (heightBelow > 0)
 -    {
 -      gg.setColor(Color.white);
 -      gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
 -    }
 -  }
 -
 -  /**
 -   * Shifts the visible alignment by the specified number of columns - left if
 -   * negative, right if positive. Copies and moves sequences and annotations (if
 -   * shown). Scales, hidden column markers and any newly visible columns must be
 -   * drawn separately.
 -   * 
 -   * @param positions
 -   */
 -  protected void shiftWrappedAlignment(int positions)
 -  {
 -    if (positions == 0)
 -    {
 -      return;
 -    }
 -    int charWidth = av.getCharWidth();
 -
 -    int canvasHeight = getHeight();
 -    ViewportRanges ranges = av.getRanges();
 -    int viewportWidth = ranges.getViewportWidth();
 -    int widthToCopy = (ranges.getViewportWidth() - Math.abs(positions))
 -            * charWidth;
 -    int heightToCopy = wrappedRepeatHeightPx - wrappedSpaceAboveAlignment;
 -    int xMax = ranges.getVisibleAlignmentWidth();
 -
 -    if (positions > 0)
 -    {
 -      /*
 -       * shift right (after scroll left)
 -       * for each wrapped width (starting with the last), copy (width-positions) 
 -       * columns from the left margin to the right margin, and copy positions 
 -       * columns from the right margin of the row above (if any) to the 
 -       * left margin of the current row
 -       */
 -
 -      /*
 -       * get y-offset of last wrapped width, first row of sequences
 -       */
 -      int y = canvasHeight / wrappedRepeatHeightPx * wrappedRepeatHeightPx;
 -      y += wrappedSpaceAboveAlignment;
 -      int copyFromLeftStart = labelWidthWest;
 -      int copyFromRightStart = copyFromLeftStart + widthToCopy;
 -
 -      while (y >= 0)
 +      else if (eventName.equals(ViewportRanges.STARTSEQ))
        {
 -        gg.copyArea(copyFromLeftStart, y, widthToCopy, heightToCopy,
 -                positions * charWidth, 0);
 -        if (y > 0)
 -        {
 -          gg.copyArea(copyFromRightStart, y - wrappedRepeatHeightPx,
 -                  positions * charWidth, heightToCopy, -widthToCopy,
 -                  wrappedRepeatHeightPx);
 -        }
 -
 -        y -= wrappedRepeatHeightPx;
 +        // scroll
 +        fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
        }
 -    }
 -    else
 -    {
 -      /*
 -       * shift left (after scroll right)
 -       * for each wrapped width (starting with the first), copy (width-positions) 
 -       * columns from the right margin to the left margin, and copy positions 
 -       * columns from the left margin of the row below (if any) to the 
 -       * right margin of the current row
 -       */
 -      int xpos = av.getRanges().getStartRes();
 -      int y = wrappedSpaceAboveAlignment;
 -      int copyFromRightStart = labelWidthWest - positions * charWidth;
 -
 -      while (y < canvasHeight)
 +      else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
        {
 -        gg.copyArea(copyFromRightStart, y, widthToCopy, heightToCopy,
 -                positions * charWidth, 0);
 -        if (y + wrappedRepeatHeightPx < canvasHeight - wrappedRepeatHeightPx
 -                && (xpos + viewportWidth <= xMax))
 -        {
 -          gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx, -positions
 -                  * charWidth, heightToCopy, widthToCopy,
 -                  -wrappedRepeatHeightPx);
 -        }
 -
 -        y += wrappedRepeatHeightPx;
 -        xpos += viewportWidth;
 +        fastPaint(scrollX, ((int[]) evt.getNewValue())[1]
 +                - ((int[]) evt.getOldValue())[1]);
        }
      }
    }
    }
  
    /**
 +   * Answers the height in pixels of a repeating section of the wrapped
 +   * alignment, including space above, scale above if shown, sequences, and
 +   * annotation panel if shown
 +   * 
 +   * @return
 +   */
 +  protected int getRepeatHeightWrapped()
 +  {
 +    // gap (and maybe scale) above
 +    int repeatHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
 +
 +    // add sequences
 +    repeatHeight += av.getRanges().getViewportHeight() * charHeight;
 +
 +    // add annotations panel height if shown
 +    repeatHeight += getAnnotationHeight();
 +
 +    return repeatHeight;
 +  }
++  
++  /**
+    * Answers the width in pixels of the left scale labels (0 if not shown)
+    * 
+    * @return
+    */
+   int getLabelWidthWest()
+   {
+     return labelWidthWest;
+   }
  }