JAL-1858 fast paint wrapped highlights unless view was scrolled
[jalview.git] / src / jalview / gui / AlignmentPanel.java
index 3994c29..027dd0f 100644 (file)
@@ -343,19 +343,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   public void highlightSearchResults(SearchResultsI results)
   {
-    scrollToPosition(results);
-    getSeqPanel().seqCanvas.highlightSearchResults(results);
-  }
+    boolean scrolled = scrollToPosition(results, 0, true, false);
 
-  /**
-   * Scroll the view to show the position of the highlighted region in results
-   * (if any) and redraw the overview
-   * 
-   * @param results
-   */
-  public boolean scrollToPosition(SearchResultsI results)
-  {
-    return scrollToPosition(results, 0, true, false);
+    boolean noFastPaint = scrolled && av.getWrapAlignment();
+
+    getSeqPanel().seqCanvas.highlightSearchResults(results, noFastPaint);
   }
 
   /**
@@ -373,8 +365,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
   }
 
   /**
-   * Scroll the view to show the position of the highlighted region in results
-   * (if any)
+   * Scrolls the view (if necessary) to show the position of the first
+   * highlighted region in results (if any). Answers true if the view was
+   * scrolled, or false if no matched region was found, or it is already
+   * visible.
    * 
    * @param results
    * @param verticalOffset
@@ -384,116 +378,117 @@ public class AlignmentPanel extends GAlignmentPanel implements
    *          - when set, the overview will be recalculated (takes longer)
    * @param centre
    *          if true, try to centre the search results horizontally in the view
-   * @return false if results were not found
+   * @return
    */
-  public boolean scrollToPosition(SearchResultsI results,
+  protected boolean scrollToPosition(SearchResultsI results,
           int verticalOffset, boolean redrawOverview, boolean centre)
   {
     int startv, endv, starts, ends;
-    // TODO: properly locate search results in view when large numbers of hidden
-    // columns exist before highlighted region
-    // do we need to scroll the panel?
-    // TODO: tons of nullpointerexceptions raised here.
-    if (results != null && results.getSize() > 0 && av != null
-            && av.getAlignment() != null)
-    {
-      int seqIndex = av.getAlignment().findIndex(results);
-      if (seqIndex == -1)
-      {
-        return false;
-      }
-      SequenceI seq = av.getAlignment().getSequenceAt(seqIndex);
 
-      int[] r = results.getResults(seq, 0, av.getAlignment().getWidth());
-      if (r == null)
-      {
-        return false;
-      }
-      int start = r[0];
-      int end = r[1];
+    if (results == null || results.isEmpty() || av == null
+            || av.getAlignment() == null)
+    {
+      return false;
+    }
+    int seqIndex = av.getAlignment().findIndex(results);
+    if (seqIndex == -1)
+    {
+      return false;
+    }
+    SequenceI seq = av.getAlignment().getSequenceAt(seqIndex);
 
-      /*
-       * To centre results, scroll to positions half the visible width
-       * left/right of the start/end positions
-       */
-      if (centre)
-      {
-        int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2
-                - 1;
-        start = Math.max(start - offset, 0);
-        end = end + offset - 1;
-      }
-      if (start < 0)
-      {
-        return false;
-      }
-      if (end == seq.getEnd())
-      {
-        return false;
-      }
-      if (av.hasHiddenColumns())
+    int[] r = results.getResults(seq, 0, av.getAlignment().getWidth());
+    if (r == null)
+    {
+      return false;
+    }
+    int start = r[0];
+    int end = r[1];
+
+    /*
+     * To centre results, scroll to positions half the visible width
+     * left/right of the start/end positions
+     */
+    if (centre)
+    {
+      int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2 - 1;
+      start = Math.max(start - offset, 0);
+      end = end + offset - 1;
+    }
+    if (start < 0)
+    {
+      return false;
+    }
+    if (end == seq.getEnd())
+    {
+      return false;
+    }
+
+    if (av.hasHiddenColumns())
+    {
+      HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+      start = hidden.findColumnPosition(start);
+      end = hidden.findColumnPosition(end);
+      if (start == end)
       {
-        HiddenColumns hidden = av.getAlignment().getHiddenColumns();
-        start = hidden.findColumnPosition(start);
-        end = hidden.findColumnPosition(end);
-        if (start == end)
+        if (!hidden.isVisible(r[0]))
         {
-          if (!hidden.isVisible(r[0]))
-          {
-            // don't scroll - position isn't visible
-            return false;
-          }
+          // don't scroll - position isn't visible
+          return false;
         }
       }
+    }
 
-      /*
-       * allow for offset of target sequence (actually scroll to one above it)
-       */
-      seqIndex = Math.max(0, seqIndex - verticalOffset);
+    /*
+     * allow for offset of target sequence (actually scroll to one above it)
+     */
+    seqIndex = Math.max(0, seqIndex - verticalOffset);
+    boolean scrollNeeded = true;
 
-      if (!av.getWrapAlignment())
+    if (!av.getWrapAlignment())
+    {
+      if ((startv = vpRanges.getStartRes()) >= start)
       {
-        if ((startv = vpRanges.getStartRes()) >= start)
-        {
-          /*
-           * Scroll left to make start of search results visible
-           */
-          setScrollValues(start, seqIndex);
-        }
-        else if ((endv = vpRanges.getEndRes()) <= end)
-        {
-          /*
-           * Scroll right to make end of search results visible
-           */
-          setScrollValues(startv + end - endv, seqIndex);
-        }
-        else if ((starts = vpRanges.getStartSeq()) > seqIndex)
-        {
-          /*
-           * Scroll up to make start of search results visible
-           */
-          setScrollValues(vpRanges.getStartRes(), seqIndex);
-        }
-        else if ((ends = vpRanges.getEndSeq()) <= seqIndex)
-        {
-          /*
-           * Scroll down to make end of search results visible
-           */
-          setScrollValues(vpRanges.getStartRes(), starts + seqIndex - ends
-                  + 1);
-        }
         /*
-         * Else results are already visible - no need to scroll
+         * Scroll left to make start of search results visible
          */
+        setScrollValues(start, seqIndex);
       }
-      else
+      else if ((endv = vpRanges.getEndRes()) <= end)
       {
-        vpRanges.scrollToWrappedVisible(start);
+        /*
+         * Scroll right to make end of search results visible
+         */
+        setScrollValues(startv + end - endv, seqIndex);
+      }
+      else if ((starts = vpRanges.getStartSeq()) > seqIndex)
+      {
+        /*
+         * Scroll up to make start of search results visible
+         */
+        setScrollValues(vpRanges.getStartRes(), seqIndex);
       }
+      else if ((ends = vpRanges.getEndSeq()) <= seqIndex)
+      {
+        /*
+         * Scroll down to make end of search results visible
+         */
+        setScrollValues(vpRanges.getStartRes(), starts + seqIndex - ends
+                + 1);
+      }
+      /*
+       * Else results are already visible - no need to scroll
+       */
+      scrollNeeded = false;
+    }
+    else
+    {
+      scrollNeeded = vpRanges.scrollToWrappedVisible(start);
     }
 
     paintAlignment(redrawOverview);
-    return true;
+
+    return scrollNeeded;
   }
 
   /**
@@ -1815,7 +1810,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @param verticalOffset
    *          the number of visible sequences to show above the mapped region
    */
-  public void scrollToCentre(SearchResultsI sr, int verticalOffset)
+  protected void scrollToCentre(SearchResultsI sr, int verticalOffset)
   {
     /*
      * To avoid jumpy vertical scrolling (if some sequences are gapped or not