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.assertFalse;
25 import static org.testng.Assert.assertNotNull;
26 import static org.testng.Assert.assertNull;
27 import static org.testng.Assert.assertTrue;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.SearchResults;
31 import jalview.datamodel.SearchResultsI;
32 import jalview.io.DataSourceType;
33 import jalview.io.FileLoader;
36 import java.awt.FontMetrics;
38 import org.testng.annotations.Test;
40 import junit.extensions.PA;
42 public class SeqCanvasTest
45 * Test the method that computes wrapped width in residues, height of wrapped
46 * widths in pixels, and the number of widths visible
48 @Test(groups = "Functional")
49 public void testCalculateWrappedGeometry_noAnnotations()
51 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
52 "examples/uniref50.fa", DataSourceType.FILE);
53 AlignViewport av = af.getViewport();
54 AlignmentI al = av.getAlignment();
55 assertEquals(al.getWidth(), 157);
56 assertEquals(al.getHeight(), 15);
57 av.getRanges().setStartEndSeq(0, 14);
59 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
61 av.setWrapAlignment(true);
62 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
63 int charHeight = av.getCharHeight();
64 int charWidth = av.getCharWidth();
65 assertEquals(charHeight, 17);
66 assertEquals(charWidth, 12);
69 * first with scales above, left, right
71 av.setShowAnnotation(false);
72 av.setScaleAboveWrapped(true);
73 av.setScaleLeftWrapped(true);
74 av.setScaleRightWrapped(true);
75 FontMetrics fm = testee.getFontMetrics(av.getFont());
76 int labelWidth = fm.stringWidth("000") + charWidth;
77 assertEquals(labelWidth, 39); // 3 x 9 + charWidth
80 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
81 * take the whole multiple of character widths
83 int canvasWidth = 400;
84 int canvasHeight = 300;
85 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
86 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
87 assertEquals(wrappedWidth, residueColumns);
88 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
89 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
90 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
92 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
93 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
94 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
97 * repeat height is 17 * (2 + 15) = 289
98 * make canvas height 2 * 289 + 3 * charHeight so just enough to
99 * draw 2 widths and the first sequence of a third
101 canvasHeight = charHeight * (17 * 2 + 3);
102 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
103 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
106 * reduce canvas height by 1 pixel
107 * - should not be enough height to draw 3 widths
110 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
111 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
114 * turn off scale above - can now fit in 2 and a bit widths
116 av.setScaleAboveWrapped(false);
117 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
118 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
121 * reduce height to enough for 2 widths and not quite a third
122 * i.e. two repeating heights + spacer + sequence - 1 pixel
124 canvasHeight = charHeight * (16 * 2 + 2) - 1;
125 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
126 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
129 * make canvas width enough for scales and 20 residues
131 canvasWidth = 2 * labelWidth + 20 * charWidth;
132 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
134 assertEquals(wrappedWidth, 20);
137 * reduce width by 1 pixel - rounds down to 19 residues
140 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
142 assertEquals(wrappedWidth, 19);
145 * turn off West scale - adds labelWidth (39) to available for residues
146 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
148 av.setScaleLeftWrapped(false);
149 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
151 assertEquals(wrappedWidth, 23);
154 * add 10 pixels to width to fit in another whole residue column
157 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
159 assertEquals(wrappedWidth, 23);
161 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
163 assertEquals(wrappedWidth, 24);
166 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
168 av.setScaleRightWrapped(false);
169 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
171 assertEquals(wrappedWidth, 27);
174 * add 9 pixels to width to gain a residue column
177 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
179 assertEquals(wrappedWidth, 27); // 8px not enough
181 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
183 assertEquals(wrappedWidth, 28); // 9px is enough
186 * now West but not East scale - lose 39 pixels or 4 columns
188 av.setScaleLeftWrapped(true);
189 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
191 assertEquals(wrappedWidth, 24);
194 * adding 3 pixels to width regains one column
197 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
199 assertEquals(wrappedWidth, 24); // 2px not enough
201 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
203 assertEquals(wrappedWidth, 25); // 3px is enough
206 * turn off scales left and right, make width exactly 157 columns
208 av.setScaleLeftWrapped(false);
209 canvasWidth = al.getWidth() * charWidth;
210 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
211 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
215 * Test the method that computes wrapped width in residues, height of wrapped
216 * widths in pixels, and the number of widths visible
218 @Test(groups = "Functional")
219 public void testCalculateWrappedGeometry_withAnnotations()
221 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
222 "examples/uniref50.fa", DataSourceType.FILE);
223 AlignViewport av = af.getViewport();
224 AlignmentI al = av.getAlignment();
225 assertEquals(al.getWidth(), 157);
226 assertEquals(al.getHeight(), 15);
228 av.setWrapAlignment(true);
229 av.getRanges().setStartEndSeq(0, 14);
230 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
231 int charHeight = av.getCharHeight();
232 int charWidth = av.getCharWidth();
233 assertEquals(charHeight, 17);
234 assertEquals(charWidth, 12);
236 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
239 * first with scales above, left, right
241 av.setShowAnnotation(true);
242 av.setScaleAboveWrapped(true);
243 av.setScaleLeftWrapped(true);
244 av.setScaleRightWrapped(true);
245 FontMetrics fm = testee.getFontMetrics(av.getFont());
246 int labelWidth = fm.stringWidth("000") + charWidth;
247 assertEquals(labelWidth, 39); // 3 x 9 + charWidth
248 int annotationHeight = testee.getAnnotationHeight();
251 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
252 * take the whole multiple of character widths
254 int canvasWidth = 400;
255 int canvasHeight = 300;
256 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
257 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
258 assertEquals(wrappedWidth, residueColumns);
259 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
260 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
261 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
263 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
264 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
265 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
266 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
269 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
270 * make canvas height 2 of these plus 3 charHeights
271 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
273 canvasHeight = charHeight * (17 * 2 + 3)
274 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
275 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
276 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
279 * reduce canvas height by 1 pixel - should not be enough height
283 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
284 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
287 * turn off scale above - can now fit in 2 and a bit widths
289 av.setScaleAboveWrapped(false);
290 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
291 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
294 * reduce height to enough for 2 widths and not quite a third
295 * i.e. two repeating heights + spacer + sequence - 1 pixel
297 canvasHeight = charHeight * (16 * 2 + 2)
298 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
299 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
300 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
303 * add 1 pixel to height - should now get 3 widths drawn
306 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
307 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
311 * Test simulates loading an unwrapped alignment, shrinking it vertically so
312 * not all sequences are visible, then changing to wrapped mode. The ranges
313 * endSeq should be unchanged, but the vertical repeat height should include
316 @Test(groups = "Functional")
317 public void testCalculateWrappedGeometry_fromScrolled()
319 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
320 "examples/uniref50.fa", DataSourceType.FILE);
321 AlignViewport av = af.getViewport();
322 AlignmentI al = av.getAlignment();
323 assertEquals(al.getWidth(), 157);
324 assertEquals(al.getHeight(), 15);
325 av.getRanges().setStartEndSeq(0, 3);
326 av.setShowAnnotation(false);
327 av.setScaleAboveWrapped(true);
329 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
331 av.setWrapAlignment(true);
332 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
333 int charHeight = av.getCharHeight();
334 int charWidth = av.getCharWidth();
335 assertEquals(charHeight, 17);
336 assertEquals(charWidth, 12);
338 int canvasWidth = 400;
339 int canvasHeight = 300;
340 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
342 assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
343 int repeatingHeight = (int) PA.getValue(testee,
344 "wrappedRepeatHeightPx");
345 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
348 @Test(groups = "Functional")
349 public void testClear_HighlightAndSelection()
351 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
352 "examples/uniref50.fa", DataSourceType.FILE);
353 AlignViewport av = af.getViewport();
354 SearchResultsI highlight = new SearchResults();
356 av.getAlignment().getSequenceAt(1).getDatasetSequence(), 50,
358 af.alignPanel.highlightSearchResults(highlight);
359 af.avc.markHighlightedColumns(false, false, false);
360 assertNotNull(av.getSearchResults(),
361 "No highlight was created on alignment");
362 assertFalse(av.getColumnSelection().isEmpty(),
363 "No selection was created from highlight");
364 af.deselectAllSequenceMenuItem_actionPerformed(null);
365 assertTrue(av.getColumnSelection().isEmpty(),
366 "No Selection should be present after deselecting all.");
367 assertNull(av.getSearchResults(),
368 "No higlighted search results should be present after deselecting all.");