JAL-2388 Corrected overview panel behaviour, updated tests
[jalview.git] / src / jalview / viewmodel / OverviewDimensions.java
index fe9f4db..ed9a155 100644 (file)
@@ -21,6 +21,8 @@
 package jalview.viewmodel;
 
 import jalview.api.AlignViewportI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenSequences;
 
 import java.awt.Graphics;
 
@@ -41,10 +43,6 @@ public class OverviewDimensions
 
   private ViewportPositionProps posProps;
 
-  private float scalew = 1f;
-
-  private float scaleh = 1f;
-
   // width of the overview panel
   private int width;
 
@@ -71,7 +69,7 @@ public class OverviewDimensions
 
   private int scrollRow = -1;
 
-  public OverviewDimensions(AlignViewportI avi)
+  public OverviewDimensions(AlignViewportI avi, boolean showAnnotationPanel)
   {
     this.av = avi;
     this.posProps = av.getPosProps();
@@ -80,9 +78,7 @@ public class OverviewDimensions
     float initialScale = (float) posProps.getAlignmentWidthInCols()
             / (float) posProps.getAlignmentHeightInRows();
 
-    // TODO: in applet this was getSequenceConsensusHash()
-    // check if it makes any functional difference
-    if (av.getAlignmentConservationAnnotation() == null)
+    if (!showAnnotationPanel)
     {
       graphHeight = 0;
     }
@@ -114,57 +110,100 @@ public class OverviewDimensions
   /**
    * Check box dimensions and scroll positions and correct if necessary
    */
-  public void setBoxPositionByMouse(int x, int y)
+  public void updateViewportFromMouse(int x, int y)
   {
     int alwidth = av.getAlignment().getWidth();
     int alheight = av.getAlignment().getAbsoluteHeight();
 
-    boxX = x;
-    boxY = y;
-    if (boxY < 0)
+    HiddenSequences hiddenSeqs = av.getAlignment().getHiddenSequences();
+    ColumnSelection hiddenCols = av.getColumnSelection();
+
+    if (x < 0)
     {
-      boxY = 0;
+      x = 0;
     }
-    else if (boxY > (sequencesHeight - boxHeight))
+    else if (x >= alwidth)
     {
-      boxY = sequencesHeight - boxHeight;
+      x = alwidth - 1;
     }
 
-    if (boxX < 0)
+    if (y < 0)
     {
-      boxX = 0;
+      y = 0;
     }
-    else if (boxX > (width - boxWidth))
+    else if (y >= alheight)
     {
-      if (av.hasHiddenColumns())
-      {
-        // Try smallest possible box
-        boxWidth = Math.round((float) (posProps.getEndRes()
-                - posProps.getStartRes() + 1)
-                * width / alwidth);
-      }
-      boxX = width - boxWidth;
+      y = alheight - 1;
     }
 
-    scrollCol = Math.round((float) boxX * alwidth / width);
-    scrollRow = Math.round((float) boxY * alheight / sequencesHeight);
+    //
+    // Convert x value to residue position
+    //
 
-    if (av.hasHiddenColumns())
-    {
-      // doesn't seem to do anything useful
-      /*if (!av.getColumnSelection().isVisible(scrollCol))
-      {
-        return;
-      }*/
+    // 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);
 
-      scrollCol = av.getColumnSelection().findColumnPosition(scrollCol);
+    // get viewport width in residues
+    int vpwidth = av.getPosProps().getEndRes()
+            - av.getPosProps().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;
+
+    // check in case we went off the edge of the alignment
+    if (endRes > alwidth)
+    {
+      // went past the end of the alignment, adjust backwards
+      endRes = alwidth;
+      // recalc xAsRes backwards from endRes
+      xAsRes = endRes - vpwidth;
     }
 
-    if (av.hasHiddenRows())
+    //
+    // 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 = av.getPosProps().getEndSeq()
+            - av.getPosProps().getStartSeq();
+
+    // 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));
+
+    // 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)
     {
-      scrollRow = av.getAlignment().getHiddenSequences()
-              .findIndexWithoutHiddenSeqs(scrollRow);
+      // went past the end of the alignment, adjust backwards
+      endSeq = alheight;
+      // recalc yAsSeq backwards from endSeq
+      yAsSeq = endSeq - vpheight;
     }
+
+    // convert absolute positions back to visible alignment positions for
+    // viewport scrolling
+    scrollCol = hiddenCols.findColumnPosition(xAsRes);
+    scrollRow = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
   }
 
   /**