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.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.Sequence;
37 import jalview.datamodel.SequenceI;
38 import jalview.gui.SeqPanel.MousePos;
39 import jalview.io.DataSourceType;
40 import jalview.io.FileLoader;
41 import jalview.util.MessageManager;
43 import java.awt.Event;
44 import java.awt.EventQueue;
45 import java.awt.event.MouseEvent;
46 import java.lang.reflect.InvocationTargetException;
48 import javax.swing.JLabel;
50 import org.testng.annotations.AfterMethod;
51 import org.testng.annotations.BeforeClass;
52 import org.testng.annotations.Test;
54 import junit.extensions.PA;
56 public class SeqPanelTest
60 @BeforeClass(alwaysRun = true)
61 public void setUpJvOptionPane()
63 Jalview.setSynchronous(true);
64 JvOptionPane.setInteractiveMode(false);
65 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
67 @Test(groups = "Functional")
68 public void testSetStatusReturnsNearestResiduePosition()
70 SequenceI seq1 = new Sequence("Seq1", "AACDE");
71 SequenceI seq2 = new Sequence("Seq2", "AA--E");
72 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
73 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
75 AlignmentI visAl = alignFrame.getViewport().getAlignment();
77 // Test either side of gap
79 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
80 visAl.getSequenceAt(1), 1, 1), 2);
81 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
82 "Sequence 2 ID: Seq2 Residue: ALA (2)");
84 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
85 visAl.getSequenceAt(1), 4, 1), 3);
86 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
87 "Sequence 2 ID: Seq2 Residue: GLU (3)");
88 // no status message at a gap, returns next residue position to the right
90 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
91 visAl.getSequenceAt(1), 2, 1), 3);
92 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
93 "Sequence 2 ID: Seq2");
95 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
96 visAl.getSequenceAt(1), 3, 1), 3);
97 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
98 "Sequence 2 ID: Seq2");
101 @Test(groups = "Functional")
102 public void testAmbiguousAminoAcidGetsStatusMessage()
104 SequenceI seq1 = new Sequence("Seq1", "ABCDE");
105 SequenceI seq2 = new Sequence("Seq2", "AB--E");
106 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
107 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
109 AlignmentI visAl = alignFrame.getViewport().getAlignment();
112 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
113 visAl.getSequenceAt(1), 1, 1), 2);
114 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
115 "Sequence 2 ID: Seq2 Residue: B (2)");
118 @Test(groups = "Functional")
119 public void testGetEditStatusMessage()
121 assertNull(SeqPanel.getEditStatusMessage(null));
123 EditCommand edit = new EditCommand(); // empty
124 assertNull(SeqPanel.getEditStatusMessage(edit));
126 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
129 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'));
130 String expected = MessageManager.formatMessage("label.insert_gap", "1");
131 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
133 // 3 more gaps makes +4
134 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-'));
135 expected = MessageManager.formatMessage("label.insert_gaps", "4");
136 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
138 // 2 deletes makes + 2
139 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
140 expected = MessageManager.formatMessage("label.insert_gaps", "2");
141 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
143 // 2 more deletes makes 0 - no text
144 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
145 assertNull(SeqPanel.getEditStatusMessage(edit));
147 // 1 more delete makes 1 delete
148 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
149 expected = MessageManager.formatMessage("label.delete_gap", "1");
150 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
152 // 1 more delete makes 2 deletes
153 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
154 expected = MessageManager.formatMessage("label.delete_gaps", "2");
155 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
159 * Tests that simulate 'locked editing', where an inserted gap is balanced by
160 * a gap deletion in the selection group, and vice versa
162 @Test(groups = "Functional")
163 public void testGetEditStatusMessage_lockedEditing()
165 EditCommand edit = new EditCommand(); // empty
166 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
168 // 1 gap inserted, balanced by 1 delete
169 Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-');
171 Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-');
172 e2.setSystemGenerated(true);
174 String expected = MessageManager.formatMessage("label.insert_gap", "1");
175 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
177 // 2 more gaps makes +3
178 Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
180 Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-');
181 e4.setSystemGenerated(true);
183 expected = MessageManager.formatMessage("label.insert_gaps", "3");
184 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
186 // 2 deletes makes + 1
187 Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
189 Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
190 e6.setSystemGenerated(true);
192 expected = MessageManager.formatMessage("label.insert_gap", "1");
193 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
195 // 1 more delete makes 0 - no text
196 Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
198 Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
199 e8.setSystemGenerated(true);
201 expected = MessageManager.formatMessage("label.insert_gaps", "2");
202 assertNull(SeqPanel.getEditStatusMessage(edit));
204 // 1 more delete makes 1 delete
205 Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
207 Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
208 e10.setSystemGenerated(true);
210 expected = MessageManager.formatMessage("label.delete_gap", "1");
211 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
213 // 2 more deletes makes 3 deletes
214 Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
216 Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
217 e12.setSystemGenerated(true);
219 expected = MessageManager.formatMessage("label.delete_gaps", "3");
220 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
223 public void testFindMousePosition_unwrapped()
225 String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
226 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData,
227 DataSourceType.PASTE);
228 AlignViewportI av = alignFrame.getViewport();
229 av.setShowAnnotation(true);
230 av.setWrapAlignment(false);
231 final int charHeight = av.getCharHeight();
232 final int charWidth = av.getCharWidth();
234 assertTrue(charHeight > 0);
235 assertTrue(charWidth > 0);
236 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
238 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
243 * mouse at top left of unwrapped panel
245 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
247 MousePos pos = testee.findMousePosition(evt);
248 assertEquals(pos.column, 0);
249 assertEquals(pos.seqIndex, 0);
250 assertEquals(pos.annotationIndex, -1);
253 @AfterMethod(alwaysRun = true)
254 public void tearDown()
256 Desktop.getInstance().closeAll_actionPerformed(null);
259 @Test(groups = "Functional")
260 public void testFindMousePosition_wrapped_annotations()
262 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "true");
263 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
264 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
265 "examples/uniref50.fa", DataSourceType.FILE);
266 AlignViewportI av = alignFrame.getViewport();
267 av.setScaleAboveWrapped(false);
268 av.setScaleLeftWrapped(false);
269 av.setScaleRightWrapped(false);
271 alignFrame.alignPanel.updateLayout();
273 final int charHeight = av.getCharHeight();
274 final int charWidth = av.getCharWidth();
275 final int alignmentHeight = av.getAlignment().getHeight();
278 assertTrue(charHeight > 0);
279 assertTrue(charWidth > 0);
280 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
282 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
287 * mouse at top left of wrapped panel; there is a gap of charHeight
288 * above the alignment
290 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
292 MousePos pos = testee.findMousePosition(evt);
293 assertEquals(pos.column, 0);
294 assertEquals(pos.seqIndex, -1); // above sequences
295 assertEquals(pos.annotationIndex, -1);
298 * cursor at bottom of gap above
301 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
303 pos = testee.findMousePosition(evt);
304 assertEquals(pos.seqIndex, -1);
305 assertEquals(pos.annotationIndex, -1);
308 * cursor over top of first sequence
311 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
313 pos = testee.findMousePosition(evt);
314 assertEquals(pos.seqIndex, 0);
315 assertEquals(pos.annotationIndex, -1);
318 * cursor at bottom of first sequence
320 y = 2 * charHeight - 1;
321 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
323 pos = testee.findMousePosition(evt);
324 assertEquals(pos.seqIndex, 0);
325 assertEquals(pos.annotationIndex, -1);
328 * cursor at top of second sequence
331 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
333 pos = testee.findMousePosition(evt);
334 assertEquals(pos.seqIndex, 1);
335 assertEquals(pos.annotationIndex, -1);
338 * cursor at bottom of second sequence
340 y = 3 * charHeight - 1;
341 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
343 pos = testee.findMousePosition(evt);
344 assertEquals(pos.seqIndex, 1);
345 assertEquals(pos.annotationIndex, -1);
348 * cursor at bottom of last sequence
350 y = charHeight * (1 + alignmentHeight) - 1;
351 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
353 pos = testee.findMousePosition(evt);
354 assertEquals(pos.seqIndex, alignmentHeight - 1);
355 assertEquals(pos.annotationIndex, -1);
358 * cursor below sequences, in 3-pixel gap above annotations
359 * method reports index of nearest sequence above
362 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
364 pos = testee.findMousePosition(evt);
365 assertEquals(pos.seqIndex, alignmentHeight - 1);
366 assertEquals(pos.annotationIndex, -1);
369 * cursor still in the gap above annotations, now at the bottom of it
371 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
372 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
374 pos = testee.findMousePosition(evt);
375 assertEquals(pos.seqIndex, alignmentHeight - 1);
376 assertEquals(pos.annotationIndex, -1);
378 AlignmentAnnotation[] annotationRows = av.getAlignment()
379 .getAlignmentAnnotation();
380 for (int n = 0; n < annotationRows.length; n++)
383 * cursor at the top of the n'th annotation
386 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
388 pos = testee.findMousePosition(evt);
389 assertEquals(pos.seqIndex, alignmentHeight - 1);
390 assertEquals(pos.annotationIndex, n); // over n'th annotation
393 * cursor at the bottom of the n'th annotation
395 y += annotationRows[n].height - 1;
396 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
398 pos = testee.findMousePosition(evt);
399 assertEquals(pos.seqIndex, alignmentHeight - 1);
400 assertEquals(pos.annotationIndex, n);
404 * cursor in gap between wrapped widths
407 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
409 pos = testee.findMousePosition(evt);
410 assertEquals(pos.seqIndex, -1);
411 assertEquals(pos.annotationIndex, -1);
414 * cursor at bottom of gap between wrapped widths
417 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
419 pos = testee.findMousePosition(evt);
420 assertEquals(pos.seqIndex, -1);
421 assertEquals(pos.annotationIndex, -1);
424 * cursor at top of first sequence, second wrapped width
427 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
429 pos = testee.findMousePosition(evt);
430 assertEquals(pos.seqIndex, 0);
431 assertEquals(pos.annotationIndex, -1);
434 @Test(groups = "Functional")
435 public void testFindMousePosition_wrapped_scaleAbove()
437 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "true");
438 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
439 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
440 "examples/uniref50.fa", DataSourceType.FILE);
441 AlignViewportI av = alignFrame.getViewport();
442 av.setScaleAboveWrapped(true);
443 av.setScaleLeftWrapped(false);
444 av.setScaleRightWrapped(false);
445 alignFrame.alignPanel.updateLayout();
447 final int charHeight = av.getCharHeight();
448 final int charWidth = av.getCharWidth();
449 final int alignmentHeight = av.getAlignment().getHeight();
452 assertTrue(charHeight > 0);
453 assertTrue(charWidth > 0);
454 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
456 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
461 * mouse at top left of wrapped panel; there is a gap of charHeight
462 * above the alignment
464 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
466 MousePos pos = testee.findMousePosition(evt);
467 assertEquals(pos.column, 0);
468 assertEquals(pos.seqIndex, -1); // above sequences
469 assertEquals(pos.annotationIndex, -1);
472 * cursor at bottom of gap above
473 * two charHeights including scale panel
475 y = 2 * charHeight - 1;
476 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
478 pos = testee.findMousePosition(evt);
479 assertEquals(pos.seqIndex, -1);
480 assertEquals(pos.annotationIndex, -1);
483 * cursor over top of first sequence
486 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
488 pos = testee.findMousePosition(evt);
489 assertEquals(pos.seqIndex, 0);
490 assertEquals(pos.annotationIndex, -1);
493 * cursor at bottom of first sequence
496 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
498 pos = testee.findMousePosition(evt);
499 assertEquals(pos.seqIndex, 0);
500 assertEquals(pos.annotationIndex, -1);
503 * cursor at top of second sequence
506 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
508 pos = testee.findMousePosition(evt);
509 assertEquals(pos.seqIndex, 1);
510 assertEquals(pos.annotationIndex, -1);
513 * cursor at bottom of second sequence
516 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
518 pos = testee.findMousePosition(evt);
519 assertEquals(pos.seqIndex, 1);
520 assertEquals(pos.annotationIndex, -1);
523 * cursor at bottom of last sequence
524 * (scale + gap + sequences)
526 y = charHeight * (2 + alignmentHeight) - 1;
527 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
529 pos = testee.findMousePosition(evt);
530 assertEquals(pos.seqIndex, alignmentHeight - 1);
531 assertEquals(pos.annotationIndex, -1);
534 * cursor below sequences, in 3-pixel gap above annotations
537 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
539 pos = testee.findMousePosition(evt);
540 assertEquals(pos.seqIndex, alignmentHeight - 1);
541 assertEquals(pos.annotationIndex, -1);
544 * cursor still in the gap above annotations, now at the bottom of it
545 * method reports index of nearest sequence above
547 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
548 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
550 pos = testee.findMousePosition(evt);
551 assertEquals(pos.seqIndex, alignmentHeight - 1);
552 assertEquals(pos.annotationIndex, -1);
554 AlignmentAnnotation[] annotationRows = av.getAlignment().getAlignmentAnnotation();
555 for (int n = 0; n < annotationRows.length; n++)
558 * cursor at the top of the n'th annotation
561 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
563 pos = testee.findMousePosition(evt);
564 assertEquals(pos.seqIndex, alignmentHeight - 1);
565 assertEquals(pos.annotationIndex, n); // over n'th annotation
568 * cursor at the bottom of the n'th annotation
570 y += annotationRows[n].height - 1;
571 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
573 pos = testee.findMousePosition(evt);
574 assertEquals(pos.seqIndex, alignmentHeight - 1);
575 assertEquals(pos.annotationIndex, n);
579 * cursor in gap between wrapped widths
582 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
584 pos = testee.findMousePosition(evt);
585 assertEquals(pos.seqIndex, -1);
586 assertEquals(pos.annotationIndex, -1);
589 * cursor at bottom of gap between wrapped widths
592 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
594 pos = testee.findMousePosition(evt);
595 assertEquals(pos.seqIndex, -1);
596 assertEquals(pos.annotationIndex, -1);
599 * cursor at top of scale, second wrapped width
602 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
604 pos = testee.findMousePosition(evt);
605 assertEquals(pos.seqIndex, -1);
606 assertEquals(pos.annotationIndex, -1);
609 * cursor at bottom of scale, second wrapped width
612 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
614 pos = testee.findMousePosition(evt);
615 assertEquals(pos.seqIndex, -1);
616 assertEquals(pos.annotationIndex, -1);
619 * cursor at top of first sequence, second wrapped width
622 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
624 pos = testee.findMousePosition(evt);
625 assertEquals(pos.seqIndex, 0);
626 assertEquals(pos.annotationIndex, -1);
629 @Test(groups = "Functional")
630 public void testFindMousePosition_wrapped_noAnnotations()
632 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "false");
633 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
634 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
635 "examples/uniref50.fa", DataSourceType.FILE);
636 AlignViewportI av = alignFrame.getViewport();
637 av.setScaleAboveWrapped(false);
638 av.setScaleLeftWrapped(false);
639 av.setScaleRightWrapped(false);
640 alignFrame.alignPanel.updateLayout();
642 final int charHeight = av.getCharHeight();
643 final int charWidth = av.getCharWidth();
644 final int alignmentHeight = av.getAlignment().getHeight();
647 assertTrue(charHeight > 0);
648 assertTrue(charWidth > 0);
649 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
651 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
656 * mouse at top left of wrapped panel; there is a gap of charHeight
657 * above the alignment
659 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
661 MousePos pos = testee.findMousePosition(evt);
662 assertEquals(pos.column, 0);
663 assertEquals(pos.seqIndex, -1); // above sequences
664 assertEquals(pos.annotationIndex, -1);
667 * cursor over top of first sequence
670 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
672 pos = testee.findMousePosition(evt);
673 assertEquals(pos.seqIndex, 0);
674 assertEquals(pos.annotationIndex, -1);
677 * cursor at bottom of last sequence
679 y = charHeight * (1 + alignmentHeight) - 1;
680 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
682 pos = testee.findMousePosition(evt);
683 assertEquals(pos.seqIndex, alignmentHeight - 1);
684 assertEquals(pos.annotationIndex, -1);
687 * cursor below sequences, at top of charHeight gap between widths
690 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
692 pos = testee.findMousePosition(evt);
693 assertEquals(pos.seqIndex, -1);
694 assertEquals(pos.annotationIndex, -1);
697 * cursor below sequences, at top of charHeight gap between widths
700 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
702 pos = testee.findMousePosition(evt);
703 assertEquals(pos.seqIndex, -1);
704 assertEquals(pos.annotationIndex, -1);
707 * cursor at the top of the first sequence, second width
710 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
712 pos = testee.findMousePosition(evt);
713 assertEquals(pos.seqIndex, 0);
714 assertEquals(pos.annotationIndex, -1);
717 @Test(groups = "Functional")
718 public void testFindColumn_unwrapped()
720 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "false");
721 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
722 "examples/uniref50.fa", DataSourceType.FILE);
723 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
725 final int charWidth = alignFrame.getViewport().getCharWidth();
726 assertTrue(charWidth > 0); // sanity check
727 assertEquals(alignFrame.getViewport().getRanges().getStartRes(), 0);
729 * mouse at top left of unwrapped panel
731 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
733 assertEquals(testee.findColumn(evt), 0);
736 * not quite one charWidth across
739 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
741 assertEquals(testee.findColumn(evt), 0);
744 * one charWidth across
747 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
749 assertEquals(testee.findColumn(evt), 1);
752 * two charWidths across
755 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
757 assertEquals(testee.findColumn(evt), 2);
760 * limited to last column of seqcanvas
763 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
765 SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas;
766 int w = seqCanvas.getWidth();
767 // limited to number of whole columns, base 0
769 int expected = w / charWidth;
771 alignFrame.getViewport().getRanges().getEndRes(),
773 int col = testee.findColumn(evt);
774 assertEquals(col, expected);
777 * hide columns 5-10 (base 1)
779 alignFrame.getViewport().hideColumns(4, 9);
780 x = 5 * charWidth + 2;
781 // x is in 6th visible column, absolute column 12, or 11 base 0
782 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
784 col = testee.findColumn(evt);
785 assertEquals(col, 11);
788 @Test(groups = "Functional")
789 public void testFindColumn_wrapped()
791 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
792 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
793 "examples/uniref50.fa", DataSourceType.FILE);
794 AlignViewport av = alignFrame.getViewport();
795 av.setScaleAboveWrapped(false);
796 av.setScaleLeftWrapped(false);
797 av.setScaleRightWrapped(false);
798 alignFrame.alignPanel.updateLayout();
799 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
801 final int charWidth = av.getCharWidth();
802 assertTrue(charWidth > 0); // sanity check
803 assertEquals(av.getRanges().getStartRes(), 0);
806 * mouse at top left of wrapped panel, no West (left) scale
808 MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
810 assertEquals(testee.findColumn(evt), 0);
813 * not quite one charWidth across
816 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
818 assertEquals(testee.findColumn(evt), 0);
821 * one charWidth across
824 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
826 assertEquals(testee.findColumn(evt), 1);
829 * x over scale left (before drawn columns) results in -1
831 av.setScaleLeftWrapped(true);
832 alignFrame.alignPanel.updateLayout();
833 SeqCanvas seqCanvas = testee.seqCanvas;
834 int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
835 assertTrue(labelWidth > 0);
837 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
839 assertEquals(testee.findColumn(evt), -1);
842 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
844 assertEquals(testee.findColumn(evt), 0);
847 * x over right edge of last residue (including scale left)
849 int residuesWide = av.getRanges().getViewportWidth();
850 assertTrue(residuesWide > 0);
851 x = labelWidth + charWidth * residuesWide - 1;
852 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
854 assertEquals(testee.findColumn(evt), residuesWide - 1);
857 * x over scale right (beyond drawn columns) results in -1
859 av.setScaleRightWrapped(true);
860 alignFrame.alignPanel.updateLayout();
861 labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
862 assertTrue(labelWidth > 0);
863 int residuesWide2 = av.getRanges().getViewportWidth();
864 assertTrue(residuesWide2 > 0);
865 assertTrue(residuesWide2 < residuesWide); // available width reduced
866 x += 1; // just over left edge of scale right
867 evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
869 assertEquals(testee.findColumn(evt), -1);
871 // todo add startRes offset, hidden columns
874 @BeforeClass(alwaysRun = true)
875 public static void setUpBeforeClass() throws Exception
878 * use read-only test properties file
880 Cache.loadProperties("test/jalview/io/testProps.jvprops");
881 Jalview.main(new String[] { "-nonews" });
885 * waits for Swing event dispatch queue to empty
887 synchronized void waitForSwing()
891 EventQueue.invokeAndWait(new Runnable()
898 } catch (InterruptedException | InvocationTargetException e)