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 Cache.loadProperties(null);
48 Desktop.getInstance().setVisible(false);
52 * Test the method that computes wrapped width in residues, height of wrapped
53 * widths in pixels, and the number of widths visible
55 @Test(groups = "Functional")
56 public void testCalculateWrappedGeometry_noAnnotations()
58 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
59 "examples/uniref50.fa", DataSourceType.FILE);
61 AlignViewport av = af.getViewport();
62 AlignmentI al = av.getAlignment();
63 assertEquals(al.getWidth(), 157);
64 assertEquals(al.getHeight(), 15);
65 av.getRanges().setStartEndSeq(0, 14);
67 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
69 av.setWrapAlignment(true);
70 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
71 int charHeight = av.getCharHeight();
72 int charWidth = av.getCharWidth();
73 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
74 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
77 * first with scales above, left, right
79 av.setShowAnnotation(false);
80 av.setScaleAboveWrapped(true);
81 av.setScaleLeftWrapped(true);
82 av.setScaleRightWrapped(true);
83 FontMetrics fm = testee.getFontMetrics(av.getFont());
84 int labelWidth = fm.stringWidth("000") + charWidth;
85 assertEquals(labelWidth,
86 !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
89 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
90 * take the whole multiple of character widths
92 int canvasWidth = 400;
93 int canvasHeight = 300;
94 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
95 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
96 assertEquals(wrappedWidth, residueColumns);
97 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
98 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
99 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
101 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
102 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
103 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
106 * repeat height is 17 * (2 + 15) = 289
107 * make canvas height 2 * 289 + 3 * charHeight so just enough to
108 * draw 2 widths and the first sequence of a third
110 canvasHeight = charHeight * (17 * 2 + 3);
111 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
112 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
115 * reduce canvas height by 1 pixel
116 * - should not be enough height to draw 3 widths
119 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
120 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
123 * turn off scale above - can now fit in 2 and a bit widths
125 av.setScaleAboveWrapped(false);
126 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
127 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
130 * reduce height to enough for 2 widths and not quite a third
131 * i.e. two repeating heights + spacer + sequence - 1 pixel
133 canvasHeight = charHeight * (16 * 2 + 2) - 1;
134 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
135 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
138 * make canvas width enough for scales and 20 residues
140 canvasWidth = 2 * labelWidth + 20 * charWidth;
141 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
143 assertEquals(wrappedWidth, 20);
146 * reduce width by 1 pixel - rounds down to 19 residues
149 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
151 assertEquals(wrappedWidth, 19);
154 * turn off West scale - adds labelWidth (39) to available for residues
155 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
157 av.setScaleLeftWrapped(false);
158 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
160 assertEquals(wrappedWidth, 23);
163 * add 10 pixels to width to fit in another whole residue column
166 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
168 assertEquals(wrappedWidth, 23);
170 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
172 assertEquals(wrappedWidth, 24);
175 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
177 av.setScaleRightWrapped(false);
178 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
180 assertEquals(wrappedWidth, 27);
183 * add 9 pixels to width to gain a residue column
186 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
188 assertEquals(wrappedWidth, 27); // 8px not enough
190 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
192 assertEquals(wrappedWidth, 28); // 9px is enough
195 * now West but not East scale - lose 39 pixels or 4 columns
197 av.setScaleLeftWrapped(true);
198 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
200 assertEquals(wrappedWidth, 24);
203 * adding 3 pixels to width regains one column
206 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
208 assertEquals(wrappedWidth, !Platform.isWin() ? 24 : 25); // 2px not enough
210 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
212 assertEquals(wrappedWidth, 25); // 3px is enough
215 * turn off scales left and right, make width exactly 157 columns
217 av.setScaleLeftWrapped(false);
218 canvasWidth = al.getWidth() * charWidth;
219 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
220 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
224 * Test the method that computes wrapped width in residues, height of wrapped
225 * widths in pixels, and the number of widths visible
227 @Test(groups = "Functional")
228 public void testCalculateWrappedGeometry_withAnnotations()
230 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
231 "examples/uniref50.fa", DataSourceType.FILE);
232 AlignViewport av = af.getViewport();
233 AlignmentI al = av.getAlignment();
234 assertEquals(al.getWidth(), 157);
235 assertEquals(al.getHeight(), 15);
237 av.setWrapAlignment(true);
238 av.getRanges().setStartEndSeq(0, 14);
239 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
240 int charHeight = av.getCharHeight();
241 int charWidth = av.getCharWidth();
243 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
244 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
246 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
249 * first with scales above, left, right
251 av.setShowAnnotation(true);
252 av.setScaleAboveWrapped(true);
253 av.setScaleLeftWrapped(true);
254 av.setScaleRightWrapped(true);
256 FontMetrics fm = testee.getFontMetrics(av.getFont());
257 int labelWidth = fm.stringWidth("000") + charWidth;
258 assertEquals(labelWidth,
259 !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
261 int annotationHeight = testee.getAnnotationHeight();
264 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
265 * take the whole multiple of character widths
267 int canvasWidth = 400;
268 int canvasHeight = 300;
269 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
270 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
271 assertEquals(wrappedWidth, residueColumns);
272 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
273 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
274 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
276 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
277 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
278 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
279 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
282 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
283 * make canvas height 2 of these plus 3 charHeights
284 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
286 canvasHeight = charHeight * (17 * 2 + 3)
287 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
288 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
289 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
292 * reduce canvas height by 1 pixel - should not be enough height
296 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
297 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
300 * turn off scale above - can now fit in 2 and a bit widths
302 av.setScaleAboveWrapped(false);
303 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
304 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
307 * reduce height to enough for 2 widths and not quite a third
308 * i.e. two repeating heights + spacer + sequence - 1 pixel
310 canvasHeight = charHeight * (16 * 2 + 2)
311 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
312 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
313 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
316 * add 1 pixel to height - should now get 3 widths drawn
319 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
320 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
324 * Test simulates loading an unwrapped alignment, shrinking it vertically so
325 * not all sequences are visible, then changing to wrapped mode. The ranges
326 * endSeq should be unchanged, but the vertical repeat height should include
329 @Test(groups = "Functional")
330 public void testCalculateWrappedGeometry_fromScrolled()
332 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
333 "examples/uniref50.fa", DataSourceType.FILE);
335 System.out.println("ap dim = " + af.alignPanel.getSize());
336 System.out.println("seqpan dim = " + af.alignPanel.getSeqPanel().getSize());
337 System.out.println("seqcan dim = " + af.alignPanel.getSeqPanel().seqCanvas.getSize());
340 AlignViewport av = af.getViewport();
341 AlignmentI al = av.getAlignment();
342 assertEquals(al.getWidth(), 157);
343 assertEquals(al.getHeight(), 15);
345 ViewportRanges ranges = av.getRanges();
346 System.out.println(ranges + " before setting to 3");
347 ranges.setStartEndSeq(0, 3);
348 int endSeq = ranges.getEndSeq();
349 System.out.println(ranges + " after setting to 3");
350 av.setShowAnnotation(false);
351 av.setScaleAboveWrapped(true);
353 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
354 av.setWrapAlignment(true);
355 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
356 int charHeight = av.getCharHeight();
357 int charWidth = av.getCharWidth();
358 // Windows h=19, w=11.
359 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
360 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
362 int canvasWidth = 400;
363 int canvasHeight = 300;
364 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
365 System.out.println(ranges);
366 assertEquals(ranges.getEndSeq(), endSeq); // unchanged
367 int repeatingHeight = (int) PA.getValue(testee,
368 "wrappedRepeatHeightPx");
369 int h = charHeight * (2 + al.getHeight());
370 assertEquals(repeatingHeight, h);