JAL-1858 handle hidden columns when computing region to redraw
[jalview.git] / src / jalview / gui / SeqCanvas.java
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);