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;
25 import jalview.bin.Cache;
26 import jalview.bin.Jalview;
27 import jalview.datamodel.AlignmentI;
28 import jalview.io.DataSourceType;
29 import jalview.io.FileLoader;
30 import jalview.util.Platform;
31 import jalview.viewmodel.ViewportRanges;
34 import java.awt.FontMetrics;
36 import org.testng.annotations.BeforeClass;
37 import org.testng.annotations.Test;
39 import junit.extensions.PA;
41 public class SeqCanvasTest
43 @BeforeClass(alwaysRun = true)
46 Jalview.setInteractive(false);
51 * Test the method that computes wrapped width in residues, height of wrapped
52 * widths in pixels, and the number of widths visible
54 @Test(groups = "Functional")
55 public void testCalculateWrappedGeometry_noAnnotations()
57 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
58 "examples/uniref50.fa", DataSourceType.FILE);
59 AlignViewport av = af.getViewport();
60 AlignmentI al = av.getAlignment();
61 assertEquals(al.getWidth(), 157);
62 assertEquals(al.getHeight(), 15);
63 av.getRanges().setStartEndSeq(0, 14);
65 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
67 av.setWrapAlignment(true);
68 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
69 int charHeight = av.getCharHeight();
70 int charWidth = av.getCharWidth();
71 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
72 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
75 * first with scales above, left, right
77 av.setShowAnnotation(false);
78 av.setScaleAboveWrapped(true);
79 av.setScaleLeftWrapped(true);
80 av.setScaleRightWrapped(true);
81 FontMetrics fm = testee.getFontMetrics(av.getFont());
82 int labelWidth = fm.stringWidth("000") + charWidth;
83 assertEquals(labelWidth,
84 !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
87 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
88 * take the whole multiple of character widths
90 int canvasWidth = 400;
91 int canvasHeight = 300;
92 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
93 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
94 assertEquals(wrappedWidth, residueColumns);
95 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
96 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
97 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
99 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
100 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
101 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
104 * repeat height is 17 * (2 + 15) = 289
105 * make canvas height 2 * 289 + 3 * charHeight so just enough to
106 * draw 2 widths and the first sequence of a third
108 canvasHeight = charHeight * (17 * 2 + 3);
109 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
110 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
113 * reduce canvas height by 1 pixel
114 * - should not be enough height to draw 3 widths
117 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
118 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
121 * turn off scale above - can now fit in 2 and a bit widths
123 av.setScaleAboveWrapped(false);
124 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
125 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
128 * reduce height to enough for 2 widths and not quite a third
129 * i.e. two repeating heights + spacer + sequence - 1 pixel
131 canvasHeight = charHeight * (16 * 2 + 2) - 1;
132 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
133 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
136 * make canvas width enough for scales and 20 residues
138 canvasWidth = 2 * labelWidth + 20 * charWidth;
139 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
141 assertEquals(wrappedWidth, 20);
144 * reduce width by 1 pixel - rounds down to 19 residues
147 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
149 assertEquals(wrappedWidth, 19);
152 * turn off West scale - adds labelWidth (39) to available for residues
153 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
155 av.setScaleLeftWrapped(false);
156 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
158 assertEquals(wrappedWidth, 23);
161 * add 10 pixels to width to fit in another whole residue column
164 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
166 assertEquals(wrappedWidth, 23);
168 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
170 assertEquals(wrappedWidth, 24);
173 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
175 av.setScaleRightWrapped(false);
176 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
178 assertEquals(wrappedWidth, 27);
181 * add 9 pixels to width to gain a residue column
184 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
186 assertEquals(wrappedWidth, 27); // 8px not enough
188 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
190 assertEquals(wrappedWidth, 28); // 9px is enough
193 * now West but not East scale - lose 39 pixels or 4 columns
195 av.setScaleLeftWrapped(true);
196 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
198 assertEquals(wrappedWidth, 24);
201 * adding 3 pixels to width regains one column
204 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
206 assertEquals(wrappedWidth, !Platform.isWin() ? 24 : 25); // 2px not enough
208 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
210 assertEquals(wrappedWidth, 25); // 3px is enough
213 * turn off scales left and right, make width exactly 157 columns
215 av.setScaleLeftWrapped(false);
216 canvasWidth = al.getWidth() * charWidth;
217 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
218 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
222 * Test the method that computes wrapped width in residues, height of wrapped
223 * widths in pixels, and the number of widths visible
225 @Test(groups = "Functional")
226 public void testCalculateWrappedGeometry_withAnnotations()
228 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
229 "examples/uniref50.fa", DataSourceType.FILE);
230 AlignViewport av = af.getViewport();
231 AlignmentI al = av.getAlignment();
232 assertEquals(al.getWidth(), 157);
233 assertEquals(al.getHeight(), 15);
235 av.setWrapAlignment(true);
236 av.getRanges().setStartEndSeq(0, 14);
237 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
238 int charHeight = av.getCharHeight();
239 int charWidth = av.getCharWidth();
241 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
242 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
244 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
247 * first with scales above, left, right
249 av.setShowAnnotation(true);
250 av.setScaleAboveWrapped(true);
251 av.setScaleLeftWrapped(true);
252 av.setScaleRightWrapped(true);
254 FontMetrics fm = testee.getFontMetrics(av.getFont());
255 int labelWidth = fm.stringWidth("000") + charWidth;
256 assertEquals(labelWidth,
257 !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
259 int annotationHeight = testee.getAnnotationHeight();
262 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
263 * take the whole multiple of character widths
265 int canvasWidth = 400;
266 int canvasHeight = 300;
267 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
268 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
269 assertEquals(wrappedWidth, residueColumns);
270 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
271 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
272 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
274 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
275 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
276 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
277 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
280 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
281 * make canvas height 2 of these plus 3 charHeights
282 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
284 canvasHeight = charHeight * (17 * 2 + 3)
285 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
286 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
287 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
290 * reduce canvas height by 1 pixel - should not be enough height
294 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
295 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
298 * turn off scale above - can now fit in 2 and a bit widths
300 av.setScaleAboveWrapped(false);
301 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
302 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
305 * reduce height to enough for 2 widths and not quite a third
306 * i.e. two repeating heights + spacer + sequence - 1 pixel
308 canvasHeight = charHeight * (16 * 2 + 2)
309 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
310 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
311 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
314 * add 1 pixel to height - should now get 3 widths drawn
317 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
318 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
322 * Test simulates loading an unwrapped alignment, shrinking it vertically so
323 * not all sequences are visible, then changing to wrapped mode. The ranges
324 * endSeq should be unchanged, but the vertical repeat height should include
327 @Test(groups = "Functional")
328 public void testCalculateWrappedGeometry_fromScrolled()
330 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
331 "examples/uniref50.fa", DataSourceType.FILE);
332 AlignViewport av = af.getViewport();
333 AlignmentI al = av.getAlignment();
334 assertEquals(al.getWidth(), 157);
335 assertEquals(al.getHeight(), 15);
337 ViewportRanges ranges = av.getRanges();
338 ranges.setStartEndSeq(0, 3);
339 System.out.println(ranges);
340 av.setShowAnnotation(false);
341 av.setScaleAboveWrapped(true);
343 System.out.println(ranges);
344 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
345 av.setWrapAlignment(true);
346 System.out.println(ranges);
347 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
348 int charHeight = av.getCharHeight();
349 int charWidth = av.getCharWidth();
350 System.out.println(ranges);
351 // Windows h=19, w=11.
352 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
353 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
354 System.out.println(ranges);
356 int canvasWidth = 400;
357 int canvasHeight = 300;
358 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
359 System.out.println(ranges);
360 assertEquals(ranges.getEndSeq(), 3); // unchanged
361 int repeatingHeight = (int) PA.getValue(testee,
362 "wrappedRepeatHeightPx");
363 int h = charHeight * (2 + al.getHeight());
364 assertEquals(repeatingHeight, h);