JAL-2611 Better
[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     int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
73     yAsSeq = hiddenSeqs.adjustForHiddenSeqs(
74             hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq));
75     int visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
76
77     updateViewportFromTopLeft(visXAsRes, visYAsSeq, hiddenSeqs, hiddenCols);
78   }
79
80   @Override
81   public void adjustViewportFromMouse(int mousex, int mousey,
82           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
83   {
84     // calculate translation in pixel terms:
85     // get mouse location in viewport coords, add translation in viewport
86     // coords,
87     // convert back to pixel coords
88     int vpx = Math.round((float) mousex * alwidth / width);
89     int visXAsRes = hiddenCols.findColumnPosition(vpx) + fixedX;
90
91     int vpy = Math.round((float) mousey * alheight / sequencesHeight);
92     int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy) + fixedY;
93
94     updateViewportFromTopLeft(visXAsRes, visYAsRes,
95             hiddenSeqs,
96             hiddenCols);
97   }
98
99   @Override
100   protected void updateViewportFromTopLeft(int visXAsRes, int visYAsSeq,
101           HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
102   {
103
104     resetAlignmentDims();
105
106     if (visXAsRes < 0)
107     {
108       visXAsRes = 0;
109     }
110
111     if (visYAsSeq < 0)
112     {
113       visYAsSeq = 0;
114     }
115
116     //
117     // Convert x value to residue position
118     //
119
120     // need to determine where scrollCol should be, given x
121     // to do this also need to know width of viewport, and some hidden column
122     // correction
123
124     // convert x to residues - this is an absolute position
125     // int xAsRes = Math.round((float) x * alwidth / width);
126
127     // get viewport width in residues
128     int vpwidth = ranges.getViewportWidth();
129
130     // get where x should be when accounting for hidden cols
131     // if x is in a hidden col region, shift to left - but we still need
132     // absolute position
133     // so convert back after getting visible region position
134
135
136     // check in case we went off the edge of the alignment
137     int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
138     if (visXAsRes + vpwidth - 1 > visAlignWidth)
139     {
140       // went past the end of the alignment, adjust backwards
141
142       // if last position was before the end of the alignment, need to update
143       if (ranges.getEndRes() < visAlignWidth)
144       {
145         visXAsRes = hiddenCols.findColumnPosition(hiddenCols
146                 .subtractVisibleColumns(vpwidth - 1, alwidth - 1));
147       }
148       else
149       {
150         visXAsRes = ranges.getStartRes();
151       }
152     }
153
154     //
155     // Convert y value to sequence position
156     //
157
158     // convert y to residues
159     // int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
160
161     // get viewport height in sequences
162     int vpheight = ranges.getViewportHeight();
163
164     // get where y should be when accounting for hidden rows
165     // if y is in a hidden row region, shift up - but we still need absolute
166     // position,
167     // so convert back after getting visible region position
168
169
170     // check in case we went off the edge of the alignment
171     int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight);
172
173     if (visYAsSeq + vpheight - 1 > visAlignHeight)
174     {
175       // went past the end of the alignment, adjust backwards
176       if (ranges.getEndSeq() < visAlignHeight)
177       {
178         visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs
179                 .subtractVisibleRows(vpheight - 1, alheight - 1));
180       }
181       else
182       {
183         visYAsSeq = ranges.getStartSeq();
184       }
185     }
186
187     // update viewport
188     ranges.setStartRes(visXAsRes);
189     ranges.setStartSeq(visYAsSeq);
190
191   }
192
193   /**
194    * Update the overview panel box when the associated alignment panel is
195    * changed
196    * 
197    * @param hiddenSeqs
198    *          hidden sequences
199    * @param hiddenCols
200    *          hidden columns
201    * @param ranges
202    *          viewport position properties
203    */
204   @Override
205   public void setBoxPosition(HiddenSequences hiddenSeqs,
206           HiddenColumns hiddenCols)
207   {
208
209     // work with absolute values of startRes and endRes
210     int startRes = hiddenCols.adjustForHiddenColumns(ranges.getStartRes());
211     int endRes = hiddenCols.adjustForHiddenColumns(ranges.getEndRes());
212
213     // work with absolute values of startSeq and endSeq
214     int startSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getStartSeq());
215     int endSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getEndSeq());
216
217     System.out.println("Update box: startres: " + startRes);
218
219     setBoxPosition(startRes, startSeq, endRes - startRes + 1, endSeq
220             - startSeq + 1);
221   }
222
223   @Override
224   public AlignmentColsCollectionI getColumns(AlignmentI al)
225   {
226     return new AllColsCollection(0,
227             ranges.getAbsoluteAlignmentWidth() - 1, al);
228   }
229
230   @Override
231   public AlignmentRowsCollectionI getRows(AlignmentI al)
232   {
233     return new AllRowsCollection(0,
234             ranges.getAbsoluteAlignmentHeight() - 1,
235             al);
236   }
237
238   @Override
239   protected void resetAlignmentDims()
240   {
241     alwidth = ranges.getAbsoluteAlignmentWidth();
242     alheight = ranges.getAbsoluteAlignmentHeight();
243   }
244
245   @Override
246   protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
247   {
248     int vpx = Math.round((float) mousex * alwidth / width);
249     return hidden.subtractVisibleColumns(ranges.getViewportWidth() / 2,
250             vpx);
251   }
252
253   @Override
254   protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
255   {
256     int vpy = Math.round((float) mousey * alheight / sequencesHeight);
257     return hidden.subtractVisibleRows(ranges.getViewportHeight() / 2, vpy);
258   }
259
260   @Override
261   public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
262           HiddenColumns hiddenCols)
263   {
264     {
265       // get alignment position of x and box (can get directly from vpranges) and calc difference
266       int vpx = Math.round((float) x * alwidth / width);
267       fixedX = ranges.getStartRes() - hiddenCols.findColumnPosition(vpx);
268
269       int vpy = Math.round((float) y * alheight / sequencesHeight);
270       fixedY = ranges.getStartSeq()
271               - hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
272     }
273   }
274
275 }