Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
SeqPanelTest | 58 | 518 | 22 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package jalview.gui; | |
22 | ||
23 | import static org.testng.Assert.assertEquals; | |
24 | import static org.testng.Assert.assertNull; | |
25 | import static org.testng.Assert.assertTrue; | |
26 | ||
27 | import java.awt.EventQueue; | |
28 | import java.awt.FontMetrics; | |
29 | import java.awt.event.MouseEvent; | |
30 | import java.lang.reflect.InvocationTargetException; | |
31 | ||
32 | import javax.swing.JLabel; | |
33 | ||
34 | import org.testng.annotations.AfterMethod; | |
35 | import org.testng.annotations.BeforeClass; | |
36 | import org.testng.annotations.Test; | |
37 | ||
38 | import jalview.api.AlignViewportI; | |
39 | import jalview.bin.Cache; | |
40 | import jalview.bin.Jalview; | |
41 | import jalview.commands.EditCommand; | |
42 | import jalview.commands.EditCommand.Action; | |
43 | import jalview.commands.EditCommand.Edit; | |
44 | import jalview.datamodel.Alignment; | |
45 | import jalview.datamodel.AlignmentAnnotation; | |
46 | import jalview.datamodel.AlignmentI; | |
47 | import jalview.datamodel.SearchResults; | |
48 | import jalview.datamodel.SearchResultsI; | |
49 | import jalview.datamodel.Sequence; | |
50 | import jalview.datamodel.SequenceI; | |
51 | import jalview.gui.SeqPanel.MousePos; | |
52 | import jalview.io.DataSourceType; | |
53 | import jalview.io.FileLoader; | |
54 | import jalview.util.MessageManager; | |
55 | import jalview.viewmodel.ViewportRanges; | |
56 | import junit.extensions.PA; | |
57 | ||
58 | public class SeqPanelTest | |
59 | { | |
60 | AlignFrame af; | |
61 | ||
62 | 1 | @BeforeClass(alwaysRun = true) |
63 | public void setUpJvOptionPane() | |
64 | { | |
65 | 1 | JvOptionPane.setInteractiveMode(false); |
66 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
67 | } | |
68 | ||
69 | 1 | @Test(groups = "Functional") |
70 | public void testSetStatusReturnsNearestResiduePosition() | |
71 | { | |
72 | 1 | SequenceI seq1 = new Sequence("Seq1", "AACDE"); |
73 | 1 | SequenceI seq2 = new Sequence("Seq2", "AA--E"); |
74 | 1 | AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 }); |
75 | 1 | AlignFrame alignFrame = new AlignFrame(al, al.getWidth(), |
76 | al.getHeight()); | |
77 | 1 | AlignmentI visAl = alignFrame.getViewport().getAlignment(); |
78 | ||
79 | // Test either side of gap | |
80 | 1 | assertEquals(alignFrame.alignPanel.getSeqPanel() |
81 | .setStatusMessage(visAl.getSequenceAt(1), 1, 1), 2); | |
82 | 1 | assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(), |
83 | "Sequence 2 ID: Seq2 Residue: ALA (2)"); | |
84 | 1 | assertEquals(alignFrame.alignPanel.getSeqPanel() |
85 | .setStatusMessage(visAl.getSequenceAt(1), 4, 1), 3); | |
86 | 1 | 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 | |
89 | 1 | assertEquals(alignFrame.alignPanel.getSeqPanel() |
90 | .setStatusMessage(visAl.getSequenceAt(1), 2, 1), 3); | |
91 | 1 | assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(), |
92 | "Sequence 2 ID: Seq2"); | |
93 | 1 | assertEquals(alignFrame.alignPanel.getSeqPanel() |
94 | .setStatusMessage(visAl.getSequenceAt(1), 3, 1), 3); | |
95 | 1 | assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(), |
96 | "Sequence 2 ID: Seq2"); | |
97 | } | |
98 | ||
99 | 1 | @Test(groups = "Functional") |
100 | public void testAmbiguousAminoAcidGetsStatusMessage() | |
101 | { | |
102 | 1 | SequenceI seq1 = new Sequence("Seq1", "ABCDE"); |
103 | 1 | SequenceI seq2 = new Sequence("Seq2", "AB--E"); |
104 | 1 | AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 }); |
105 | 1 | AlignFrame alignFrame = new AlignFrame(al, al.getWidth(), |
106 | al.getHeight()); | |
107 | 1 | AlignmentI visAl = alignFrame.getViewport().getAlignment(); |
108 | ||
109 | 1 | assertEquals(alignFrame.alignPanel.getSeqPanel() |
110 | .setStatusMessage(visAl.getSequenceAt(1), 1, 1), 2); | |
111 | 1 | assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(), |
112 | "Sequence 2 ID: Seq2 Residue: B (2)"); | |
113 | } | |
114 | ||
115 | 1 | @Test(groups = "Functional") |
116 | public void testGetEditStatusMessage() | |
117 | { | |
118 | 1 | assertNull(SeqPanel.getEditStatusMessage(null)); |
119 | ||
120 | 1 | EditCommand edit = new EditCommand(); // empty |
121 | 1 | assertNull(SeqPanel.getEditStatusMessage(edit)); |
122 | ||
123 | 1 | SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") }; |
124 | ||
125 | // 1 gap | |
126 | 1 | edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-')); |
127 | 1 | String expected = MessageManager.formatMessage("label.insert_gap", "1"); |
128 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
129 | ||
130 | // 3 more gaps makes +4 | |
131 | 1 | edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-')); |
132 | 1 | expected = MessageManager.formatMessage("label.insert_gaps", "4"); |
133 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
134 | ||
135 | // 2 deletes makes + 2 | |
136 | 1 | edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-')); |
137 | 1 | expected = MessageManager.formatMessage("label.insert_gaps", "2"); |
138 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
139 | ||
140 | // 2 more deletes makes 0 - no text | |
141 | 1 | edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-')); |
142 | 1 | assertNull(SeqPanel.getEditStatusMessage(edit)); |
143 | ||
144 | // 1 more delete makes 1 delete | |
145 | 1 | edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-')); |
146 | 1 | expected = MessageManager.formatMessage("label.delete_gap", "1"); |
147 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
148 | ||
149 | // 1 more delete makes 2 deletes | |
150 | 1 | edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-')); |
151 | 1 | expected = MessageManager.formatMessage("label.delete_gaps", "2"); |
152 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
153 | } | |
154 | ||
155 | /** | |
156 | * Tests that simulate 'locked editing', where an inserted gap is balanced by | |
157 | * a gap deletion in the selection group, and vice versa | |
158 | */ | |
159 | 1 | @Test(groups = "Functional") |
160 | public void testGetEditStatusMessage_lockedEditing() | |
161 | { | |
162 | 1 | EditCommand edit = new EditCommand(); // empty |
163 | 1 | SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") }; |
164 | ||
165 | // 1 gap inserted, balanced by 1 delete | |
166 | 1 | Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'); |
167 | 1 | edit.addEdit(e1); |
168 | 1 | Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-'); |
169 | 1 | e2.setSystemGenerated(true); |
170 | 1 | edit.addEdit(e2); |
171 | 1 | String expected = MessageManager.formatMessage("label.insert_gap", "1"); |
172 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
173 | ||
174 | // 2 more gaps makes +3 | |
175 | 1 | Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-'); |
176 | 1 | edit.addEdit(e3); |
177 | 1 | Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-'); |
178 | 1 | e4.setSystemGenerated(true); |
179 | 1 | edit.addEdit(e4); |
180 | 1 | expected = MessageManager.formatMessage("label.insert_gaps", "3"); |
181 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
182 | ||
183 | // 2 deletes makes + 1 | |
184 | 1 | Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'); |
185 | 1 | edit.addEdit(e5); |
186 | 1 | Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-'); |
187 | 1 | e6.setSystemGenerated(true); |
188 | 1 | edit.addEdit(e6); |
189 | 1 | expected = MessageManager.formatMessage("label.insert_gap", "1"); |
190 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
191 | ||
192 | // 1 more delete makes 0 - no text | |
193 | 1 | Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'); |
194 | 1 | edit.addEdit(e7); |
195 | 1 | Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-'); |
196 | 1 | e8.setSystemGenerated(true); |
197 | 1 | edit.addEdit(e8); |
198 | 1 | expected = MessageManager.formatMessage("label.insert_gaps", "2"); |
199 | 1 | assertNull(SeqPanel.getEditStatusMessage(edit)); |
200 | ||
201 | // 1 more delete makes 1 delete | |
202 | 1 | Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'); |
203 | 1 | edit.addEdit(e9); |
204 | 1 | Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-'); |
205 | 1 | e10.setSystemGenerated(true); |
206 | 1 | edit.addEdit(e10); |
207 | 1 | expected = MessageManager.formatMessage("label.delete_gap", "1"); |
208 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
209 | ||
210 | // 2 more deletes makes 3 deletes | |
211 | 1 | Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'); |
212 | 1 | edit.addEdit(e11); |
213 | 1 | Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-'); |
214 | 1 | e12.setSystemGenerated(true); |
215 | 1 | edit.addEdit(e12); |
216 | 1 | expected = MessageManager.formatMessage("label.delete_gaps", "3"); |
217 | 1 | assertEquals(SeqPanel.getEditStatusMessage(edit), expected); |
218 | } | |
219 | ||
220 | 0 | public void testFindMousePosition_unwrapped() |
221 | { | |
222 | 0 | String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n"; |
223 | 0 | AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData, |
224 | DataSourceType.PASTE); | |
225 | 0 | AlignViewportI av = alignFrame.getViewport(); |
226 | 0 | av.setShowAnnotation(true); |
227 | 0 | av.setWrapAlignment(false); |
228 | 0 | final int charHeight = av.getCharHeight(); |
229 | 0 | final int charWidth = av.getCharWidth(); |
230 | // sanity checks: | |
231 | 0 | assertTrue(charHeight > 0); |
232 | 0 | assertTrue(charWidth > 0); |
233 | 0 | assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0); |
234 | ||
235 | 0 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
236 | 0 | int x = 0; |
237 | 0 | int y = 0; |
238 | ||
239 | /* | |
240 | * mouse at top left of unwrapped panel | |
241 | */ | |
242 | 0 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
243 | x, y, 0, 0, 0, false, 0); | |
244 | 0 | MousePos pos = testee.findMousePosition(evt); |
245 | 0 | assertEquals(pos.column, 0); |
246 | 0 | assertEquals(pos.seqIndex, 0); |
247 | 0 | assertEquals(pos.annotationIndex, -1); |
248 | } | |
249 | ||
250 | 10 | @AfterMethod(alwaysRun = true) |
251 | public void tearDown() | |
252 | { | |
253 | 10 | if (Desktop.instance != null) |
254 | 10 | Desktop.instance.closeAll_actionPerformed(null); |
255 | } | |
256 | ||
257 | 1 | @Test(groups = "Functional") |
258 | public void testFindMousePosition_wrapped_annotations() | |
259 | { | |
260 | 1 | Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true"); |
261 | 1 | Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true"); |
262 | 1 | AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded( |
263 | "examples/uniref50.fa", DataSourceType.FILE); | |
264 | 1 | AlignViewportI av = alignFrame.getViewport(); |
265 | 1 | av.setScaleAboveWrapped(false); |
266 | 1 | av.setScaleLeftWrapped(false); |
267 | 1 | av.setScaleRightWrapped(false); |
268 | ||
269 | 1 | alignFrame.alignPanel.updateLayout(); |
270 | ||
271 | 1 | final int charHeight = av.getCharHeight(); |
272 | 1 | final int charWidth = av.getCharWidth(); |
273 | 1 | final int alignmentHeight = av.getAlignment().getHeight(); |
274 | ||
275 | // sanity checks: | |
276 | 1 | assertTrue(charHeight > 0); |
277 | 1 | assertTrue(charWidth > 0); |
278 | 1 | assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0); |
279 | ||
280 | 1 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
281 | 1 | int x = 0; |
282 | 1 | int y = 0; |
283 | ||
284 | /* | |
285 | * mouse at top left of wrapped panel; there is a gap of charHeight | |
286 | * above the alignment | |
287 | */ | |
288 | 1 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
289 | x, y, 0, 0, 0, false, 0); | |
290 | 1 | MousePos pos = testee.findMousePosition(evt); |
291 | 1 | assertEquals(pos.column, 0); |
292 | 1 | assertEquals(pos.seqIndex, -1); // above sequences |
293 | 1 | assertEquals(pos.annotationIndex, -1); |
294 | ||
295 | /* | |
296 | * cursor at bottom of gap above | |
297 | */ | |
298 | 1 | y = charHeight - 1; |
299 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
300 | 0, false, 0); | |
301 | 1 | pos = testee.findMousePosition(evt); |
302 | 1 | assertEquals(pos.seqIndex, -1); |
303 | 1 | assertEquals(pos.annotationIndex, -1); |
304 | ||
305 | /* | |
306 | * cursor over top of first sequence | |
307 | */ | |
308 | 1 | y = charHeight; |
309 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
310 | 0, false, 0); | |
311 | 1 | pos = testee.findMousePosition(evt); |
312 | 1 | assertEquals(pos.seqIndex, 0); |
313 | 1 | assertEquals(pos.annotationIndex, -1); |
314 | ||
315 | /* | |
316 | * cursor at bottom of first sequence | |
317 | */ | |
318 | 1 | y = 2 * charHeight - 1; |
319 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
320 | 0, false, 0); | |
321 | 1 | pos = testee.findMousePosition(evt); |
322 | 1 | assertEquals(pos.seqIndex, 0); |
323 | 1 | assertEquals(pos.annotationIndex, -1); |
324 | ||
325 | /* | |
326 | * cursor at top of second sequence | |
327 | */ | |
328 | 1 | y = 2 * charHeight; |
329 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
330 | 0, false, 0); | |
331 | 1 | pos = testee.findMousePosition(evt); |
332 | 1 | assertEquals(pos.seqIndex, 1); |
333 | 1 | assertEquals(pos.annotationIndex, -1); |
334 | ||
335 | /* | |
336 | * cursor at bottom of second sequence | |
337 | */ | |
338 | 1 | y = 3 * charHeight - 1; |
339 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
340 | 0, false, 0); | |
341 | 1 | pos = testee.findMousePosition(evt); |
342 | 1 | assertEquals(pos.seqIndex, 1); |
343 | 1 | assertEquals(pos.annotationIndex, -1); |
344 | ||
345 | /* | |
346 | * cursor at bottom of last sequence | |
347 | */ | |
348 | 1 | y = charHeight * (1 + alignmentHeight) - 1; |
349 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
350 | 0, false, 0); | |
351 | 1 | pos = testee.findMousePosition(evt); |
352 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
353 | 1 | assertEquals(pos.annotationIndex, -1); |
354 | ||
355 | /* | |
356 | * cursor below sequences, in 3-pixel gap above annotations | |
357 | * method reports index of nearest sequence above | |
358 | */ | |
359 | 1 | y += 1; |
360 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
361 | 0, false, 0); | |
362 | 1 | pos = testee.findMousePosition(evt); |
363 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
364 | 1 | assertEquals(pos.annotationIndex, -1); |
365 | ||
366 | /* | |
367 | * cursor still in the gap above annotations, now at the bottom of it | |
368 | */ | |
369 | 1 | y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2 |
370 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
371 | 0, false, 0); | |
372 | 1 | pos = testee.findMousePosition(evt); |
373 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
374 | 1 | assertEquals(pos.annotationIndex, -1); |
375 | ||
376 | 1 | AlignmentAnnotation[] annotationRows = av.getAlignment() |
377 | .getAlignmentAnnotation(); | |
378 | 5 | for (int n = 0; n < annotationRows.length; n++) |
379 | { | |
380 | /* | |
381 | * cursor at the top of the n'th annotation | |
382 | */ | |
383 | 4 | y += 1; |
384 | 4 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, |
385 | 0, 0, false, 0); | |
386 | 4 | pos = testee.findMousePosition(evt); |
387 | 4 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
388 | 4 | assertEquals(pos.annotationIndex, n); // over n'th annotation |
389 | ||
390 | /* | |
391 | * cursor at the bottom of the n'th annotation | |
392 | */ | |
393 | 4 | y += annotationRows[n].height - 1; |
394 | 4 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, |
395 | 0, 0, false, 0); | |
396 | 4 | pos = testee.findMousePosition(evt); |
397 | 4 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
398 | 4 | assertEquals(pos.annotationIndex, n); |
399 | } | |
400 | ||
401 | /* | |
402 | * cursor in gap between wrapped widths | |
403 | */ | |
404 | 1 | y += 1; |
405 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
406 | 0, false, 0); | |
407 | 1 | pos = testee.findMousePosition(evt); |
408 | 1 | assertEquals(pos.seqIndex, -1); |
409 | 1 | assertEquals(pos.annotationIndex, -1); |
410 | ||
411 | /* | |
412 | * cursor at bottom of gap between wrapped widths | |
413 | */ | |
414 | 1 | y += charHeight - 1; |
415 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
416 | 0, false, 0); | |
417 | 1 | pos = testee.findMousePosition(evt); |
418 | 1 | assertEquals(pos.seqIndex, -1); |
419 | 1 | assertEquals(pos.annotationIndex, -1); |
420 | ||
421 | /* | |
422 | * cursor at top of first sequence, second wrapped width | |
423 | */ | |
424 | 1 | y += 1; |
425 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
426 | 0, false, 0); | |
427 | 1 | pos = testee.findMousePosition(evt); |
428 | 1 | assertEquals(pos.seqIndex, 0); |
429 | 1 | assertEquals(pos.annotationIndex, -1); |
430 | } | |
431 | ||
432 | 1 | @Test(groups = "Functional") |
433 | public void testFindMousePosition_wrapped_scaleAbove() | |
434 | { | |
435 | 1 | Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true"); |
436 | 1 | Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true"); |
437 | 1 | AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded( |
438 | "examples/uniref50.fa", DataSourceType.FILE); | |
439 | 1 | AlignViewportI av = alignFrame.getViewport(); |
440 | 1 | av.setScaleAboveWrapped(true); |
441 | 1 | av.setScaleLeftWrapped(false); |
442 | 1 | av.setScaleRightWrapped(false); |
443 | 1 | alignFrame.alignPanel.updateLayout(); |
444 | ||
445 | 1 | final int charHeight = av.getCharHeight(); |
446 | 1 | final int charWidth = av.getCharWidth(); |
447 | 1 | final int alignmentHeight = av.getAlignment().getHeight(); |
448 | ||
449 | // sanity checks: | |
450 | 1 | assertTrue(charHeight > 0); |
451 | 1 | assertTrue(charWidth > 0); |
452 | 1 | assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0); |
453 | ||
454 | 1 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
455 | 1 | int x = 0; |
456 | 1 | int y = 0; |
457 | ||
458 | /* | |
459 | * mouse at top left of wrapped panel; there is a gap of charHeight | |
460 | * above the alignment | |
461 | */ | |
462 | 1 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
463 | x, y, 0, 0, 0, false, 0); | |
464 | 1 | MousePos pos = testee.findMousePosition(evt); |
465 | 1 | assertEquals(pos.column, 0); |
466 | 1 | assertEquals(pos.seqIndex, -1); // above sequences |
467 | 1 | assertEquals(pos.annotationIndex, -1); |
468 | ||
469 | /* | |
470 | * cursor at bottom of gap above | |
471 | * two charHeights including scale panel | |
472 | */ | |
473 | 1 | y = 2 * charHeight - 1; |
474 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
475 | 0, false, 0); | |
476 | 1 | pos = testee.findMousePosition(evt); |
477 | 1 | assertEquals(pos.seqIndex, -1); |
478 | 1 | assertEquals(pos.annotationIndex, -1); |
479 | ||
480 | /* | |
481 | * cursor over top of first sequence | |
482 | */ | |
483 | 1 | y += 1; |
484 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
485 | 0, false, 0); | |
486 | 1 | pos = testee.findMousePosition(evt); |
487 | 1 | assertEquals(pos.seqIndex, 0); |
488 | 1 | assertEquals(pos.annotationIndex, -1); |
489 | ||
490 | /* | |
491 | * cursor at bottom of first sequence | |
492 | */ | |
493 | 1 | y += charHeight - 1; |
494 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
495 | 0, false, 0); | |
496 | 1 | pos = testee.findMousePosition(evt); |
497 | 1 | assertEquals(pos.seqIndex, 0); |
498 | 1 | assertEquals(pos.annotationIndex, -1); |
499 | ||
500 | /* | |
501 | * cursor at top of second sequence | |
502 | */ | |
503 | 1 | y += 1; |
504 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
505 | 0, false, 0); | |
506 | 1 | pos = testee.findMousePosition(evt); |
507 | 1 | assertEquals(pos.seqIndex, 1); |
508 | 1 | assertEquals(pos.annotationIndex, -1); |
509 | ||
510 | /* | |
511 | * cursor at bottom of second sequence | |
512 | */ | |
513 | 1 | y += charHeight - 1; |
514 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
515 | 0, false, 0); | |
516 | 1 | pos = testee.findMousePosition(evt); |
517 | 1 | assertEquals(pos.seqIndex, 1); |
518 | 1 | assertEquals(pos.annotationIndex, -1); |
519 | ||
520 | /* | |
521 | * cursor at bottom of last sequence | |
522 | * (scale + gap + sequences) | |
523 | */ | |
524 | 1 | y = charHeight * (2 + alignmentHeight) - 1; |
525 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
526 | 0, false, 0); | |
527 | 1 | pos = testee.findMousePosition(evt); |
528 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
529 | 1 | assertEquals(pos.annotationIndex, -1); |
530 | ||
531 | /* | |
532 | * cursor below sequences, in 3-pixel gap above annotations | |
533 | */ | |
534 | 1 | y += 1; |
535 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
536 | 0, false, 0); | |
537 | 1 | pos = testee.findMousePosition(evt); |
538 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
539 | 1 | assertEquals(pos.annotationIndex, -1); |
540 | ||
541 | /* | |
542 | * cursor still in the gap above annotations, now at the bottom of it | |
543 | * method reports index of nearest sequence above | |
544 | */ | |
545 | 1 | y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2 |
546 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
547 | 0, false, 0); | |
548 | 1 | pos = testee.findMousePosition(evt); |
549 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
550 | 1 | assertEquals(pos.annotationIndex, -1); |
551 | ||
552 | 1 | AlignmentAnnotation[] annotationRows = av.getAlignment() |
553 | .getAlignmentAnnotation(); | |
554 | 5 | for (int n = 0; n < annotationRows.length; n++) |
555 | { | |
556 | /* | |
557 | * cursor at the top of the n'th annotation | |
558 | */ | |
559 | 4 | y += 1; |
560 | 4 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, |
561 | 0, 0, false, 0); | |
562 | 4 | pos = testee.findMousePosition(evt); |
563 | 4 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
564 | 4 | assertEquals(pos.annotationIndex, n); // over n'th annotation |
565 | ||
566 | /* | |
567 | * cursor at the bottom of the n'th annotation | |
568 | */ | |
569 | 4 | y += annotationRows[n].height - 1; |
570 | 4 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, |
571 | 0, 0, false, 0); | |
572 | 4 | pos = testee.findMousePosition(evt); |
573 | 4 | SeqCanvas sc = testee.seqCanvas; |
574 | 4 | 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 | 4 | assertEquals(pos.annotationIndex, n); |
580 | } | |
581 | ||
582 | /* | |
583 | * cursor in gap between wrapped widths | |
584 | */ | |
585 | 1 | y += 1; |
586 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
587 | 0, false, 0); | |
588 | 1 | pos = testee.findMousePosition(evt); |
589 | 1 | assertEquals(pos.seqIndex, -1); |
590 | 1 | assertEquals(pos.annotationIndex, -1); |
591 | ||
592 | /* | |
593 | * cursor at bottom of gap between wrapped widths | |
594 | */ | |
595 | 1 | y += charHeight - 1; |
596 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
597 | 0, false, 0); | |
598 | 1 | pos = testee.findMousePosition(evt); |
599 | 1 | assertEquals(pos.seqIndex, -1); |
600 | 1 | assertEquals(pos.annotationIndex, -1); |
601 | ||
602 | /* | |
603 | * cursor at top of scale, second wrapped width | |
604 | */ | |
605 | 1 | y += 1; |
606 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
607 | 0, false, 0); | |
608 | 1 | pos = testee.findMousePosition(evt); |
609 | 1 | assertEquals(pos.seqIndex, -1); |
610 | 1 | assertEquals(pos.annotationIndex, -1); |
611 | ||
612 | /* | |
613 | * cursor at bottom of scale, second wrapped width | |
614 | */ | |
615 | 1 | y += charHeight - 1; |
616 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
617 | 0, false, 0); | |
618 | 1 | pos = testee.findMousePosition(evt); |
619 | 1 | assertEquals(pos.seqIndex, -1); |
620 | 1 | assertEquals(pos.annotationIndex, -1); |
621 | ||
622 | /* | |
623 | * cursor at top of first sequence, second wrapped width | |
624 | */ | |
625 | 1 | y += 1; |
626 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
627 | 0, false, 0); | |
628 | 1 | pos = testee.findMousePosition(evt); |
629 | 1 | assertEquals(pos.seqIndex, 0); |
630 | 1 | assertEquals(pos.annotationIndex, -1); |
631 | } | |
632 | ||
633 | 1 | @Test(groups = "Functional") |
634 | public void testFindMousePosition_wrapped_noAnnotations() | |
635 | { | |
636 | 1 | Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "false"); |
637 | 1 | Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true"); |
638 | 1 | Cache.applicationProperties.setProperty("FONT_SIZE", "10"); |
639 | 1 | AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded( |
640 | "examples/uniref50.fa", DataSourceType.FILE); | |
641 | 1 | AlignViewportI av = alignFrame.getViewport(); |
642 | 1 | av.setScaleAboveWrapped(false); |
643 | 1 | av.setScaleLeftWrapped(false); |
644 | 1 | av.setScaleRightWrapped(false); |
645 | 1 | alignFrame.alignPanel.updateLayout(); |
646 | ||
647 | 1 | final int charHeight = av.getCharHeight(); |
648 | 1 | final int charWidth = av.getCharWidth(); |
649 | 1 | final int alignmentHeight = av.getAlignment().getHeight(); |
650 | ||
651 | // sanity checks: | |
652 | 1 | assertTrue(charHeight > 0); |
653 | 1 | assertTrue(charWidth > 0); |
654 | 1 | assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0); |
655 | ||
656 | 1 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
657 | 1 | int x = 0; |
658 | 1 | int y = 0; |
659 | ||
660 | /* | |
661 | * mouse at top left of wrapped panel; there is a gap of charHeight | |
662 | * above the alignment | |
663 | */ | |
664 | 1 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
665 | x, y, 0, 0, 0, false, 0); | |
666 | 1 | MousePos pos = testee.findMousePosition(evt); |
667 | 1 | assertEquals(pos.column, 0); |
668 | 1 | assertEquals(pos.seqIndex, -1); // above sequences |
669 | 1 | assertEquals(pos.annotationIndex, -1); |
670 | ||
671 | /* | |
672 | * cursor over top of first sequence | |
673 | */ | |
674 | 1 | y = charHeight; |
675 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
676 | 0, false, 0); | |
677 | 1 | pos = testee.findMousePosition(evt); |
678 | 1 | assertEquals(pos.seqIndex, 0); |
679 | 1 | assertEquals(pos.annotationIndex, -1); |
680 | ||
681 | /* | |
682 | * cursor at bottom of last sequence | |
683 | */ | |
684 | 1 | y = charHeight * (1 + alignmentHeight) - 1; |
685 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
686 | 0, false, 0); | |
687 | 1 | pos = testee.findMousePosition(evt); |
688 | 1 | assertEquals(pos.seqIndex, alignmentHeight - 1); |
689 | 1 | assertEquals(pos.annotationIndex, -1); |
690 | ||
691 | /* | |
692 | * cursor below sequences, at top of charHeight gap between widths | |
693 | */ | |
694 | 1 | y += 1; |
695 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
696 | 0, false, 0); | |
697 | 1 | pos = testee.findMousePosition(evt); |
698 | 1 | assertEquals(pos.seqIndex, -1); |
699 | 1 | assertEquals(pos.annotationIndex, -1); |
700 | ||
701 | /* | |
702 | * cursor below sequences, at top of charHeight gap between widths | |
703 | */ | |
704 | 1 | y += charHeight - 1; |
705 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
706 | 0, false, 0); | |
707 | 1 | pos = testee.findMousePosition(evt); |
708 | 1 | assertEquals(pos.seqIndex, -1); |
709 | 1 | assertEquals(pos.annotationIndex, -1); |
710 | ||
711 | /* | |
712 | * cursor at the top of the first sequence, second width | |
713 | */ | |
714 | 1 | y += 1; |
715 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
716 | 0, false, 0); | |
717 | 1 | pos = testee.findMousePosition(evt); |
718 | 1 | assertEquals(pos.seqIndex, 0); |
719 | 1 | assertEquals(pos.annotationIndex, -1); |
720 | } | |
721 | ||
722 | 1 | @Test(groups = "Functional") |
723 | public void testFindColumn_unwrapped() | |
724 | { | |
725 | 1 | Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "false"); |
726 | 1 | AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded( |
727 | "examples/uniref50.fa", DataSourceType.FILE); | |
728 | 1 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
729 | 1 | int x = 0; |
730 | 1 | final int charWidth = alignFrame.getViewport().getCharWidth(); |
731 | 1 | assertTrue(charWidth > 0); // sanity check |
732 | 1 | ViewportRanges ranges = alignFrame.getViewport().getRanges(); |
733 | 1 | assertEquals(ranges.getStartRes(), 0); |
734 | ||
735 | /* | |
736 | * mouse at top left of unwrapped panel | |
737 | */ | |
738 | 1 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
739 | x, 0, 0, 0, 0, false, 0); | |
740 | 1 | assertEquals(testee.findColumn(evt), 0); |
741 | ||
742 | /* | |
743 | * not quite one charWidth across | |
744 | */ | |
745 | 1 | x = charWidth - 1; |
746 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
747 | 0, false, 0); | |
748 | 1 | assertEquals(testee.findColumn(evt), 0); |
749 | ||
750 | /* | |
751 | * one charWidth across | |
752 | */ | |
753 | 1 | x = charWidth; |
754 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
755 | 0, false, 0); | |
756 | 1 | assertEquals(testee.findColumn(evt), 1); |
757 | ||
758 | /* | |
759 | * two charWidths across | |
760 | */ | |
761 | 1 | x = 2 * charWidth; |
762 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
763 | 0, false, 0); | |
764 | 1 | assertEquals(testee.findColumn(evt), 2); |
765 | ||
766 | /* | |
767 | * limited to last column of seqcanvas | |
768 | */ | |
769 | 1 | x = 20000; |
770 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
771 | 0, false, 0); | |
772 | 1 | SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas; |
773 | 1 | int w = seqCanvas.getWidth(); |
774 | // limited to number of whole columns, base 0, | |
775 | // and to end of visible range | |
776 | 1 | int expected = w / charWidth; |
777 | 1 | expected = Math.min(expected, ranges.getEndRes()); |
778 | 1 | assertEquals(testee.findColumn(evt), expected); |
779 | ||
780 | /* | |
781 | * hide columns 5-10 (base 1) | |
782 | */ | |
783 | 1 | alignFrame.getViewport().hideColumns(4, 9); |
784 | 1 | x = 5 * charWidth + 2; |
785 | // x is in 6th visible column, absolute column 12, or 11 base 0 | |
786 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
787 | 0, false, 0); | |
788 | 1 | assertEquals(testee.findColumn(evt), 11); |
789 | } | |
790 | ||
791 | 1 | @Test(groups = "Functional") |
792 | public void testFindColumn_and_FindAlignmentColumn_wrapped() | |
793 | { | |
794 | 1 | Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true"); |
795 | 1 | AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded( |
796 | "examples/uniref50.fa", DataSourceType.FILE); | |
797 | 1 | AlignViewport av = alignFrame.getViewport(); |
798 | 1 | av.setScaleAboveWrapped(false); |
799 | 1 | av.setScaleLeftWrapped(false); |
800 | 1 | av.setScaleRightWrapped(false); |
801 | 1 | alignFrame.alignPanel.updateLayout(); |
802 | 1 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
803 | 1 | int x = 0; |
804 | 1 | final int charWidth = av.getCharWidth(); |
805 | 1 | assertTrue(charWidth > 0); // sanity check |
806 | 1 | assertEquals(av.getRanges().getStartRes(), 0); |
807 | ||
808 | /* | |
809 | * mouse at top left of wrapped panel, no West (left) scale | |
810 | */ | |
811 | 1 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
812 | x, 0, 0, 0, 0, false, 0); | |
813 | 1 | assertEquals(testee.findColumn(evt), 0); |
814 | 1 | assertEquals(testee.findAlignmentColumn(evt), 0); |
815 | ||
816 | /* | |
817 | * not quite one charWidth across | |
818 | */ | |
819 | 1 | x = charWidth - 1; |
820 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
821 | 0, false, 0); | |
822 | 1 | assertEquals(testee.findColumn(evt), 0); |
823 | 1 | assertEquals(testee.findAlignmentColumn(evt), 0); |
824 | ||
825 | /* | |
826 | * one charWidth across | |
827 | */ | |
828 | 1 | x = charWidth; |
829 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
830 | 0, false, 0); | |
831 | 1 | assertEquals(testee.findColumn(evt), 1); |
832 | 1 | assertEquals(testee.findAlignmentColumn(evt), 1); |
833 | ||
834 | /* | |
835 | * x over scale left (before drawn columns) results in -1 | |
836 | */ | |
837 | 1 | av.setScaleLeftWrapped(true); |
838 | 1 | alignFrame.alignPanel.updateLayout(); |
839 | 1 | SeqCanvas seqCanvas = testee.seqCanvas; |
840 | 1 | int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest"); |
841 | 1 | assertTrue(labelWidth > 0); |
842 | 1 | x = labelWidth - 1; |
843 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
844 | 0, false, 0); | |
845 | 1 | assertEquals(testee.findColumn(evt), -1); |
846 | 1 | assertEquals(testee.findAlignmentColumn(evt), 0); |
847 | ||
848 | 1 | x = labelWidth; |
849 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
850 | 0, false, 0); | |
851 | 1 | assertEquals(testee.findColumn(evt), 0); |
852 | 1 | assertEquals(testee.findAlignmentColumn(evt), 0); |
853 | ||
854 | /* | |
855 | * x over right edge of last residue (including scale left) | |
856 | */ | |
857 | 1 | int residuesWide = av.getRanges().getViewportWidth(); |
858 | 1 | assertTrue(residuesWide > 0); |
859 | 1 | x = labelWidth + charWidth * residuesWide - 1; |
860 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
861 | 0, false, 0); | |
862 | 1 | assertEquals(testee.findColumn(evt), residuesWide - 1); |
863 | 1 | assertEquals(testee.findAlignmentColumn(evt), residuesWide - 1); |
864 | ||
865 | /* | |
866 | * x over scale right (beyond drawn columns) results in -1 | |
867 | */ | |
868 | 1 | av.setScaleRightWrapped(true); |
869 | 1 | alignFrame.alignPanel.updateLayout(); |
870 | 1 | labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast"); |
871 | 1 | assertTrue(labelWidth > 0); |
872 | 1 | int residuesWide2 = av.getRanges().getViewportWidth(); |
873 | 1 | assertTrue(residuesWide2 > 0); |
874 | 1 | assertTrue(residuesWide2 < residuesWide); // available width reduced |
875 | 1 | x += 1; // just over left edge of scale right |
876 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0, |
877 | 0, false, 0); | |
878 | // on scale | |
879 | 1 | assertEquals(testee.findColumn(evt), -1); |
880 | // return right-most column visible | |
881 | 1 | assertEquals(testee.findAlignmentColumn(evt), residuesWide2 - 1); |
882 | ||
883 | // todo add startRes offset, hidden columns | |
884 | ||
885 | } | |
886 | ||
887 | 1 | @BeforeClass(alwaysRun = true) |
888 | public static void setUpBeforeClass() throws Exception | |
889 | { | |
890 | /* | |
891 | * use read-only test properties file | |
892 | */ | |
893 | 1 | Cache.loadProperties("test/jalview/io/testProps.jvprops"); |
894 | 1 | Jalview.main(new String[] { "--nonews" }); |
895 | } | |
896 | ||
897 | /** | |
898 | * waits for Swing event dispatch queue to empty | |
899 | */ | |
900 | 0 | synchronized void waitForSwing() |
901 | { | |
902 | 0 | try |
903 | { | |
904 | 0 | EventQueue.invokeAndWait(new Runnable() |
905 | { | |
906 | 0 | @Override |
907 | public void run() | |
908 | { | |
909 | } | |
910 | }); | |
911 | } catch (InterruptedException | InvocationTargetException e) | |
912 | { | |
913 | 0 | e.printStackTrace(); |
914 | } | |
915 | } | |
916 | ||
917 | 1 | @Test(groups = "Functional") |
918 | public void testFindMousePosition_wrapped_scales_longSequence() | |
919 | { | |
920 | 1 | Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "false"); |
921 | 1 | Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true"); |
922 | 1 | Cache.applicationProperties.setProperty("FONT_SIZE", "14"); |
923 | 1 | Cache.applicationProperties.setProperty("FONT_NAME", "SansSerif"); |
924 | 1 | Cache.applicationProperties.setProperty("FONT_STYLE", "0"); |
925 | // sequence of 50 bases, doubled 10 times, = 51200 bases | |
926 | 1 | String dna = "ATGGCCATTGGGCCCAAATTTCCCAAAGGGTTTCCCTGAGGTCAGTCAGA"; |
927 | 11 | for (int i = 0; i < 10; i++) |
928 | { | |
929 | 10 | dna += dna; |
930 | } | |
931 | 1 | assertEquals(dna.length(), 51200); |
932 | 1 | AlignFrame alignFrame = new FileLoader() |
933 | .LoadFileWaitTillLoaded("dna " + dna, DataSourceType.PASTE); | |
934 | 1 | SeqPanel testee = alignFrame.alignPanel.getSeqPanel(); |
935 | 1 | AlignViewport av = alignFrame.getViewport(); |
936 | 1 | av.setScaleAboveWrapped(true); |
937 | 1 | av.setScaleLeftWrapped(true); |
938 | 1 | av.setScaleRightWrapped(true); |
939 | 1 | alignFrame.alignPanel.updateLayout(); |
940 | ||
941 | 1 | try |
942 | { | |
943 | 1 | Thread.sleep(200); |
944 | } catch (InterruptedException e) | |
945 | { | |
946 | } | |
947 | ||
948 | 1 | final int charHeight = av.getCharHeight(); |
949 | 1 | final int charWidth = av.getCharWidth(); |
950 | 1 | assertEquals(charHeight, 17); |
951 | 1 | assertEquals(charWidth, 12); |
952 | ||
953 | 1 | double scaling = JvSwingUtilsTest.getScaling(alignFrame.alignPanel); |
954 | ||
955 | 1 | FontMetrics fm = testee.getFontMetrics(av.getFont()); |
956 | 1 | int labelWidth = fm.stringWidth("00000") + charWidth; |
957 | // some leeway for different OS rendering of text | |
958 | 1 | assertTrue(labelWidth >= 52 && labelWidth <= 57); |
959 | 1 | assertEquals(testee.seqCanvas.getLabelWidthWest(), labelWidth); |
960 | ||
961 | 1 | int x = 0; |
962 | 1 | int y = 0; |
963 | ||
964 | /* | |
965 | * mouse at top left of wrapped panel; there is a gap of 2 * charHeight | |
966 | * above the alignment | |
967 | */ | |
968 | 1 | MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, |
969 | x, y, 0, 0, 0, false, 0); | |
970 | 1 | MousePos pos = testee.findMousePosition(evt); |
971 | 1 | assertEquals(pos.column, -1); // over scale left, not an alignment column |
972 | 1 | assertEquals(pos.seqIndex, -1); // above sequences |
973 | 1 | assertEquals(pos.annotationIndex, -1); |
974 | ||
975 | /* | |
976 | * cursor over scale above first sequence | |
977 | */ | |
978 | 1 | y += charHeight; |
979 | 1 | x = labelWidth; |
980 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
981 | 0, false, 0); | |
982 | 1 | pos = testee.findMousePosition(evt); |
983 | 1 | assertEquals(pos.seqIndex, -1); |
984 | 1 | assertEquals(pos.column, 0); |
985 | 1 | assertEquals(pos.annotationIndex, -1); |
986 | ||
987 | /* | |
988 | * cursor over scale left of first sequence | |
989 | */ | |
990 | 1 | y += charHeight; |
991 | 1 | x = 0; |
992 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
993 | 0, false, 0); | |
994 | 1 | pos = testee.findMousePosition(evt); |
995 | 1 | assertEquals(pos.seqIndex, 0); |
996 | 1 | assertEquals(pos.column, -1); |
997 | 1 | assertEquals(pos.annotationIndex, -1); |
998 | ||
999 | /* | |
1000 | * cursor over start of first sequence | |
1001 | */ | |
1002 | 1 | x = labelWidth; |
1003 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
1004 | 0, false, 0); | |
1005 | 1 | pos = testee.findMousePosition(evt); |
1006 | 1 | assertEquals(pos.seqIndex, 0); |
1007 | 1 | assertEquals(pos.column, 0); |
1008 | 1 | assertEquals(pos.annotationIndex, -1); |
1009 | ||
1010 | /* | |
1011 | * move one character right, to bottom pixel of same row | |
1012 | */ | |
1013 | 1 | x += charWidth; |
1014 | 1 | y += charHeight - 1; |
1015 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
1016 | 0, false, 0); | |
1017 | 1 | pos = testee.findMousePosition(evt); |
1018 | 1 | assertEquals(pos.seqIndex, 0); |
1019 | 1 | assertEquals(pos.column, 1); |
1020 | ||
1021 | /* | |
1022 | * move down one pixel - now in the no man's land between rows | |
1023 | */ | |
1024 | 1 | y += 1; |
1025 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
1026 | 0, false, 0); | |
1027 | 1 | pos = testee.findMousePosition(evt); |
1028 | 1 | assertEquals(pos.seqIndex, -1); |
1029 | 1 | assertEquals(pos.column, 1); |
1030 | ||
1031 | /* | |
1032 | * move down two char heights less one pixel - still in the no man's land | |
1033 | * (scale above + spacer line) | |
1034 | */ | |
1035 | 1 | y += (2 * charHeight - 1); |
1036 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
1037 | 0, false, 0); | |
1038 | 1 | pos = testee.findMousePosition(evt); |
1039 | 1 | assertEquals(pos.seqIndex, -1); |
1040 | 1 | assertEquals(pos.column, 1); |
1041 | ||
1042 | /* | |
1043 | * move down one more pixel - now on the next row of the sequence | |
1044 | */ | |
1045 | 1 | y += 1; |
1046 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
1047 | 0, false, 0); | |
1048 | 1 | pos = testee.findMousePosition(evt); |
1049 | 1 | assertEquals(pos.seqIndex, 0); |
1050 | 1 | assertEquals(pos.column, 1 + av.getWrappedWidth()); |
1051 | ||
1052 | /* | |
1053 | * scroll to near the end of the sequence | |
1054 | */ | |
1055 | 1 | SearchResultsI sr = new SearchResults(); |
1056 | 1 | int scrollTo = dna.length() - 1000; |
1057 | 1 | sr.addResult(av.getAlignment().getSequenceAt(0), scrollTo, scrollTo); |
1058 | 1 | alignFrame.alignPanel.scrollToPosition(sr); |
1059 | ||
1060 | /* | |
1061 | * place the mouse on the first column of the 6th sequence, and | |
1062 | * verify that (computed) findMousePosition matches (actual) ViewportRanges | |
1063 | */ | |
1064 | 1 | x = labelWidth; |
1065 | 1 | y = 17 * charHeight; // 17 = 6 times two header rows and 5 sequence rows |
1066 | 1 | evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0, |
1067 | 0, false, 0); | |
1068 | 1 | pos = testee.findMousePosition(evt); |
1069 | 1 | assertEquals(pos.seqIndex, 0); |
1070 | 1 | int expected = av.getRanges().getStartRes() + 5 * av.getWrappedWidth(); |
1071 | 1 | assertEquals(pos.column, expected); |
1072 | } | |
1073 | } |