JAL-2491 Make it work with cursor movement
[jalview.git] / src / jalview / viewmodel / ViewportRanges.java
index 72155aa..ebacab1 100644 (file)
  */
 package jalview.viewmodel;
 
+import jalview.api.AlignViewportI;
 import jalview.datamodel.AlignmentI;
 
 /**
- * Embryonic class which: Supplies and updates viewport properties relating to
- * position such as: start and end residues and sequences; ideally will serve
- * hidden columns/rows too. Intention also to support calculations for
- * positioning, scrolling etc. such as finding the middle of the viewport,
+ * Slightly less embryonic class which: Supplies and updates viewport properties
+ * relating to position such as: start and end residues and sequences; ideally
+ * will serve hidden columns/rows too. Intention also to support calculations
+ * for positioning, scrolling etc. such as finding the middle of the viewport,
  * checking for scrolls off screen
  */
 public class ViewportRanges extends ViewportProperties
@@ -90,30 +91,42 @@ public class ViewportRanges extends ViewportProperties
     setStartEndRes(res, res + width - 1);
   }
 
-  public void setStartEndRes(int startres, int endres)
+  /**
+   * Set start and end residues at the same time. This method only fires one
+   * event for the two changes, and should be used in preference to separate
+   * calls to setStartRes and setEndRes.
+   * 
+   * @param start
+   *          the start residue
+   * @param end
+   *          the end residue
+   */
+  public void setStartEndRes(int start, int end)
   {
     int oldres = this.startRes;
-    if (startres > al.getWidth() - 1)
+    if (start > al.getWidth() - 1)
     {
-      startres = al.getWidth() - 1;
+      startRes = al.getWidth() - 1;
     }
-    else if (startres < 0)
+    else if (start < 0)
     {
-      startres = 0;
+      startRes = 0;
+    }
+    else
+    {
+      startRes = start;
     }
-    this.startRes = startres;
 
-    if (endres >= al.getWidth())
+    if (end < 0)
     {
-      endres = al.getWidth() - 1;
+      endRes = 0;
     }
-    else if (endres < 0)
+    else
     {
-      endres = 0;
+      endRes = end;
     }
-    this.endRes = endres;
 
-    changeSupport.firePropertyChange("startres", oldres, startres);
+    changeSupport.firePropertyChange("startres", oldres, start);
   }
 
   /**
@@ -140,29 +153,46 @@ public class ViewportRanges extends ViewportProperties
     setStartEndSeq(seq, seq + height - 1);
   }
 
-  public void setStartEndSeq(int startseq, int endseq)
+  /**
+   * Set start and end sequences at the same time. This method only fires one
+   * event for the two changes, and should be used in preference to separate
+   * calls to setStartSeq and setEndSeq.
+   * 
+   * @param start
+   *          the start sequence
+   * @param end
+   *          the end sequence
+   */
+  public void setStartEndSeq(int start, int end)
   {
     int oldseq = this.startSeq;
-    if (startseq > al.getHeight() - 1)
+    if (start > al.getHeight() - 1)
+    {
+      startSeq = al.getHeight() - 1;
+    }
+    else if (start < 0)
     {
-      startseq = al.getHeight() - 1;
+      startSeq = 0;
     }
-    else if (startseq < 0)
+    else
     {
-      startseq = 0;
+      startSeq = start;
     }
-    this.startSeq = startseq;
 
-    if (endseq >= al.getHeight())
+    if (end >= al.getHeight())
     {
-      endseq = al.getHeight() - 1;
+      endSeq = al.getHeight() - 1;
     }
-    else if (endseq < 0)
+    else if (end < 0)
     {
-      endseq = 0;
+      endSeq = 0;
     }
-    this.endSeq = endseq;
-    changeSupport.firePropertyChange("startseq", oldseq, startseq);
+    else
+    {
+      endSeq = end;
+    }
+
+    changeSupport.firePropertyChange("startseq", oldseq, start);
   }
 
   /**
@@ -210,13 +240,67 @@ public class ViewportRanges extends ViewportProperties
   }
 
   /**
+   * Set viewport width in residues, without changing startRes. Use in
+   * preference to calculating endRes from the width, to avoid out by one
+   * errors!
+   * 
+   * @param w
+   *          width in residues
+   */
+  public void setViewportWidth(int w)
+  {
+    setStartEndRes(startRes, startRes + w - 1);
+  }
+
+  /**
+   * Set viewport height in residues, without changing startSeq. Use in
+   * preference to calculating endSeq from the height, to avoid out by one
+   * errors!
+   * 
+   * @param h
+   *          height in sequences
+   */
+  public void setViewportHeight(int h)
+  {
+    setStartEndSeq(startSeq, startSeq + h - 1);
+  }
+
+  /**
+   * Set viewport horizontal start position and width. Use in preference to
+   * calculating endRes from the width, to avoid out by one errors!
+   * 
+   * @param start
+   *          start residue
+   * @param w
+   *          width in residues
+   */
+  public void setViewportStartAndWidth(int start, int w)
+  {
+    setStartEndRes(start, start + w - 1);
+  }
+
+  /**
+   * Set viewport vertical start position and height. Use in preference to
+   * calculating endSeq from the height, to avoid out by one errors!
+   * 
+   * @param start
+   *          start sequence
+   * @param h
+   *          height in sequences
+   */
+  public void setViewportStartAndHeight(int start, int h)
+  {
+    setStartEndSeq(start, start + h - 1);
+  }
+
+  /**
    * Get width of viewport in residues
    * 
    * @return width of viewport
    */
   public int getViewportWidth()
   {
-    return (endRes - startRes + 1); // TODO get for wrapped alignments too
+    return (endRes - startRes + 1);
   }
 
   /**
@@ -229,7 +313,14 @@ public class ViewportRanges extends ViewportProperties
     return (endSeq - startSeq + 1);
   }
 
-  // return value is true if the scroll is valid
+  /**
+   * Scroll the viewport range vertically
+   * 
+   * @param up
+   *          true if scrolling up, false if down
+   * 
+   * @return true if the scroll is valid
+   */
   public boolean scrollUp(boolean up)
   {
     if (up)
@@ -254,12 +345,12 @@ public class ViewportRanges extends ViewportProperties
   }
 
   /**
-   * DOCUMENT ME!
+   * Scroll the viewport range horizontally
    * 
    * @param right
-   *          DOCUMENT ME!
+   *          true if scrolling right, false if left
    * 
-   * @return DOCUMENT ME!
+   * @return true if the scroll is valid
    */
   public boolean scrollRight(boolean right)
   {
@@ -285,13 +376,56 @@ public class ViewportRanges extends ViewportProperties
     return true;
   }
 
+  /**
+   * Scroll a wrapped alignment so that the specified residue is visible
+   * 
+   * @param res
+   *          residue position to scroll to
+   */
   public void scrollToWrappedVisible(int res)
   {
-    if (res < startRes || res > endRes)
+    // get the start residue of the wrapped row which res is in
+    // and set that as our start residue
+    int width = getViewportWidth();
+    setStartRes((res / width) * width);
+  }
+
+  /**
+   * Scroll so that (x,y) is visible
+   * 
+   * @param x
+   *          x position in alignment
+   * @param y
+   *          y position in alignment
+   * @param av
+   *          viewport to be visible in. Here until hidden columns JAL-2388
+   *          merged, then use alignment to get hidden cols
+   */
+  public void scrollToVisible(int x, int y, AlignViewportI av)
+  {
+    while (y < startSeq)
+    {
+      scrollUp(true);
+    }
+    while (y > endSeq)
     {
-      setEndSeq(res / getViewportWidth());
+      scrollUp(false);
     }
 
+    while (x < av.getColumnSelection().adjustForHiddenColumns(startRes))
+    {
+      if (!scrollRight(false))
+      {
+        break;
+      }
+    }
+    while (x > av.getColumnSelection().adjustForHiddenColumns(endRes))
+    {
+      if (!scrollRight(true))
+      {
+        break;
+      }
+    }
   }
 
 }