X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FSeqCanvas.java;h=0e312461ab54154139e2a931e9a77578048136c9;hb=c4b90e7ff57436d6bb96d316eed24c887b241f4d;hp=c05c1721d45ef1b1ac6a0c176e59baa6edac056b;hpb=d065bc916cb63af83cdab7319f5177a855724aba;p=jalview.git diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index c05c172..0e31246 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -288,8 +288,6 @@ public class SeqCanvas extends JComponent implements ViewportListenerI fastpainting = true; fastPaint = true; updateViewport(); - gg.copyArea(horizontal * charWidth, vertical * charHeight, imgWidth, - imgHeight, -horizontal * charWidth, -vertical * charHeight); ViewportRanges ranges = av.getRanges(); int startRes = ranges.getStartRes(); @@ -299,6 +297,9 @@ public class SeqCanvas extends JComponent implements ViewportListenerI int transX = 0; int transY = 0; + gg.copyArea(horizontal * charWidth, vertical * charHeight, imgWidth, + imgHeight, -horizontal * charWidth, -vertical * charHeight); + if (horizontal > 0) // scrollbar pulled right, image to the left { transX = (endRes - startRes - horizontal) * charWidth; @@ -413,14 +414,15 @@ public class SeqCanvas extends JComponent implements ViewportListenerI } /** - * DOCUMENT ME! + * Returns the visible width of the canvas in residues, after allowing for + * East or West scales (if shown) * - * @param cwidth - * DOCUMENT ME! + * @param canvasWidth + * the width in pixels (possibly including scales) * - * @return DOCUMENT ME! + * @return */ - public int getWrappedCanvasWidth(int cwidth) + public int getWrappedCanvasWidth(int canvasWidth) { FontMetrics fm = getFontMetrics(av.getFont()); @@ -434,10 +436,11 @@ public class SeqCanvas extends JComponent implements ViewportListenerI if (av.getScaleLeftWrapped()) { - labelWidthWest = getLabelWidth(fm); + labelWidthWest = labelWidthEast > 0 ? labelWidthEast + : getLabelWidth(fm); } - return (cwidth - labelWidthEast - labelWidthWest) / charWidth; + return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth; } /** @@ -450,11 +453,15 @@ public class SeqCanvas extends JComponent implements ViewportListenerI */ protected int getLabelWidth(FontMetrics fm) { + /* + * find the biggest sequence end position we need to show + * (note this is not necessarily the sequence length) + */ int maxWidth = 0; - for (int i = 0; i < av.getAlignment().getHeight(); i++) + AlignmentI alignment = av.getAlignment(); + for (int i = 0; i < alignment.getHeight(); i++) { - maxWidth = Math.max(maxWidth, av.getAlignment().getSequenceAt(i) - .getEnd()); + maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd()); } int length = 2; @@ -505,16 +512,16 @@ public class SeqCanvas extends JComponent implements ViewportListenerI av.setWrappedWidth(cWidth); - av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth - 1); + av.getRanges().setViewportStartAndWidth(startRes, cWidth); int endx; int ypos = hgap; - int maxwidth = av.getAlignment().getWidth() - 1; + int maxwidth = av.getAlignment().getWidth(); if (av.hasHiddenColumns()) { maxwidth = av.getAlignment().getHiddenColumns() - .findColumnPosition(maxwidth) - 1; + .findColumnPosition(maxwidth); } int annotationHeight = getAnnotationHeight(); @@ -993,32 +1000,33 @@ public class SeqCanvas extends JComponent implements ViewportListenerI * on a black background. Any previous highlighting is removed. Answers true * if any highlight was left on the visible alignment (so status bar should be * set to match), else false. + *
+ * Currently fastPaint is not implemented for wrapped alignments. If a wrapped
+ * alignment had to be scrolled to show the highlighted region, then it should
+ * be fully redrawn, otherwise a fast paint can be performed. This argument
+ * could be removed if fast paint of scrolled wrapped alignment is coded in
+ * future (JAL-2609).
*
* @param results
+ * @param noFastPaint
* @return
*/
- public boolean highlightSearchResults(SearchResultsI results)
+ public boolean highlightSearchResults(SearchResultsI results,
+ boolean noFastPaint)
{
- updateViewport();
-
- /*
- * for now, don't attempt fastpaint if wrapped format
- */
- boolean wrapped = av.getWrapAlignment();
- if (wrapped)
+ if (fastpainting)
{
- // drawWrappedMappedPositions(results);
- // img = null;
- // av.setSearchResults(results);
- // repaint();
- // return;
+ return false;
}
-
- fastpainting = true;
- fastPaint = true;
+ boolean wrapped = av.getWrapAlignment();
try
{
+ fastPaint = !noFastPaint;
+ fastpainting = fastPaint;
+
+ updateViewport();
+
/*
* to avoid redrawing the whole visible region, we instead
* redraw just the minimal regions to remove previous highlights
@@ -1030,8 +1038,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
boolean drawn = false;
if (wrapped)
{
- redrawn = drawWrappedMappedPositions(previous);
- drawn = drawWrappedMappedPositions(results);
+ redrawn = drawMappedPositionsWrapped(previous);
+ drawn = drawMappedPositionsWrapped(results);
redrawn |= drawn;
}
else
@@ -1058,7 +1066,6 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
{
fastpainting = false;
}
-
}
/**
@@ -1157,44 +1164,64 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- if (!av.getWrapAlignment())
+ String eventName = evt.getPropertyName();
+
+ if (av.getWrapAlignment())
+ {
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ repaint();
+ }
+ }
+ else
{
- if (evt.getPropertyName().equals("startres")
- || evt.getPropertyName().equals("endres"))
+ int scrollX = 0;
+ if (eventName.equals(ViewportRanges.STARTRES))
{
// Make sure we're not trying to draw a panel
// larger than the visible window
ViewportRanges vpRanges = av.getRanges();
- int scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes();
+ if (scrollX > range)
{
- scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
+ scrollX = range;
}
- else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
+ else if (scrollX < -range)
{
- scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
+ scrollX = -range;
}
+ }
+
+ // 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))
+ {
+ // scroll - startres and endres both change
fastPaint(scrollX, 0);
}
- else if (evt.getPropertyName().equals("startseq")
- || evt.getPropertyName().equals("endseq"))
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
{
+ // scroll
fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
}
}
}
/**
- * Redraws any positions in the search results in the visible region. Any
- * highlights are drawn depending on the search results set on the Viewport,
- * not the results parameter. This allows this method to be called to either
- * clear highlighting (passing the previous search results), or set new
- * highlighting.
+ * Redraws any positions in the search results in the visible region of a
+ * wrapped alignment. Any highlights are drawn depending on the search results
+ * set on the Viewport, not the results
argument. This allows
+ * this method to be called either to clear highlights (passing the previous
+ * search results), or to draw new highlights.
*
* @param results
* @return
*/
- protected boolean drawWrappedMappedPositions(SearchResultsI results)
+ protected boolean drawMappedPositionsWrapped(SearchResultsI results)
{
if (results == null)
{
@@ -1202,15 +1229,22 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
}
boolean matchFound = false;
-
- /*
- * Viewport ranges are set for the 'row' of the wrapped alignment
- * the cursor is in, not the whole visible region; really we want
- * the latter; +-6 a temporary fudge for codons wrapping across lines
- */
+
+ int wrappedWidth = av.getWrappedWidth();
+ int wrappedHeight = getRepeatHeightWrapped();
+
ViewportRanges ranges = av.getRanges();
- int firstVisibleColumn = ranges.getStartRes() - 6;
- int lastVisibleColumn = ranges.getEndRes() + 6;
+ int canvasHeight = getHeight();
+ int repeats = canvasHeight / wrappedHeight;
+ if (canvasHeight / wrappedHeight > 0)
+ {
+ repeats++;
+ }
+
+ int firstVisibleColumn = ranges.getStartRes();
+ int lastVisibleColumn = ranges.getStartRes() + repeats
+ * ranges.getViewportWidth() - 1;
+
AlignmentI alignment = av.getAlignment();
if (av.hasHiddenColumns())
{
@@ -1219,17 +1253,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
lastVisibleColumn = alignment.getHiddenColumns()
.adjustForHiddenColumns(lastVisibleColumn);
}
-
- /*
- * find width of alignment in residues, and height of alignment,
- * so we can calculate where to render each matched position
- */
- int wrappedWidth = av.getWrappedWidth();
- int wrappedHeight = av.getAlignment().getHeight() * av.getCharHeight();
- int gapHeight = av.getCharHeight()
- * (av.getScaleAboveWrapped() ? 2 : 1);
- wrappedHeight += gapHeight;
- wrappedHeight += getAnnotationHeight();
+
+ int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
.getEndSeq(); seqNo++)
@@ -1279,7 +1304,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
* transY: offset from top edge of canvas to residue position
*/
int transY = gapHeight;
- transY += (displayColumn / wrappedWidth) * wrappedHeight;
+ transY += (displayColumn - ranges.getStartRes())
+ / wrappedWidth * wrappedHeight;
transY += (seqNo - ranges.getStartSeq()) * av.getCharHeight();
/*
@@ -1302,4 +1328,25 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
return matchFound;
}
+
+ /**
+ * 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;
+ }
}