JAL-2388 Unit tests and tidies
[jalview.git] / src / jalview / viewmodel / OverviewDimensions.java
index ed9a155..b34c85d 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.viewmodel;
 
-import jalview.api.AlignViewportI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenSequences;
 
@@ -39,10 +38,6 @@ public class OverviewDimensions
 
   private static final int MAX_SEQ_HEIGHT = 300;
 
-  private AlignViewportI av;
-
-  private ViewportPositionProps posProps;
-
   // width of the overview panel
   private int width;
 
@@ -65,30 +60,38 @@ public class OverviewDimensions
   // height of box
   private int boxHeight = -1;
 
+  // scroll position in viewport corresponding to boxX
   private int scrollCol = -1;
 
+  // scroll position in viewport corresponding to boxY
   private int scrollRow = -1;
 
-  public OverviewDimensions(AlignViewportI avi, boolean showAnnotationPanel)
+  /**
+   * Create an OverviewDimensions object
+   * 
+   * @param props
+   *          positional properties of the viewport
+   * @param showAnnotationPanel
+   *          true if the annotation panel is to be shown, false otherwise
+   */
+  public OverviewDimensions(ViewportPositionProps props,
+          boolean showAnnotationPanel)
   {
-    this.av = avi;
-    this.posProps = av.getPosProps();
-
     // scale the initial size of overviewpanel to shape of alignment
-    float initialScale = (float) posProps.getAlignmentWidthInCols()
-            / (float) posProps.getAlignmentHeightInRows();
+    float initialScale = (float) props.getAbsoluteAlignmentWidth()
+            / (float) props.getAbsoluteAlignmentHeight();
 
     if (!showAnnotationPanel)
     {
       graphHeight = 0;
     }
 
-    if (posProps.getAlignmentWidthInCols() > posProps
-            .getAlignmentHeightInRows())
+    if (props.getAbsoluteAlignmentWidth() > props
+            .getAbsoluteAlignmentHeight())
     {
       // wider
       width = MAX_WIDTH;
-      sequencesHeight = (int) (MAX_WIDTH / initialScale);
+      sequencesHeight = Math.round(MAX_WIDTH / initialScale);
       if (sequencesHeight < MIN_SEQ_HEIGHT)
       {
         sequencesHeight = MIN_SEQ_HEIGHT;
@@ -97,7 +100,7 @@ public class OverviewDimensions
     else
     {
       // taller
-      width = (int) (MAX_WIDTH * initialScale);
+      width = Math.round(MAX_WIDTH * initialScale);
       sequencesHeight = MAX_SEQ_HEIGHT;
 
       if (width < MIN_WIDTH)
@@ -109,32 +112,37 @@ public class OverviewDimensions
 
   /**
    * Check box dimensions and scroll positions and correct if necessary
+   * 
+   * @param mousex
+   *          x position in overview panel
+   * @param mousey
+   *          y position in overview panel
+   * @param hiddenSeqs
+   *          hidden sequences
+   * @param hiddenCols
+   *          hidden columns
+   * @param props
+   *          viewport position properties
    */
-  public void updateViewportFromMouse(int x, int y)
+  public void updateViewportFromMouse(int mousex, int mousey,
+          HiddenSequences hiddenSeqs, ColumnSelection hiddenCols,
+          ViewportPositionProps props)
   {
-    int alwidth = av.getAlignment().getWidth();
-    int alheight = av.getAlignment().getAbsoluteHeight();
+    int x = mousex;
+    int y = mousey;
 
-    HiddenSequences hiddenSeqs = av.getAlignment().getHiddenSequences();
-    ColumnSelection hiddenCols = av.getColumnSelection();
+    int alwidth = props.getAbsoluteAlignmentWidth();
+    int alheight = props.getAbsoluteAlignmentHeight();
 
     if (x < 0)
     {
       x = 0;
     }
-    else if (x >= alwidth)
-    {
-      x = alwidth - 1;
-    }
 
     if (y < 0)
     {
       y = 0;
     }
-    else if (y >= alheight)
-    {
-      y = alheight - 1;
-    }
 
     //
     // Convert x value to residue position
@@ -148,26 +156,30 @@ public class OverviewDimensions
     int xAsRes = Math.round((float) x * alwidth / width);
 
     // get viewport width in residues
-    int vpwidth = av.getPosProps().getEndRes()
-            - av.getPosProps().getStartRes() + 1;
+    int vpwidth = props.getEndRes() - props.getStartRes() + 1;
 
     // get where x should be when accounting for hidden cols
     // if x is in a hidden col region, shift to left - but we still need
     // absolute position
     // so convert back after getting visible region position
-    xAsRes = hiddenCols.adjustForHiddenColumns(hiddenCols
-            .findColumnPosition(xAsRes));
-
-    // get where end res should be by adding the viewport width on
-    int endRes = xAsRes + vpwidth;
+    int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
 
     // check in case we went off the edge of the alignment
-    if (endRes > alwidth)
+    int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
+    if (visXAsRes + vpwidth - 1 > visAlignWidth)
     {
       // went past the end of the alignment, adjust backwards
-      endRes = alwidth;
-      // recalc xAsRes backwards from endRes
-      xAsRes = endRes - vpwidth;
+
+      // if last position was before the end of the alignment, need to update
+      if ((scrollCol + vpwidth - 1) < visAlignWidth)
+      {
+        visXAsRes = hiddenCols.findColumnPosition(hiddenCols
+                .findColumnNToLeft(vpwidth - 1, alwidth - 1));
+      }
+      else
+      {
+        visXAsRes = scrollCol;
+      }
     }
 
     //
@@ -178,8 +190,8 @@ public class OverviewDimensions
     int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
 
     // get viewport height in sequences
-    int vpheight = av.getPosProps().getEndSeq()
-            - av.getPosProps().getStartSeq();
+    // add 1 because height includes both endSeq and startSeq
+    int vpheight = props.getEndSeq() - props.getStartSeq() + 1;
 
     // get where y should be when accounting for hidden rows
     // if y is in a hidden row region, shift up - but we still need absolute
@@ -188,46 +200,66 @@ public class OverviewDimensions
     yAsSeq = hiddenSeqs.adjustForHiddenSeqs(hiddenSeqs
             .findIndexWithoutHiddenSeqs(yAsSeq));
 
-    // get where end seq should be by adding the viewport height on
-    int endSeq = yAsSeq + vpheight;
-
     // check in case we went off the edge of the alignment
-    if (endSeq > alheight)
+    int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
+    int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
+    if (visYAsRes + vpheight - 1 > visAlignHeight)
     {
       // went past the end of the alignment, adjust backwards
-      endSeq = alheight;
-      // recalc yAsSeq backwards from endSeq
-      yAsSeq = endSeq - vpheight;
+      if ((scrollRow + vpheight - 1) < visAlignHeight)
+      {
+        visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs
+                .findIndexNAboveRow(vpheight - 1, alheight - 1));
+      }
+      else
+      {
+        visYAsRes = scrollRow;
+      }
     }
 
-    // convert absolute positions back to visible alignment positions for
-    // viewport scrolling
-    scrollCol = hiddenCols.findColumnPosition(xAsRes);
-    scrollRow = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
+    // update scroll values
+    scrollCol = visXAsRes;
+    scrollRow = visYAsRes;
+
   }
 
   /**
    * Update the overview panel box when the associated alignment panel is
    * changed
    * 
+   * @param hiddenSeqs
+   *          hidden sequences
+   * @param hiddenCols
+   *          hidden columns
+   * @param props
+   *          viewport position properties
    */
-  public void setBoxPosition()
+  public void setBoxPosition(HiddenSequences hiddenSeqs,
+          ColumnSelection hiddenCols, ViewportPositionProps props)
   {
-    int alwidth = av.getAlignment().getWidth();
-    int alheight = av.getAlignment().getAbsoluteHeight();
+    int alwidth = props.getAbsoluteAlignmentWidth();
+    int alheight = props.getAbsoluteAlignmentHeight();
 
-    int startRes = av.getPosProps().getAbsoluteStartRes();
-    int endRes = av.getPosProps().getAbsoluteEndRes();
+    // work with absolute values of startRes and endRes
+    int startRes = hiddenCols.adjustForHiddenColumns(props.getStartRes());
+    int endRes = hiddenCols.adjustForHiddenColumns(props.getEndRes());
 
-    int startSeq = av.getPosProps().getAbsoluteStartSeq();
-    int endSeq = av.getPosProps().getAbsoluteEndSeq();
+    // work with absolute values of startSeq and endSeq
+    int startSeq = hiddenSeqs.adjustForHiddenSeqs(props.getStartSeq());
+    int endSeq = hiddenSeqs.adjustForHiddenSeqs(props.getEndSeq());
 
+    // boxX, boxY is the x,y location equivalent to startRes, startSeq
     boxX = Math.round((float) startRes * width / alwidth);
     boxY = Math.round((float) startSeq * sequencesHeight / alheight);
 
+    // boxWidth is the width in residues translated to pixels
+    // since the box includes both the start and end residues, add 1 to the
+    // difference
     boxWidth = Math
             .round((float) (endRes - startRes + 1) * width / alwidth);
-    boxHeight = Math.round((float) (endSeq - startSeq) * sequencesHeight
+    // boxHeight is the height in sequences translated to pixels
+    boxHeight = Math.round((float) (endSeq - startSeq + 1)
+            * sequencesHeight
             / alheight);
   }
 
@@ -243,7 +275,6 @@ public class OverviewDimensions
     g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
   }
 
-  // don't like this, scroll vals are separate from setting code
   public int getScrollCol()
   {
     return scrollCol;
@@ -280,16 +311,6 @@ public class OverviewDimensions
     return boxHeight;
   }
 
-  public void setBoxX(int x)
-  {
-    boxX = x;
-  }
-
-  public void setBoxY(int y)
-  {
-    boxY = y;
-  }
-
   public void setWidth(int w)
   {
     width = w;