Merge branch 'develop' into merged_2_11_2_0_to_2_12
[jalview.git] / src / jalview / viewmodel / OverviewDimensionsShowHidden.java
index 4ab27de..b4fa934 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.viewmodel;
 
+import java.awt.Dimension;
+
 import jalview.api.AlignmentColsCollectionI;
 import jalview.api.AlignmentRowsCollectionI;
 import jalview.datamodel.AlignmentI;
@@ -32,6 +34,24 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
 {
   private ViewportRanges ranges;
 
+  private int xdiff; // when dragging, difference in alignment units between
+                     // start residue and original mouse click position
+
+  private int ydiff; // when dragging, difference in alignment units between
+                     // start sequence and original mouse click position
+
+  
+  /**
+   * for testng only
+   * 
+   * @param vpranges
+   * @param showAnnotationPanel
+   */  
+  @Deprecated
+  public OverviewDimensionsShowHidden(ViewportRanges vpranges, boolean showAnnotationPanel) {
+    this(vpranges, showAnnotationPanel, null);
+  }
+
   /**
    * Create an OverviewDimensions object
    * 
@@ -41,9 +61,9 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
    *          true if the annotation panel is to be shown, false otherwise
    */
   public OverviewDimensionsShowHidden(ViewportRanges vpranges,
-          boolean showAnnotationPanel)
+          boolean showAnnotationPanel, Dimension dim)
   {
-    super(vpranges, showAnnotationPanel);
+    super(vpranges, showAnnotationPanel, dim);
     ranges = vpranges;
     resetAlignmentDims();
   }
@@ -66,165 +86,78 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
   public void updateViewportFromMouse(int mousex, int mousey,
           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
   {
+    resetAlignmentDims();
+
+    // convert mousex and mousey to alignment units as well as
+    // translating to top left corner of viewport - this is an absolute position
     int xAsRes = getLeftXFromCentreX(mousex, hiddenCols);
     int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs);
 
-    updateViewportFromTopLeft(xAsRes, yAsSeq, hiddenSeqs, hiddenCols);
+    // convert to visible positions
+    int visXAsRes = hiddenCols.absoluteToVisibleColumn(xAsRes);
+    yAsSeq = hiddenSeqs.adjustForHiddenSeqs(
+            hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq));
+    yAsSeq = Math.max(yAsSeq, 0); // -1 if before first visible sequence
+    int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
+    visYAsSeq = Math.max(visYAsSeq, 0); // -1 if before first visible sequence
+
+    // update viewport accordingly
+    updateViewportFromTopLeft(visXAsRes, visYAsSeq, hiddenSeqs, hiddenCols);
   }
 
   @Override
   public void adjustViewportFromMouse(int mousex, int mousey,
           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
   {
+    resetAlignmentDims();
+
     // calculate translation in pixel terms:
     // get mouse location in viewport coords, add translation in viewport
     // coords,
     // convert back to pixel coords
     int vpx = Math.round((float) mousex * alwidth / width);
-    // int visXAsRes = hiddenCols.findColumnPosition(vpx);
-
-    int vpy = Math.round((float) mousey * alheight / sequencesHeight);
-    // int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
-
-    System.out.println("vpx: " + vpx);
-    // System.out.println("VisXAsRes: " + visXAsRes);
-    System.out.println("transX: " + transX);
-    // updateViewportFromTopLeft(vpx + transX, vpy + transY,
-    // hiddenSeqs,
-    // hiddenCols);
-
-    int xAsRes = vpx + transX;
-    int yAsSeq = vpy + transY;
-
-    resetAlignmentDims();
-
-    if (xAsRes < 0)
-    {
-      xAsRes = 0;
-    }
-
-    if (yAsSeq < 0)
-    {
-      yAsSeq = 0;
-    }
-
-    //
-    // Convert x value to residue position
-    //
-
-    // need to determine where scrollCol should be, given x
-    // to do this also need to know width of viewport, and some hidden column
-    // correction
-
-    // convert x to residues - this is an absolute position
-    // int xAsRes = Math.round((float) x * alwidth / width);
-
-    // get viewport width in residues
-    int vpwidth = ranges.getViewportWidth();
-
-    // 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
-    // int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
-    int visXAsRes = xAsRes;
-
-    // check in case we went off the edge of the alignment
-    int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
-    /*    if (visXAsRes + vpwidth - 1 > visAlignWidth)
-    {
-      // went past the end of the alignment, adjust backwards
-    
-      // if last position was before the end of the alignment, need to update
-      if (ranges.getEndRes() < visAlignWidth)
-      {
-        visXAsRes = hiddenCols.findColumnPosition(hiddenCols
-                .subtractVisibleColumns(vpwidth - 1, alwidth - 1));
-      }
-      else
-      {
-        visXAsRes = ranges.getStartRes();
-      }
-    }*/
-
-    //
-    // Convert y value to sequence position
-    //
-
-    // convert y to residues
-    // int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
-
-    // get viewport height in sequences
-    int vpheight = ranges.getViewportHeight();
+    int visXAsRes = hiddenCols.absoluteToVisibleColumn(vpx) + xdiff;
 
-    // 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
-    // position,
-    // so convert back after getting visible region position
-    yAsSeq = hiddenSeqs.adjustForHiddenSeqs(
-            hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq));
+    int vpy = Math.round(mousey * heightRatio);
+    int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy) + ydiff;
 
-    // check in case we went off the edge of the alignment
-    int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
-    int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
-    if (visYAsSeq + vpheight - 1 > visAlignHeight)
-    {
-      // went past the end of the alignment, adjust backwards
-      if (ranges.getEndSeq() < visAlignHeight)
-      {
-        visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(
-                hiddenSeqs.subtractVisibleRows(vpheight - 1, alheight - 1));
-      }
-      else
-      {
-        visYAsSeq = ranges.getStartSeq();
-      }
-    }
-
-    // update viewport
-    ranges.setStartRes(visXAsRes);
-    ranges.setStartSeq(visYAsSeq);
+    // update viewport accordingly
+    updateViewportFromTopLeft(visXAsRes, visYAsRes, hiddenSeqs, hiddenCols);
   }
 
+  /**
+   * {@inheritDoc} Callers should have already called resetAlignmentDims to
+   * refresh alwidth, alheight and width/height ratios
+   */
   @Override
-  protected void updateViewportFromTopLeft(int xAsRes, int yAsSeq,
+  protected void updateViewportFromTopLeft(int leftx, int topy,
           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
   {
+    int visXAsRes = leftx;
+    int visYAsSeq = topy;
 
-    resetAlignmentDims();
-
-    if (xAsRes < 0)
+    if (visXAsRes < 0)
     {
-      xAsRes = 0;
+      visXAsRes = 0;
     }
 
-    if (yAsSeq < 0)
+    if (visYAsSeq < 0)
     {
-      yAsSeq = 0;
+      visYAsSeq = 0;
     }
 
-    //
-    // Convert x value to residue position
-    //
-
-    // need to determine where scrollCol should be, given x
-    // to do this also need to know width of viewport, and some hidden column
-    // correction
+    if (ranges.isWrappedMode())
+    {
+      visYAsSeq = 0; // sorry, no vertical scroll when wrapped
+    }
 
-    // convert x to residues - this is an absolute position
-    // int xAsRes = Math.round((float) x * alwidth / width);
+    // Determine where scrollCol should be, given visXAsRes
 
     // get viewport width in residues
     int vpwidth = ranges.getViewportWidth();
 
-    // 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
-    int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
-
     // check in case we went off the edge of the alignment
-    int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
+    int visAlignWidth = hiddenCols.absoluteToVisibleColumn(alwidth - 1);
     if (visXAsRes + vpwidth - 1 > visAlignWidth)
     {
       // went past the end of the alignment, adjust backwards
@@ -232,8 +165,8 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
       // if last position was before the end of the alignment, need to update
       if (ranges.getEndRes() < visAlignWidth)
       {
-        visXAsRes = hiddenCols.findColumnPosition(hiddenCols
-                .subtractVisibleColumns(vpwidth - 1, alwidth - 1));
+        visXAsRes = hiddenCols.absoluteToVisibleColumn(hiddenCols
+                .offsetByVisibleColumns(-(vpwidth - 1), alwidth - 1));
       }
       else
       {
@@ -241,33 +174,21 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
       }
     }
 
-    //
-    // Convert y value to sequence position
-    //
-
-    // convert y to residues
-    // int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
+    // Determine where scrollRow should be, given visYAsSeq
 
     // get viewport height in sequences
     int vpheight = ranges.getViewportHeight();
 
-    // 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
-    // position,
-    // so convert back after getting visible region position
-    yAsSeq = hiddenSeqs.adjustForHiddenSeqs(hiddenSeqs
-            .findIndexWithoutHiddenSeqs(yAsSeq));
-
     // check in case we went off the edge of the alignment
     int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
-    int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
+
     if (visYAsSeq + vpheight - 1 > visAlignHeight)
     {
       // went past the end of the alignment, adjust backwards
       if (ranges.getEndSeq() < visAlignHeight)
       {
-        visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs
-                .subtractVisibleRows(vpheight - 1, alheight - 1));
+        visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(
+                hiddenSeqs.subtractVisibleRows(vpheight - 1, alheight - 1));
       }
       else
       {
@@ -276,9 +197,7 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
     }
 
     // update viewport
-    ranges.setStartRes(visXAsRes);
-    ranges.setStartSeq(visYAsSeq);
-
+    ranges.setStartResAndSeq(visXAsRes, visYAsSeq);
   }
 
   /**
@@ -296,31 +215,29 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
   public void setBoxPosition(HiddenSequences hiddenSeqs,
           HiddenColumns hiddenCols)
   {
-
     // work with absolute values of startRes and endRes
-    int startRes = hiddenCols.adjustForHiddenColumns(ranges.getStartRes());
-    int endRes = hiddenCols.adjustForHiddenColumns(ranges.getEndRes());
+    int startRes = hiddenCols.visibleToAbsoluteColumn(ranges.getStartRes());
+    int endRes = hiddenCols.visibleToAbsoluteColumn(ranges.getEndRes());
 
     // work with absolute values of startSeq and endSeq
     int startSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getStartSeq());
     int endSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getEndSeq());
 
-    setBoxPosition(startRes, startSeq, endRes - startRes + 1, endSeq
-            - startSeq + 1);
+    setBoxPosition(startRes, startSeq, endRes - startRes + 1,
+            endSeq - startSeq + 1);
   }
 
   @Override
   public AlignmentColsCollectionI getColumns(AlignmentI al)
   {
-    return new AllColsCollection(0,
-            ranges.getAbsoluteAlignmentWidth() - 1, al);
+    return new AllColsCollection(0, ranges.getAbsoluteAlignmentWidth() - 1,
+            al);
   }
 
   @Override
   public AlignmentRowsCollectionI getRows(AlignmentI al)
   {
-    return new AllRowsCollection(0,
-            ranges.getAbsoluteAlignmentHeight() - 1,
+    return new AllRowsCollection(0, ranges.getAbsoluteAlignmentHeight() - 1,
             al);
   }
 
@@ -329,20 +246,31 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
   {
     alwidth = ranges.getAbsoluteAlignmentWidth();
     alheight = ranges.getAbsoluteAlignmentHeight();
+
+    widthRatio = (float) alwidth / width;
+    heightRatio = (float) alheight / sequencesHeight;
   }
 
+  /**
+   * {@inheritDoc} Callers should have already called resetAlignmentDims to
+   * refresh widthRatio
+   */
   @Override
   protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
   {
     int vpx = Math.round((float) mousex * alwidth / width);
-    return hidden.subtractVisibleColumns(ranges.getViewportWidth() / 2,
+    return hidden.offsetByVisibleColumns(-ranges.getViewportWidth() / 2,
             vpx);
   }
 
+  /**
+   * {@inheritDoc} Callers should have already called resetAlignmentDims to
+   * refresh heightRatio
+   */
   @Override
   protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
   {
-    int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+    int vpy = Math.round(mousey * heightRatio);
     return hidden.subtractVisibleRows(ranges.getViewportHeight() / 2, vpy);
   }
 
@@ -350,17 +278,16 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions
   public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
           HiddenColumns hiddenCols)
   {
-    {
-      // get alignment position of x and box (can get directly from vpranges) and calc difference
-      int vpx = Math.round((float) x * alwidth / width);
-      int visXAsRes = hiddenCols.findColumnPosition(vpx);
-      
-      int vpy = Math.round((float) y * alheight / sequencesHeight);
-      int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
-
-      transX = ranges.getStartRes() - visXAsRes;
-      transY = ranges.getStartSeq() - visYAsRes;
-    }
+    resetAlignmentDims();
+
+    // get alignment position of x and box (can get directly from vpranges) and
+    // calculate difference between the positions
+    int vpx = Math.round(x * widthRatio);
+    int vpy = Math.round(y * heightRatio);
+
+    xdiff = ranges.getStartRes() - hiddenCols.absoluteToVisibleColumn(vpx);
+    ydiff = ranges.getStartSeq()
+            - hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
   }
 
 }