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