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;
42 import jalview.viewmodel.ViewportRanges;
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 JvOptionPane.setInteractiveMode(false);
64 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
66 @Test(groups = "Functional")
67 public void testSetStatusReturnsNearestResiduePosition()
69 SequenceI seq1 = new Sequence("Seq1", "AACDE");
70 SequenceI seq2 = new Sequence("Seq2", "AA--E");
71 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
72 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
74 AlignmentI visAl = alignFrame.getViewport().getAlignment();
76 // Test either side of gap
78 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
79 visAl.getSequenceAt(1), 1, 1), 2);
80 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
81 "Sequence 2 ID: Seq2 Residue: ALA (2)");
83 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
84 visAl.getSequenceAt(1), 4, 1), 3);
85 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
86 "Sequence 2 ID: Seq2 Residue: GLU (3)");
87 // no status message at a gap, returns next residue position to the right
89 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
90 visAl.getSequenceAt(1), 2, 1), 3);
91 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
92 "Sequence 2 ID: Seq2");
94 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
95 visAl.getSequenceAt(1), 3, 1), 3);
96 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
97 "Sequence 2 ID: Seq2");
100 @Test(groups = "Functional")
101 public void testAmbiguousAminoAcidGetsStatusMessage()
103 SequenceI seq1 = new Sequence("Seq1", "ABCDE");
104 SequenceI seq2 = new Sequence("Seq2", "AB--E");
105 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
106 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
108 AlignmentI visAl = alignFrame.getViewport().getAlignment();
111 alignFrame.alignPanel.getSeqPanel().setStatusMessage(
112 visAl.getSequenceAt(1), 1, 1), 2);
113 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
114 "Sequence 2 ID: Seq2 Residue: B (2)");
117 @Test(groups = "Functional")
118 public void testGetEditStatusMessage()
120 assertNull(SeqPanel.getEditStatusMessage(null));
122 EditCommand edit = new EditCommand(); // empty
123 assertNull(SeqPanel.getEditStatusMessage(edit));
125 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
128 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'));
129 String expected = MessageManager.formatMessage("label.insert_gap", "1");
130 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
132 // 3 more gaps makes +4
133 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-'));
134 expected = MessageManager.formatMessage("label.insert_gaps", "4");
135 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
137 // 2 deletes makes + 2
138 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
139 expected = MessageManager.formatMessage("label.insert_gaps", "2");
140 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
142 // 2 more deletes makes 0 - no text
143 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
144 assertNull(SeqPanel.getEditStatusMessage(edit));
146 // 1 more delete makes 1 delete
147 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
148 expected = MessageManager.formatMessage("label.delete_gap", "1");
149 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
151 // 1 more delete makes 2 deletes
152 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
153 expected = MessageManager.formatMessage("label.delete_gaps", "2");
154 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
158 * Tests that simulate 'locked editing', where an inserted gap is balanced by
159 * a gap deletion in the selection group, and vice versa
161 @Test(groups = "Functional")
162 public void testGetEditStatusMessage_lockedEditing()
164 EditCommand edit = new EditCommand(); // empty
165 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
167 // 1 gap inserted, balanced by 1 delete
168 Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-');
170 Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-');
171 e2.setSystemGenerated(true);
173 String expected = MessageManager.formatMessage("label.insert_gap", "1");
174 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
176 // 2 more gaps makes +3
177 Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
179 Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-');
180 e4.setSystemGenerated(true);
182 expected = MessageManager.formatMessage("label.insert_gaps", "3");
183 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
185 // 2 deletes makes + 1
186 Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
188 Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
189 e6.setSystemGenerated(true);
191 expected = MessageManager.formatMessage("label.insert_gap", "1");
192 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
194 // 1 more delete makes 0 - no text
195 Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
197 Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
198 e8.setSystemGenerated(true);
200 expected = MessageManager.formatMessage("label.insert_gaps", "2");
201 assertNull(SeqPanel.getEditStatusMessage(edit));
203 // 1 more delete makes 1 delete
204 Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
206 Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
207 e10.setSystemGenerated(true);
209 expected = MessageManager.formatMessage("label.delete_gap", "1");
210 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
212 // 2 more deletes makes 3 deletes
213 Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
215 Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
216 e12.setSystemGenerated(true);
218 expected = MessageManager.formatMessage("label.delete_gaps", "3");
219 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
222 public void testFindMousePosition_unwrapped()
224 String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
225 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData,
226 DataSourceType.PASTE);
227 AlignViewportI av = alignFrame.getViewport();
228 av.setShowAnnotation(true);
229 av.setWrapAlignment(false);
230 final int charHeight = av.getCharHeight();
231 final int charWidth = av.getCharWidth();
233 assertTrue(charHeight > 0);
234 assertTrue(charWidth > 0);
235 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
237 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
242 * mouse at top left of unwrapped panel
244 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y,
246 MousePos pos = testee.findMousePosition(evt);
247 assertEquals(pos.column, 0);
248 assertEquals(pos.seqIndex, 0);
249 assertEquals(pos.annotationIndex, -1);
252 @AfterMethod(alwaysRun = true)
253 public void tearDown()
255 Desktop.getInstance().closeAll_actionPerformed(null);
258 @Test(groups = "Functional")
259 public void testFindMousePosition_wrapped_annotations()
261 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "true");
262 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
263 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
264 "examples/uniref50.fa", DataSourceType.FILE);
265 AlignViewportI av = alignFrame.getViewport();
266 av.setScaleAboveWrapped(false);
267 av.setScaleLeftWrapped(false);
268 av.setScaleRightWrapped(false);
270 alignFrame.alignPanel.updateLayout();
272 final int charHeight = av.getCharHeight();
273 final int charWidth = av.getCharWidth();
274 final int alignmentHeight = av.getAlignment().getHeight();
277 assertTrue(charHeight > 0);
278 assertTrue(charWidth > 0);
279 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
281 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
286 * mouse at top left of wrapped panel; there is a gap of charHeight
287 * above the alignment
289 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y,
291 MousePos pos = testee.findMousePosition(evt);
292 assertEquals(pos.column, 0);
293 assertEquals(pos.seqIndex, -1); // above sequences
294 assertEquals(pos.annotationIndex, -1);
297 * cursor at bottom of gap above
300 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
302 pos = testee.findMousePosition(evt);
303 assertEquals(pos.seqIndex, -1);
304 assertEquals(pos.annotationIndex, -1);
307 * cursor over top of first sequence
310 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
312 pos = testee.findMousePosition(evt);
313 assertEquals(pos.seqIndex, 0);
314 assertEquals(pos.annotationIndex, -1);
317 * cursor at bottom of first sequence
319 y = 2 * charHeight - 1;
320 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
322 pos = testee.findMousePosition(evt);
323 assertEquals(pos.seqIndex, 0);
324 assertEquals(pos.annotationIndex, -1);
327 * cursor at top of second sequence
330 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
332 pos = testee.findMousePosition(evt);
333 assertEquals(pos.seqIndex, 1);
334 assertEquals(pos.annotationIndex, -1);
337 * cursor at bottom of second sequence
339 y = 3 * charHeight - 1;
340 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
342 pos = testee.findMousePosition(evt);
343 assertEquals(pos.seqIndex, 1);
344 assertEquals(pos.annotationIndex, -1);
347 * cursor at bottom of last sequence
349 y = charHeight * (1 + alignmentHeight) - 1;
350 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
352 pos = testee.findMousePosition(evt);
353 assertEquals(pos.seqIndex, alignmentHeight - 1);
354 assertEquals(pos.annotationIndex, -1);
357 * cursor below sequences, in 3-pixel gap above annotations
358 * method reports index of nearest sequence above
361 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
363 pos = testee.findMousePosition(evt);
364 assertEquals(pos.seqIndex, alignmentHeight - 1);
365 assertEquals(pos.annotationIndex, -1);
368 * cursor still in the gap above annotations, now at the bottom of it
370 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
371 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
373 pos = testee.findMousePosition(evt);
374 assertEquals(pos.seqIndex, alignmentHeight - 1);
375 assertEquals(pos.annotationIndex, -1);
377 AlignmentAnnotation[] annotationRows = av.getAlignment()
378 .getAlignmentAnnotation();
379 for (int n = 0; n < annotationRows.length; n++)
382 * cursor at the top of the n'th annotation
385 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
387 pos = testee.findMousePosition(evt);
388 assertEquals(pos.seqIndex, alignmentHeight - 1);
389 assertEquals(pos.annotationIndex, n); // over n'th annotation
392 * cursor at the bottom of the n'th annotation
394 y += annotationRows[n].height - 1;
395 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
397 pos = testee.findMousePosition(evt);
398 assertEquals(pos.seqIndex, alignmentHeight - 1);
399 assertEquals(pos.annotationIndex, n);
403 * cursor in gap between wrapped widths
406 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
408 pos = testee.findMousePosition(evt);
409 assertEquals(pos.seqIndex, -1);
410 assertEquals(pos.annotationIndex, -1);
413 * cursor at bottom of gap between wrapped widths
416 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
418 pos = testee.findMousePosition(evt);
419 assertEquals(pos.seqIndex, -1);
420 assertEquals(pos.annotationIndex, -1);
423 * cursor at top of first sequence, second wrapped width
426 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
428 pos = testee.findMousePosition(evt);
429 assertEquals(pos.seqIndex, 0);
430 assertEquals(pos.annotationIndex, -1);
433 @Test(groups = "Functional")
434 public void testFindMousePosition_wrapped_scaleAbove()
436 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "true");
437 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
438 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
439 "examples/uniref50.fa", DataSourceType.FILE);
440 AlignViewportI av = alignFrame.getViewport();
441 av.setScaleAboveWrapped(true);
442 av.setScaleLeftWrapped(false);
443 av.setScaleRightWrapped(false);
444 alignFrame.alignPanel.updateLayout();
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 SeqCanvas sc = testee.seqCanvas;
574 assertEquals(pos.seqIndex, alignmentHeight - 1,
575 String.format("%s n=%d y=%d %d, %d, %d, %d",
576 annotationRows[n].label, n, y, sc.getWidth(),
577 sc.getHeight(), sc.wrappedRepeatHeightPx,
578 sc.wrappedSpaceAboveAlignment));
579 assertEquals(pos.annotationIndex, n);
583 * cursor in gap between wrapped widths
586 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
588 pos = testee.findMousePosition(evt);
589 assertEquals(pos.seqIndex, -1);
590 assertEquals(pos.annotationIndex, -1);
593 * cursor at bottom of gap between wrapped widths
596 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
598 pos = testee.findMousePosition(evt);
599 assertEquals(pos.seqIndex, -1);
600 assertEquals(pos.annotationIndex, -1);
603 * cursor at top of scale, second wrapped width
606 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
608 pos = testee.findMousePosition(evt);
609 assertEquals(pos.seqIndex, -1);
610 assertEquals(pos.annotationIndex, -1);
613 * cursor at bottom of scale, second wrapped width
616 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
618 pos = testee.findMousePosition(evt);
619 assertEquals(pos.seqIndex, -1);
620 assertEquals(pos.annotationIndex, -1);
623 * cursor at top of first sequence, second wrapped width
626 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
628 pos = testee.findMousePosition(evt);
629 assertEquals(pos.seqIndex, 0);
630 assertEquals(pos.annotationIndex, -1);
633 @Test(groups = "Functional")
634 public void testFindMousePosition_wrapped_noAnnotations()
636 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "false");
637 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
638 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
639 "examples/uniref50.fa", DataSourceType.FILE);
640 AlignViewportI av = alignFrame.getViewport();
641 av.setScaleAboveWrapped(false);
642 av.setScaleLeftWrapped(false);
643 av.setScaleRightWrapped(false);
644 alignFrame.alignPanel.updateLayout();
646 final int charHeight = av.getCharHeight();
647 final int charWidth = av.getCharWidth();
648 final int alignmentHeight = av.getAlignment().getHeight();
651 assertTrue(charHeight > 0);
652 assertTrue(charWidth > 0);
653 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
655 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
660 * mouse at top left of wrapped panel; there is a gap of charHeight
661 * above the alignment
663 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y,
665 MousePos pos = testee.findMousePosition(evt);
666 assertEquals(pos.column, 0);
667 assertEquals(pos.seqIndex, -1); // above sequences
668 assertEquals(pos.annotationIndex, -1);
671 * cursor over top of first sequence
674 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
676 pos = testee.findMousePosition(evt);
677 assertEquals(pos.seqIndex, 0);
678 assertEquals(pos.annotationIndex, -1);
681 * cursor at bottom of last sequence
683 y = charHeight * (1 + alignmentHeight) - 1;
684 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
686 pos = testee.findMousePosition(evt);
687 assertEquals(pos.seqIndex, alignmentHeight - 1);
688 assertEquals(pos.annotationIndex, -1);
691 * cursor below sequences, at top of charHeight gap between widths
694 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
696 pos = testee.findMousePosition(evt);
697 assertEquals(pos.seqIndex, -1);
698 assertEquals(pos.annotationIndex, -1);
701 * cursor below sequences, at top of charHeight gap between widths
704 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
706 pos = testee.findMousePosition(evt);
707 assertEquals(pos.seqIndex, -1);
708 assertEquals(pos.annotationIndex, -1);
711 * cursor at the top of the first sequence, second width
714 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, 0,
716 pos = testee.findMousePosition(evt);
717 assertEquals(pos.seqIndex, 0);
718 assertEquals(pos.annotationIndex, -1);
721 @Test(groups = "Functional")
722 public void testFindColumn_unwrapped()
724 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "false");
725 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
726 "examples/uniref50.fa", DataSourceType.FILE);
727 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
729 final int charWidth = alignFrame.getViewport().getCharWidth();
730 assertTrue(charWidth > 0); // sanity check
731 ViewportRanges ranges = alignFrame.getViewport().getRanges();
732 assertEquals(ranges.getStartRes(), 0);
735 * mouse at top left of unwrapped panel
737 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
739 assertEquals(testee.findColumn(evt), 0);
742 * not quite one charWidth across
745 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
747 assertEquals(testee.findColumn(evt), 0);
750 * one charWidth across
753 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
755 assertEquals(testee.findColumn(evt), 1);
758 * two charWidths across
761 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
763 assertEquals(testee.findColumn(evt), 2);
766 * limited to last column of seqcanvas
769 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
771 SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas;
772 int w = seqCanvas.getWidth();
773 // limited to number of whole columns, base 0,
774 // and to end of visible range
775 int expected = w / charWidth;
776 expected = Math.min(expected, ranges.getEndRes());
777 assertEquals(testee.findColumn(evt), expected);
780 * hide columns 5-10 (base 1)
782 alignFrame.getViewport().hideColumns(4, 9);
783 x = 5 * charWidth + 2;
784 // x is in 6th visible column, absolute column 12, or 11 base 0
785 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
787 assertEquals(testee.findColumn(evt), 11);
790 @Test(groups = "Functional")
791 public void testFindColumn_wrapped()
793 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
794 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
795 "examples/uniref50.fa", DataSourceType.FILE);
796 AlignViewport av = alignFrame.getViewport();
797 av.setScaleAboveWrapped(false);
798 av.setScaleLeftWrapped(false);
799 av.setScaleRightWrapped(false);
800 alignFrame.alignPanel.updateLayout();
801 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
803 final int charWidth = av.getCharWidth();
804 assertTrue(charWidth > 0); // sanity check
805 assertEquals(av.getRanges().getStartRes(), 0);
808 * mouse at top left of wrapped panel, no West (left) scale
810 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
812 assertEquals(testee.findColumn(evt), 0);
815 * not quite one charWidth across
818 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0,
820 assertEquals(testee.findColumn(evt), 0);
823 * one charWidth across
826 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
828 assertEquals(testee.findColumn(evt), 1);
831 * x over scale left (before drawn columns) results in -1
833 av.setScaleLeftWrapped(true);
834 alignFrame.alignPanel.updateLayout();
835 SeqCanvas seqCanvas = testee.seqCanvas;
836 int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
837 assertTrue(labelWidth > 0);
839 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
841 assertEquals(testee.findColumn(evt), -1);
844 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
846 assertEquals(testee.findColumn(evt), 0);
849 * x over right edge of last residue (including scale left)
851 int residuesWide = av.getRanges().getViewportWidth();
852 assertTrue(residuesWide > 0);
853 x = labelWidth + charWidth * residuesWide - 1;
854 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
856 assertEquals(testee.findColumn(evt), residuesWide - 1);
859 * x over scale right (beyond drawn columns) results in -1
861 av.setScaleRightWrapped(true);
862 alignFrame.alignPanel.updateLayout();
863 labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
864 assertTrue(labelWidth > 0);
865 int residuesWide2 = av.getRanges().getViewportWidth();
866 assertTrue(residuesWide2 > 0);
867 assertTrue(residuesWide2 < residuesWide); // available width reduced
868 x += 1; // just over left edge of scale right
869 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, 0,
871 assertEquals(testee.findColumn(evt), -1);
873 // todo add startRes offset, hidden columns
876 @BeforeClass(alwaysRun = true)
877 public static void setUpBeforeClass() throws Exception
880 * use read-only test properties file
882 Cache.loadProperties("test/jalview/io/testProps.jvprops");
883 Jalview.main(new String[] { "-nonews" });
887 * waits for Swing event dispatch queue to empty
889 synchronized void waitForSwing()
893 EventQueue.invokeAndWait(new Runnable()
900 } catch (InterruptedException | InvocationTargetException e)