From f89f3ea0068a1be259c1705277eecf1614484616 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 23 Jun 2017 13:13:02 +0100 Subject: [PATCH] JAL-1858 'fastPaint' of minimal region for highlights; todo: hidden columns --- src/jalview/gui/SeqCanvas.java | 140 +++++++++++++++++++++++++++++++--------- 1 file changed, 109 insertions(+), 31 deletions(-) diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index a74db48..ca1c64a 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -290,29 +290,29 @@ public class SeqCanvas extends JComponent implements ViewportListenerI imgHeight, -horizontal * charWidth, -vertical * charHeight); ViewportRanges ranges = av.getRanges(); - int sr = ranges.getStartRes(); - int er = ranges.getEndRes(); - int ss = ranges.getStartSeq(); - int es = ranges.getEndSeq(); + int startRes = ranges.getStartRes(); + int endRes = ranges.getEndRes(); + int startSeq = ranges.getStartSeq(); + int endSeq = ranges.getEndSeq(); int transX = 0; int transY = 0; if (horizontal > 0) // scrollbar pulled right, image to the left { - transX = (er - sr - horizontal) * charWidth; - sr = er - horizontal; + transX = (endRes - startRes - horizontal) * charWidth; + startRes = endRes - horizontal; } else if (horizontal < 0) { - er = sr - horizontal; + endRes = startRes - horizontal; } else if (vertical > 0) // scroll down { - ss = es - vertical; + startSeq = endSeq - vertical; - if (ss < ranges.getStartSeq()) + if (startSeq < ranges.getStartSeq()) { // ie scrolling too fast, more than a page at a time - ss = ranges.getStartSeq(); + startSeq = ranges.getStartSeq(); } else { @@ -321,32 +321,22 @@ public class SeqCanvas extends JComponent implements ViewportListenerI } else if (vertical < 0) { - es = ss - vertical; + endSeq = startSeq - vertical; - if (es > ranges.getEndSeq()) + if (endSeq > ranges.getEndSeq()) { - es = ranges.getEndSeq(); + endSeq = ranges.getEndSeq(); } } gg.translate(transX, transY); - drawPanel(gg, sr, er, ss, es, 0); + drawPanel(gg, startRes, endRes, startSeq, endSeq, 0); gg.translate(-transX, -transY); repaint(); fastpainting = false; } - /** - * Definitions of startx and endx (hopefully): SMJS This is what I'm working - * towards! startx is the first residue (starting at 0) to display. endx is - * the last residue to display (starting at 0). starty is the first sequence - * to display (starting at 0). endy is the last sequence to display (starting - * at 0). NOTE 1: The av limits are set in setFont in this class and in the - * adjustment listener in SeqPanel when the scrollbars move. - */ - - // Set this to false to force a full panel paint @Override public void paintComponent(Graphics g) { @@ -774,11 +764,13 @@ public class SeqCanvas extends JComponent implements ViewportListenerI + ((i - startSeq) * charHeight), false); } - // / Highlight search Results once all sequences have been drawn - // //////////////////////////////////////////////////////// + /* + * highlight search Results once sequence has been drawn + */ if (av.hasSearchResults()) { - int[] visibleResults = av.getSearchResults().getResults(nextSeq, + SearchResultsI searchResults = av.getSearchResults(); + int[] visibleResults = searchResults.getResults(nextSeq, startRes, endRes); if (visibleResults != null) { @@ -996,18 +988,104 @@ public class SeqCanvas extends JComponent implements ViewportListenerI } /** - * DOCUMENT ME! + * Highlights search results in the visible region by rendering as white text + * on a black background. Any previous highlighting is removed. * * @param results - * DOCUMENT ME! */ public void highlightSearchResults(SearchResultsI results) { - img = null; + updateViewport(); + fastpainting = true; + fastPaint = true; + + /* + * calculate the minimal rectangle to draw that includes + * both the new and any existing search results + */ + SearchResultsI previous = av.getSearchResults(); + int firstSeq = Integer.MAX_VALUE; + int lastSeq = -1; + int firstCol = Integer.MAX_VALUE; + int lastCol = -1; + boolean matchFound = false; + + ViewportRanges ranges = av.getRanges(); + for (int seqNo = ranges.getStartSeq(); seqNo <= ranges + .getEndSeq(); seqNo++) + { + SequenceI seq = av.getAlignment().getSequenceAt(seqNo); + if (previous != null) + { + /* + * find the bounding rectangle enclosing last search results + */ + int[] visibleResults = previous.getResults(seq, + ranges.getStartRes(), ranges.getEndRes()); + if (visibleResults != null) + { + int firstMatchedColumn = visibleResults[0]; + int lastMatchedColumn = visibleResults[visibleResults.length - 1]; + if (firstMatchedColumn <= ranges.getEndRes() + && lastMatchedColumn >= ranges.getStartRes()) + { + /* + * a previous 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, + ranges.getStartRes()); + lastMatchedColumn = Math.min(lastMatchedColumn, + ranges.getEndRes()); + firstCol = Math.min(firstCol, firstMatchedColumn); + lastCol = Math.max(lastCol, lastMatchedColumn); + } + } + } + + /* + * and repeat for the new search results + */ + int[] visibleResults = results.getResults(seq, ranges.getStartRes(), + ranges.getEndRes()); + if (visibleResults != null) + { + int firstMatchedColumn = visibleResults[0]; + int lastMatchedColumn = visibleResults[visibleResults.length - 1]; + if (firstMatchedColumn <= ranges.getEndRes() + && lastMatchedColumn >= ranges.getStartRes()) + { + matchFound = true; + firstSeq = Math.min(firstSeq, seqNo); + lastSeq = Math.max(lastSeq, seqNo); + firstMatchedColumn = Math.max(firstMatchedColumn, + ranges.getStartRes()); + lastMatchedColumn = Math.min(lastMatchedColumn, + ranges.getEndRes()); + firstCol = Math.min(firstCol, firstMatchedColumn); + lastCol = Math.max(lastCol, lastMatchedColumn); + } + } + } av.setSearchResults(results); - repaint(); + if (matchFound) + { + 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); + + repaint(); + } + + fastpainting = false; // todo in finally block? } @Override -- 1.7.10.2