minor Platform.isAMac() clean up
[jalview.git] / src / jalview / jbgui / GSplitFrame.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.jbgui;
22
23 import jalview.util.Platform;
24
25 import java.awt.Component;
26 import java.awt.MouseInfo;
27 import java.awt.Point;
28 import java.awt.Rectangle;
29
30 import javax.swing.JInternalFrame;
31 import javax.swing.JSplitPane;
32 import javax.swing.plaf.basic.BasicInternalFrameUI;
33
34 public class GSplitFrame extends JInternalFrame
35 {
36   protected static final int DIVIDER_SIZE = 5;
37
38   private static final long serialVersionUID = 1L;
39
40   private GAlignFrame topFrame;
41
42   private GAlignFrame bottomFrame;
43
44   private JSplitPane splitPane;
45
46   /*
47    * proportional position of split divider; saving this allows it to be
48    * restored after hiding one half and resizing
49    */
50   private double dividerRatio;
51
52   /**
53    * Constructor
54    * 
55    * @param top
56    * @param bottom
57    */
58   public GSplitFrame(GAlignFrame top, GAlignFrame bottom)
59   {
60     this.topFrame = top;
61     this.bottomFrame = bottom;
62
63     hideTitleBars();
64
65     addSplitPane();
66   }
67
68   /**
69    * Create and add the split pane containing the top and bottom components.
70    */
71   protected void addSplitPane()
72   {
73     splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame,
74             bottomFrame);
75     splitPane.setVisible(true);
76
77     /*
78      * set divider split at 50:50, or restore saved split if loading from
79      * project
80      */
81     int topFrameHeight = topFrame.getHeight();
82     /**
83      * TODO SplitFrame.setDividerLocation
84      * 
85      * @j2sNative
86      */
87     {
88       splitPane.setDividerSize(DIVIDER_SIZE);
89       if (topFrameHeight == 0)
90       {
91         setRelativeDividerLocation(0.5d); // as a proportion
92       }
93       else
94       {
95         int dividerPosition = topFrameHeight + DIVIDER_SIZE / 2;
96         splitPane.setDividerLocation(dividerPosition); // absolute position
97       }
98       splitPane.setResizeWeight(0.5d);
99     }
100     add(splitPane);
101   }
102
103   /**
104    * Try to hide the title bars as a waste of precious space.
105    * 
106    * @see http
107    *      ://stackoverflow.com/questions/7218971/java-method-works-on-windows
108    *      -but-not-macintosh -java
109    */
110   protected void hideTitleBars()
111   {
112     if (Platform.isAMac())
113     {
114       // this saves some space - but doesn't hide the title bar
115       topFrame.putClientProperty("JInternalFrame.isPalette", true);
116       // topFrame.getRootPane().putClientProperty("Window.style", "small");
117       bottomFrame.putClientProperty("JInternalFrame.isPalette", true);
118     }
119     else
120     {
121       /**
122        * @j2sNative
123        */
124       {
125         ((BasicInternalFrameUI) topFrame.getUI()).setNorthPane(null);
126         ((BasicInternalFrameUI) bottomFrame.getUI()).setNorthPane(null);
127       }
128     }
129   }
130
131   public GAlignFrame getTopFrame()
132   {
133     return topFrame;
134   }
135
136   public GAlignFrame getBottomFrame()
137   {
138     return bottomFrame;
139   }
140
141   /**
142    * Returns the split pane component the mouse is in, or null if neither.
143    * 
144    * @return
145    */
146   protected GAlignFrame getFrameAtMouse()
147   {
148     Point loc = MouseInfo.getPointerInfo().getLocation();
149
150     if (isIn(loc, splitPane.getTopComponent()))
151     {
152       return getTopFrame();
153     }
154     else if (isIn(loc, splitPane.getBottomComponent()))
155     {
156       return getBottomFrame();
157     }
158     return null;
159   }
160
161   private boolean isIn(Point loc, Component comp)
162   {
163     if (!comp.isVisible())
164     {
165       return false;
166     }
167     Point p = comp.getLocationOnScreen();
168     Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(),
169             comp.getHeight());
170     return r.contains(loc);
171   }
172
173   /**
174    * Makes the complement of the specified split component visible or hidden,
175    * restoring or saving the position of the split divide.
176    */
177   public void setComplementVisible(Object alignFrame, boolean show)
178   {
179     /*
180      * save divider ratio on hide, restore on show
181      */
182     if (show)
183     {
184       setRelativeDividerLocation(dividerRatio);
185     }
186     else
187     {
188       this.dividerRatio = splitPane.getDividerLocation()
189               / (double) (splitPane.getHeight()
190                       - splitPane.getDividerSize());
191     }
192
193     if (alignFrame == this.topFrame)
194     {
195       this.bottomFrame.setVisible(show);
196     }
197     else if (alignFrame == this.bottomFrame)
198     {
199       this.topFrame.setVisible(show);
200     }
201
202     validate();
203   }
204
205   /**
206    * Set the divider location as a proportion (0 <= r <= 1) of the height <br>
207    * Warning: this overloads setDividerLocation(int), and getDividerLocation()
208    * returns the int (pixel count) value
209    * 
210    * @param r
211    */
212   public void setRelativeDividerLocation(double r)
213   {
214     this.dividerRatio = r;
215     /**
216      * @j2sNative
217      */
218     {
219       splitPane.setDividerLocation(r);
220     }
221   }
222
223   /**
224    * Sets the divider location (in pixels from top)
225    * 
226    * @return
227    */
228   protected void setDividerLocation(int p)
229   {
230     /**
231      * @j2sNative
232      */
233     {
234       splitPane.setDividerLocation(p);
235     }
236   }
237
238   /**
239    * Returns the divider location (in pixels from top)
240    * 
241    * @return
242    */
243   protected int getDividerLocation()
244   {
245     return splitPane.getDividerLocation();
246   }
247 }