JAL-2388 Initial refactor of OverviewPanel
[jalview.git] / src / jalview / viewmodel / OverviewDimensions.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.viewmodel;
22
23 import jalview.api.AlignViewportI;
24
25 public class OverviewDimensions
26 {
27   // Default width and height values
28   private static final int DEFAULT_GRAPH_HEIGHT = 20;
29
30   private static final int MAX_WIDTH = 400;
31
32   private static final int MIN_WIDTH = 120;
33
34   private static final int MIN_SEQ_HEIGHT = 40;
35
36   private static final int MAX_SEQ_HEIGHT = 300;
37
38   private AlignViewportI av;
39
40   private float scalew = 1f;
41
42   private float scaleh = 1f;
43
44   // width of the overview panel
45   private int width;
46
47   // height of sequences part of the overview panel
48   private int sequencesHeight;
49
50   // height of the graphs part of the overview panel
51   private int graphHeight = DEFAULT_GRAPH_HEIGHT;
52
53   // dimensions of box outlining current extent of view in alignment panel
54   // location of left side of box
55   private int boxX = -1;
56
57   // location of bottom of box
58   private int boxY = -1;
59
60   // width of box
61   private int boxWidth = -1;
62
63   // height of box
64   private int boxHeight = -1;
65
66   private int scrollCol = -1;
67
68   private int scrollRow = -1;
69
70   public OverviewDimensions(AlignViewportI avi)
71   {
72     this.av = avi;
73
74     // scale the initial size of overviewpanel to shape of alignment
75     float initialScale = (float) av.getAlignment().getWidth()
76             / (float) av.getAlignment().getHeight();
77
78     // TODO: in applet this was getSequenceConsensusHash()
79     // check if it makes any functional difference
80     if (av.getAlignmentConservationAnnotation() == null)
81     {
82       graphHeight = 0;
83     }
84
85     if (av.getAlignment().getWidth() > av.getAlignment().getHeight())
86     {
87       // wider
88       width = MAX_WIDTH;
89       sequencesHeight = (int) (MAX_WIDTH / initialScale);
90       if (sequencesHeight < MIN_SEQ_HEIGHT)
91       {
92         sequencesHeight = MIN_SEQ_HEIGHT;
93       }
94     }
95     else
96     {
97       // taller
98       width = (int) (MAX_WIDTH * initialScale);
99       sequencesHeight = MAX_SEQ_HEIGHT;
100
101       if (width < MIN_WIDTH)
102       {
103         width = MIN_WIDTH;
104       }
105     }
106   }
107
108   /**
109    * Check box dimensions and scroll positions and correct if necessary
110    */
111   public void checkValid()
112   {
113     if (boxY < 0)
114     {
115       boxY = 0;
116     }
117
118     if (boxY > (sequencesHeight - boxHeight))
119     {
120       boxY = sequencesHeight - boxHeight + 1;
121     }
122
123     if (boxX < 0)
124     {
125       boxX = 0;
126     }
127
128     if (boxX > (width - boxWidth))
129     {
130       if (av.hasHiddenColumns())
131       {
132         // Try smallest possible box
133         boxWidth = (int) ((av.getEndRes() - av.getStartRes() + 1)
134                 * av.getCharWidth() * scalew);
135       }
136       boxX = width - boxWidth;
137     }
138
139     scrollCol = (int) (boxX / scalew / av.getCharWidth());
140     scrollRow = (int) (boxY / scaleh / av.getCharHeight());
141
142     if (av.hasHiddenColumns())
143     {
144       if (!av.getColumnSelection().isVisible(scrollCol))
145       {
146         return;
147       }
148
149       scrollCol = av.getColumnSelection().findColumnPosition(scrollCol);
150     }
151
152     if (av.hasHiddenRows())
153     {
154       scrollRow = av.getAlignment().getHiddenSequences()
155               .findIndexWithoutHiddenSeqs(scrollRow);
156     }
157   }
158
159   /**
160    * Update the overview panel box when the associated alignment panel is
161    * changed
162    * 
163    */
164   public void setBoxPosition()
165   {
166     updateScales();
167
168     int startRes = av.getStartRes();
169     int endRes = av.getEndRes();
170
171     if (av.hasHiddenColumns())
172     {
173       startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
174       endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
175     }
176
177     int startSeq = av.getStartSeq();
178     int endSeq = av.getEndSeq();
179
180     if (av.hasHiddenRows())
181     {
182       startSeq = av.getAlignment().getHiddenSequences()
183               .adjustForHiddenSeqs(startSeq);
184
185       endSeq = av.getAlignment().getHiddenSequences()
186               .adjustForHiddenSeqs(endSeq);
187
188     }
189
190     boxX = (int) (startRes * av.getCharWidth() * scalew);
191     boxY = (int) (startSeq * av.getCharHeight() * scaleh);
192
193     if (av.hasHiddenColumns())
194     {
195       boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
196     }
197     else
198     {
199       boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
200     }
201
202     boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
203   }
204
205   /**
206    * Update width and height scales in terms of the alignment width and height
207    */
208   public void updateScales()
209   {
210     int alwidth = av.getAlignment().getWidth();
211     int alheight = av.getAlignment().getHeight()
212             + av.getAlignment().getHiddenSequences().getSize();
213
214     int fullsizeWidth = alwidth * av.getCharWidth();
215     int fullsizeHeight = alheight * av.getCharHeight();
216
217     scalew = (float) width / fullsizeWidth;
218     scaleh = (float) sequencesHeight / fullsizeHeight;
219   }
220
221   // don't like this, scroll vals are separate from setting code
222   public int getScrollCol()
223   {
224     return scrollCol;
225   }
226
227   public int getScrollRow()
228   {
229     return scrollRow;
230   }
231
232   public int getBoxX()
233   {
234     return boxX;
235   }
236
237   public int getBoxY()
238   {
239     return boxY;
240   }
241
242   public int getBoxWidth()
243   {
244     return boxWidth;
245   }
246
247   public int getBoxHeight()
248   {
249     return boxHeight;
250   }
251
252   public void setBoxX(int x)
253   {
254     boxX = x;
255   }
256
257   public void setBoxY(int y)
258   {
259     boxY = y;
260   }
261
262   public void setWidth(int w)
263   {
264     width = w;
265   }
266
267   public void setHeight(int h)
268   {
269     sequencesHeight = h - graphHeight;
270   }
271
272   public int getWidth()
273   {
274     return width;
275   }
276
277   public int getHeight()
278   {
279     return sequencesHeight + graphHeight;
280   }
281
282   public int getSequencesHeight()
283   {
284     return sequencesHeight;
285   }
286
287   public int getGraphHeight()
288   {
289     return graphHeight;
290   }
291 }