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.datamodel.AlignmentI;
27 import jalview.io.DataSourceType;
28 import jalview.io.FileLoader;
31 import java.awt.FontMetrics;
33 import org.testng.annotations.BeforeClass;
34 import org.testng.annotations.Test;
36 import junit.extensions.PA;
38 public class SeqCanvasTest
40 @BeforeClass(alwaysRun = true)
47 * Test the method that computes wrapped width in residues, height of wrapped
48 * widths in pixels, and the number of widths visible
50 @Test(groups = "Functional")
51 public void testCalculateWrappedGeometry_noAnnotations()
53 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
54 "examples/uniref50.fa", DataSourceType.FILE);
55 AlignViewport av = af.getViewport();
56 AlignmentI al = av.getAlignment();
57 assertEquals(al.getWidth(), 157);
58 assertEquals(al.getHeight(), 15);
59 av.getRanges().setStartEndSeq(0, 14);
61 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
63 av.setWrapAlignment(true);
64 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
65 int charHeight = av.getCharHeight();
66 int charWidth = av.getCharWidth();
67 assertEquals(charHeight, 17);
68 assertEquals(charWidth, 12);
71 * first with scales above, left, right
73 av.setShowAnnotation(false);
74 av.setScaleAboveWrapped(true);
75 av.setScaleLeftWrapped(true);
76 av.setScaleRightWrapped(true);
77 FontMetrics fm = testee.getFontMetrics(av.getFont());
78 int labelWidth = fm.stringWidth("000") + charWidth;
79 assertEquals(labelWidth, 39); // 3 x 9 + charWidth
82 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
83 * take the whole multiple of character widths
85 int canvasWidth = 400;
86 int canvasHeight = 300;
87 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
88 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
89 assertEquals(wrappedWidth, residueColumns);
90 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
91 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
92 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
94 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
95 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
96 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
99 * repeat height is 17 * (2 + 15) = 289
100 * make canvas height 2 * 289 + 3 * charHeight so just enough to
101 * draw 2 widths and the first sequence of a third
103 canvasHeight = charHeight * (17 * 2 + 3);
104 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
105 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
108 * reduce canvas height by 1 pixel
109 * - should not be enough height to draw 3 widths
112 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
113 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
116 * turn off scale above - can now fit in 2 and a bit widths
118 av.setScaleAboveWrapped(false);
119 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
120 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
123 * reduce height to enough for 2 widths and not quite a third
124 * i.e. two repeating heights + spacer + sequence - 1 pixel
126 canvasHeight = charHeight * (16 * 2 + 2) - 1;
127 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
128 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
131 * make canvas width enough for scales and 20 residues
133 canvasWidth = 2 * labelWidth + 20 * charWidth;
134 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
136 assertEquals(wrappedWidth, 20);
139 * reduce width by 1 pixel - rounds down to 19 residues
142 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
144 assertEquals(wrappedWidth, 19);
147 * turn off West scale - adds labelWidth (39) to available for residues
148 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
150 av.setScaleLeftWrapped(false);
151 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
153 assertEquals(wrappedWidth, 23);
156 * add 10 pixels to width to fit in another whole residue column
159 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
161 assertEquals(wrappedWidth, 23);
163 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
165 assertEquals(wrappedWidth, 24);
168 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
170 av.setScaleRightWrapped(false);
171 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
173 assertEquals(wrappedWidth, 27);
176 * add 9 pixels to width to gain a residue column
179 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
181 assertEquals(wrappedWidth, 27); // 8px not enough
183 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
185 assertEquals(wrappedWidth, 28); // 9px is enough
188 * now West but not East scale - lose 39 pixels or 4 columns
190 av.setScaleLeftWrapped(true);
191 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
193 assertEquals(wrappedWidth, 24);
196 * adding 3 pixels to width regains one column
199 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
201 assertEquals(wrappedWidth, 24); // 2px not enough
203 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
205 assertEquals(wrappedWidth, 25); // 3px is enough
208 * turn off scales left and right, make width exactly 157 columns
210 av.setScaleLeftWrapped(false);
211 canvasWidth = al.getWidth() * charWidth;
212 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
213 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
217 * Test the method that computes wrapped width in residues, height of wrapped
218 * widths in pixels, and the number of widths visible
220 @Test(groups = "Functional")
221 public void testCalculateWrappedGeometry_withAnnotations()
223 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
224 "examples/uniref50.fa", DataSourceType.FILE);
225 AlignViewport av = af.getViewport();
226 AlignmentI al = av.getAlignment();
227 assertEquals(al.getWidth(), 157);
228 assertEquals(al.getHeight(), 15);
230 av.setWrapAlignment(true);
231 av.getRanges().setStartEndSeq(0, 14);
232 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
233 int charHeight = av.getCharHeight();
234 int charWidth = av.getCharWidth();
235 assertEquals(charHeight, 17);
236 assertEquals(charWidth, 12);
238 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
241 * first with scales above, left, right
243 av.setShowAnnotation(true);
244 av.setScaleAboveWrapped(true);
245 av.setScaleLeftWrapped(true);
246 av.setScaleRightWrapped(true);
247 FontMetrics fm = testee.getFontMetrics(av.getFont());
248 int labelWidth = fm.stringWidth("000") + charWidth;
249 assertEquals(labelWidth, 39); // 3 x 9 + charWidth
250 int annotationHeight = testee.getAnnotationHeight();
253 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
254 * take the whole multiple of character widths
256 int canvasWidth = 400;
257 int canvasHeight = 300;
258 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
259 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
260 assertEquals(wrappedWidth, residueColumns);
261 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
262 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
263 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
265 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
266 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
267 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
268 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
271 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
272 * make canvas height 2 of these plus 3 charHeights
273 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
275 canvasHeight = charHeight * (17 * 2 + 3)
276 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
277 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
278 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
281 * reduce canvas height by 1 pixel - should not be enough height
285 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
286 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
289 * turn off scale above - can now fit in 2 and a bit widths
291 av.setScaleAboveWrapped(false);
292 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
293 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
296 * reduce height to enough for 2 widths and not quite a third
297 * i.e. two repeating heights + spacer + sequence - 1 pixel
299 canvasHeight = charHeight * (16 * 2 + 2)
300 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
301 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
302 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
305 * add 1 pixel to height - should now get 3 widths drawn
308 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
309 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
313 * Test simulates loading an unwrapped alignment, shrinking it vertically so
314 * not all sequences are visible, then changing to wrapped mode. The ranges
315 * endSeq should be unchanged, but the vertical repeat height should include
318 @Test(groups = "Functional")
319 public void testCalculateWrappedGeometry_fromScrolled()
321 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
322 "examples/uniref50.fa", DataSourceType.FILE);
323 AlignViewport av = af.getViewport();
324 AlignmentI al = av.getAlignment();
325 assertEquals(al.getWidth(), 157);
326 assertEquals(al.getHeight(), 15);
327 av.getRanges().setStartEndSeq(0, 3);
328 av.setShowAnnotation(false);
329 av.setScaleAboveWrapped(true);
331 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
333 av.setWrapAlignment(true);
334 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
335 int charHeight = av.getCharHeight();
336 int charWidth = av.getCharWidth();
337 assertEquals(charHeight, 17);
338 assertEquals(charWidth, 12);
340 int canvasWidth = 400;
341 int canvasHeight = 300;
342 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
344 assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
345 int repeatingHeight = (int) PA.getValue(testee,
346 "wrappedRepeatHeightPx");
347 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));