JAL-1925 update source version in license
[jalview.git] / src / jalview / gui / SplitFrame.java
index 5c4e4d2..f3d852c 100644 (file)
@@ -1,5 +1,34 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
+ * Copyright (C) 2015 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.gui;
 
+import jalview.api.SplitContainerI;
+import jalview.api.ViewStyleI;
+import jalview.datamodel.AlignmentI;
+import jalview.jbgui.GAlignFrame;
+import jalview.jbgui.GSplitFrame;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Platform;
+import jalview.viewmodel.AlignmentViewport;
+
 import java.awt.Component;
 import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
@@ -9,23 +38,18 @@ import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.beans.PropertyVetoException;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import javax.swing.AbstractAction;
 import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.JMenuItem;
 import javax.swing.KeyStroke;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
 
-import jalview.api.SplitContainerI;
-import jalview.api.ViewStyleI;
-import jalview.datamodel.AlignmentI;
-import jalview.jbgui.GAlignFrame;
-import jalview.jbgui.GSplitFrame;
-import jalview.structure.StructureSelectionManager;
-import jalview.viewmodel.AlignmentViewport;
-
 /**
  * An internal frame on the desktop that hosts a horizontally split view of
  * linked DNA and Protein alignments. Additional views can be created in linked
@@ -61,18 +85,30 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     ((AlignFrame) getTopFrame()).getViewport().setCodingComplement(
             ((AlignFrame) getBottomFrame()).getViewport());
 
-    int width = ((AlignFrame) getTopFrame()).getWidth();
-    // about 50 pixels for the SplitFrame's title bar etc
+    /*
+     * estimate width and height of SplitFrame; this.getInsets() doesn't seem to
+     * give the full additional size (a few pixels short)
+     */
+    UIDefaults defaults = UIManager.getDefaults();
+    Set<Object> keySet = defaults.keySet();
+    for (Object key : keySet)
+    {
+      System.out.println(key.toString() + " = "
+              + UIManager.get(key).toString());
+    }
+    int widthFudge = Platform.isAMac() ? 28 : 28; // Windows tbc
+    int heightFudge = Platform.isAMac() ? 50 : 50; // tbc
+    int width = ((AlignFrame) getTopFrame()).getWidth() + widthFudge;
     int height = ((AlignFrame) getTopFrame()).getHeight()
-            + ((AlignFrame) getBottomFrame()).getHeight() + 50;
-    height = Math.min(height, Desktop.instance.getHeight() - 20);
-    // setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20);
+            + ((AlignFrame) getBottomFrame()).getHeight() + DIVIDER_SIZE
+            + heightFudge;
+    height = fitHeightToDesktop(height);
     setSize(width, height);
 
     adjustLayout();
 
     addCloseFrameListener();
-    
+
     addKeyListener();
 
     addKeyBindings();
@@ -81,6 +117,27 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
   }
 
   /**
+   * Reduce the height if too large to fit in the Desktop. Also adjust the
+   * divider location in proportion.
+   * 
+   * @param height
+   *          in pixels
+   * @return original or reduced height
+   */
+  public int fitHeightToDesktop(int height)
+  {
+    // allow about 65 pixels for Desktop decorators on Windows
+
+    int newHeight = Math.min(height, Desktop.instance.getHeight() - 65);
+    if (newHeight != height)
+    {
+      int oldDividerLocation = getDividerLocation();
+      setDividerLocation(oldDividerLocation * newHeight / height);
+    }
+    return newHeight;
+  }
+
+  /**
    * Set the top and bottom frames to listen to each others Commands (e.g. Edit,
    * Order).
    */
@@ -100,7 +157,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
   public void adjustLayout()
   {
     /*
-     * Ensure sequence ids are the same width for good alignment.
+     * Ensure sequence ids are the same width so sequences line up
      */
     int w1 = ((AlignFrame) getTopFrame()).getViewport().getIdWidth();
     int w2 = ((AlignFrame) getBottomFrame()).getViewport().getIdWidth();
@@ -115,26 +172,22 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     }
 
     /*
-     * Set the character width for protein to 3 times that for dna.
+     * Scale protein to either 1 or 3 times character width of dna
      */
-    boolean scaleThreeToOne = true; // TODO a new Preference option?
-    if (scaleThreeToOne)
+    final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport;
+    final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport;
+    final AlignmentI topAlignment = topViewport.getAlignment();
+    final AlignmentI bottomAlignment = bottomViewport.getAlignment();
+    AlignmentViewport cdna = topAlignment.isNucleotide() ? topViewport
+            : (bottomAlignment.isNucleotide() ? bottomViewport : null);
+    AlignmentViewport protein = !topAlignment.isNucleotide() ? topViewport
+            : (!bottomAlignment.isNucleotide() ? bottomViewport : null);
+    if (protein != null && cdna != null)
     {
-      final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport;
-      final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport;
-      final AlignmentI topAlignment = topViewport.getAlignment();
-      final AlignmentI bottomAlignment = bottomViewport.getAlignment();
-      AlignmentViewport cdna = topAlignment.isNucleotide() ? topViewport
-              : (bottomAlignment.isNucleotide() ? bottomViewport : null);
-      AlignmentViewport protein = !topAlignment.isNucleotide() ? topViewport
-              : (!bottomAlignment.isNucleotide() ? bottomViewport : null);
-      if (protein != null && cdna != null)
-      {
-        ViewStyleI vs = cdna.getViewStyle();
-        ViewStyleI vs2 = protein.getViewStyle();
-        vs2.setCharWidth(3 * vs.getCharWidth());
-        protein.setViewStyle(vs2);
-      }
+      ViewStyleI vs = protein.getViewStyle();
+      int scale = vs.isScaleProteinAsCdna() ? 3 : 1;
+      vs.setCharWidth(scale * cdna.getViewStyle().getCharWidth());
+      protein.setViewStyle(vs);
     }
   }
 
@@ -148,16 +201,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
       @Override
       public void internalFrameClosed(InternalFrameEvent evt)
       {
-        if (getTopFrame() instanceof AlignFrame)
-        {
-          ((AlignFrame) getTopFrame())
-                  .closeMenuItem_actionPerformed(true);
-        }
-        if (getBottomFrame() instanceof AlignFrame)
-        {
-          ((AlignFrame) getBottomFrame())
-                  .closeMenuItem_actionPerformed(true);
-        }
+        close();
       };
     });
   }
@@ -168,7 +212,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
    */
   protected void addKeyListener()
   {
-    addKeyListener(new KeyAdapter() {
+    addKeyListener(new KeyAdapter()
+    {
 
       @Override
       public void keyPressed(KeyEvent e)
@@ -202,7 +247,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
           }
         }
       }
-      
+
     });
   }
 
@@ -396,6 +441,8 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
   {
     AlignFrame topFrame = (AlignFrame) getTopFrame();
     AlignFrame bottomFrame = (AlignFrame) getBottomFrame();
+    final boolean scaleProteinAsCdna = topFrame.viewport
+            .isScaleProteinAsCdna();
 
     AlignmentPanel newTopPanel = topFrame.newView(null, true);
     AlignmentPanel newBottomPanel = bottomFrame.newView(null, true);
@@ -414,6 +461,19 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     newBottomPanel.av.viewName = newTopPanel.av.viewName;
     newTopPanel.av.setCodingComplement(newBottomPanel.av);
 
+    /*
+     * These lines can be removed once scaleProteinAsCdna is added to element
+     * Viewport in jalview.xsd, as Jalview2XML.copyAlignPanel will then take
+     * care of it
+     */
+    newTopPanel.av.setScaleProteinAsCdna(scaleProteinAsCdna);
+    newBottomPanel.av.setScaleProteinAsCdna(scaleProteinAsCdna);
+
+    /*
+     * Line up id labels etc
+     */
+    adjustLayout();
+
     final StructureSelectionManager ssm = StructureSelectionManager
             .getStructureSelectionManager(Desktop.instance);
     ssm.addCommandListener(newTopPanel.av);
@@ -636,4 +696,3 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     overrideKeyBinding(key_cmdF, action);
   }
 }
-