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.InputEvent;import java.awt.EventQueue;
44 import java.awt.event.MouseEvent;
45 import java.lang.reflect.InvocationTargetException;
47 import javax.swing.JLabel;
49 import org.testng.annotations.AfterMethod;
50 import org.testng.annotations.BeforeClass;
51 import org.testng.annotations.Test;
53 import junit.extensions.PA;
55 public class SeqPanelTest
59 @BeforeClass(alwaysRun = true)
60 public void setUpJvOptionPane()
62 JvOptionPane.setInteractiveMode(false);
63 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
65 @Test(groups = "Functional")
66 public void testSetStatusReturnsNearestResiduePosition()
68 SequenceI seq1 = new Sequence("Seq1", "AACDE");
69 SequenceI seq2 = new Sequence("Seq2", "AA--E");
70 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
71 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
73 AlignmentI visAl = alignFrame.getViewport().getAlignment();
75 // Test either side of gap
77 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
78 visAl.getSequenceAt(1), 1, 1), 2);
79 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
80 "Sequence 2 ID: Seq2 Residue: ALA (2)");
82 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
83 visAl.getSequenceAt(1), 4, 1), 3);
84 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
85 "Sequence 2 ID: Seq2 Residue: GLU (3)");
86 // no status message at a gap, returns next residue position to the right
88 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
89 visAl.getSequenceAt(1), 2, 1), 3);
90 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
91 "Sequence 2 ID: Seq2");
93 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
94 visAl.getSequenceAt(1), 3, 1), 3);
95 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
96 "Sequence 2 ID: Seq2");
99 @Test(groups = "Functional")
100 public void testAmbiguousAminoAcidGetsStatusMessage()
102 SequenceI seq1 = new Sequence("Seq1", "ABCDE");
103 SequenceI seq2 = new Sequence("Seq2", "AB--E");
104 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
105 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
107 AlignmentI visAl = alignFrame.getViewport().getAlignment();
110 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
111 visAl.getSequenceAt(1), 1, 1), 2);
112 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
113 "Sequence 2 ID: Seq2 Residue: B (2)");
116 @Test(groups = "Functional")
117 public void testGetEditStatusMessage()
119 assertNull(SeqPanel.getEditStatusMessage(null));
121 EditCommand edit = new EditCommand(); // empty
122 assertNull(SeqPanel.getEditStatusMessage(edit));
124 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
127 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'));
128 String expected = MessageManager.formatMessage("label.insert_gap", "1");
129 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
131 // 3 more gaps makes +4
132 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-'));
133 expected = MessageManager.formatMessage("label.insert_gaps", "4");
134 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
136 // 2 deletes makes + 2
137 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
138 expected = MessageManager.formatMessage("label.insert_gaps", "2");
139 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
141 // 2 more deletes makes 0 - no text
142 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
143 assertNull(SeqPanel.getEditStatusMessage(edit));
145 // 1 more delete makes 1 delete
146 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
147 expected = MessageManager.formatMessage("label.delete_gap", "1");
148 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
150 // 1 more delete makes 2 deletes
151 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
152 expected = MessageManager.formatMessage("label.delete_gaps", "2");
153 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
157 * Tests that simulate 'locked editing', where an inserted gap is balanced by
158 * a gap deletion in the selection group, and vice versa
160 @Test(groups = "Functional")
161 public void testGetEditStatusMessage_lockedEditing()
163 EditCommand edit = new EditCommand(); // empty
164 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
166 // 1 gap inserted, balanced by 1 delete
167 Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-');
169 Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-');
170 e2.setSystemGenerated(true);
172 String expected = MessageManager.formatMessage("label.insert_gap", "1");
173 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
175 // 2 more gaps makes +3
176 Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
178 Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-');
179 e4.setSystemGenerated(true);
181 expected = MessageManager.formatMessage("label.insert_gaps", "3");
182 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
184 // 2 deletes makes + 1
185 Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
187 Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
188 e6.setSystemGenerated(true);
190 expected = MessageManager.formatMessage("label.insert_gap", "1");
191 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
193 // 1 more delete makes 0 - no text
194 Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
196 Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
197 e8.setSystemGenerated(true);
199 expected = MessageManager.formatMessage("label.insert_gaps", "2");
200 assertNull(SeqPanel.getEditStatusMessage(edit));
202 // 1 more delete makes 1 delete
203 Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
205 Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
206 e10.setSystemGenerated(true);
208 expected = MessageManager.formatMessage("label.delete_gap", "1");
209 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
211 // 2 more deletes makes 3 deletes
212 Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
214 Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
215 e12.setSystemGenerated(true);
217 expected = MessageManager.formatMessage("label.delete_gaps", "3");
218 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
221 public void testFindMousePosition_unwrapped()
223 String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
224 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData,
225 DataSourceType.PASTE);
226 AlignViewportI av = alignFrame.getViewport();
227 av.setShowAnnotation(true);
228 av.setWrapAlignment(false);
229 final int charHeight = av.getCharHeight();
230 final int charWidth = av.getCharWidth();
232 assertTrue(charHeight > 0);
233 assertTrue(charWidth > 0);
234 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
236 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
241 * mouse at top left of unwrapped panel
243 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y,
245 MousePos pos = testee.findMousePosition(evt);
246 assertEquals(pos.column, 0);
247 assertEquals(pos.seqIndex, 0);
248 assertEquals(pos.annotationIndex, -1);
251 @AfterMethod(alwaysRun = true)
252 public void tearDown()
254 Desktop.instance.closeAll_actionPerformed(null);
257 @Test(groups = "Functional")
258 public void testFindMousePosition_wrapped_annotations()
260 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true");
261 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
262 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
263 "examples/uniref50.fa", DataSourceType.FILE);
264 AlignViewportI av = alignFrame.getViewport();
265 av.setScaleAboveWrapped(false);
266 av.setScaleLeftWrapped(false);
267 av.setScaleRightWrapped(false);
268 alignFrame.alignPanel.paintAlignment(false, false);
269 waitForSwing(); // for Swing thread
271 final int charHeight = av.getCharHeight();
272 final int charWidth = av.getCharWidth();
273 final int alignmentHeight = av.getAlignment().getHeight();
276 assertTrue(charHeight > 0);
277 assertTrue(charWidth > 0);
278 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
280 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
285 * mouse at top left of wrapped panel; there is a gap of charHeight
286 * above the alignment
288 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y,
290 MousePos pos = testee.findMousePosition(evt);
291 assertEquals(pos.column, 0);
292 assertEquals(pos.seqIndex, -1); // above sequences
293 assertEquals(pos.annotationIndex, -1);
296 * cursor at bottom of gap above
299 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
301 pos = testee.findMousePosition(evt);
302 assertEquals(pos.seqIndex, -1);
303 assertEquals(pos.annotationIndex, -1);
306 * cursor over top of first sequence
309 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
311 pos = testee.findMousePosition(evt);
312 assertEquals(pos.seqIndex, 0);
313 assertEquals(pos.annotationIndex, -1);
316 * cursor at bottom of first sequence
318 y = 2 * charHeight - 1;
319 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
321 pos = testee.findMousePosition(evt);
322 assertEquals(pos.seqIndex, 0);
323 assertEquals(pos.annotationIndex, -1);
326 * cursor at top of second sequence
329 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
331 pos = testee.findMousePosition(evt);
332 assertEquals(pos.seqIndex, 1);
333 assertEquals(pos.annotationIndex, -1);
336 * cursor at bottom of second sequence
338 y = 3 * charHeight - 1;
339 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
341 pos = testee.findMousePosition(evt);
342 assertEquals(pos.seqIndex, 1);
343 assertEquals(pos.annotationIndex, -1);
346 * cursor at bottom of last sequence
348 y = charHeight * (1 + alignmentHeight) - 1;
349 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
351 pos = testee.findMousePosition(evt);
352 assertEquals(pos.seqIndex, alignmentHeight - 1);
353 assertEquals(pos.annotationIndex, -1);
356 * cursor below sequences, in 3-pixel gap above annotations
357 * method reports index of nearest sequence above
360 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
362 pos = testee.findMousePosition(evt);
363 assertEquals(pos.seqIndex, alignmentHeight - 1);
364 assertEquals(pos.annotationIndex, -1);
367 * cursor still in the gap above annotations, now at the bottom of it
369 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
370 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
372 pos = testee.findMousePosition(evt);
373 assertEquals(pos.seqIndex, alignmentHeight - 1);
374 assertEquals(pos.annotationIndex, -1);
376 AlignmentAnnotation[] annotationRows = av.getAlignment()
377 .getAlignmentAnnotation();
378 for (int n = 0; n < annotationRows.length; n++)
381 * cursor at the top of the n'th annotation
384 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
386 pos = testee.findMousePosition(evt);
387 assertEquals(pos.seqIndex, alignmentHeight - 1);
388 assertEquals(pos.annotationIndex, n); // over n'th annotation
391 * cursor at the bottom of the n'th annotation
393 y += annotationRows[n].height - 1;
394 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
396 pos = testee.findMousePosition(evt);
397 assertEquals(pos.seqIndex, alignmentHeight - 1);
398 assertEquals(pos.annotationIndex, n);
402 * cursor in gap between wrapped widths
405 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
407 pos = testee.findMousePosition(evt);
408 assertEquals(pos.seqIndex, -1);
409 assertEquals(pos.annotationIndex, -1);
412 * cursor at bottom of gap between wrapped widths
415 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
417 pos = testee.findMousePosition(evt);
418 assertEquals(pos.seqIndex, -1);
419 assertEquals(pos.annotationIndex, -1);
422 * cursor at top of first sequence, second wrapped width
425 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
427 pos = testee.findMousePosition(evt);
428 assertEquals(pos.seqIndex, 0);
429 assertEquals(pos.annotationIndex, -1);
432 @Test(groups = "Functional")
433 public void testFindMousePosition_wrapped_scaleAbove()
435 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true");
436 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
437 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
438 "examples/uniref50.fa", DataSourceType.FILE);
439 AlignViewportI av = alignFrame.getViewport();
440 av.setScaleAboveWrapped(true);
441 av.setScaleLeftWrapped(false);
442 av.setScaleRightWrapped(false);
443 alignFrame.alignPanel.paintAlignment(false, false);
446 final int charHeight = av.getCharHeight();
447 final int charWidth = av.getCharWidth();
448 final int alignmentHeight = av.getAlignment().getHeight();
451 assertTrue(charHeight > 0);
452 assertTrue(charWidth > 0);
453 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
455 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
460 * mouse at top left of wrapped panel; there is a gap of charHeight
461 * above the alignment
463 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y,
465 MousePos pos = testee.findMousePosition(evt);
466 assertEquals(pos.column, 0);
467 assertEquals(pos.seqIndex, -1); // above sequences
468 assertEquals(pos.annotationIndex, -1);
471 * cursor at bottom of gap above
472 * two charHeights including scale panel
474 y = 2 * charHeight - 1;
475 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
477 pos = testee.findMousePosition(evt);
478 assertEquals(pos.seqIndex, -1);
479 assertEquals(pos.annotationIndex, -1);
482 * cursor over top of first sequence
485 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
487 pos = testee.findMousePosition(evt);
488 assertEquals(pos.seqIndex, 0);
489 assertEquals(pos.annotationIndex, -1);
492 * cursor at bottom of first sequence
495 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
497 pos = testee.findMousePosition(evt);
498 assertEquals(pos.seqIndex, 0);
499 assertEquals(pos.annotationIndex, -1);
502 * cursor at top of second sequence
505 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
507 pos = testee.findMousePosition(evt);
508 assertEquals(pos.seqIndex, 1);
509 assertEquals(pos.annotationIndex, -1);
512 * cursor at bottom of second sequence
515 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
517 pos = testee.findMousePosition(evt);
518 assertEquals(pos.seqIndex, 1);
519 assertEquals(pos.annotationIndex, -1);
522 * cursor at bottom of last sequence
523 * (scale + gap + sequences)
525 y = charHeight * (2 + alignmentHeight) - 1;
526 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
528 pos = testee.findMousePosition(evt);
529 assertEquals(pos.seqIndex, alignmentHeight - 1);
530 assertEquals(pos.annotationIndex, -1);
533 * cursor below sequences, in 3-pixel gap above annotations
536 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
538 pos = testee.findMousePosition(evt);
539 assertEquals(pos.seqIndex, alignmentHeight - 1);
540 assertEquals(pos.annotationIndex, -1);
543 * cursor still in the gap above annotations, now at the bottom of it
544 * method reports index of nearest sequence above
546 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
547 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
549 pos = testee.findMousePosition(evt);
550 assertEquals(pos.seqIndex, alignmentHeight - 1);
551 assertEquals(pos.annotationIndex, -1);
553 AlignmentAnnotation[] annotationRows = av.getAlignment().getAlignmentAnnotation();
554 for (int n = 0; n < annotationRows.length; n++)
557 * cursor at the top of the n'th annotation
560 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
562 pos = testee.findMousePosition(evt);
563 assertEquals(pos.seqIndex, alignmentHeight - 1);
564 assertEquals(pos.annotationIndex, n); // over n'th annotation
567 * cursor at the bottom of the n'th annotation
569 y += annotationRows[n].height - 1;
570 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
572 pos = testee.findMousePosition(evt);
573 assertEquals(pos.seqIndex, alignmentHeight - 1);
574 assertEquals(pos.annotationIndex, n);
578 * cursor in gap between wrapped widths
581 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
583 pos = testee.findMousePosition(evt);
584 assertEquals(pos.seqIndex, -1);
585 assertEquals(pos.annotationIndex, -1);
588 * cursor at bottom of gap between wrapped widths
591 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
593 pos = testee.findMousePosition(evt);
594 assertEquals(pos.seqIndex, -1);
595 assertEquals(pos.annotationIndex, -1);
598 * cursor at top of scale, second wrapped width
601 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
603 pos = testee.findMousePosition(evt);
604 assertEquals(pos.seqIndex, -1);
605 assertEquals(pos.annotationIndex, -1);
608 * cursor at bottom of scale, second wrapped width
611 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
613 pos = testee.findMousePosition(evt);
614 assertEquals(pos.seqIndex, -1);
615 assertEquals(pos.annotationIndex, -1);
618 * cursor at top of first sequence, second wrapped width
621 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
623 pos = testee.findMousePosition(evt);
624 assertEquals(pos.seqIndex, 0);
625 assertEquals(pos.annotationIndex, -1);
628 @Test(groups = "Functional")
629 public void testFindMousePosition_wrapped_noAnnotations()
631 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "false");
632 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
633 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
634 "examples/uniref50.fa", DataSourceType.FILE);
635 AlignViewportI av = alignFrame.getViewport();
636 av.setScaleAboveWrapped(false);
637 av.setScaleLeftWrapped(false);
638 av.setScaleRightWrapped(false);
639 alignFrame.alignPanel.paintAlignment(false, false);
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, MouseEvent.MOUSE_MOVED, 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, MouseEvent.MOUSE_MOVED, 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, MouseEvent.MOUSE_MOVED, 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, MouseEvent.MOUSE_MOVED, 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, MouseEvent.MOUSE_MOVED, 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, MouseEvent.MOUSE_MOVED, 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.applicationProperties.setProperty("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);
730 * mouse at top left of unwrapped panel
732 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
734 assertEquals(testee.findColumn(evt), 0);
737 * not quite one charWidth across
740 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
742 assertEquals(testee.findColumn(evt), 0);
745 * one charWidth across
748 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
750 assertEquals(testee.findColumn(evt), 1);
753 * two charWidths across
756 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
758 assertEquals(testee.findColumn(evt), 2);
761 * limited to last column of seqcanvas
764 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
766 SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas;
767 int w = seqCanvas.getWidth();
768 // limited to number of whole columns, base 0
769 int expected = w / charWidth - 1;
770 assertEquals(testee.findColumn(evt), expected);
773 * hide columns 5-10 (base 1)
775 alignFrame.getViewport().hideColumns(4, 9);
776 x = 5 * charWidth + 2;
777 // x is in 6th visible column, absolute column 12, or 11 base 0
778 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
780 assertEquals(testee.findColumn(evt), 11);
783 @Test(groups = "Functional")
784 public void testFindColumn_wrapped()
786 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
787 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
788 "examples/uniref50.fa", DataSourceType.FILE);
789 AlignViewport av = alignFrame.getViewport();
790 av.setScaleAboveWrapped(false);
791 av.setScaleLeftWrapped(false);
792 av.setScaleRightWrapped(false);
793 alignFrame.alignPanel.paintAlignment(false, false);
794 // need to wait for repaint to finish!
796 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
798 final int charWidth = av.getCharWidth();
799 assertTrue(charWidth > 0); // sanity check
800 assertEquals(av.getRanges().getStartRes(), 0);
803 * mouse at top left of wrapped panel, no West (left) scale
805 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
807 assertEquals(testee.findColumn(evt), 0);
810 * not quite one charWidth across
813 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
815 assertEquals(testee.findColumn(evt), 0);
818 * one charWidth across
821 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
823 assertEquals(testee.findColumn(evt), 1);
826 * x over scale left (before drawn columns) results in -1
828 av.setScaleLeftWrapped(true);
829 alignFrame.alignPanel.paintAlignment(false, false);
831 SeqCanvas seqCanvas = testee.seqCanvas;
832 int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
833 assertTrue(labelWidth > 0);
835 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
837 assertEquals(testee.findColumn(evt), -1);
840 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
842 assertEquals(testee.findColumn(evt), 0);
845 * x over right edge of last residue (including scale left)
847 int residuesWide = av.getRanges().getViewportWidth();
848 assertTrue(residuesWide > 0);
849 x = labelWidth + charWidth * residuesWide - 1;
850 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
852 assertEquals(testee.findColumn(evt), residuesWide - 1);
855 * x over scale right (beyond drawn columns) results in -1
857 av.setScaleRightWrapped(true);
858 alignFrame.alignPanel.paintAlignment(false, false);
860 labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
861 assertTrue(labelWidth > 0);
862 int residuesWide2 = av.getRanges().getViewportWidth();
863 assertTrue(residuesWide2 > 0);
864 assertTrue(residuesWide2 < residuesWide); // available width reduced
865 x += 1; // just over left edge of scale right
866 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
868 assertEquals(testee.findColumn(evt), -1);
870 // todo add startRes offset, hidden columns
873 @BeforeClass(alwaysRun = true)
874 public static void setUpBeforeClass() throws Exception
877 * use read-only test properties file
879 Cache.loadProperties("test/jalview/io/testProps.jvprops");
880 Jalview.main(new String[] { "-nonews" });
884 * waits for Swing event dispatch queue to empty
886 synchronized void waitForSwing()
890 EventQueue.invokeAndWait(new Runnable()
897 } catch (InterruptedException | InvocationTargetException e)