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;
26 import java.awt.FontMetrics;
28 import org.testng.annotations.BeforeMethod;
29 import org.testng.annotations.Test;
31 import jalview.bin.Cache;
32 import jalview.datamodel.AlignmentI;
33 import jalview.io.DataSourceType;
34 import jalview.io.FileLoader;
35 import junit.extensions.PA;
37 public class SeqCanvasTest
39 private AlignFrame af;
42 * Test the method that computes wrapped width in residues, height of wrapped
43 * widths in pixels, and the number of widths visible
45 @Test(groups = "Functional")
46 public void testCalculateWrappedGeometry_noAnnotations()
48 AlignViewport av = af.getViewport();
49 AlignmentI al = av.getAlignment();
50 assertEquals(al.getWidth(), 157);
51 assertEquals(al.getHeight(), 15);
52 av.getRanges().setStartEndSeq(0, 14);
54 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
56 av.setWrapAlignment(true);
57 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
58 int charHeight = av.getCharHeight();
59 int charWidth = av.getCharWidth();
60 assertEquals(charHeight, 17);
61 assertEquals(charWidth, 12);
64 * first with scales above, left, right
66 av.setShowAnnotation(false);
67 av.setScaleAboveWrapped(true);
68 av.setScaleLeftWrapped(true);
69 av.setScaleRightWrapped(true);
70 FontMetrics fm = testee.getFontMetrics(av.getFont());
71 int labelWidth = fm.stringWidth("000") + charWidth;
72 assertEquals(labelWidth, 39); // 3 x 9 + charWidth
75 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
76 * take the whole multiple of character widths
78 int canvasWidth = 400;
79 int canvasHeight = 300;
80 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
81 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
82 assertEquals(wrappedWidth, residueColumns);
83 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
84 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
85 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
87 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
88 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
89 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
92 * repeat height is 17 * (2 + 15) = 289
93 * make canvas height 2 * 289 + 3 * charHeight so just enough to
94 * draw 2 widths and the first sequence of a third
96 canvasHeight = charHeight * (17 * 2 + 3);
97 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
98 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
101 * reduce canvas height by 1 pixel
102 * - should not be enough height to draw 3 widths
105 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
106 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
109 * turn off scale above - can now fit in 2 and a bit widths
111 av.setScaleAboveWrapped(false);
112 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
113 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
116 * reduce height to enough for 2 widths and not quite a third
117 * i.e. two repeating heights + spacer + sequence - 1 pixel
119 canvasHeight = charHeight * (16 * 2 + 2) - 1;
120 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
121 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
124 * make canvas width enough for scales and 20 residues
126 canvasWidth = 2 * labelWidth + 20 * charWidth;
127 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
129 assertEquals(wrappedWidth, 20);
132 * reduce width by 1 pixel - rounds down to 19 residues
135 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
137 assertEquals(wrappedWidth, 19);
140 * turn off West scale - adds labelWidth (39) to available for residues
141 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
143 av.setScaleLeftWrapped(false);
144 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
146 assertEquals(wrappedWidth, 23);
149 * add 10 pixels to width to fit in another whole residue column
152 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
154 assertEquals(wrappedWidth, 23);
156 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
158 assertEquals(wrappedWidth, 24);
161 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
163 av.setScaleRightWrapped(false);
164 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
166 assertEquals(wrappedWidth, 27);
169 * add 9 pixels to width to gain a residue column
172 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
174 assertEquals(wrappedWidth, 27); // 8px not enough
176 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
178 assertEquals(wrappedWidth, 28); // 9px is enough
181 * now West but not East scale - lose 39 pixels or 4 columns
183 av.setScaleLeftWrapped(true);
184 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
186 assertEquals(wrappedWidth, 24);
189 * adding 3 pixels to width regains one column
192 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
194 assertEquals(wrappedWidth, 24); // 2px not enough
196 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
198 assertEquals(wrappedWidth, 25); // 3px is enough
201 * turn off scales left and right, make width exactly 157 columns
203 av.setScaleLeftWrapped(false);
204 canvasWidth = al.getWidth() * charWidth;
205 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
206 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
210 * Test the method that computes wrapped width in residues, height of wrapped
211 * widths in pixels, and the number of widths visible
213 @Test(groups = "Functional")
214 public void testCalculateWrappedGeometry_withAnnotations()
216 AlignViewport av = af.getViewport();
217 AlignmentI al = av.getAlignment();
218 assertEquals(al.getWidth(), 157);
219 assertEquals(al.getHeight(), 15);
221 av.setWrapAlignment(true);
222 av.getRanges().setStartEndSeq(0, 14);
223 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
224 int charHeight = av.getCharHeight();
225 int charWidth = av.getCharWidth();
226 assertEquals(charHeight, 17);
227 assertEquals(charWidth, 12);
229 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
232 * first with scales above, left, right
234 av.setShowAnnotation(true);
235 av.setScaleAboveWrapped(true);
236 av.setScaleLeftWrapped(true);
237 av.setScaleRightWrapped(true);
238 FontMetrics fm = testee.getFontMetrics(av.getFont());
239 int labelWidth = fm.stringWidth("000") + charWidth;
240 assertEquals(labelWidth, 39); // 3 x 9 + charWidth
241 int annotationHeight = testee.getAnnotationHeight();
244 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
245 * take the whole multiple of character widths
247 int canvasWidth = 400;
248 int canvasHeight = 300;
249 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
250 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
251 assertEquals(wrappedWidth, residueColumns);
252 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
253 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
254 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
256 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
257 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
258 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
259 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
262 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
263 * make canvas height 2 of these plus 3 charHeights
264 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
266 canvasHeight = charHeight * (17 * 2 + 3)
267 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
268 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
269 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
272 * reduce canvas height by 1 pixel - should not be enough height
276 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
277 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
280 * turn off scale above - can now fit in 2 and a bit widths
282 av.setScaleAboveWrapped(false);
283 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
284 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
287 * reduce height to enough for 2 widths and not quite a third
288 * i.e. two repeating heights + spacer + sequence - 1 pixel
290 canvasHeight = charHeight * (16 * 2 + 2)
291 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
292 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
293 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
296 * add 1 pixel to height - should now get 3 widths drawn
299 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
300 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
304 * Test simulates loading an unwrapped alignment, shrinking it vertically so
305 * not all sequences are visible, then changing to wrapped mode. The ranges
306 * endSeq should be unchanged, but the vertical repeat height should include
309 @Test(groups = "Functional")
310 public void testCalculateWrappedGeometry_fromScrolled()
312 AlignViewport av = af.getViewport();
313 AlignmentI al = av.getAlignment();
314 assertEquals(al.getWidth(), 157);
315 assertEquals(al.getHeight(), 15);
316 av.getRanges().setStartEndSeq(0, 3);
317 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
318 av.setWrapAlignment(true);
319 av.setShowAnnotation(false);
320 av.setScaleAboveWrapped(true);
322 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
324 int charHeight = av.getCharHeight();
325 int charWidth = av.getCharWidth();
326 assertEquals(charHeight, 17);
327 assertEquals(charWidth, 12);
329 int canvasWidth = 400;
330 int canvasHeight = 300;
331 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
333 assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
334 int repeatingHeight = (int) PA.getValue(testee,
335 "wrappedRepeatHeightPx");
336 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
339 @BeforeMethod(alwaysRun = true)
342 Cache.loadProperties("test/jalview/io/testProps.jvprops");
343 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
344 Boolean.TRUE.toString());
345 af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
346 DataSourceType.FILE);
349 * wait for Consensus thread to complete
356 } catch (InterruptedException x)
359 } while (af.getViewport().getCalcManager().isWorking());