JAL-1807 explicit imports (jalview.structure)
[jalview.git] / src / jalview / gui / AlignmentPanel.java
index c7ef3ce..4c66214 100644 (file)
  */
 package jalview.gui;
 
+import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.HTMLOutput;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.math.AlignmentDimension;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.ImageMaker;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Container;
@@ -27,6 +45,7 @@ import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
+import java.awt.Insets;
 import java.awt.event.AdjustmentEvent;
 import java.awt.event.AdjustmentListener;
 import java.awt.print.PageFormat;
@@ -41,21 +60,6 @@ import java.util.List;
 
 import javax.swing.SwingUtilities;
 
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.jbgui.GAlignmentPanel;
-import jalview.math.AlignmentDimension;
-import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.MessageManager;
-
 /**
  * DOCUMENT ME!
  * 
@@ -304,7 +308,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   public boolean scrollToPosition(SearchResults results)
   {
-    return scrollToPosition(results, true, false);
+    return scrollToPosition(results, 0, true, false);
   }
 
   /**
@@ -317,7 +321,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   public boolean scrollToPosition(SearchResults searchResults, boolean redrawOverview)
   {
-    return scrollToPosition(searchResults, redrawOverview, false);
+    return scrollToPosition(searchResults, 0, redrawOverview, false);
   }
 
   /**
@@ -325,6 +329,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * (if any)
    * 
    * @param results
+   * @param verticalOffset
+   *          if greater than zero, allows scrolling to a position below the
+   *          first displayed sequence
    * @param redrawOverview
    *          - when set, the overview will be recalculated (takes longer)
    * @param centre
@@ -332,6 +339,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @return false if results were not found
    */
   public boolean scrollToPosition(SearchResults results,
+          int verticalOffset,
           boolean redrawOverview, boolean centre)
   {
     int startv, endv, starts, ends;
@@ -390,6 +398,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
           }
         }
       }
+
+      /*
+       * allow for offset of target sequence (actually scroll to one above it)
+       */
+      seqIndex = Math.max(0, seqIndex - verticalOffset);
+
       if (!av.getWrapAlignment())
       {
         if ((startv = av.getStartRes()) >= start)
@@ -397,14 +411,16 @@ public class AlignmentPanel extends GAlignmentPanel implements
           /*
            * Scroll left to make start of search results visible
            */
-          setScrollValues(start - 1, seqIndex);
+          // setScrollValues(start - 1, seqIndex); // plus one residue
+          setScrollValues(start, seqIndex);
         }
         else if ((endv = av.getEndRes()) <= end)
         {
           /*
            * Scroll right to make end of search results visible
            */
-          setScrollValues(startv + 1 + end - endv, seqIndex);
+          // setScrollValues(startv + 1 + end - endv, seqIndex); // plus one
+          setScrollValues(startv + end - endv, seqIndex);
         }
         else if ((starts = av.getStartSeq()) > seqIndex)
         {
@@ -509,47 +525,47 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   protected void validateAnnotationDimensions(boolean adjustPanelHeight)
   {
-    int height = getAnnotationPanel().adjustPanelHeight();
-
-    int theight = av.getCharHeight()
-            * (av.getAlignment().getHeight() + (!av.hasHiddenRows() ? 0
-                    : av.getAlignment().getHiddenSequences().getSize()));
-    float sscaling = (float) (theight / (1.0 * theight + height));
-    float ascaling = (float) (height * 1.0 / alignFrame.getHeight());
-    int rheight = alignFrame.getHeight() - height - av.getCharHeight();
+    int annotationHeight = getAnnotationPanel().adjustPanelHeight();
+
     if (adjustPanelHeight)
     {
-      // NOTE: this logic is different in the applet. Need a better algorithm to
-      // define behaviour
-      // try and set height according to alignment
-      if (ascaling > 0 && sscaling < 0.5)
-      {
-        // if the alignment is too big then
-        // default is 0.5 split
-        height = alignFrame.getHeight() / 2;
-      }
-      else
+      int rowHeight = av.getCharHeight();
+      int alignmentHeight = rowHeight * av.getAlignment().getHeight();
+
+      /*
+       * Estimate available height in the AlignFrame for alignment +
+       * annotations. Deduct an estimate for title bar, menu bar, scale panel,
+       * hscroll, status bar (as these are not laid out we can't inspect their
+       * actual heights). Insets gives frame borders.
+       */
+      int stuff = Platform.isAMac() ? 80 : 100;
+      Insets insets = alignFrame.getInsets();
+      int availableHeight = alignFrame.getHeight() - stuff - insets.top
+              - insets.bottom;
+
+      /*
+       * If not enough vertical space, maximize annotation height while keeping
+       * at least two rows of alignment visible
+       */
+      if (annotationHeight + alignmentHeight > availableHeight)
       {
-        // if space for more than one sequence row left when annotation is fully
-        // displayed then set height to annotation height
-        // otherwise, leave at least two lines of sequence shown.
-        height = (rheight > av.getCharHeight()) ? height
-                : (-av.getCharHeight() * 3 + (int) (alignFrame.getHeight() * (1 - sscaling)));
+        annotationHeight = Math.min(annotationHeight, availableHeight - 2
+                * rowHeight);
       }
     }
     else
     {
       // maintain same window layout whilst updating sliders
-      height = annotationScroller.getSize().height;
+      annotationHeight = annotationScroller.getSize().height;
     }
     hscroll.addNotify();
 
     annotationScroller.setPreferredSize(new Dimension(annotationScroller
-            .getWidth(), height));
+            .getWidth(), annotationHeight));
 
     annotationSpaceFillerHolder.setPreferredSize(new Dimension(
-            annotationSpaceFillerHolder.getWidth(), height));
-    annotationScroller.validate();// repaint();
+            annotationSpaceFillerHolder.getWidth(), annotationHeight));
+    annotationScroller.validate();
     annotationScroller.addNotify();
   }
 
@@ -1223,7 +1239,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     return idwidth.intValue() + 4;
   }
 
-  void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file)
+  void makeAlignmentImage(ImageMaker.TYPE type, File file)
   {
     long progress = System.currentTimeMillis();
     headless = (System.getProperty("java.awt.headless") != null && System
@@ -1239,14 +1255,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
       AlignmentDimension aDimension = getAlignmentDimension();
       try
       {
-        jalview.util.ImageMaker im;
+        ImageMaker im;
         final String imageAction, imageTitle;
-        if (type == jalview.util.ImageMaker.TYPE.PNG)
+        if (type == ImageMaker.TYPE.PNG)
         {
           imageAction = "Create PNG image from alignment";
           imageTitle = null;
         }
-        else if (type == jalview.util.ImageMaker.TYPE.EPS)
+        else if (type == ImageMaker.TYPE.EPS)
         {
           imageAction = "Create EPS file from alignment";
           imageTitle = alignFrame.getTitle();
@@ -1257,7 +1273,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
           imageTitle = alignFrame.getTitle();
         }
 
-        im = new jalview.util.ImageMaker(this, type, imageAction,
+        im = new ImageMaker(this, type, imageAction,
                 aDimension.getWidth(), aDimension.getHeight(), file,
                 imageTitle);
         if (av.getWrapAlignment())
@@ -1343,7 +1359,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   public void makeEPS(File epsFile)
   {
-    makeAlignmentImage(jalview.util.ImageMaker.TYPE.EPS, epsFile);
+    makeAlignmentImage(ImageMaker.TYPE.EPS, epsFile);
   }
 
   /**
@@ -1351,12 +1367,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   public void makePNG(File pngFile)
   {
-    makeAlignmentImage(jalview.util.ImageMaker.TYPE.PNG, pngFile);
+    makeAlignmentImage(ImageMaker.TYPE.PNG, pngFile);
   }
 
   public void makeSVG(File svgFile)
   {
-    makeAlignmentImage(jalview.util.ImageMaker.TYPE.SVG, svgFile);
+    makeAlignmentImage(ImageMaker.TYPE.SVG, svgFile);
   }
   public void makePNGImageMap(File imgMapFile, String imageName)
   {
@@ -1376,7 +1392,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
                 .getAlignment().getWidth(), g, gSize, f, fSize, sy;
         StringBuffer text = new StringBuffer();
         PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
-        out.println(jalview.io.HTMLOutput.getImageMapHTML());
+        out.println(HTMLOutput.getImageMapHTML());
         out.println("<img src=\"" + imageName
                 + "\" border=\"0\" usemap=\"#Map\" >"
                 + "<map name=\"Map\">");
@@ -1552,7 +1568,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     PaintRefresher.RemoveComponent(this);
     if (av != null)
     {
-      jalview.structure.StructureSelectionManager ssm = av
+      StructureSelectionManager ssm = av
               .getStructureSelectionManager();
       ssm.removeStructureViewerListener(getSeqPanel(), null);
       ssm.removeSelectionListener(getSeqPanel());
@@ -1614,11 +1630,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
   {
     try
     {
+      if (alignFrame.getSplitViewContainer() != null)
+      {
+        /*
+         * bring enclosing SplitFrame to front first if there is one
+         */
+        ((SplitFrame) alignFrame.getSplitViewContainer()).setSelected(b);
+      }
       alignFrame.setSelected(b);
     } catch (Exception ex)
     {
     }
-    ;
 
     if (b)
     {
@@ -1719,10 +1741,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @param sr
    *          holds mapped region(s) of this alignment that we are scrolling
    *          'to'; may be modified for sequence offset by this method
-   * @param seqOffset
+   * @param verticalOffset
    *          the number of visible sequences to show above the mapped region
    */
-  public void scrollToCentre(SearchResults sr, int seqOffset)
+  public void scrollToCentre(SearchResults sr, int verticalOffset)
   {
     /*
      * To avoid jumpy vertical scrolling (if some sequences are gapped or not
@@ -1736,7 +1758,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
      * This is like AlignmentI.findIndex(seq) but here we are matching the
      * dataset sequence not the aligned sequence
      */
-    int sequenceIndex = 0;
     boolean matched = false;
     for (SequenceI seq : seqs)
     {
@@ -1745,20 +1766,16 @@ public class AlignmentPanel extends GAlignmentPanel implements
         matched = true;
         break;
       }
-      sequenceIndex++;
     }
     if (!matched)
     {
       return; // failsafe, shouldn't happen
     }
-    sequenceIndex = Math.max(0, sequenceIndex - seqOffset);
-    sr.getResults().get(0)
-            .setSequence(av.getAlignment().getSequenceAt(sequenceIndex));
 
     /*
      * Scroll to position but centring the target residue.
      */
-    scrollToPosition(sr, true, true);
+    scrollToPosition(sr, verticalOffset, true, true);
   }
 
   /**