From: kiramt Date: Tue, 31 Oct 2017 13:59:31 +0000 (+0000) Subject: Merge remote-tracking branch 'origin/develop' into imp/JAL-2774 X-Git-Tag: Release_2_10_4~67^2~20 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=c78840385a5ac9dd6d16a37aa7b55cfaeb360456 Merge remote-tracking branch 'origin/develop' into imp/JAL-2774 Conflicts: src/jalview/gui/SeqCanvas.java --- c78840385a5ac9dd6d16a37aa7b55cfaeb360456 diff --cc src/jalview/gui/SeqCanvas.java index 403cbcf,2a9c704..320102f --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@@ -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]); } } } @@@ -1679,23 -2076,12 +1680,33 @@@ } /** + * 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; + } }