{
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;
+ }
}