From: Jim Procter Date: Tue, 5 Sep 2017 12:41:45 +0000 (+0100) Subject: Merge branch 'master' into portforward/JAL-2675_2102b1to2103 X-Git-Tag: Release_2_10_3b1~141 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=b5a209613f14ad6e75f43aa537a96484d847ce0a;p=jalview.git Merge branch 'master' into portforward/JAL-2675_2102b1to2103 update and resolve conflicts after 2.10.2b1 release Conflicts: src/jalview/gui/SeqCanvas.java --- b5a209613f14ad6e75f43aa537a96484d847ce0a diff --cc src/jalview/gui/SeqCanvas.java index d4b3e73,3d8b8aa..05cc6a9 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@@ -52,11 -53,9 +53,11 @@@ import javax.swing.JComponent */ public class SeqCanvas extends JComponent implements ViewportListenerI { + private static String ZEROS = "0000000000"; + final FeatureRenderer fr; - final SequenceRenderer sr; + final SequenceRenderer seqRdr; BufferedImage img; @@@ -977,188 -1246,66 +1270,217 @@@ inGroup = false; } + } + } - groupIndex++; + if (inGroup) + { + sy = verticalOffset + ((i - startSeq) * charHeight); + if (sx >= 0 && sx < visWidth) + { + g.drawLine(sx, oldY, sx, sy); + } - g.setStroke(new BasicStroke()); + if (sx + xwidth < visWidth) + { + g.drawLine(sx + xwidth, oldY, sx + xwidth, sy); + } - if (groupIndex >= av.getAlignment().getGroups().size()) - { - break; - } + if (sx < 0) + { + xwidth += sx; + sx = 0; + } - group = av.getAlignment().getGroups().get(groupIndex); + if (sx + xwidth > visWidth) + { + xwidth = visWidth; + } + else if (sx + xwidth >= (endRes - startRes + 1) * charWidth) + { + xwidth = (endRes - startRes + 1) * charWidth; + } - } while (groupIndex < av.getAlignment().getGroups().size()); + if (top != -1) + { + g.drawLine(sx, top, sx + xwidth, top); + top = -1; + } - } + if (bottom != -1) + { + g.drawLine(sx, bottom - 1, sx + xwidth, bottom - 1); + bottom = -1; + } + inGroup = false; + } } - + /** - * DOCUMENT ME! + * Highlights search results in the visible region by rendering as white text + * 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 - * DOCUMENT ME! + * @param noFastPaint + * @return */ - public void highlightSearchResults(SearchResultsI results) + public boolean highlightSearchResults(SearchResultsI results, + boolean noFastPaint) { - img = null; + if (fastpainting) + { + return false; + } + 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 + * and add new ones + */ + SearchResultsI previous = av.getSearchResults(); + av.setSearchResults(results); + boolean redrawn = false; + boolean drawn = false; + if (wrapped) + { + redrawn = drawMappedPositionsWrapped(previous); + drawn = drawMappedPositionsWrapped(results); + redrawn |= drawn; + } + else + { + redrawn = drawMappedPositions(previous); + drawn = drawMappedPositions(results); + redrawn |= drawn; + } - av.setSearchResults(results); + /* + * if highlights were either removed or added, repaint + */ + if (redrawn) + { + repaint(); + } - repaint(); + /* + * return true only if highlights were added + */ + return drawn; + + } finally + { + fastpainting = false; + } + } + + /** + * Redraws the minimal rectangle in the visible region (if any) that includes + * mapped positions of the given search results. Whether or not positions are + * highlighted depends on the SearchResults set on the Viewport. This allows + * this method to be called to either clear or set highlighting. Answers true + * if any positions were drawn (in which case a repaint is still required), + * else false. + * + * @param results + * @return + */ + protected boolean drawMappedPositions(SearchResultsI results) + { + if (results == null) + { + return false; + } + + /* + * calculate the minimal rectangle to redraw that + * includes both new and existing search results + */ + int firstSeq = Integer.MAX_VALUE; + int lastSeq = -1; + int firstCol = Integer.MAX_VALUE; + int lastCol = -1; + boolean matchFound = false; + + ViewportRanges ranges = av.getRanges(); + int firstVisibleColumn = ranges.getStartRes(); + int lastVisibleColumn = ranges.getEndRes(); + AlignmentI alignment = av.getAlignment(); + if (av.hasHiddenColumns()) + { + firstVisibleColumn = alignment.getHiddenColumns() + .adjustForHiddenColumns(firstVisibleColumn); + lastVisibleColumn = alignment.getHiddenColumns() + .adjustForHiddenColumns(lastVisibleColumn); + } + + for (int seqNo = ranges.getStartSeq(); seqNo <= ranges + .getEndSeq(); seqNo++) + { + SequenceI seq = alignment.getSequenceAt(seqNo); + + int[] visibleResults = results.getResults(seq, firstVisibleColumn, + lastVisibleColumn); + if (visibleResults != null) + { + for (int i = 0; i < visibleResults.length - 1; i += 2) + { + int firstMatchedColumn = visibleResults[i]; + int lastMatchedColumn = visibleResults[i + 1]; + if (firstMatchedColumn <= lastVisibleColumn + && lastMatchedColumn >= firstVisibleColumn) + { + /* + * found a search results match in the visible region - + * remember the first and last sequence matched, and the first + * and last visible columns in the matched positions + */ + matchFound = true; + firstSeq = Math.min(firstSeq, seqNo); + lastSeq = Math.max(lastSeq, seqNo); + firstMatchedColumn = Math.max(firstMatchedColumn, + firstVisibleColumn); + lastMatchedColumn = Math.min(lastMatchedColumn, + lastVisibleColumn); + firstCol = Math.min(firstCol, firstMatchedColumn); + lastCol = Math.max(lastCol, lastMatchedColumn); + } + } + } + } + + if (matchFound) + { + if (av.hasHiddenColumns()) + { + firstCol = alignment.getHiddenColumns() + .findColumnPosition(firstCol); + lastCol = alignment.getHiddenColumns().findColumnPosition(lastCol); + } + int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth(); + int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight(); + gg.translate(transX, transY); + drawPanel(gg, firstCol, lastCol, firstSeq, lastSeq, 0); + gg.translate(-transX, -transY); + } + + return matchFound; } @Override