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