JAL-2611 Still not happy with behaviour
[jalview.git] / src / jalview / viewmodel / OverviewDimensionsShowHidden.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.AllColsCollection;
27 import jalview.datamodel.AllRowsCollection;
28 import jalview.datamodel.HiddenColumns;
29 import jalview.datamodel.HiddenSequences;
30
31 public class OverviewDimensionsShowHidden extends OverviewDimensions
32 {
33   private ViewportRanges ranges;
34
35   /**
36    * Create an OverviewDimensions object
37    * 
38    * @param ranges
39    *          positional properties of the viewport
40    * @param showAnnotationPanel
41    *          true if the annotation panel is to be shown, false otherwise
42    */
43   public OverviewDimensionsShowHidden(ViewportRanges vpranges,
44           boolean showAnnotationPanel)
45   {
46     super(vpranges, showAnnotationPanel);
47     ranges = vpranges;
48     resetAlignmentDims();
49   }
50
51   /**
52    * Check box dimensions and scroll positions and correct if necessary
53    * 
54    * @param mousex
55    *          x position in overview panel
56    * @param mousey
57    *          y position in overview panel
58    * @param hiddenSeqs
59    *          hidden sequences
60    * @param hiddenCols
61    *          hidden columns
62    * @param ranges
63    *          viewport position properties
64    */
65   @Override
66   public void updateViewportFromMouse(int mousex, int mousey,
67           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
68   {
69     int xAsRes = getLeftXFromCentreX(mousex, hiddenCols);
70     int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs);
71
72     updateViewportFromTopLeft(xAsRes, yAsSeq, hiddenSeqs, hiddenCols);
73   }
74
75   @Override
76   public void adjustViewportFromMouse(int mousex, int mousey,
77           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
78   {
79     // calculate translation in pixel terms:
80     // get mouse location in viewport coords, add translation in viewport
81     // coords,
82     // convert back to pixel coords
83     int vpx = Math.round((float) mousex * alwidth / width);
84     // int visXAsRes = hiddenCols.findColumnPosition(vpx);
85
86     int vpy = Math.round((float) mousey * alheight / sequencesHeight);
87     // int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
88
89     System.out.println("vpx: " + vpx);
90     // System.out.println("VisXAsRes: " + visXAsRes);
91     System.out.println("transX: " + transX);
92     // updateViewportFromTopLeft(vpx + transX, vpy + transY,
93     // hiddenSeqs,
94     // hiddenCols);
95
96     int xAsRes = vpx + transX;
97     int yAsSeq = vpy + transY;
98
99     resetAlignmentDims();
100
101     if (xAsRes < 0)
102     {
103       xAsRes = 0;
104     }
105
106     if (yAsSeq < 0)
107     {
108       yAsSeq = 0;
109     }
110
111     //
112     // Convert x value to residue position
113     //
114
115     // need to determine where scrollCol should be, given x
116     // to do this also need to know width of viewport, and some hidden column
117     // correction
118
119     // convert x to residues - this is an absolute position
120     // int xAsRes = Math.round((float) x * alwidth / width);
121
122     // get viewport width in residues
123     int vpwidth = ranges.getViewportWidth();
124
125     // get where x should be when accounting for hidden cols
126     // if x is in a hidden col region, shift to left - but we still need
127     // absolute position
128     // so convert back after getting visible region position
129     // int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
130     int visXAsRes = xAsRes;
131
132     // check in case we went off the edge of the alignment
133     int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
134     /*    if (visXAsRes + vpwidth - 1 > visAlignWidth)
135     {
136       // went past the end of the alignment, adjust backwards
137     
138       // if last position was before the end of the alignment, need to update
139       if (ranges.getEndRes() < visAlignWidth)
140       {
141         visXAsRes = hiddenCols.findColumnPosition(hiddenCols
142                 .subtractVisibleColumns(vpwidth - 1, alwidth - 1));
143       }
144       else
145       {
146         visXAsRes = ranges.getStartRes();
147       }
148     }*/
149
150     //
151     // Convert y value to sequence position
152     //
153
154     // convert y to residues
155     // int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
156
157     // get viewport height in sequences
158     int vpheight = ranges.getViewportHeight();
159
160     // get where y should be when accounting for hidden rows
161     // if y is in a hidden row region, shift up - but we still need absolute
162     // position,
163     // so convert back after getting visible region position
164     yAsSeq = hiddenSeqs.adjustForHiddenSeqs(
165             hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq));
166
167     // check in case we went off the edge of the alignment
168     int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
169     int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
170     if (visYAsSeq + vpheight - 1 > visAlignHeight)
171     {
172       // went past the end of the alignment, adjust backwards
173       if (ranges.getEndSeq() < visAlignHeight)
174       {
175         visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(
176                 hiddenSeqs.subtractVisibleRows(vpheight - 1, alheight - 1));
177       }
178       else
179       {
180         visYAsSeq = ranges.getStartSeq();
181       }
182     }
183
184     // update viewport
185     ranges.setStartRes(visXAsRes);
186     ranges.setStartSeq(visYAsSeq);
187   }
188
189   @Override
190   protected void updateViewportFromTopLeft(int xAsRes, int yAsSeq,
191           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
192   {
193
194     resetAlignmentDims();
195
196     if (xAsRes < 0)
197     {
198       xAsRes = 0;
199     }
200
201     if (yAsSeq < 0)
202     {
203       yAsSeq = 0;
204     }
205
206     //
207     // Convert x value to residue position
208     //
209
210     // need to determine where scrollCol should be, given x
211     // to do this also need to know width of viewport, and some hidden column
212     // correction
213
214     // convert x to residues - this is an absolute position
215     // int xAsRes = Math.round((float) x * alwidth / width);
216
217     // get viewport width in residues
218     int vpwidth = ranges.getViewportWidth();
219
220     // get where x should be when accounting for hidden cols
221     // if x is in a hidden col region, shift to left - but we still need
222     // absolute position
223     // so convert back after getting visible region position
224     int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
225
226     // check in case we went off the edge of the alignment
227     int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
228     if (visXAsRes + vpwidth - 1 > visAlignWidth)
229     {
230       // went past the end of the alignment, adjust backwards
231
232       // if last position was before the end of the alignment, need to update
233       if (ranges.getEndRes() < visAlignWidth)
234       {
235         visXAsRes = hiddenCols.findColumnPosition(hiddenCols
236                 .subtractVisibleColumns(vpwidth - 1, alwidth - 1));
237       }
238       else
239       {
240         visXAsRes = ranges.getStartRes();
241       }
242     }
243
244     //
245     // Convert y value to sequence position
246     //
247
248     // convert y to residues
249     // int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
250
251     // get viewport height in sequences
252     int vpheight = ranges.getViewportHeight();
253
254     // get where y should be when accounting for hidden rows
255     // if y is in a hidden row region, shift up - but we still need absolute
256     // position,
257     // so convert back after getting visible region position
258     yAsSeq = hiddenSeqs.adjustForHiddenSeqs(hiddenSeqs
259             .findIndexWithoutHiddenSeqs(yAsSeq));
260
261     // check in case we went off the edge of the alignment
262     int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
263     int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
264     if (visYAsSeq + vpheight - 1 > visAlignHeight)
265     {
266       // went past the end of the alignment, adjust backwards
267       if (ranges.getEndSeq() < visAlignHeight)
268       {
269         visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs
270                 .subtractVisibleRows(vpheight - 1, alheight - 1));
271       }
272       else
273       {
274         visYAsSeq = ranges.getStartSeq();
275       }
276     }
277
278     // update viewport
279     ranges.setStartRes(visXAsRes);
280     ranges.setStartSeq(visYAsSeq);
281
282   }
283
284   /**
285    * Update the overview panel box when the associated alignment panel is
286    * changed
287    * 
288    * @param hiddenSeqs
289    *          hidden sequences
290    * @param hiddenCols
291    *          hidden columns
292    * @param ranges
293    *          viewport position properties
294    */
295   @Override
296   public void setBoxPosition(HiddenSequences hiddenSeqs,
297           HiddenColumns hiddenCols)
298   {
299
300     // work with absolute values of startRes and endRes
301     int startRes = hiddenCols.adjustForHiddenColumns(ranges.getStartRes());
302     int endRes = hiddenCols.adjustForHiddenColumns(ranges.getEndRes());
303
304     // work with absolute values of startSeq and endSeq
305     int startSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getStartSeq());
306     int endSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getEndSeq());
307
308     setBoxPosition(startRes, startSeq, endRes - startRes + 1, endSeq
309             - startSeq + 1);
310   }
311
312   @Override
313   public AlignmentColsCollectionI getColumns(AlignmentI al)
314   {
315     return new AllColsCollection(0,
316             ranges.getAbsoluteAlignmentWidth() - 1, al);
317   }
318
319   @Override
320   public AlignmentRowsCollectionI getRows(AlignmentI al)
321   {
322     return new AllRowsCollection(0,
323             ranges.getAbsoluteAlignmentHeight() - 1,
324             al);
325   }
326
327   @Override
328   protected void resetAlignmentDims()
329   {
330     alwidth = ranges.getAbsoluteAlignmentWidth();
331     alheight = ranges.getAbsoluteAlignmentHeight();
332   }
333
334   @Override
335   protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
336   {
337     int vpx = Math.round((float) mousex * alwidth / width);
338     return hidden.subtractVisibleColumns(ranges.getViewportWidth() / 2,
339             vpx);
340   }
341
342   @Override
343   protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
344   {
345     int vpy = Math.round((float) mousey * alheight / sequencesHeight);
346     return hidden.subtractVisibleRows(ranges.getViewportHeight() / 2, vpy);
347   }
348
349   @Override
350   public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
351           HiddenColumns hiddenCols)
352   {
353     {
354       // get alignment position of x and box (can get directly from vpranges) and calc difference
355       int vpx = Math.round((float) x * alwidth / width);
356       int visXAsRes = hiddenCols.findColumnPosition(vpx);
357       
358       int vpy = Math.round((float) y * alheight / sequencesHeight);
359       int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
360
361       transX = ranges.getStartRes() - visXAsRes;
362       transY = ranges.getStartSeq() - visYAsRes;
363     }
364   }
365
366 }