JAL-2491 Wrapped panel scrolling
[jalview.git] / src / jalview / gui / AlignmentPanel.java
index 8ade5d6..a2773e8 100644 (file)
@@ -35,6 +35,7 @@ import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.viewmodel.ViewportListenerI;
 import jalview.viewmodel.ViewportRanges;
 
 import java.awt.BorderLayout;
@@ -66,7 +67,8 @@ import javax.swing.SwingUtilities;
  * @version $Revision: 1.161 $
  */
 public class AlignmentPanel extends GAlignmentPanel implements
-        AdjustmentListener, Printable, AlignmentViewPanel
+        AdjustmentListener, Printable, AlignmentViewPanel,
+        ViewportListenerI
 {
   public AlignViewport av;
 
@@ -154,6 +156,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
       }
     };
     av.addPropertyChangeListener(propertyChangeListener);
+
+    av.getRanges().addPropertyChangeListener(this);
     fontChanged();
     adjustAnnotationHeight();
     updateLayout();
@@ -473,7 +477,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
             || res >= (vpRanges.getStartRes() + cwidth))
     {
       vscroll.setValue((res / cwidth));
-      vpRanges.setStartRes(vscroll.getValue() * cwidth);
+      // vpRanges.setStartRes(vscroll.getValue() * cwidth);
     }
 
   }
@@ -698,61 +702,66 @@ public class AlignmentPanel extends GAlignmentPanel implements
     {
       return;
     }
-    int width = av.getAlignment().getWidth();
-    int height = av.getAlignment().getHeight();
 
-    if (av.hasHiddenColumns())
+    if (av.getWrapAlignment())
     {
-      // reset the width to exclude hidden columns
-      width = av.getColumnSelection().findColumnPosition(width);
+      setScrollingForWrappedPanel(x, y);
     }
+    else
+    {
 
-    hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
-    vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
+      int width = av.getAlignment().getWidth();
+      int height = av.getAlignment().getHeight();
 
-    if (hextent > width)
-    {
-      hextent = width;
-    }
+      if (av.hasHiddenColumns())
+      {
+        // reset the width to exclude hidden columns
+        width = av.getColumnSelection().findColumnPosition(width);
+      }
 
-    if (vextent > height)
-    {
-      vextent = height;
-    }
+      hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
+      vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
 
-    if ((hextent + x) > width)
-    {
-      x = width - hextent;
-    }
+      if (hextent > width)
+      {
+        hextent = width;
+      }
 
-    if ((vextent + y) > height)
-    {
-      y = height - vextent;
-    }
+      if (vextent > height)
+      {
+        vextent = height;
+      }
 
-    if (y < 0)
-    {
-      y = 0;
-    }
+      if ((hextent + x) > width)
+      {
+        x = width - hextent;
+      }
 
-    if (x < 0)
-    {
-      x = 0;
-    }
+      if ((vextent + y) > height)
+      {
+        y = height - vextent;
+      }
+
+      if (y < 0)
+      {
+        y = 0;
+      }
 
-    // update endRes after x has (possibly) been adjusted
-    vpRanges.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
-            .getCharWidth())) - 1);
+      if (x < 0)
+      {
+        x = 0;
+      }
 
-    /*
-     * each scroll adjustment triggers adjustmentValueChanged, which resets the
-     * 'do not scroll complement' flag; ensure it is the same for both
-     * operations
-     */
-    boolean flag = isDontScrollComplement();
-    hscroll.setValues(x, hextent, 0, width);
-    setDontScrollComplement(flag);
-    vscroll.setValues(y, vextent, 0, height);
+      /*
+       * each scroll adjustment triggers adjustmentValueChanged, which resets the
+       * 'do not scroll complement' flag; ensure it is the same for both
+       * operations
+       */
+      // boolean flag = isDontScrollComplement();
+      hscroll.setValues(x, hextent, 0, width);
+      // setDontScrollComplement(flag);
+      vscroll.setValues(y, vextent, 0, height);
+    }
   }
 
   /**
@@ -767,26 +776,24 @@ public class AlignmentPanel extends GAlignmentPanel implements
     int oldX = vpRanges.getStartRes();
     int oldY = vpRanges.getStartSeq();
 
-    if (evt.getSource() == hscroll)
-    {
-      int x = hscroll.getValue();
-      vpRanges.setStartRes(x);
-      vpRanges.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
-              .getCharWidth())) - 1);
-    }
-
-    if (evt.getSource() == vscroll)
+    if (av.getWrapAlignment())
     {
-      int offy = vscroll.getValue();
-
-      if (av.getWrapAlignment())
+      if (evt.getSource() == hscroll)
+      {
+        return; // no horizontal scroll when wrapped
+      }
+      else if (evt.getSource() == vscroll)
       {
-        if (offy > -1)
+        int offy = vscroll.getValue();
+        int rowSize = getSeqPanel().seqCanvas
+                .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
+        if (offy * rowSize == oldX)
         {
-          int rowSize = getSeqPanel().seqCanvas
-                  .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
-          vpRanges.setStartRes(offy * rowSize);
-          vpRanges.setEndRes((offy + 1) * rowSize);
+          return;
+        }
+        else if (offy > -1)
+        {
+          vpRanges.setStartEndRes(offy * rowSize, (offy + 1) * rowSize);
         }
         else
         {
@@ -804,63 +811,39 @@ public class AlignmentPanel extends GAlignmentPanel implements
           });
         }
       }
-      else
-      {
-        vpRanges.setStartSeq(offy);
-        vpRanges.setEndSeq(offy
-                + (getSeqPanel().seqCanvas.getHeight() / av.getCharHeight())
-                - 1);
-      }
-    }
-
-    if (overviewPanel != null)
-    {
-      overviewPanel.setBoxPosition();
-    }
-
-    int scrollX = vpRanges.getStartRes() - oldX;
-    int scrollY = vpRanges.getStartSeq() - oldY;
-
-    if (av.getWrapAlignment() || !fastPaint)
-    {
       repaint();
     }
     else
     {
-      // Make sure we're not trying to draw a panel
-      // larger than the visible window
-      if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
-      {
-        scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
-      }
-      else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
+      // horizontal scroll
+      if (evt.getSource() == hscroll)
       {
-        scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
+        int x = hscroll.getValue();
+        if (x == oldX)
+        {
+          return;
+        }
+        vpRanges.setStartEndRes(x,
+                (x + (getSeqPanel().seqCanvas.getWidth() / av
+                        .getCharWidth())) - 1);
       }
-
-      if (scrollX != 0 || scrollY != 0)
+      else if (evt.getSource() == vscroll)
       {
-        getIdPanel().getIdCanvas().fastPaint(scrollY);
-        getSeqPanel().seqCanvas.fastPaint(scrollX, scrollY);
-        getScalePanel().repaint();
-
-        if (av.isShowAnnotation() && scrollX != 0)
+        int offy = vscroll.getValue();
+        if (offy == oldY)
         {
-          getAnnotationPanel().fastPaint(scrollX);
+          return;
         }
+        vpRanges.setStartEndSeq(
+                offy,
+                offy
+                        + (getSeqPanel().seqCanvas.getHeight() / av
+                                .getCharHeight()) - 1);
+      }
+      if (!fastPaint)
+      {
+        repaint();
       }
-    }
-    /*
-     * If there is one, scroll the (Protein/cDNA) complementary alignment to
-     * match, unless we are ourselves doing that.
-     */
-    if (isDontScrollComplement())
-    {
-      setDontScrollComplement(false);
-    }
-    else
-    {
-      av.scrollComplementaryAlignment();
     }
   }
 
@@ -909,33 +892,33 @@ public class AlignmentPanel extends GAlignmentPanel implements
      * set scroll bar positions; first suppress this being 'followed' in any
      * complementary split pane
      */
-    setDontScrollComplement(true);
 
-    if (av.getWrapAlignment())
-    {
-      int maxwidth = av.getAlignment().getWidth();
+    // setDontScrollComplement(true);
+    setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+  }
 
-      if (av.hasHiddenColumns())
-      {
-        maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
-      }
+  /*
+   * Set vertical scroll bar parameters for wrapped panel
+   */
+  private void setScrollingForWrappedPanel(int x, int y)
+  {
+    int maxwidth = av.getAlignment().getWidth();
 
-      int canvasWidth = getSeqPanel().seqCanvas
-              .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
-      if (canvasWidth > 0)
-      {
-        int max = maxwidth
-                / getSeqPanel().seqCanvas
-                        .getWrappedCanvasWidth(getSeqPanel().seqCanvas
-                                .getWidth()) + 1;
-        vscroll.setMaximum(max);
-        vscroll.setUnitIncrement(1);
-        vscroll.setVisibleAmount(1);
-      }
+    if (av.hasHiddenColumns())
+    {
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
     }
-    else
+
+    int canvasWidth = getSeqPanel().seqCanvas
+            .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
+    if (canvasWidth > 0)
     {
-      setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+      int current = x / canvasWidth;
+      int max = maxwidth / canvasWidth + 1;
+      vscroll.setMaximum(max);
+      vscroll.setUnitIncrement(1);
+      vscroll.setVisibleAmount(1);
+      vscroll.setValues(current, 1, 0, max);
     }
   }
 
@@ -1906,4 +1889,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
       repaint();
     }
   }
+
+  @Override
+  public void propertyChange(PropertyChangeEvent evt)
+  {
+    int x = vpRanges.getStartRes();
+    int y = vpRanges.getStartSeq();
+    setScrollValues(x, y);
+    av.scrollComplementaryAlignment();
+  }
 }