From c55e1fa5d2782cc46e515c11a91cf502f37386ab Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 23 Jun 2017 16:05:53 +0100 Subject: [PATCH] JAL-1858 handle hidden columns when computing region to redraw --- src/jalview/datamodel/SearchResults.java | 19 ++++--- src/jalview/datamodel/SearchResultsI.java | 7 +++ src/jalview/gui/SeqCanvas.java | 87 ++++++++++++++++------------- 3 files changed, 64 insertions(+), 49 deletions(-) diff --git a/src/jalview/datamodel/SearchResults.java b/src/jalview/datamodel/SearchResults.java index 8d98fc4..8ed47dc 100755 --- a/src/jalview/datamodel/SearchResults.java +++ b/src/jalview/datamodel/SearchResults.java @@ -34,7 +34,7 @@ import java.util.List; public class SearchResults implements SearchResultsI { - private List matches = new ArrayList(); + private List matches = new ArrayList<>(); /** * One match consists of a sequence reference, start and end positions. @@ -42,17 +42,17 @@ public class SearchResults implements SearchResultsI */ public class Match implements SearchResultMatchI { - SequenceI sequence; + final SequenceI sequence; /** * Start position of match in sequence (base 1) */ - int start; + final int start; /** * End position (inclusive) (base 1) */ - int end; + final int end; /** * create a Match on a range of sequence. Match always holds region in @@ -133,11 +133,6 @@ public class SearchResults implements SearchResultsI return sb.toString(); } - public void setSequence(SequenceI seq) - { - this.sequence = seq; - } - /** * Hashcode is the hashcode of the matched sequence plus a hash of start and * end positions. Match objects that pass the test for equals are guaranteed @@ -358,4 +353,10 @@ public class SearchResults implements SearchResultsI SearchResultsI sr = (SearchResultsI) obj; return matches.equals(sr.getResults()); } + + @Override + public void addSearchResults(SearchResultsI toAdd) + { + matches.addAll(toAdd.getResults()); + } } diff --git a/src/jalview/datamodel/SearchResultsI.java b/src/jalview/datamodel/SearchResultsI.java index 52a0467..c3dc0e8 100644 --- a/src/jalview/datamodel/SearchResultsI.java +++ b/src/jalview/datamodel/SearchResultsI.java @@ -44,6 +44,13 @@ public interface SearchResultsI SearchResultMatchI addResult(SequenceI seq, int start, int end); /** + * adds all match results in the argument to this set + * + * @param toAdd + */ + void addSearchResults(SearchResultsI toAdd); + + /** * Answers true if the search results include the given sequence (or its * dataset sequence), else false * diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index ca1c64a..7035142 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -22,6 +22,7 @@ package jalview.gui; import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; +import jalview.datamodel.SearchResults; import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -1000,10 +1001,25 @@ public class SeqCanvas extends JComponent implements ViewportListenerI fastPaint = true; /* - * calculate the minimal rectangle to draw that includes + * to avoid redrawing the whole visible region, we instead + * calculate the minimal redraw to remove previous highlights + * and add new ones; + * first make a temporary SearchResults that includes * both the new and any existing search results */ + SearchResultsI combined = results; SearchResultsI previous = av.getSearchResults(); + if (previous != null) + { + combined = new SearchResults(); + combined.addSearchResults(results); + combined.addSearchResults(previous); + } + + /* + * 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; @@ -1011,26 +1027,34 @@ public class SeqCanvas extends JComponent implements ViewportListenerI boolean matchFound = false; ViewportRanges ranges = av.getRanges(); + int firstVisibleColumn = ranges.getStartRes(); + int lastVisibleColumn = ranges.getEndRes(); + if (av.hasHiddenColumns()) + { + firstVisibleColumn = av.getAlignment().getHiddenColumns() + .adjustForHiddenColumns(firstVisibleColumn); + lastVisibleColumn = av.getAlignment().getHiddenColumns() + .adjustForHiddenColumns(lastVisibleColumn); + } + for (int seqNo = ranges.getStartSeq(); seqNo <= ranges .getEndSeq(); seqNo++) { SequenceI seq = av.getAlignment().getSequenceAt(seqNo); - if (previous != null) + + int[] visibleResults = combined.getResults(seq, firstVisibleColumn, + lastVisibleColumn); + if (visibleResults != null) { - /* - * find the bounding rectangle enclosing last search results - */ - int[] visibleResults = previous.getResults(seq, - ranges.getStartRes(), ranges.getEndRes()); - if (visibleResults != null) + for (int i = 0; i < visibleResults.length - 1; i += 2) { - int firstMatchedColumn = visibleResults[0]; - int lastMatchedColumn = visibleResults[visibleResults.length - 1]; - if (firstMatchedColumn <= ranges.getEndRes() - && lastMatchedColumn >= ranges.getStartRes()) + int firstMatchedColumn = visibleResults[i]; + int lastMatchedColumn = visibleResults[i + 1]; + if (firstMatchedColumn <= lastVisibleColumn + && lastMatchedColumn >= firstVisibleColumn) { /* - * a previous search results match in the visible region + * 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 */ @@ -1038,45 +1062,28 @@ public class SeqCanvas extends JComponent implements ViewportListenerI firstSeq = Math.min(firstSeq, seqNo); lastSeq = Math.max(lastSeq, seqNo); firstMatchedColumn = Math.max(firstMatchedColumn, - ranges.getStartRes()); + firstVisibleColumn); lastMatchedColumn = Math.min(lastMatchedColumn, - ranges.getEndRes()); + lastVisibleColumn); 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); if (matchFound) { - int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth(); + if (av.hasHiddenColumns()) + { + firstCol = av.getAlignment().getHiddenColumns() + .findColumnPosition(firstCol); + lastCol = av.getAlignment().getHiddenColumns() + .findColumnPosition(lastCol); + } + int transX = (firstCol - firstVisibleColumn) * av.getCharWidth(); int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight(); gg.translate(transX, transY); drawPanel(gg, firstCol, lastCol, firstSeq, lastSeq, 0); -- 1.7.10.2