JAL-1684 better window size parameters; match up sequence id lengths
[jalview.git] / src / jalview / appletgui / SplitFrame.java
1 package jalview.appletgui;
2
3 import jalview.analysis.AlignmentUtils;
4 import jalview.analysis.AlignmentUtils.MappingResult;
5 import jalview.api.ViewStyleI;
6 import jalview.bin.JalviewLite;
7 import jalview.datamodel.AlignmentI;
8 import jalview.structure.StructureSelectionManager;
9
10 import java.awt.BorderLayout;
11 import java.awt.Dimension;
12 import java.awt.GridLayout;
13 import java.awt.Panel;
14
15 public class SplitFrame extends EmbmenuFrame
16 {
17   private static final long serialVersionUID = 1L;
18
19   private AlignFrame topFrame;
20
21   private AlignFrame bottomFrame;
22
23   private Panel outermost;
24
25   /**
26    * Constructor
27    */
28   public SplitFrame(AlignFrame af1, AlignFrame af2)
29   {
30     topFrame = af1;
31     bottomFrame = af2;
32     init();
33   }
34
35   /**
36    * Creates a Panel containing two Panels, and adds the first and second
37    * AlignFrame's components to each. At this stage we have not yet committed to
38    * whether the enclosing panel will be added to this frame, for display as a
39    * separate frame, or added to the applet (embedded mode).
40    */
41   public void init()
42   {
43     constructSplit();
44
45     /*
46      * Try to make and add dna/protein sequence mappings
47      */
48     final AlignViewport topViewport = topFrame.viewport;
49     final AlignViewport bottomViewport = bottomFrame.viewport;
50     final AlignmentI topAlignment = topViewport.getAlignment();
51     final AlignmentI bottomAlignment = bottomViewport.getAlignment();
52     AlignViewport cdna = topAlignment.isNucleotide() ? topViewport
53             : (bottomAlignment.isNucleotide() ? bottomViewport : null);
54     AlignViewport protein = !topAlignment.isNucleotide() ? topViewport
55             : (!bottomAlignment.isNucleotide() ? bottomViewport : null);
56
57     MappingResult mapped = AlignmentUtils.mapProteinToCdna(
58             protein.getAlignment(), cdna.getAlignment());
59     if (mapped != MappingResult.NotMapped)
60     {
61       final StructureSelectionManager ssm = StructureSelectionManager
62               .getStructureSelectionManager(topViewport.applet);
63       ssm.addMappings(protein.getAlignment().getCodonFrames());
64       topViewport.setCodingComplement(bottomViewport);
65       ssm.addCommandListener(cdna);
66       ssm.addCommandListener(protein);
67     }
68
69     adjustLayout();
70   }
71
72   /**
73    * 
74    */
75   protected void constructSplit()
76   {
77     setMenuBar(null);
78     outermost = new Panel(new GridLayout(2, 1));
79
80     Panel topPanel = new Panel();
81     Panel bottomPanel = new Panel();
82     outermost.add(topPanel);
83     outermost.add(bottomPanel);
84
85     addAlignFrameComponents(topFrame, topPanel);
86     addAlignFrameComponents(bottomFrame, bottomPanel);
87   }
88
89   /**
90    * Make any adjustments to the layout
91    */
92   protected void adjustLayout()
93   {
94     AlignViewport cdna = topFrame.getAlignViewport().getAlignment()
95             .isNucleotide() ? topFrame.viewport : bottomFrame.viewport;
96     AlignViewport protein = cdna == topFrame.viewport ? bottomFrame.viewport
97             : topFrame.viewport;
98
99     /*
100      * Ensure sequence ids are the same width for good alignment.
101      */
102     // TODO should do this via av.getViewStyle/setViewStyle
103     // however at present av.viewStyle is not set in IdPanel.fontChanged
104     int w1 = topFrame.alignPanel.idPanel.idCanvas.getWidth();
105     int w2 = bottomFrame.alignPanel.idPanel.idCanvas.getWidth();
106     int w3 = Math.max(w1, w2);
107     if (w1 != w3)
108     {
109       Dimension d = topFrame.alignPanel.idPanel.idCanvas.getSize();
110       topFrame.alignPanel.idPanel.idCanvas.setSize(new Dimension(w3,
111               d.height));
112     }
113     if (w2 != w3)
114     {
115       Dimension d = bottomFrame.alignPanel.idPanel.idCanvas.getSize();
116       bottomFrame.alignPanel.idPanel.idCanvas.setSize(new Dimension(w3,
117               d.height));
118     }
119
120     /*
121      * Expand protein to 3 times character width of dna
122      */
123     if (protein != null && cdna != null)
124     {
125       ViewStyleI vs = protein.getViewStyle();
126       vs.setCharWidth(3 * vs.getCharWidth());
127       protein.setViewStyle(vs);
128     }
129   }
130
131   /**
132    * Add the menu bar, alignment panel and status bar from the AlignFrame to the
133    * panel. The menu bar is a panel 'reconstructed' from the AlignFrame's frame
134    * menu bar. This allows each half of the SplitFrame to have its own menu bar.
135    * 
136    * @param af
137    * @param panel
138    */
139   private void addAlignFrameComponents(AlignFrame af, Panel panel)
140   {
141     panel.setLayout(new BorderLayout());
142     Panel menuPanel = af
143             .makeEmbeddedPopupMenu(af.getMenuBar(), true, false);
144     panel.add(menuPanel, BorderLayout.NORTH);
145     panel.add(af.statusBar, BorderLayout.SOUTH);
146     panel.add(af.alignPanel, BorderLayout.CENTER);
147   }
148
149   /**
150    * Display the content panel either as a new frame or embedded in the applet.
151    * 
152    * @param embedded
153    * @param applet
154    */
155   public void addToDisplay(boolean embedded, JalviewLite applet)
156   {
157     createSplitFrameWindow(embedded, applet);
158     validate();
159     topFrame.alignPanel.adjustAnnotationHeight();
160     topFrame.alignPanel.paintAlignment(true);
161     bottomFrame.alignPanel.adjustAnnotationHeight();
162     bottomFrame.alignPanel.paintAlignment(true);
163   }
164
165   /**
166    * Either show the content panel in this frame as a new frame, or (if
167    * embed=true) add it to the applet container instead.
168    * 
169    * @param embed
170    * @param applet
171    */
172   protected void createSplitFrameWindow(boolean embed, JalviewLite applet)
173   {
174     if (embed)
175     {
176       applet.add(outermost);
177       applet.validate();
178     }
179     else
180     {
181       this.add(outermost);
182       int width = Math.max(topFrame.DEFAULT_WIDTH,
183               bottomFrame.DEFAULT_WIDTH);
184       int height = topFrame.DEFAULT_HEIGHT + bottomFrame.DEFAULT_HEIGHT;
185       jalview.bin.JalviewLite
186               .addFrame(this, this.getTitle(), width, height);
187     }
188   }
189 }