2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertNull;
25 import static org.testng.Assert.assertTrue;
27 import jalview.api.AlignViewportI;
28 import jalview.bin.Cache;
29 import jalview.bin.Jalview;
30 import jalview.commands.EditCommand;
31 import jalview.commands.EditCommand.Action;
32 import jalview.commands.EditCommand.Edit;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentI;
35 import jalview.datamodel.Sequence;
36 import jalview.datamodel.SequenceI;
37 import jalview.gui.SeqPanel.MousePos;
38 import jalview.io.DataSourceType;
39 import jalview.io.FileLoader;
40 import jalview.util.MessageManager;
42 import java.awt.Event;
43 import java.awt.event.MouseEvent;
45 import javax.swing.JLabel;
47 import org.testng.annotations.AfterMethod;
48 import org.testng.annotations.BeforeClass;
49 import org.testng.annotations.Test;
51 import junit.extensions.PA;
53 public class SeqPanelTest
57 @BeforeClass(alwaysRun = true)
58 public void setUpJvOptionPane()
60 JvOptionPane.setInteractiveMode(false);
61 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
63 @Test(groups = "Functional")
64 public void testSetStatusReturnsNearestResiduePosition()
66 SequenceI seq1 = new Sequence("Seq1", "AACDE");
67 SequenceI seq2 = new Sequence("Seq2", "AA--E");
68 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
69 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
71 AlignmentI visAl = alignFrame.getViewport().getAlignment();
73 // Test either side of gap
75 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
76 visAl.getSequenceAt(1), 1, 1), 2);
77 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
78 "Sequence 2 ID: Seq2 Residue: ALA (2)");
80 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
81 visAl.getSequenceAt(1), 4, 1), 3);
82 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
83 "Sequence 2 ID: Seq2 Residue: GLU (3)");
84 // no status message at a gap, returns next residue position to the right
86 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
87 visAl.getSequenceAt(1), 2, 1), 3);
88 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
89 "Sequence 2 ID: Seq2");
91 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
92 visAl.getSequenceAt(1), 3, 1), 3);
93 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
94 "Sequence 2 ID: Seq2");
97 @Test(groups = "Functional")
98 public void testAmbiguousAminoAcidGetsStatusMessage()
100 SequenceI seq1 = new Sequence("Seq1", "ABCDE");
101 SequenceI seq2 = new Sequence("Seq2", "AB--E");
102 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
103 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
105 AlignmentI visAl = alignFrame.getViewport().getAlignment();
108 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
109 visAl.getSequenceAt(1), 1, 1), 2);
110 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
111 "Sequence 2 ID: Seq2 Residue: B (2)");
114 @Test(groups = "Functional")
115 public void testGetEditStatusMessage()
117 assertNull(SeqPanel.getEditStatusMessage(null));
119 EditCommand edit = new EditCommand(); // empty
120 assertNull(SeqPanel.getEditStatusMessage(edit));
122 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
125 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'));
126 String expected = MessageManager.formatMessage("label.insert_gap", "1");
127 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
129 // 3 more gaps makes +4
130 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-'));
131 expected = MessageManager.formatMessage("label.insert_gaps", "4");
132 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
134 // 2 deletes makes + 2
135 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
136 expected = MessageManager.formatMessage("label.insert_gaps", "2");
137 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
139 // 2 more deletes makes 0 - no text
140 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
141 assertNull(SeqPanel.getEditStatusMessage(edit));
143 // 1 more delete makes 1 delete
144 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
145 expected = MessageManager.formatMessage("label.delete_gap", "1");
146 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
148 // 1 more delete makes 2 deletes
149 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
150 expected = MessageManager.formatMessage("label.delete_gaps", "2");
151 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
155 * Tests that simulate 'locked editing', where an inserted gap is balanced by
156 * a gap deletion in the selection group, and vice versa
158 @Test(groups = "Functional")
159 public void testGetEditStatusMessage_lockedEditing()
161 EditCommand edit = new EditCommand(); // empty
162 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
164 // 1 gap inserted, balanced by 1 delete
165 Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-');
167 Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-');
168 e2.setSystemGenerated(true);
170 String expected = MessageManager.formatMessage("label.insert_gap", "1");
171 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
173 // 2 more gaps makes +3
174 Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
176 Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-');
177 e4.setSystemGenerated(true);
179 expected = MessageManager.formatMessage("label.insert_gaps", "3");
180 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
182 // 2 deletes makes + 1
183 Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
185 Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
186 e6.setSystemGenerated(true);
188 expected = MessageManager.formatMessage("label.insert_gap", "1");
189 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
191 // 1 more delete makes 0 - no text
192 Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
194 Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
195 e8.setSystemGenerated(true);
197 expected = MessageManager.formatMessage("label.insert_gaps", "2");
198 assertNull(SeqPanel.getEditStatusMessage(edit));
200 // 1 more delete makes 1 delete
201 Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
203 Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
204 e10.setSystemGenerated(true);
206 expected = MessageManager.formatMessage("label.delete_gap", "1");
207 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
209 // 2 more deletes makes 3 deletes
210 Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
212 Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
213 e12.setSystemGenerated(true);
215 expected = MessageManager.formatMessage("label.delete_gaps", "3");
216 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
219 public void testFindMousePosition_unwrapped()
221 String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
222 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData,
223 DataSourceType.PASTE);
224 AlignViewportI av = alignFrame.getViewport();
225 av.setShowAnnotation(true);
226 av.setWrapAlignment(false);
227 final int charHeight = av.getCharHeight();
228 final int charWidth = av.getCharWidth();
230 assertTrue(charHeight > 0);
231 assertTrue(charWidth > 0);
232 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
234 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
239 * mouse at top left of unwrapped panel
241 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
243 MousePos pos = testee.findMousePosition(evt);
244 assertEquals(pos.column, 0);
245 assertEquals(pos.seqIndex, 0);
246 assertEquals(pos.annotationIndex, -1);
249 @AfterMethod(alwaysRun = true)
250 public void tearDown()
252 Desktop.instance.closeAll_actionPerformed(null);
255 @Test(groups = "Functional")
256 public void testFindMousePosition_wrapped_annotations()
258 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true");
259 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
260 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
261 "examples/uniref50.fa", DataSourceType.FILE);
262 AlignViewportI av = alignFrame.getViewport();
263 av.setScaleAboveWrapped(false);
264 av.setScaleLeftWrapped(false);
265 av.setScaleRightWrapped(false);
266 alignFrame.alignPanel.paintAlignment(false, false);
267 waitForSwing(); // for Swing thread
269 final int charHeight = av.getCharHeight();
270 final int charWidth = av.getCharWidth();
271 final int alignmentHeight = av.getAlignment().getHeight();
274 assertTrue(charHeight > 0);
275 assertTrue(charWidth > 0);
276 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
278 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
283 * mouse at top left of wrapped panel; there is a gap of charHeight
284 * above the alignment
286 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
288 MousePos pos = testee.findMousePosition(evt);
289 assertEquals(pos.column, 0);
290 assertEquals(pos.seqIndex, -1); // above sequences
291 assertEquals(pos.annotationIndex, -1);
294 * cursor at bottom of gap above
297 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
299 pos = testee.findMousePosition(evt);
300 assertEquals(pos.seqIndex, -1);
301 assertEquals(pos.annotationIndex, -1);
304 * cursor over top of first sequence
307 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
309 pos = testee.findMousePosition(evt);
310 assertEquals(pos.seqIndex, 0);
311 assertEquals(pos.annotationIndex, -1);
314 * cursor at bottom of first sequence
316 y = 2 * charHeight - 1;
317 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
319 pos = testee.findMousePosition(evt);
320 assertEquals(pos.seqIndex, 0);
321 assertEquals(pos.annotationIndex, -1);
324 * cursor at top of second sequence
327 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
329 pos = testee.findMousePosition(evt);
330 assertEquals(pos.seqIndex, 1);
331 assertEquals(pos.annotationIndex, -1);
334 * cursor at bottom of second sequence
336 y = 3 * charHeight - 1;
337 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
339 pos = testee.findMousePosition(evt);
340 assertEquals(pos.seqIndex, 1);
341 assertEquals(pos.annotationIndex, -1);
344 * cursor at bottom of last sequence
346 y = charHeight * (1 + alignmentHeight) - 1;
347 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
349 pos = testee.findMousePosition(evt);
350 assertEquals(pos.seqIndex, alignmentHeight - 1);
351 assertEquals(pos.annotationIndex, -1);
354 * cursor below sequences, in 3-pixel gap above annotations
355 * method reports index of nearest sequence above
358 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
360 pos = testee.findMousePosition(evt);
361 assertEquals(pos.seqIndex, alignmentHeight - 1);
362 assertEquals(pos.annotationIndex, -1);
365 * cursor still in the gap above annotations, now at the bottom of it
367 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
368 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
370 pos = testee.findMousePosition(evt);
371 assertEquals(pos.seqIndex, alignmentHeight - 1);
372 assertEquals(pos.annotationIndex, -1);
375 * cursor at the top of the first annotation
378 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
380 pos = testee.findMousePosition(evt);
381 assertEquals(pos.seqIndex, alignmentHeight - 1);
382 assertEquals(pos.annotationIndex, 0); // over first annotation
385 * cursor at the bottom of the first annotation
387 y += av.getAlignment().getAlignmentAnnotation()[0].height - 1;
388 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
390 pos = testee.findMousePosition(evt);
391 assertEquals(pos.seqIndex, alignmentHeight - 1);
392 assertEquals(pos.annotationIndex, 0);
395 * cursor at the top of the second annotation
398 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
400 pos = testee.findMousePosition(evt);
401 assertEquals(pos.seqIndex, alignmentHeight - 1);
402 assertEquals(pos.annotationIndex, 1);
405 * cursor at the bottom of the second annotation
407 y += av.getAlignment().getAlignmentAnnotation()[1].height - 1;
408 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
410 pos = testee.findMousePosition(evt);
411 assertEquals(pos.seqIndex, alignmentHeight - 1);
412 assertEquals(pos.annotationIndex, 1);
415 * cursor at the top of the third annotation
418 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
420 pos = testee.findMousePosition(evt);
421 assertEquals(pos.seqIndex, alignmentHeight - 1);
422 assertEquals(pos.annotationIndex, 2);
425 * cursor at the bottom of the third annotation
427 y += av.getAlignment().getAlignmentAnnotation()[2].height - 1;
428 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
430 pos = testee.findMousePosition(evt);
431 assertEquals(pos.seqIndex, alignmentHeight - 1);
432 assertEquals(pos.annotationIndex, 2);
435 * cursor in gap between wrapped widths
438 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
440 pos = testee.findMousePosition(evt);
441 assertEquals(pos.seqIndex, -1);
442 assertEquals(pos.annotationIndex, -1);
445 * cursor at bottom of gap between wrapped widths
448 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
450 pos = testee.findMousePosition(evt);
451 assertEquals(pos.seqIndex, -1);
452 assertEquals(pos.annotationIndex, -1);
455 * cursor at top of first sequence, second wrapped width
458 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
460 pos = testee.findMousePosition(evt);
461 assertEquals(pos.seqIndex, 0);
462 assertEquals(pos.annotationIndex, -1);
465 @Test(groups = "Functional")
466 public void testFindMousePosition_wrapped_scaleAbove()
468 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true");
469 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
470 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
471 "examples/uniref50.fa", DataSourceType.FILE);
472 AlignViewportI av = alignFrame.getViewport();
473 av.setScaleAboveWrapped(true);
474 av.setScaleLeftWrapped(false);
475 av.setScaleRightWrapped(false);
476 alignFrame.alignPanel.paintAlignment(false, false);
479 final int charHeight = av.getCharHeight();
480 final int charWidth = av.getCharWidth();
481 final int alignmentHeight = av.getAlignment().getHeight();
484 assertTrue(charHeight > 0);
485 assertTrue(charWidth > 0);
486 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
488 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
493 * mouse at top left of wrapped panel; there is a gap of charHeight
494 * above the alignment
496 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
498 MousePos pos = testee.findMousePosition(evt);
499 assertEquals(pos.column, 0);
500 assertEquals(pos.seqIndex, -1); // above sequences
501 assertEquals(pos.annotationIndex, -1);
504 * cursor at bottom of gap above
505 * two charHeights including scale panel
507 y = 2 * charHeight - 1;
508 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
510 pos = testee.findMousePosition(evt);
511 assertEquals(pos.seqIndex, -1);
512 assertEquals(pos.annotationIndex, -1);
515 * cursor over top of first sequence
518 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
520 pos = testee.findMousePosition(evt);
521 assertEquals(pos.seqIndex, 0);
522 assertEquals(pos.annotationIndex, -1);
525 * cursor at bottom of first sequence
528 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
530 pos = testee.findMousePosition(evt);
531 assertEquals(pos.seqIndex, 0);
532 assertEquals(pos.annotationIndex, -1);
535 * cursor at top of second sequence
538 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
540 pos = testee.findMousePosition(evt);
541 assertEquals(pos.seqIndex, 1);
542 assertEquals(pos.annotationIndex, -1);
545 * cursor at bottom of second sequence
548 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
550 pos = testee.findMousePosition(evt);
551 assertEquals(pos.seqIndex, 1);
552 assertEquals(pos.annotationIndex, -1);
555 * cursor at bottom of last sequence
556 * (scale + gap + sequences)
558 y = charHeight * (2 + alignmentHeight) - 1;
559 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
561 pos = testee.findMousePosition(evt);
562 assertEquals(pos.seqIndex, alignmentHeight - 1);
563 assertEquals(pos.annotationIndex, -1);
566 * cursor below sequences, in 3-pixel gap above annotations
569 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
571 pos = testee.findMousePosition(evt);
572 assertEquals(pos.seqIndex, alignmentHeight - 1);
573 assertEquals(pos.annotationIndex, -1);
576 * cursor still in the gap above annotations, now at the bottom of it
577 * method reports index of nearest sequence above
579 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
580 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
582 pos = testee.findMousePosition(evt);
583 assertEquals(pos.seqIndex, alignmentHeight - 1);
584 assertEquals(pos.annotationIndex, -1);
587 * cursor at the top of the first annotation
590 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
592 pos = testee.findMousePosition(evt);
593 assertEquals(pos.seqIndex, alignmentHeight - 1);
594 assertEquals(pos.annotationIndex, 0); // over first annotation
597 * cursor at the bottom of the first annotation
599 y += av.getAlignment().getAlignmentAnnotation()[0].height - 1;
600 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
602 pos = testee.findMousePosition(evt);
603 assertEquals(pos.seqIndex, alignmentHeight - 1);
604 assertEquals(pos.annotationIndex, 0);
607 * cursor at the top of the second annotation
610 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
612 pos = testee.findMousePosition(evt);
613 assertEquals(pos.seqIndex, alignmentHeight - 1);
614 assertEquals(pos.annotationIndex, 1);
617 * cursor at the bottom of the second annotation
619 y += av.getAlignment().getAlignmentAnnotation()[1].height - 1;
620 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
622 pos = testee.findMousePosition(evt);
623 assertEquals(pos.seqIndex, alignmentHeight - 1);
624 assertEquals(pos.annotationIndex, 1);
627 * cursor at the top of the third annotation
630 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
632 pos = testee.findMousePosition(evt);
633 assertEquals(pos.seqIndex, alignmentHeight - 1);
634 assertEquals(pos.annotationIndex, 2);
637 * cursor at the bottom of the third annotation
639 y += av.getAlignment().getAlignmentAnnotation()[2].height - 1;
640 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
642 pos = testee.findMousePosition(evt);
643 assertEquals(pos.seqIndex, alignmentHeight - 1);
644 assertEquals(pos.annotationIndex, 2);
647 * cursor in gap between wrapped widths
650 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
652 pos = testee.findMousePosition(evt);
653 assertEquals(pos.seqIndex, -1);
654 assertEquals(pos.annotationIndex, -1);
657 * cursor at bottom of gap between wrapped widths
660 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
662 pos = testee.findMousePosition(evt);
663 assertEquals(pos.seqIndex, -1);
664 assertEquals(pos.annotationIndex, -1);
667 * cursor at top of scale, second wrapped width
670 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
672 pos = testee.findMousePosition(evt);
673 assertEquals(pos.seqIndex, -1);
674 assertEquals(pos.annotationIndex, -1);
677 * cursor at bottom of scale, second wrapped width
680 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
682 pos = testee.findMousePosition(evt);
683 assertEquals(pos.seqIndex, -1);
684 assertEquals(pos.annotationIndex, -1);
687 * cursor at top of first sequence, second wrapped width
690 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
692 pos = testee.findMousePosition(evt);
693 assertEquals(pos.seqIndex, 0);
694 assertEquals(pos.annotationIndex, -1);
697 @Test(groups = "Functional")
698 public void testFindMousePosition_wrapped_noAnnotations()
700 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "false");
701 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
702 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
703 "examples/uniref50.fa", DataSourceType.FILE);
704 AlignViewportI av = alignFrame.getViewport();
705 av.setScaleAboveWrapped(false);
706 av.setScaleLeftWrapped(false);
707 av.setScaleRightWrapped(false);
708 alignFrame.alignPanel.paintAlignment(false, false);
711 final int charHeight = av.getCharHeight();
712 final int charWidth = av.getCharWidth();
713 final int alignmentHeight = av.getAlignment().getHeight();
716 assertTrue(charHeight > 0);
717 assertTrue(charWidth > 0);
718 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
720 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
725 * mouse at top left of wrapped panel; there is a gap of charHeight
726 * above the alignment
728 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
730 MousePos pos = testee.findMousePosition(evt);
731 assertEquals(pos.column, 0);
732 assertEquals(pos.seqIndex, -1); // above sequences
733 assertEquals(pos.annotationIndex, -1);
736 * cursor over top of first sequence
739 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
741 pos = testee.findMousePosition(evt);
742 assertEquals(pos.seqIndex, 0);
743 assertEquals(pos.annotationIndex, -1);
746 * cursor at bottom of last sequence
748 y = charHeight * (1 + alignmentHeight) - 1;
749 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
751 pos = testee.findMousePosition(evt);
752 assertEquals(pos.seqIndex, alignmentHeight - 1);
753 assertEquals(pos.annotationIndex, -1);
756 * cursor below sequences, at top of charHeight gap between widths
759 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
761 pos = testee.findMousePosition(evt);
762 assertEquals(pos.seqIndex, -1);
763 assertEquals(pos.annotationIndex, -1);
766 * cursor below sequences, at top of charHeight gap between widths
769 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
771 pos = testee.findMousePosition(evt);
772 assertEquals(pos.seqIndex, -1);
773 assertEquals(pos.annotationIndex, -1);
776 * cursor at the top of the first sequence, second width
779 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
781 pos = testee.findMousePosition(evt);
782 assertEquals(pos.seqIndex, 0);
783 assertEquals(pos.annotationIndex, -1);
786 @Test(groups = "Functional")
787 public void testFindColumn_unwrapped()
789 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "false");
790 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
791 "examples/uniref50.fa", DataSourceType.FILE);
792 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
794 final int charWidth = alignFrame.getViewport().getCharWidth();
795 assertTrue(charWidth > 0); // sanity check
796 assertEquals(alignFrame.getViewport().getRanges().getStartRes(), 0);
799 * mouse at top left of unwrapped panel
801 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
803 assertEquals(testee.findColumn(evt), 0);
806 * not quite one charWidth across
809 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
811 assertEquals(testee.findColumn(evt), 0);
814 * one charWidth across
817 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
819 assertEquals(testee.findColumn(evt), 1);
822 * two charWidths across
825 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
827 assertEquals(testee.findColumn(evt), 2);
830 * limited to last column of seqcanvas
833 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
835 SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas;
836 int w = seqCanvas.getWidth();
837 // limited to number of whole columns, base 0
838 int expected = w / charWidth - 1;
839 assertEquals(testee.findColumn(evt), expected);
842 * hide columns 5-10 (base 1)
844 alignFrame.getViewport().hideColumns(4, 9);
845 x = 5 * charWidth + 2;
846 // x is in 6th visible column, absolute column 12, or 11 base 0
847 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
849 assertEquals(testee.findColumn(evt), 11);
852 @Test(groups = "Functional")
853 public void testFindColumn_wrapped()
855 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
856 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
857 "examples/uniref50.fa", DataSourceType.FILE);
858 AlignViewport av = alignFrame.getViewport();
859 av.setScaleAboveWrapped(false);
860 av.setScaleLeftWrapped(false);
861 av.setScaleRightWrapped(false);
862 alignFrame.alignPanel.paintAlignment(false, false);
863 // need to wait for repaint to finish!
865 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
867 final int charWidth = av.getCharWidth();
868 assertTrue(charWidth > 0); // sanity check
869 assertEquals(av.getRanges().getStartRes(), 0);
872 * mouse at top left of wrapped panel, no West (left) scale
874 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
876 assertEquals(testee.findColumn(evt), 0);
879 * not quite one charWidth across
882 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
884 assertEquals(testee.findColumn(evt), 0);
887 * one charWidth across
890 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
892 assertEquals(testee.findColumn(evt), 1);
895 * x over scale left (before drawn columns) results in -1
897 av.setScaleLeftWrapped(true);
898 alignFrame.alignPanel.paintAlignment(false, false);
900 SeqCanvas seqCanvas = testee.seqCanvas;
901 int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
902 assertTrue(labelWidth > 0);
904 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
906 assertEquals(testee.findColumn(evt), -1);
909 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
911 assertEquals(testee.findColumn(evt), 0);
914 * x over right edge of last residue (including scale left)
916 int residuesWide = av.getRanges().getViewportWidth();
917 assertTrue(residuesWide > 0);
918 x = labelWidth + charWidth * residuesWide - 1;
919 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
921 assertEquals(testee.findColumn(evt), residuesWide - 1);
924 * x over scale right (beyond drawn columns) results in -1
926 av.setScaleRightWrapped(true);
927 alignFrame.alignPanel.paintAlignment(false, false);
929 labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
930 assertTrue(labelWidth > 0);
931 int residuesWide2 = av.getRanges().getViewportWidth();
932 assertTrue(residuesWide2 > 0);
933 assertTrue(residuesWide2 < residuesWide); // available width reduced
934 x += 1; // just over left edge of scale right
935 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
937 assertEquals(testee.findColumn(evt), -1);
939 // todo add startRes offset, hidden columns
942 @BeforeClass(alwaysRun = true)
943 public static void setUpBeforeClass() throws Exception
946 * use read-only test properties file
948 Cache.loadProperties("test/jalview/io/testProps.jvprops");
949 Jalview.main(new String[] { "-nonews" });
953 * waits a few ms for Swing to do something
955 synchronized void waitForSwing()
960 } catch (InterruptedException e)