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