842a0fd4dcc93abf5d5b76a59f1e5978b237bcbb
[jalview.git] / test / jalview / viewmodel / OverviewDimensionsShowHiddenTest.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 static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertFalse;
25 import static org.testng.Assert.assertTrue;
26
27 import jalview.analysis.AlignmentGenerator;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.ColumnSelection;
31 import jalview.datamodel.HiddenColumns;
32 import jalview.datamodel.Sequence;
33 import jalview.datamodel.SequenceCollectionI;
34 import jalview.datamodel.SequenceGroup;
35 import jalview.datamodel.SequenceI;
36
37 import java.util.Hashtable;
38
39 import org.testng.annotations.AfterClass;
40 import org.testng.annotations.BeforeClass;
41 import org.testng.annotations.BeforeMethod;
42 import org.testng.annotations.Test;
43
44 @Test(singleThreaded = true)
45 public class OverviewDimensionsShowHiddenTest
46 {
47   AlignmentI al;
48   OverviewDimensionsShowHidden od;
49
50   // cached widths and heights
51   int boxWidth;
52   int boxHeight;
53   int viewHeight;
54   int viewWidth;
55   int alheight;
56   int alwidth;
57
58   ViewportRanges vpranges;
59
60   Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<>();
61
62   HiddenColumns hiddenCols = new HiddenColumns();
63
64   @BeforeClass(alwaysRun = true)
65   public void setUpAlignment()
66   {
67     // create random alignment
68     AlignmentGenerator gen = new AlignmentGenerator(false);
69     al = gen.generate(157, 525, 123, 5, 5);
70   }
71
72   @BeforeMethod(alwaysRun = true)
73   public void setUp()
74   {
75     if (!hiddenRepSequences.isEmpty())
76     {
77       al.getHiddenSequences().showAll(hiddenRepSequences);
78     }
79     ColumnSelection colsel = new ColumnSelection();
80     hiddenCols.revealAllHiddenColumns(colsel);
81     
82     vpranges = new ViewportRanges(al);
83     vpranges.setViewportStartAndHeight(0, 18);
84     vpranges.setViewportStartAndWidth(0, 63);
85
86     viewHeight = vpranges.getEndSeq() - vpranges.getStartSeq() + 1;
87     viewWidth = vpranges.getEndRes() - vpranges.getStartRes() + 1;
88
89     HiddenColumns hiddenCols = new HiddenColumns();
90
91     od = new OverviewDimensionsShowHidden(vpranges, true);
92     // Initial box sizing - default path through code
93     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
94
95     mouseClick(od, 0, 0);
96     moveViewport(0, 0);
97
98     // calculate before hidden columns so we get absolute values
99     alheight = vpranges.getAbsoluteAlignmentHeight();
100     alwidth = vpranges.getAbsoluteAlignmentWidth();
101
102     boxWidth = Math.round((float) (vpranges.getEndRes()
103             - vpranges.getStartRes() + 1)
104             * od.getWidth() / alwidth);
105     boxHeight = Math.round((float) (vpranges.getEndSeq()
106             - vpranges.getStartSeq() + 1)
107             * od.getSequencesHeight() / alheight);
108   }
109
110   @AfterClass(alwaysRun = true)
111   public void cleanUp()
112   {
113     al = null;
114   }
115
116   /**
117    * Test that the OverviewDimensions constructor sets width and height
118    * correctly
119    */
120   @Test(groups = { "Functional" })
121   public void testConstructor()
122   {
123     SequenceI seqa = new Sequence("Seq1", "ABC");
124     SequenceI seqb = new Sequence("Seq2", "ABC");
125     SequenceI seqc = new Sequence("Seq3", "ABC");
126     SequenceI seqd = new Sequence("Seq4", "ABC");
127     SequenceI seqe = new Sequence("Seq5",
128             "ABCABCABCABCABCABCABCABCBACBACBACBAC");
129
130     int defaultGraphHeight = 20;
131     int maxWidth = 400;
132     int minWidth = 120;
133     int maxSeqHeight = 300;
134     int minSeqHeight = 40;
135
136     // test for alignment with width > height
137     SequenceI[] seqs1 = new SequenceI[] { seqa, seqb };
138     Alignment al1 = new Alignment(seqs1);
139     ViewportRanges props = new ViewportRanges(al1);
140
141     OverviewDimensions od = new OverviewDimensionsShowHidden(props, true);
142     int scaledHeight = 267;
143     assertEquals(od.getGraphHeight(), defaultGraphHeight);
144     assertEquals(od.getSequencesHeight(), scaledHeight);
145     assertEquals(od.getWidth(), maxWidth);
146     assertEquals(od.getHeight(), scaledHeight + defaultGraphHeight);
147
148     // test for alignment with width < height
149     SequenceI[] seqs2 = new SequenceI[] { seqa, seqb, seqc, seqd };
150     Alignment al2 = new Alignment(seqs2);
151     props = new ViewportRanges(al2);
152
153     od = new OverviewDimensionsShowHidden(props, true);
154     int scaledWidth = 300;
155     assertEquals(od.getGraphHeight(), defaultGraphHeight);
156     assertEquals(od.getSequencesHeight(), maxSeqHeight);
157     assertEquals(od.getWidth(), scaledWidth);
158     assertEquals(od.getHeight(), scaledWidth + defaultGraphHeight);
159
160     // test for alignment with width > height and sequence height scaled below
161     // min value
162     SequenceI[] seqs3 = new SequenceI[] { seqe };
163     Alignment al3 = new Alignment(seqs3);
164     props = new ViewportRanges(al3);
165
166     od = new OverviewDimensionsShowHidden(props, true);
167     assertEquals(od.getGraphHeight(), defaultGraphHeight);
168     assertEquals(od.getSequencesHeight(), minSeqHeight);
169     assertEquals(od.getWidth(), maxWidth);
170     assertEquals(od.getHeight(), minSeqHeight + defaultGraphHeight);
171
172     // test for alignment with width < height and width scaled below min value
173     SequenceI[] seqs4 = new SequenceI[] { seqa, seqb, seqc, seqd, seqa,
174         seqb, seqc, seqd, seqa, seqb, seqc, seqd, seqa, seqb, seqc, seqd };
175     Alignment al4 = new Alignment(seqs4);
176     props = new ViewportRanges(al4);
177
178     od = new OverviewDimensionsShowHidden(props, true);
179     assertEquals(od.getGraphHeight(), defaultGraphHeight);
180     assertEquals(od.getSequencesHeight(), maxSeqHeight);
181     assertEquals(od.getWidth(), minWidth);
182     assertEquals(od.getHeight(), maxSeqHeight + defaultGraphHeight);
183
184     Alignment al5 = new Alignment(seqs4);
185     props = new ViewportRanges(al5);
186
187     od = new OverviewDimensionsShowHidden(props, false);
188     assertEquals(od.getGraphHeight(), 0);
189     assertEquals(od.getSequencesHeight(), maxSeqHeight);
190     assertEquals(od.getWidth(), minWidth);
191     assertEquals(od.getHeight(), maxSeqHeight);
192   }
193
194   /**
195    * Test that validation after mouse adjustments to boxX and boxY sets box
196    * dimensions and scroll values correctly, when there are no hidden rows or
197    * columns.
198    */
199   @Test(groups = { "Functional" })
200   public void testSetBoxFromMouseClick()
201   {
202     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
203     assertEquals(od.getBoxX(), 0);
204     assertEquals(od.getBoxY(), 0);
205     assertEquals(od.getBoxWidth(), boxWidth);
206     assertEquals(vpranges.getStartRes(), 0);
207     assertEquals(vpranges.getStartSeq(), 0);
208
209     // negative boxX value reset to 0
210     mouseClick(od, -5, 10);
211     assertEquals(od.getBoxX(), 0);
212     assertEquals(od.getBoxWidth(), boxWidth);
213     assertEquals(od.getBoxHeight(), boxHeight);
214     assertEquals(vpranges.getStartSeq() + vpranges.getViewportHeight() / 2,
215             Math.round((float) 10 * alheight / od.getSequencesHeight()));
216     assertEquals(vpranges.getStartRes(), 0);
217
218     // negative boxY value reset to 0
219     mouseClick(od, 6, -2);
220     assertEquals(od.getBoxY(), 0);
221     assertEquals(od.getBoxWidth(), boxWidth);
222     assertEquals(od.getBoxHeight(), boxHeight);
223     assertEquals(vpranges.getStartRes(), 0);
224     assertEquals(vpranges.getStartSeq(), 0);
225
226     // overly large boxX value reset to width-boxWidth
227     mouseClick(od, 101, 6);
228     assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
229     assertEquals(od.getBoxY(), 1);
230     assertEquals(od.getBoxWidth(), boxWidth);
231     assertEquals(od.getBoxHeight(), boxHeight);
232     assertEquals(vpranges.getStartRes(),
233             Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
234     assertEquals(
235             vpranges.getStartSeq(),
236             Math.round((float) od.getBoxY() * alheight
237                     / od.getSequencesHeight()));
238
239     // overly large boxY value reset to sequenceHeight - boxHeight
240     mouseClick(od, 10, 520);
241     assertEquals(od.getBoxX(), 0);
242     assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
243     assertEquals(od.getBoxWidth(), boxWidth);
244     assertEquals(od.getBoxHeight(), boxHeight);
245     assertEquals(0,
246             Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
247
248     // here (float) od.getBoxY() * alheight / od.getSequencesHeight() = 507.5
249     // and round rounds to 508; however we get 507 working with row values
250     // hence the subtraction of 1
251     assertEquals(
252             vpranges.getStartSeq(),
253             Math.round((float) od.getBoxY() * alheight
254                     / od.getSequencesHeight()) - 1);
255
256     // click past end of alignment, as above
257     mouseClick(od, 3000, 5);
258     assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
259     assertEquals(od.getBoxWidth(), boxWidth);
260     assertEquals(od.getBoxHeight(), boxHeight);
261     assertEquals(vpranges.getStartRes(),
262             Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
263     assertEquals(
264             vpranges.getStartSeq(),
265             Math.round((float) od.getBoxY() * alheight
266                     / od.getSequencesHeight()));
267
268     // move viewport so startRes non-zero and then mouseclick
269     moveViewportH(20);
270
271     // click at viewport position
272     int oldboxx = od.getBoxX();
273     int oldboxy = od.getBoxY();
274     mouseClick(od, od.getBoxX() + od.getBoxWidth() / 2 + 6,
275             od.getBoxY() + od.getBoxHeight() / 2 + 3);
276     assertEquals(od.getBoxX(), oldboxx + 6);
277     assertEquals(od.getBoxWidth(), boxWidth);
278     assertEquals(od.getBoxHeight(), boxHeight);
279     assertEquals(vpranges.getStartRes(),
280             Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
281     assertEquals(od.getBoxY(), oldboxy + 3);
282     assertEquals(
283             vpranges.getStartSeq(),
284             Math.round((float) od.getBoxY() * alheight
285                     / od.getSequencesHeight()));
286
287     // click at top corner
288     mouseClick(od, 0, 0);
289     assertEquals(od.getBoxX(), 0);
290     assertEquals(vpranges.getStartRes(), 0);
291     assertEquals(od.getBoxY(), 0);
292     assertEquals(vpranges.getStartSeq(), 0);
293     assertEquals(od.getBoxWidth(), boxWidth);
294     assertEquals(od.getBoxHeight(), boxHeight);
295   }
296
297   /**
298    * Test setting of the box position, when there are hidden cols at the start
299    * of the alignment
300    */
301   @Test(groups = { "Functional" })
302   public void testFromMouseWithHiddenColsAtStart()
303   {
304     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
305     assertEquals(od.getBoxX(), 0);
306     assertEquals(od.getBoxY(), 0);
307     assertEquals(od.getBoxWidth(), boxWidth);
308     assertEquals(vpranges.getStartRes(), 0);
309     assertEquals(vpranges.getStartSeq(), 0);
310
311     // hide cols at start and check updated box position is correct
312     // changes boxX but not boxwidth
313     int lastHiddenCol = 30;
314     hiddenCols.hideColumns(0, lastHiddenCol);
315
316     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
317     assertEquals(od.getBoxX(),
318             Math.round((float) (lastHiddenCol + 1) * od.getWidth()
319                     / alwidth));
320     assertEquals(od.getBoxWidth(), boxWidth);
321     assertEquals(od.getBoxHeight(), boxHeight);
322
323     // try to click in hidden cols, check box does not move
324     int xpos = 10;
325     mouseClick(od, xpos, 0);
326     assertEquals(
327             od.getBoxX(),
328             Math.round((float) (lastHiddenCol + 1) * od.getWidth()
329                     / alwidth));
330     assertEquals(od.getBoxY(), 0);
331     assertEquals(od.getBoxWidth(), boxWidth);
332     assertEquals(od.getBoxHeight(), boxHeight);
333     assertEquals(vpranges.getStartSeq(), 0);
334     assertEquals(vpranges.getStartRes(), 0);
335
336     // click to right of hidden columns, box moves to click point
337     mouseClick(od, 60 + boxWidth / 2, boxHeight / 2);
338     assertEquals(od.getBoxX(), 60);
339     assertEquals(od.getBoxY(), 0);
340     assertEquals(od.getBoxWidth(), boxWidth);
341     assertEquals(od.getBoxHeight(), boxHeight);
342     assertEquals(vpranges.getStartSeq(), 0);
343     assertEquals(vpranges.getStartRes(),
344             Math.round(
345                     (float) 60 * alwidth / od.getWidth())
346                     - (lastHiddenCol + 1));
347
348     // click to right of hidden columns such that box runs over right hand side
349     // of alignment
350     // box position is adjusted away from the edge
351     // overly large boxX value reset to width-boxWidth
352     xpos = 100;
353     mouseClick(od, xpos + boxWidth / 2, 5 + boxHeight / 2);
354     assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
355     assertEquals(od.getBoxY(), 5);
356     assertEquals(od.getBoxWidth(), boxWidth);
357     assertEquals(od.getBoxHeight(), boxHeight);
358     assertEquals(vpranges.getStartRes(),
359             Math.round((float) od.getBoxX() * alwidth / od.getWidth())
360                     - (lastHiddenCol + 1));
361     assertEquals(
362             vpranges.getStartSeq(),
363             Math.round((float) od.getBoxY() * alheight
364                     / od.getSequencesHeight()));
365   }
366
367   /**
368    * Test setting of the box position, when there are hidden cols in the middle
369    * of the alignment
370    */
371   @Test(groups = { "Functional" })
372   public void testFromMouseWithHiddenColsInMiddle()
373   {
374     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
375     assertEquals(od.getBoxX(), 0);
376     assertEquals(od.getBoxY(), 0);
377     assertEquals(od.getBoxWidth(), boxWidth);
378     assertEquals(vpranges.getStartRes(), 0);
379     assertEquals(vpranges.getStartSeq(), 0);
380     
381     // hide columns 63-73, no change to box position or dimensions
382     int firstHidden = 63;
383     int lastHidden = 73;
384     hiddenCols.hideColumns(firstHidden, lastHidden);
385
386     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
387     assertEquals(od.getBoxX(), 0);
388     assertEquals(od.getBoxY(), 0);
389     assertEquals(od.getBoxWidth(), boxWidth);
390     assertEquals(vpranges.getStartRes(), 0);
391     assertEquals(vpranges.getStartSeq(), 0);
392
393     // move box so that it overlaps with hidden cols on one side
394     // box width changes, boxX and scrollCol as for unhidden case
395     int xpos = 54 - boxWidth / 2; // 54 is position in overview approx halfway
396                               // between cols 60 and 70
397     mouseClick(od, xpos, boxHeight / 2);
398     assertEquals(od.getBoxX(), xpos - boxWidth / 2);
399     assertEquals(od.getBoxY(), 0);
400     assertEquals(
401             od.getBoxWidth(),
402             Math.round(boxWidth + (float) (lastHidden - firstHidden + 1)
403                     * od.getWidth() / alwidth));
404     assertEquals(od.getBoxHeight(), boxHeight);
405     assertEquals(vpranges.getStartRes(),
406             Math.round((xpos - boxWidth / 2) * alwidth / od.getWidth())
407                     + 1); // +1 for rounding
408     assertEquals(vpranges.getStartSeq(), 0);
409
410     // move box so that it completely covers hidden cols
411     // box width changes, boxX and scrollCol as for hidden case
412     xpos = 24 + boxWidth / 2;
413     mouseClick(od, xpos, 0);
414     assertEquals(od.getBoxX(), 24);
415     assertEquals(od.getBoxY(), 0);
416     assertEquals(
417             od.getBoxWidth(),
418             Math.round(boxWidth + (float) (lastHidden - firstHidden + 1)
419                     * od.getWidth() / alwidth));
420     assertEquals(od.getBoxHeight(), boxHeight);
421     assertEquals(vpranges.getStartRes(),
422             Math.round((float) 24 * alwidth / od.getWidth()));
423     assertEquals(vpranges.getStartSeq(), 0);
424
425     // move box so boxX is to right of hidden cols, but does not go beyond full
426     // width of alignment
427     // box width, boxX and scrollCol all as for non-hidden case
428     xpos = Math.round((float) 75 * od.getWidth() / alwidth) + boxWidth / 2;
429     mouseClick(od, xpos, boxHeight / 2);
430     assertEquals(od.getBoxX(), xpos - boxWidth / 2);
431     assertEquals(od.getBoxY(), 0);
432     assertEquals(od.getBoxWidth(), boxWidth);
433     assertEquals(od.getBoxHeight(), boxHeight);
434     assertEquals(vpranges.getStartSeq(), 0);
435     assertEquals(vpranges.getStartRes(),
436             75 - (lastHidden - firstHidden + 1));
437     
438     // move box so it goes beyond full width of alignment
439     // boxX, scrollCol adjusted back, box width normal
440     xpos = 3000;
441     mouseClick(od, xpos, 5);
442     assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
443     assertEquals(od.getBoxY(), 0);
444     assertEquals(od.getBoxWidth(), boxWidth);
445     assertEquals(od.getBoxHeight(), boxHeight);
446     assertEquals(
447             vpranges.getStartRes(),
448             Math.round(((float) od.getBoxX() * alwidth / od.getWidth())
449                     - (lastHidden - firstHidden + 1)));
450     assertEquals(
451             vpranges.getStartSeq(),
452             Math.round((float) od.getBoxY() * alheight
453                     / od.getSequencesHeight()));
454
455   }
456
457   /**
458    * Test setting of the box position, when there are hidden cols at the end of
459    * the alignment
460    */
461   @Test(groups = { "Functional" })
462   public void testFromMouseWithHiddenColsAtEnd()
463   {
464     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
465     assertEquals(od.getBoxX(), 0);
466     assertEquals(od.getBoxY(), 0);
467     assertEquals(od.getBoxWidth(), boxWidth);
468     assertEquals(vpranges.getStartRes(), 0);
469     assertEquals(vpranges.getStartSeq(), 0);
470
471     // hide columns 140-164, no change to box position or dimensions
472     int firstHidden = 140;
473     int lastHidden = 164;
474     hiddenCols.hideColumns(firstHidden, lastHidden);
475     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
476     assertEquals(od.getBoxX(), 0);
477     assertEquals(od.getBoxY(), 0);
478     assertEquals(od.getBoxWidth(), boxWidth);
479     assertEquals(vpranges.getStartRes(), 0);
480     assertEquals(vpranges.getStartSeq(), 0);
481
482     // click to left of hidden cols, without overlapping
483     // boxX, scrollCol and width as normal
484     int xpos = 30;
485     int ypos = 6;
486     testBoxIsAtClickPoint(xpos, ypos);
487     assertEquals(vpranges.getStartSeq(), Math
488             .round((float) (ypos - boxHeight / 2) * alheight
489                     / od.getHeight()));
490     assertEquals(vpranges.getStartRes(), Math.round(
491             (float) (xpos - boxWidth / 2) * alwidth / od.getWidth()));
492
493     // click to left of hidden cols, with overlap
494     // boxX and scrollCol adjusted for hidden cols, width normal
495     xpos = Math.round((float) 145 * od.getWidth() / alwidth) - boxWidth;
496     mouseClick(od, xpos + boxWidth / 2, boxHeight / 2);
497     assertEquals(od.getBoxX(),
498             Math.round((float) (firstHidden - 1)
499                     * od.getWidth() / alwidth)
500                     - boxWidth + 1);
501     assertEquals(od.getBoxY(), 0);
502     assertEquals(od.getBoxWidth(), boxWidth);
503     assertEquals(od.getBoxHeight(), boxHeight);
504     assertEquals(vpranges.getStartRes(),
505             Math.round((float) (od.getBoxX()) * alwidth
506                     / od.getWidth()));
507     assertEquals(vpranges.getStartSeq(), 0);
508
509     // click in hidden cols
510     // boxX and scrollCol adjusted for hidden cols, width normal
511     xpos = 115;
512     assertEquals(od.getBoxX(),
513             Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth)
514                     - boxWidth + 1);
515     assertEquals(od.getBoxY(), 0);
516     assertEquals(od.getBoxWidth(), boxWidth);
517     assertEquals(od.getBoxHeight(), boxHeight);
518     assertEquals(vpranges.getStartRes(),
519             Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
520     assertEquals(vpranges.getStartSeq(), 0);
521
522     // click off end of alignment
523     // boxX and scrollCol adjusted for hidden cols, width normal
524     xpos = 3000;
525     assertEquals(od.getBoxX(),
526             Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth)
527                     - boxWidth + 1);
528     assertEquals(od.getBoxY(), 0);
529     assertEquals(od.getBoxWidth(), boxWidth);
530     assertEquals(od.getBoxHeight(), boxHeight);
531     assertEquals(vpranges.getStartRes(),
532             Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
533     assertEquals(vpranges.getStartSeq(), 0);
534   }
535
536   /**
537    * Test that the box position is set correctly when set from the viewport,
538    * with no hidden rows or columns
539    */
540   @Test(groups = { "Functional" })
541   public void testSetBoxFromViewport()
542   {
543     // move viewport to start of alignment
544     moveViewport(0, 0);
545     assertEquals(od.getBoxX(), 0);
546     assertEquals(od.getBoxY(), 0);
547     assertEquals(od.getBoxWidth(), boxWidth);
548     assertEquals(od.getBoxHeight(), boxHeight);
549
550     // move viewport to right
551     moveViewportH(70);
552     assertEquals(od.getBoxX(),
553             Math.round((float) 70 * od.getWidth() / alwidth));
554     assertEquals(od.getBoxY(), 0);
555     assertEquals(od.getBoxWidth(), boxWidth);
556     assertEquals(od.getBoxHeight(), boxHeight);
557
558     // move viewport down
559     moveViewportV(100);
560     assertEquals(od.getBoxX(),
561             Math.round((float) 70 * od.getWidth() / alwidth));
562     assertEquals(od.getBoxY(),
563             Math.round(100 * od.getSequencesHeight() / alheight));
564     assertEquals(od.getBoxWidth(), boxWidth);
565     assertEquals(od.getBoxHeight(), boxHeight);
566
567     // move viewport to bottom right
568     moveViewport(98, 508);
569     assertEquals(od.getBoxX(),
570             Math.round((float) 98 * od.getWidth() / alwidth));
571     assertEquals(od.getBoxY(),
572             Math.round((float) 508 * od.getSequencesHeight() / alheight));
573     assertEquals(od.getBoxWidth(), boxWidth);
574     assertEquals(od.getBoxHeight(), boxHeight);
575   }
576
577   /**
578    * Test that the box position is set correctly when there are hidden columns
579    * at the start
580    */
581   @Test(groups = { "Functional" })
582   public void testSetBoxFromViewportHiddenColsAtStart()
583   {
584     int firstHidden = 0;
585     int lastHidden = 20;
586     hiddenCols.hideColumns(firstHidden, lastHidden);
587
588     // move viewport to start of alignment
589     moveViewport(0, 0);
590     assertEquals(od.getBoxX(),
591             Math.round((float) (lastHidden + 1) * od.getWidth() / alwidth));
592     assertEquals(od.getBoxY(), 0);
593     assertEquals(od.getBoxWidth(), boxWidth);
594     assertEquals(od.getBoxHeight(), boxHeight);
595
596     // move viewport to end of alignment - need to make startRes by removing
597     // hidden cols because of how viewport/overview are implemented
598     moveViewport(98 - lastHidden - 1, 0);
599     assertEquals(od.getBoxX(),
600             Math.round((float) 98 * od.getWidth() / alwidth));
601     assertEquals(od.getBoxY(), 0);
602     assertEquals(od.getBoxWidth(), boxWidth);
603     assertEquals(od.getBoxHeight(), boxHeight);
604   }
605
606   /**
607    * Test that the box position is set correctly when there are hidden columns
608    * in the middle
609    */
610   @Test(groups = { "Functional" })
611   public void testSetBoxFromViewportHiddenColsInMiddle()
612   {
613     int firstHidden = 68;
614     int lastHidden = 78;
615     hiddenCols.hideColumns(firstHidden, lastHidden);
616
617     // move viewport before hidden columns
618     moveViewport(3, 0);
619
620     assertEquals(od.getBoxX(),
621             Math.round((float) 3 * od.getWidth() / alwidth));
622     assertEquals(od.getBoxY(), 0);
623     assertEquals(od.getBoxWidth(), boxWidth);
624     assertEquals(od.getBoxHeight(), boxHeight);
625
626     // move viewport to left of hidden columns with overlap
627     moveViewport(10, 0);
628     assertEquals(od.getBoxX(),
629             Math.round((float) 10 * od.getWidth() / alwidth));
630     assertEquals(od.getBoxY(), 0);
631     assertEquals(
632             od.getBoxWidth(),
633             boxWidth
634                     + Math.round((float) (lastHidden - firstHidden + 1)
635                             * od.getWidth() / alwidth));
636     assertEquals(od.getBoxHeight(), boxHeight);
637
638     // move viewport to straddle hidden columns
639     moveViewport(63, 0);
640     assertEquals(od.getBoxX(),
641             Math.round((float) 63 * od.getWidth() / alwidth));
642     assertEquals(od.getBoxY(), 0);
643     assertEquals(
644             od.getBoxWidth(),
645             boxWidth
646                     + Math.round((lastHidden - firstHidden + 1)
647                             * od.getWidth() / alwidth));
648     assertEquals(od.getBoxHeight(), boxHeight);
649
650     // move viewport to right of hidden columns, no overlap
651     moveViewport(80 - (lastHidden - firstHidden + 1), 0);
652     assertEquals(od.getBoxX(),
653             Math.round((float) 80 * od.getWidth() / alwidth));
654     assertEquals(od.getBoxY(), 0);
655     assertEquals(od.getBoxWidth(), boxWidth);
656     assertEquals(od.getBoxHeight(), boxHeight);
657
658   }
659
660   /**
661    * Test that the box position is set correctly when there are hidden columns
662    * at the end
663    */
664   @Test(groups = { "Functional" })
665   public void testSetBoxFromViewportHiddenColsAtEnd()
666   {
667     int firstHidden = 152;
668     int lastHidden = 164;
669     hiddenCols.hideColumns(firstHidden, lastHidden);
670
671     // move viewport before hidden columns
672     moveViewport(3, 0);
673     assertEquals(od.getBoxX(),
674             Math.round((float) 3 * od.getWidth() / alwidth));
675     assertEquals(od.getBoxY(), 0);
676     assertEquals(od.getBoxWidth(), boxWidth);
677     assertEquals(od.getBoxHeight(), boxHeight);
678
679     // move viewport to hidden columns
680     // viewport can't actually extend into hidden cols,
681     // so move to the far right edge of the viewport
682     moveViewport(firstHidden - viewWidth, 0);
683     assertEquals(od.getBoxX(),
684             Math.round((float) (firstHidden - viewWidth)
685                     * od.getWidth() / alwidth));
686     assertEquals(od.getBoxY(), 0);
687     assertEquals(od.getBoxWidth(), boxWidth);
688     assertEquals(od.getBoxHeight(), boxHeight);
689   }
690
691   /**
692    * Test that the box position is set correctly when there are hidden rows at
693    * the start
694    */
695   @Test(groups = { "Functional" })
696   public void testSetBoxFromViewportHiddenRowsAtStart()
697   {
698     int firstHidden = 0;
699     int lastHidden = 20;
700     hideSequences(firstHidden, lastHidden);
701
702     // move viewport to start of alignment:
703     // box moves to below hidden rows, height remains same
704     moveViewport(0, 0);
705     assertEquals(od.getBoxX(), 0);
706     assertEquals(od.getBoxY(),
707             Math.round((float) (lastHidden + 1) * od.getSequencesHeight()
708                     / alheight));
709     assertEquals(od.getBoxWidth(), boxWidth);
710     assertEquals(od.getBoxHeight(), boxHeight);
711
712     // move viewport to end of alignment
713     moveViewport(0, 525 - viewHeight - lastHidden - 1);
714     assertEquals(od.getBoxX(), 0);
715     assertEquals(
716             od.getBoxY(),
717             Math.round((float) (525 - viewHeight) * od.getSequencesHeight()
718                     / alheight));
719     assertEquals(od.getBoxWidth(), boxWidth);
720     assertEquals(od.getBoxHeight(), boxHeight);
721   }
722
723   /**
724    * Test that the box position is set correctly when there are hidden rows in
725    * the middle
726    */
727   @Test(groups = { "Functional" })
728   public void testSetBoxFromViewportHiddenRowsInMiddle()
729   {
730     int firstHidden = 200;
731     int lastHidden = 210;
732     hideSequences(firstHidden, lastHidden);
733
734     // move viewport to start of alignment:
735     // box, height etc as in non-hidden case
736     moveViewport(0, 0);
737     assertEquals(od.getBoxX(), 0);
738     assertEquals(od.getBoxY(), 0);
739     assertEquals(od.getBoxWidth(), boxWidth);
740     assertEquals(od.getBoxHeight(), boxHeight);
741
742     // move viewport to straddle hidden rows
743     moveViewport(0, 198);
744     assertEquals(od.getBoxX(), 0);
745     assertEquals(od.getBoxY(), Math.round ((float)198 * od.getSequencesHeight()
746             / alheight));
747     assertEquals(od.getBoxWidth(), boxWidth);
748     assertEquals(
749             od.getBoxHeight(),
750             Math.round((float) (viewHeight + lastHidden - firstHidden + 1)
751                     * od.getSequencesHeight() / alheight));
752   }
753
754   /**
755    * Test that the box position is set correctly when there are hidden rows at
756    * the bottom
757    */
758   @Test(groups = { "Functional" })
759   public void testSetBoxFromViewportHiddenRowsAtEnd()
760   {
761     int firstHidden = 500;
762     int lastHidden = 524;
763     hideSequences(firstHidden, lastHidden);
764
765     // move viewport to start of alignment:
766     // box, height etc as in non-hidden case
767     moveViewport(0, 0);
768     assertEquals(od.getBoxX(), 0);
769     assertEquals(od.getBoxY(), 0);
770     assertEquals(od.getBoxWidth(), boxWidth);
771     assertEquals(od.getBoxHeight(), boxHeight);
772
773     // move viewport to end of alignment
774     // viewport sits above hidden rows and does not include them
775     moveViewport(0, firstHidden - viewHeight - 1);
776     assertEquals(od.getBoxX(), 0);
777     assertEquals(
778             od.getBoxY(),
779             Math.round((float) (firstHidden - viewHeight - 1)
780                     * od.getSequencesHeight() / alheight));
781     assertEquals(od.getBoxWidth(), boxWidth);
782     assertEquals(od.getBoxHeight(), boxHeight);
783
784   }
785
786   /**
787    * Test setting of the box position, when there are hidden rows at the start
788    * of the alignment
789    */
790   @Test(groups = { "Functional" })
791   public void testFromMouseWithHiddenRowsAtStart()
792   {
793     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
794     assertEquals(od.getBoxX(), 0);
795     assertEquals(od.getBoxY(), 0);
796     assertEquals(od.getBoxHeight(), boxHeight);
797     assertEquals(od.getBoxWidth(), boxWidth);
798     assertEquals(vpranges.getStartRes(), 0);
799     assertEquals(vpranges.getStartSeq(), 0);
800
801     // hide rows at start and check updated box position is correct
802     // changes boxY but not boxheight
803     int lastHiddenRow = 30;
804     hideSequences(0, lastHiddenRow);
805
806     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
807     assertEquals(od.getBoxX(), 0);
808     assertEquals(od.getBoxY(),
809             Math.round((float) (lastHiddenRow + 1)
810                     * od.getSequencesHeight() / alheight));
811     assertEquals(od.getBoxWidth(), boxWidth);
812     assertEquals(od.getBoxHeight(), boxHeight);
813
814     // click in hidden rows - same result
815     mouseClick(od, 0, 0);
816     assertEquals(od.getBoxX(), 0);
817     assertEquals(
818             od.getBoxY(),
819             Math.round((float) (lastHiddenRow + 1)
820                     * od.getSequencesHeight() / alheight));
821     assertEquals(od.getBoxWidth(), boxWidth);
822     assertEquals(od.getBoxHeight(), boxHeight);
823
824     // click below hidden rows
825     mouseClick(od, 0, 150 + boxHeight/2);
826     assertEquals(od.getBoxX(), 0);
827     assertEquals(od.getBoxY(), 150);
828     assertEquals(od.getBoxWidth(), boxWidth);
829     assertEquals(od.getBoxHeight(), boxHeight);
830   }
831
832   /**
833    * Test setting of the box position, when there are hidden rows at the middle
834    * of the alignment
835    */
836   @Test(groups = { "Functional" })
837   public void testFromMouseWithHiddenRowsInMiddle()
838   {
839     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
840
841     assertEquals(od.getBoxX(), 0);
842     assertEquals(od.getBoxY(), 0);
843     assertEquals(od.getBoxWidth(), boxWidth);
844     assertEquals(od.getBoxHeight(), boxHeight);
845     assertEquals(vpranges.getStartRes(), 0);
846     assertEquals(vpranges.getStartSeq(), 0);
847
848     // hide rows in middle and check updated box position is correct
849     // no changes
850     int firstHiddenRow = 50;
851     int lastHiddenRow = 54;
852     hideSequences(firstHiddenRow, lastHiddenRow);
853
854     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
855
856     assertEquals(od.getBoxX(), 0);
857     assertEquals(od.getBoxY(), 0);
858     assertEquals(od.getBoxWidth(), boxWidth);
859     assertEquals(od.getBoxHeight(), boxHeight);
860
861     // click above hidden rows, so that box overlaps
862     int rowpos = 35; // row value in residues
863     int centrepos = 43; // centre row
864     mouseClick(od, 0,
865             Math.round((float) centrepos * od.getSequencesHeight()
866                     / alheight));
867     assertEquals(od.getBoxX(), 0);
868     assertEquals(od.getBoxY(),
869             Math.round(
870                     (float) rowpos * od.getSequencesHeight() / alheight));
871     assertEquals(od.getBoxWidth(), boxWidth);
872     assertEquals(
873             od.getBoxHeight(),
874             boxHeight
875                     + Math.round((float) (lastHiddenRow - firstHiddenRow + 1)
876                             * od.getSequencesHeight() / alheight));
877   }
878
879   /**
880    * Test setting of the box position, when there are hidden rows at the end of
881    * the alignment
882    */
883   @Test(groups = { "Functional" })
884   public void testFromMouseWithHiddenRowsAtEnd()
885   {
886     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
887     assertEquals(od.getBoxX(), 0);
888     assertEquals(od.getBoxY(), 0);
889     assertEquals(od.getBoxWidth(), boxWidth);
890     assertEquals(od.getBoxHeight(), boxHeight);
891     assertEquals(vpranges.getStartRes(), 0);
892     assertEquals(vpranges.getStartSeq(), 0);
893
894     // hide rows at end and check updated box position is correct
895     // no changes
896     int firstHidden = 500;
897     int lastHidden = 524;
898     hideSequences(firstHidden, lastHidden);
899
900     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
901     assertEquals(od.getBoxX(), 0);
902     assertEquals(od.getBoxY(), 0);
903     assertEquals(od.getBoxWidth(), boxWidth);
904     assertEquals(od.getBoxHeight(), boxHeight);
905
906     // click above hidden rows, no overlap
907     int ypos = 40 + viewHeight / 2; // top is row 40
908     mouseClick(od, 0,
909             Math.round((float) ypos * od.getSequencesHeight() / alheight));
910     assertEquals(od.getBoxX(), 0);
911     assertEquals(od.getBoxY(),
912             Math.round((float) 40 * od.getSequencesHeight() / alheight));
913     assertEquals(od.getBoxWidth(), boxWidth);
914     assertEquals(od.getBoxHeight(), boxHeight);
915
916     // click above hidden rows so box overlaps
917     // boxY moved upwards, boxHeight remains same
918     ypos = 497 + viewHeight / 2; // row 497
919     mouseClick(od, 0,
920             Math.round((float) ypos * od.getSequencesHeight() / alheight));
921     assertEquals(od.getBoxX(), 0);
922     assertEquals(
923             od.getBoxY(),
924             Math.round((float) (firstHidden - viewHeight)
925                     * od.getSequencesHeight() / alheight));
926     assertEquals(od.getBoxWidth(), boxWidth);
927     assertEquals(od.getBoxHeight(), boxHeight);
928
929     // click within hidden rows
930     ypos = 505 + boxHeight / 2;
931     mouseClick(od, 0,
932             Math.round((float) ypos * od.getSequencesHeight() / alheight));
933     assertEquals(od.getBoxX(), 0);
934     assertEquals(
935             od.getBoxY(),
936             Math.round((firstHidden - viewHeight) * od.getSequencesHeight()
937                     / alheight));
938     assertEquals(od.getBoxWidth(), boxWidth);
939     assertEquals(od.getBoxHeight(), boxHeight);
940   }
941
942   /**
943    * Test the function to determine if a point is in the overview's box or not
944    */
945   @Test(groups = { "Functional" })
946   public void testPositionInBox()
947   {
948     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
949
950     assertFalse(od.isPositionInBox(0, 0));
951     assertTrue(od.isPositionInBox(10, 9));
952     assertFalse(od.isPositionInBox(0, 9));
953     assertFalse(od.isPositionInBox(9, 0));
954     assertFalse(od.isPositionInBox(75, 20));
955
956     assertTrue(od.isPositionInBox(47, 6));
957     assertFalse(od.isPositionInBox(48, 6));
958     assertTrue(od.isPositionInBox(47, 9));
959     assertFalse(od.isPositionInBox(47, 10));
960
961     // hide columns in the box area
962     // extends area where a point is considered to be in the box
963     hiddenCols.hideColumns(1, 4);
964     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
965     assertFalse(od.isPositionInBox(0, 0));
966     assertTrue(od.isPositionInBox(10, 9));
967     assertFalse(od.isPositionInBox(0, 9));
968     assertFalse(od.isPositionInBox(9, 0));
969     assertFalse(od.isPositionInBox(75, 20));
970
971     assertTrue(od.isPositionInBox(47, 6));
972     assertTrue(od.isPositionInBox(48, 6));
973     assertTrue(od.isPositionInBox(47, 9));
974     assertFalse(od.isPositionInBox(47, 10));
975
976     // hide sequences in box area
977     // extends area where a point is considered to be in the box
978     hideSequences(1, 3);
979     ColumnSelection cs = new ColumnSelection();
980     hiddenCols.revealAllHiddenColumns(cs);
981     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
982     assertFalse(od.isPositionInBox(0, 0));
983     assertTrue(od.isPositionInBox(10, 9));
984     assertFalse(od.isPositionInBox(0, 9));
985     assertFalse(od.isPositionInBox(9, 0));
986     assertFalse(od.isPositionInBox(75, 20));
987
988     assertTrue(od.isPositionInBox(47, 6));
989     assertFalse(od.isPositionInBox(48, 6));
990     assertTrue(od.isPositionInBox(47, 9));
991     assertTrue(od.isPositionInBox(47, 10));
992   }
993
994   /**
995    * Test the dragging functionality
996    */
997   @Test(groups = { "Functional" })
998   public void testDragging()
999   {
1000     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
1001     od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
1002     od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
1003
1004     // updates require an OverviewPanel to exist which it doesn't here
1005     // so call setBoxPosition() as it would be called by the AlignmentPanel
1006     // normally
1007     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1008
1009     // corner moves 16 (20-4) right and 6 (22-16) up
1010     assertEquals(od.getBoxX(), 16);
1011     assertEquals(od.getBoxY(), 6);
1012
1013     // hide columns - box moves drag distance + hidden cols, vertically makes no
1014     // difference
1015     hiddenCols.hideColumns(1, 4);
1016     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
1017     od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
1018     od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
1019     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1020
1021     // corner moves 16 (20-4) + hiddenCols right and 6 (22-16) down
1022     assertEquals(od.getBoxX(),
1023             16 + Math.round((float) 4 * od.getWidth() / alwidth));
1024     assertEquals(od.getBoxY(), 6);
1025
1026     // hide sequences in box area
1027     // makes absolutely no difference
1028     hideSequences(1, 3);
1029     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
1030     od.setDragPoint(4, 16, al.getHiddenSequences(), hiddenCols);
1031     od.adjustViewportFromMouse(20, 22, al.getHiddenSequences(), hiddenCols);
1032     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1033
1034     // corner moves 16 (20-4) + hiddenCols right and 6 (22-16) + hiddenRows down
1035     assertEquals(od.getBoxX(),
1036             16 + Math.round((float) 4 * od.getWidth() / alwidth));
1037     assertEquals(od.getBoxY(),
1038             6 + Math.round((float) 3 * od.getHeight() / alheight));
1039   }
1040
1041   /*
1042    * Move viewport horizontally: startRes + previous width gives new horizontal extent. Vertical extent stays the same.
1043    */
1044   private void moveViewportH(int startRes)
1045   {
1046     vpranges.setViewportStartAndWidth(startRes, viewWidth);
1047     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1048   }
1049
1050   /*
1051    * Move viewport vertically: startSeq and endSeq give new vertical extent. Horizontal extent stays the same.
1052    */
1053   private void moveViewportV(int startSeq)
1054   {
1055     vpranges.setViewportStartAndHeight(startSeq, viewHeight);
1056     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1057   }
1058
1059   /*
1060    * Move viewport horizontally and vertically.
1061    */
1062   private void moveViewport(int startRes, int startSeq)
1063   {
1064     vpranges.setViewportStartAndWidth(startRes, viewWidth);
1065     vpranges.setViewportStartAndHeight(startSeq, viewHeight);
1066     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1067   }
1068
1069   /*
1070    * Mouse click as position x,y in overview window
1071    */
1072   private void mouseClick(OverviewDimensions od, int x, int y)
1073   {
1074     od.updateViewportFromMouse(x, y, al.getHiddenSequences(), hiddenCols);
1075
1076     // updates require an OverviewPanel to exist which it doesn't here
1077     // so call setBoxPosition() as it would be called by the AlignmentPanel
1078     // normally
1079     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1080   }
1081   
1082   /*
1083    * Test that the box is positioned with the centre at xpos, ypos
1084    * and with the original width and height
1085    */
1086   private void testBoxIsAtClickPoint(int xpos, int ypos)
1087   {
1088     mouseClick(od, xpos, ypos);
1089     assertEquals(od.getBoxX() + od.getBoxWidth() / 2, xpos);
1090     assertEquals(od.getBoxY() + od.getBoxHeight() / 2, ypos);
1091     assertEquals(od.getBoxWidth(), boxWidth);
1092     assertEquals(od.getBoxHeight(), boxHeight);
1093
1094   }
1095
1096   /*
1097    * Hide sequences between start and end
1098    */
1099   private void hideSequences(int start, int end)
1100   {
1101     SequenceI[] allseqs = al.getSequencesArray();
1102     SequenceGroup theseSeqs = new SequenceGroup();
1103     
1104     for (int i = start; i <= end; i++)
1105     {
1106       theseSeqs.addSequence(allseqs[i], false);
1107       al.getHiddenSequences().hideSequence(allseqs[i]);
1108     }
1109
1110     hiddenRepSequences.put(allseqs[start], theseSeqs);
1111   }
1112
1113   /**
1114    * Test setting of the box position, when there are hidden rows at the start
1115    * of the alignment
1116    */
1117   @Test(groups = { "Functional" })
1118   public void testFromMouseWithHiddenRowsAtStartWrapped()
1119   {
1120     vpranges.setWrappedMode(true);
1121     od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
1122     assertEquals(od.getBoxX(), 0);
1123     assertEquals(od.getBoxY(), 0);
1124     assertEquals(od.getBoxHeight(), boxHeight);
1125     assertEquals(od.getBoxWidth(), boxWidth);
1126     assertEquals(vpranges.getStartRes(), 0);
1127     assertEquals(vpranges.getStartSeq(), 0);
1128   
1129     // hide rows at start and check updated box position is correct
1130     // changes boxY but not boxheight
1131     int lastHiddenRow = 30;
1132     hideSequences(0, lastHiddenRow);
1133   
1134     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
1135     assertEquals(od.getBoxX(), 0);
1136     assertEquals(od.getBoxY(),
1137             Math.round((float) (lastHiddenRow + 1)
1138                     * od.getSequencesHeight() / alheight));
1139     assertEquals(od.getBoxWidth(), boxWidth);
1140     assertEquals(od.getBoxHeight(), boxHeight);
1141   
1142     // click in hidden rows - same result
1143     mouseClick(od, 0, 0);
1144     assertEquals(od.getBoxX(), 0);
1145     int boxY = od.getBoxY();
1146     assertEquals(
1147             boxY,
1148             Math.round((float) (lastHiddenRow + 1)
1149                     * od.getSequencesHeight() / alheight));
1150     assertEquals(od.getBoxWidth(), boxWidth);
1151     assertEquals(od.getBoxHeight(), boxHeight);
1152   
1153     // click below hidden rows
1154     // vertical move of overview box is suppressed in wrapped mode
1155     mouseClick(od, 0, 150);
1156     assertEquals(od.getBoxX(), 0);
1157     assertEquals(od.getBoxY(), boxY); // unchanged
1158     assertEquals(od.getBoxWidth(), boxWidth);
1159     assertEquals(od.getBoxHeight(), boxHeight);
1160   }
1161 }