JAL-1858 handle hidden columns when computing region to redraw
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 23 Jun 2017 15:05:53 +0000 (16:05 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 23 Jun 2017 15:05:53 +0000 (16:05 +0100)
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/SearchResultsI.java
src/jalview/gui/SeqCanvas.java

index 8d98fc4..8ed47dc 100755 (executable)
@@ -34,7 +34,7 @@ import java.util.List;
 public class SearchResults implements SearchResultsI
 {
 
-  private List<SearchResultMatchI> matches = new ArrayList<SearchResultMatchI>();
+  private List<SearchResultMatchI> 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());
+  }
 }
index 52a0467..c3dc0e8 100644 (file)
@@ -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
    * 
index ca1c64a..7035142 100755 (executable)
@@ -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);