c153dc1505545ecf79fc1a7d10c2a9e71a09a6d1
[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.AlignmentColsCollectionI;
24 import jalview.api.AlignmentRowsCollectionI;
25 import jalview.datamodel.AlignmentI;
26 import jalview.datamodel.HiddenColumns;
27 import jalview.datamodel.HiddenSequences;
28
29 import java.awt.Dimension;
30 import java.awt.Graphics;
31
32 public abstract class OverviewDimensions
33 {
34   protected static final int MAX_WIDTH = 400;
35
36   protected static final int MIN_WIDTH = 120;
37
38   protected static final int MIN_SEQ_HEIGHT = 40;
39
40   protected static final int MAX_SEQ_HEIGHT = 300;
41
42   private static final int DEFAULT_GRAPH_HEIGHT = 20;
43
44   protected int width;
45
46   protected int sequencesHeight;
47
48   protected int graphHeight = DEFAULT_GRAPH_HEIGHT;
49
50   protected int boxX = -1;
51
52   protected int boxY = -1;
53
54   protected int boxWidth = -1;
55
56   protected int boxHeight = -1;
57
58   protected int alwidth;
59
60   protected int alheight;
61
62   protected float widthRatio;
63
64   protected float heightRatio;
65
66   /**
67    * Create an OverviewDimensions object
68    * 
69    * @param ranges
70    *          positional properties of the viewport
71    * @param showAnnotationPanel
72    *          true if the annotation panel is to be shown, false otherwise
73    */
74   public OverviewDimensions(ViewportRanges ranges,
75           boolean showAnnotationPanel, Dimension dim)
76   {
77     if (!showAnnotationPanel)
78     {
79       graphHeight = 0;
80     }
81
82     // scale the initial size of overviewpanel to shape of alignment
83     float initialScale = (float) ranges.getAbsoluteAlignmentWidth()
84             / (float) ranges.getAbsoluteAlignmentHeight();
85
86     if (dim != null)
87     {
88       width = dim.width;
89       sequencesHeight = dim.height;
90       return;
91     }
92
93     if (ranges.getAbsoluteAlignmentWidth() > ranges
94             .getAbsoluteAlignmentHeight())
95     {
96       // wider
97       width = MAX_WIDTH;
98       sequencesHeight = Math.round(MAX_WIDTH / initialScale);
99       if (sequencesHeight < MIN_SEQ_HEIGHT)
100       {
101         sequencesHeight = MIN_SEQ_HEIGHT;
102       }
103     }
104     else
105     {
106       // taller
107       width = Math.round(MAX_WIDTH * initialScale);
108       sequencesHeight = MAX_SEQ_HEIGHT;
109
110       if (width < MIN_WIDTH)
111       {
112         width = MIN_WIDTH;
113       }
114     }
115   }
116
117   /**
118    * Draw the overview panel's viewport box on a graphics object
119    * 
120    * @param g
121    *          the graphics object to draw on
122    */
123   public void drawBox(Graphics g)
124   {
125     g.drawRect(boxX, boxY, boxWidth, boxHeight);
126     g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
127   }
128
129   public int getBoxX()
130   {
131     return boxX;
132   }
133
134   public int getBoxY()
135   {
136     return boxY;
137   }
138
139   public int getBoxWidth()
140   {
141     return boxWidth;
142   }
143
144   public int getBoxHeight()
145   {
146     return boxHeight;
147   }
148
149   public int getWidth()
150   {
151     return width;
152   }
153
154   public int getHeight()
155   {
156     return sequencesHeight + graphHeight;
157   }
158
159   public int getSequencesHeight()
160   {
161     return sequencesHeight;
162   }
163
164   public int getGraphHeight()
165   {
166     return graphHeight;
167   }
168
169   public float getPixelsPerCol()
170   {
171     resetAlignmentDims();
172     return 1 / widthRatio;
173   }
174
175   public float getPixelsPerSeq()
176   {
177     resetAlignmentDims();
178     return 1 / heightRatio;
179   }
180
181   public void setWidth(int w)
182   {
183     width = w;
184     widthRatio = (float) alwidth / width;
185   }
186
187   public void setHeight(int h)
188   {
189     sequencesHeight = h - graphHeight;
190     heightRatio = (float) alheight / sequencesHeight;
191   }
192
193   /**
194    * Update the viewport location from a mouse click in the overview panel
195    * 
196    * @param mousex
197    *          x location of mouse
198    * @param mousey
199    *          y location of mouse
200    * @param hiddenSeqs
201    *          the alignment's hidden sequences
202    * @param hiddenCols
203    *          the alignment's hidden columns
204    */
205   public abstract void updateViewportFromMouse(int mousex, int mousey,
206           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
207
208   /**
209    * Update the viewport location from a mouse drag within the overview's box
210    * 
211    * @param mousex
212    *          x location of mouse
213    * @param mousey
214    *          y location of mouse
215    * @param hiddenSeqs
216    *          the alignment's hidden sequences
217    * @param hiddenCols
218    *          the alignment's hidden columns
219    */
220   public abstract void adjustViewportFromMouse(int mousex, int mousey,
221           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
222
223   /**
224    * Initialise dragging from the mouse - must be called on initial mouse click
225    * before using adjustViewportFromMouse in drag operations
226    * 
227    * @param mousex
228    *          x location of mouse
229    * @param mousey
230    *          y location of mouse
231    * @param hiddenSeqs
232    *          the alignment's hidden sequences
233    * @param hiddenCols
234    *          the alignment's hidden columns
235    */
236   public abstract void setDragPoint(int x, int y,
237           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
238
239   /*
240    * Move the viewport so that the top left corner of the overview's box 
241    * is at the mouse position (leftx, topy)
242    */
243   protected abstract void updateViewportFromTopLeft(int leftx, int topy,
244           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
245
246   /**
247    * Set the overview panel's box position to match the viewport
248    * 
249    * @param hiddenSeqs
250    *          the alignment's hidden sequences
251    * @param hiddenCols
252    *          the alignment's hidden columns
253    */
254   public abstract void setBoxPosition(HiddenSequences hiddenSeqs,
255           HiddenColumns hiddenCols);
256
257   /**
258    * Get the collection of columns used by this overview dimensions object
259    * 
260    * @param hiddenCols
261    *          the alignment's hidden columns
262    * @return a column collection
263    */
264   public abstract AlignmentColsCollectionI getColumns(AlignmentI al);
265
266   /**
267    * Get the collection of rows used by this overview dimensions object
268    * 
269    * @param al
270    *          the alignment
271    * @return a row collection
272    */
273   public abstract AlignmentRowsCollectionI getRows(AlignmentI al);
274
275   /**
276    * Updates overview dimensions to account for current alignment dimensions
277    */
278   protected abstract void resetAlignmentDims();
279
280   /*
281    * Given the box coordinates in residues and sequences, set the box dimensions in the overview window
282    */
283   protected void setBoxPosition(int startRes, int startSeq, int vpwidth,
284           int vpheight)
285   {
286     resetAlignmentDims();
287
288     // boxX, boxY is the x,y location equivalent to startRes, startSeq
289     int xPos = Math.min(startRes, alwidth - vpwidth + 1);
290     boxX = Math.round(xPos / widthRatio);
291     boxY = Math.round(startSeq / heightRatio);
292
293     // boxWidth is the width in residues translated to pixels
294     boxWidth = Math.round(vpwidth / widthRatio);
295
296     // boxHeight is the height in sequences translated to pixels
297     boxHeight = Math.round(vpheight / heightRatio);
298   }
299
300   /**
301    * Answers if a mouse position is in the overview's red box
302    * 
303    * @param x
304    *          mouse x position
305    * @param y
306    *          mouse y position
307    * @return true if (x,y) is inside the box
308    */
309   public boolean isPositionInBox(int x, int y)
310   {
311     return (x > boxX && y > boxY && x < boxX + boxWidth
312             && y < boxY + boxHeight);
313   }
314
315   /*
316    * Given the centre x position, calculate the box's left x position
317    */
318   protected abstract int getLeftXFromCentreX(int mousex,
319           HiddenColumns hidden);
320
321   /*
322    * Given the centre y position, calculate the box's top y position
323    */
324   protected abstract int getTopYFromCentreY(int mousey,
325           HiddenSequences hidden);
326
327 }