JAL-1858 don't fastpaint highlights if wrapped format
[jalview.git] / src / jalview / gui / SeqCanvas.java
index ca1c64a..858b8c8 100755 (executable)
@@ -996,14 +996,63 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
   public void highlightSearchResults(SearchResultsI results)
   {
     updateViewport();
+
+    /*
+     * for now, don't attempt fastpaint if wrapped format
+     */
+    if (av.getWrapAlignment())
+    {
+      av.setSearchResults(results);
+      repaint();
+      return;
+    }
+    
     fastpainting = true;
     fastPaint = true;
 
+    try
+    {
+      /*
+       * 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 = drawMappedPositions(previous);
+      redrawn |= drawMappedPositions(results);
+      if (redrawn)
+      {
+        repaint();
+      }
+    } 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 draw that includes 
-     * both the new and any existing search results
+     * calculate the minimal rectangle to redraw that 
+     * includes both new and existing search results
      */
-    SearchResultsI previous = av.getSearchResults();
     int firstSeq = Integer.MAX_VALUE;
     int lastSeq = -1;
     int firstCol = Integer.MAX_VALUE;
@@ -1011,26 +1060,35 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
     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 = av.getAlignment().getSequenceAt(seqNo);
-      if (previous != null)
+      SequenceI seq = alignment.getSequenceAt(seqNo);
+
+      int[] visibleResults = results.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,54 +1096,32 @@ 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)
     {
+      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);
-
-      repaint();
     }
 
-    fastpainting = false; // todo in finally block?
+    return matchFound;
   }
 
   @Override