JAL-3116 parse EMBL XML with JAXB (todo: update unit tests)
[jalview.git] / src / jalview / gui / SplitFrame.java
index c1039ee..a0d31cf 100644 (file)
@@ -21,7 +21,6 @@
 package jalview.gui;
 
 import jalview.api.SplitContainerI;
-import jalview.api.ViewStyleI;
 import jalview.datamodel.AlignmentI;
 import jalview.jbgui.GAlignFrame;
 import jalview.jbgui.GSplitFrame;
@@ -70,7 +69,9 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
   private static final int WINDOWS_INSETS_HEIGHT = 50; // tbc
 
   private static final int MAC_INSETS_HEIGHT = 50;
+
   private static final int DESKTOP_DECORATORS_HEIGHT = 65;
+
   private static final long serialVersionUID = 1L;
 
   public SplitFrame(GAlignFrame top, GAlignFrame bottom)
@@ -130,8 +131,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
   {
     // allow about 65 pixels for Desktop decorators on Windows
 
-    int newHeight = Math.min(height, Desktop.instance.getHeight()
-            - DESKTOP_DECORATORS_HEIGHT);
+    int newHeight = Math.min(height,
+            Desktop.instance.getHeight() - DESKTOP_DECORATORS_HEIGHT);
     if (newHeight != height)
     {
       int oldDividerLocation = getDividerLocation();
@@ -187,23 +188,35 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
             : (!bottomAlignment.isNucleotide() ? bottomViewport : null);
     if (protein != null && cdna != null)
     {
-      ViewStyleI vs = protein.getViewStyle();
-      int scale = vs.isScaleProteinAsCdna() ? 3 : 1;
-      vs.setCharWidth(scale * cdna.getViewStyle().getCharWidth());
-      protein.setViewStyle(vs);
+      int scale = protein.isScaleProteinAsCdna() ? 3 : 1;
+      protein.setCharWidth(scale * cdna.getViewStyle().getCharWidth());
     }
   }
 
   /**
-   * Adjust the divider for a sensible split of the real estate (for example,
+   * Adjusts the divider for a sensible split of the real estate (for example,
    * when many transcripts are shown with a single protein). This should only be
    * called after the split pane has been laid out (made visible) so it has a
-   * height.
+   * height. The aim is to avoid unnecessary vertical scroll bars, while
+   * ensuring that at least 2 sequences are visible in each panel.
+   * <p>
+   * Once laid out, the user may choose to customise as they wish, so this
+   * method is not called again after the initial layout.
    */
-  protected void adjustDivider()
+  protected void adjustInitialLayout()
   {
-    final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport;
-    final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport;
+    AlignFrame topFrame = (AlignFrame) getTopFrame();
+    AlignFrame bottomFrame = (AlignFrame) getBottomFrame();
+
+    /*
+     * recompute layout of top and bottom panels to reflect their
+     * actual (rather than requested) height
+     */
+    topFrame.alignPanel.adjustAnnotationHeight();
+    bottomFrame.alignPanel.adjustAnnotationHeight();
+
+    final AlignViewport topViewport = topFrame.viewport;
+    final AlignViewport bottomViewport = bottomFrame.viewport;
     final AlignmentI topAlignment = topViewport.getAlignment();
     final AlignmentI bottomAlignment = bottomViewport.getAlignment();
     boolean topAnnotations = topViewport.isShowAnnotation();
@@ -215,6 +228,29 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     int bottomCharHeight = bottomViewport.getViewStyle().getCharHeight();
 
     /*
+     * calculate the minimum ratio that leaves at least the height 
+     * of two sequences (after rounding) visible in the top panel
+     */
+    int topPanelHeight = topFrame.getHeight();
+    int bottomPanelHeight = bottomFrame.getHeight();
+    int topSequencesHeight = topFrame.alignPanel.getSeqPanel().seqCanvas
+            .getHeight();
+    int topPanelMinHeight = topPanelHeight
+            - Math.max(0, topSequencesHeight - 3 * topCharHeight);
+    double totalHeight = (double) topPanelHeight + bottomPanelHeight;
+    double minRatio = topPanelMinHeight / totalHeight;
+
+    /*
+     * calculate the maximum ratio that leaves at least the height 
+     * of two sequences (after rounding) visible in the bottom panel
+     */
+    int bottomSequencesHeight = bottomFrame.alignPanel.getSeqPanel().seqCanvas
+            .getHeight();
+    int bottomPanelMinHeight = bottomPanelHeight
+            - Math.max(0, bottomSequencesHeight - 3 * bottomCharHeight);
+    double maxRatio = (totalHeight - bottomPanelMinHeight) / totalHeight;
+
+    /*
      * estimate ratio of (topFrameContent / bottomFrameContent)
      */
     int insets = Platform.isAMac() ? MAC_INSETS_HEIGHT
@@ -224,13 +260,14 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
             + (topAnnotations ? topViewport.calcPanelHeight() : 0);
     int bottomHeight = insets + (3 + bottomCount) * bottomCharHeight
             + (bottomAnnotations ? bottomViewport.calcPanelHeight() : 0);
-    double ratio = ((double) topHeight) / (topHeight + bottomHeight);
+    double ratio = ((double) topHeight)
+            / (double) (topHeight + bottomHeight);
 
     /*
-     * limit to 0.2 <= ratio <= 0.8 to avoid concealing all sequences
+     * limit ratio to avoid concealing all sequences
      */
-    ratio = Math.min(ratio, 0.8d);
-    ratio = Math.max(ratio, 0.2d);
+    ratio = Math.min(ratio, maxRatio);
+    ratio = Math.max(ratio, minRatio);
     setRelativeDividerLocation(ratio);
   }
 
@@ -336,6 +373,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
         actioned = true;
         e.consume();
       }
+      break;
     default:
     }
     return actioned;
@@ -373,8 +411,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     /*
      * Ctrl-W / Cmd-W - close view or window
      */
-    KeyStroke key_cmdW = KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit
-            .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+    KeyStroke key_cmdW = KeyStroke.getKeyStroke(KeyEvent.VK_W,
+            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
     action = new AbstractAction()
     {
       @Override
@@ -394,8 +432,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     /*
      * Ctrl-T / Cmd-T open new view
      */
-    KeyStroke key_cmdT = KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit
-            .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+    KeyStroke key_cmdT = KeyStroke.getKeyStroke(KeyEvent.VK_T,
+            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
     AbstractAction action = new AbstractAction()
     {
       @Override
@@ -448,8 +486,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
         Component c = getFrameAtMouse();
         if (c != null && c instanceof AlignFrame)
         {
-          for (ActionListener a : ((AlignFrame) c).getAccelerators()
-                  .get(ks).getActionListeners())
+          for (ActionListener a : ((AlignFrame) c).getAccelerators().get(ks)
+                  .getActionListeners())
           {
             a.actionPerformed(null);
           }
@@ -501,7 +539,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
       topFrame.setDisplayedView(newTopPanel);
     }
 
-    newBottomPanel.av.viewName = newTopPanel.av.viewName;
+    newBottomPanel.av.setViewName(newTopPanel.av.getViewName());
     newTopPanel.av.setCodingComplement(newBottomPanel.av);
 
     /*
@@ -719,9 +757,11 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
    */
   public List<AlignFrame> getAlignFrames()
   {
-    return Arrays.asList(new AlignFrame[] { (AlignFrame) getTopFrame(),
-        (AlignFrame) getBottomFrame() });
+    return Arrays
+            .asList(new AlignFrame[]
+            { (AlignFrame) getTopFrame(), (AlignFrame) getBottomFrame() });
   }
+
   /**
    * Replace Cmd-F Find action with our version. This is necessary because the
    * 'default' Finder searches in the first AlignFrame it finds. We need it to
@@ -732,8 +772,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     /*
      * Ctrl-F / Cmd-F open Finder dialog, 'focused' on the right alignment
      */
-    KeyStroke key_cmdF = KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit
-            .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+    KeyStroke key_cmdF = KeyStroke.getKeyStroke(KeyEvent.VK_F,
+            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
     AbstractAction action = new AbstractAction()
     {
       @Override