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;
29 import jalview.util.Platform;
32 import java.awt.FontMetrics;
34 import org.testng.annotations.BeforeClass;
35 import org.testng.annotations.Test;
37 import junit.extensions.PA;
39 public class SeqCanvasTest
41 @BeforeClass(alwaysRun = true)
48 * Test the method that computes wrapped width in residues, height of wrapped
49 * widths in pixels, and the number of widths visible
51 @Test(groups = "BHTEST")
52 public void testCalculateWrappedGeometry_noAnnotations()
54 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
55 "examples/uniref50.fa", DataSourceType.FILE);
56 AlignViewport av = af.getViewport();
57 AlignmentI al = av.getAlignment();
58 assertEquals(al.getWidth(), 157);
59 assertEquals(al.getHeight(), 15);
60 av.getRanges().setStartEndSeq(0, 14);
62 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
64 av.setWrapAlignment(true);
65 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
66 int charHeight = av.getCharHeight();
67 int charWidth = av.getCharWidth();
68 assertEquals(charHeight, Platform.isMac() ? 17 : 19);
69 assertEquals(charWidth, Platform.isMac() ? 12 : 11);
72 * first with scales above, left, right
74 av.setShowAnnotation(false);
75 av.setScaleAboveWrapped(true);
76 av.setScaleLeftWrapped(true);
77 av.setScaleRightWrapped(true);
78 FontMetrics fm = testee.getFontMetrics(av.getFont());
79 int labelWidth = fm.stringWidth("000") + charWidth;
80 assertEquals(labelWidth,
81 Platform.isMac() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
84 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
85 * take the whole multiple of character widths
87 int canvasWidth = 400;
88 int canvasHeight = 300;
89 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
90 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
91 assertEquals(wrappedWidth, residueColumns);
92 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
93 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
94 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
96 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
97 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
98 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
101 * repeat height is 17 * (2 + 15) = 289
102 * make canvas height 2 * 289 + 3 * charHeight so just enough to
103 * draw 2 widths and the first sequence of a third
105 canvasHeight = charHeight * (17 * 2 + 3);
106 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
107 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
110 * reduce canvas height by 1 pixel
111 * - should not be enough height to draw 3 widths
114 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
115 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
118 * turn off scale above - can now fit in 2 and a bit widths
120 av.setScaleAboveWrapped(false);
121 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
122 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
125 * reduce height to enough for 2 widths and not quite a third
126 * i.e. two repeating heights + spacer + sequence - 1 pixel
128 canvasHeight = charHeight * (16 * 2 + 2) - 1;
129 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
130 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
133 * make canvas width enough for scales and 20 residues
135 canvasWidth = 2 * labelWidth + 20 * charWidth;
136 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
138 assertEquals(wrappedWidth, 20);
141 * reduce width by 1 pixel - rounds down to 19 residues
144 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
146 assertEquals(wrappedWidth, 19);
149 * turn off West scale - adds labelWidth (39) to available for residues
150 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
152 av.setScaleLeftWrapped(false);
153 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
155 assertEquals(wrappedWidth, 23);
158 * add 10 pixels to width to fit in another whole residue column
161 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
163 assertEquals(wrappedWidth, 23);
165 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
167 assertEquals(wrappedWidth, 24);
170 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
172 av.setScaleRightWrapped(false);
173 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
175 assertEquals(wrappedWidth, 27);
178 * add 9 pixels to width to gain a residue column
181 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
183 assertEquals(wrappedWidth, 27); // 8px not enough
185 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
187 assertEquals(wrappedWidth, 28); // 9px is enough
190 * now West but not East scale - lose 39 pixels or 4 columns
192 av.setScaleLeftWrapped(true);
193 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
195 assertEquals(wrappedWidth, 24);
198 * adding 3 pixels to width regains one column
201 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
203 assertEquals(wrappedWidth, Platform.isMac() ? 24 : 25); // 2px not enough
205 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
207 assertEquals(wrappedWidth, 25); // 3px is enough
210 * turn off scales left and right, make width exactly 157 columns
212 av.setScaleLeftWrapped(false);
213 canvasWidth = al.getWidth() * charWidth;
214 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
215 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
219 * Test the method that computes wrapped width in residues, height of wrapped
220 * widths in pixels, and the number of widths visible
222 @Test(groups = "BHTEST")
223 public void testCalculateWrappedGeometry_withAnnotations()
225 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
226 "examples/uniref50.fa", DataSourceType.FILE);
227 AlignViewport av = af.getViewport();
228 AlignmentI al = av.getAlignment();
229 assertEquals(al.getWidth(), 157);
230 assertEquals(al.getHeight(), 15);
232 av.setWrapAlignment(true);
233 av.getRanges().setStartEndSeq(0, 14);
234 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
235 int charHeight = av.getCharHeight();
236 int charWidth = av.getCharWidth();
238 assertEquals(charHeight, Platform.isMac() ? 17 : 19);
239 assertEquals(charWidth, Platform.isMac() ? 12 : 11);
241 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
244 * first with scales above, left, right
246 av.setShowAnnotation(true);
247 av.setScaleAboveWrapped(true);
248 av.setScaleLeftWrapped(true);
249 av.setScaleRightWrapped(true);
251 FontMetrics fm = testee.getFontMetrics(av.getFont());
252 int labelWidth = fm.stringWidth("000") + charWidth;
253 assertEquals(labelWidth,
254 Platform.isMac() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
256 int annotationHeight = testee.getAnnotationHeight();
259 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
260 * take the whole multiple of character widths
262 int canvasWidth = 400;
263 int canvasHeight = 300;
264 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
265 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
266 assertEquals(wrappedWidth, residueColumns);
267 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
268 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
269 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
271 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
272 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
273 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
274 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
277 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
278 * make canvas height 2 of these plus 3 charHeights
279 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
281 canvasHeight = charHeight * (17 * 2 + 3)
282 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
283 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
284 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
287 * reduce canvas height by 1 pixel - should not be enough height
291 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
292 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
295 * turn off scale above - can now fit in 2 and a bit widths
297 av.setScaleAboveWrapped(false);
298 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
299 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
302 * reduce height to enough for 2 widths and not quite a third
303 * i.e. two repeating heights + spacer + sequence - 1 pixel
305 canvasHeight = charHeight * (16 * 2 + 2)
306 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
307 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
308 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
311 * add 1 pixel to height - should now get 3 widths drawn
314 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
315 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
319 * Test simulates loading an unwrapped alignment, shrinking it vertically so
320 * not all sequences are visible, then changing to wrapped mode. The ranges
321 * endSeq should be unchanged, but the vertical repeat height should include
324 @Test(groups = "BHTEST")
325 public void testCalculateWrappedGeometry_fromScrolled()
327 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
328 "examples/uniref50.fa", DataSourceType.FILE);
329 AlignViewport av = af.getViewport();
330 AlignmentI al = av.getAlignment();
331 assertEquals(al.getWidth(), 157);
332 assertEquals(al.getHeight(), 15);
333 av.getRanges().setStartEndSeq(0, 3);
334 System.out.println("SCT1 " + av.getRanges().getEndSeq());
335 av.setShowAnnotation(false);
336 av.setScaleAboveWrapped(true);
338 System.out.println("SCT2 " + av.getRanges().getEndSeq());
340 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
342 System.out.println("SCT3 " + av.getRanges().getEndSeq());
344 av.setWrapAlignment(true);
346 System.out.println("SCT4 " + av.getRanges().getEndSeq());
348 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
350 System.out.println("SCT5 " + av.getRanges().getEndSeq());
352 int charHeight = av.getCharHeight();
353 int charWidth = av.getCharWidth();
354 // Windows h=19, w=11.
355 assertEquals(charHeight, Platform.isMac() ? 17 : 19);
356 assertEquals(charWidth, Platform.isMac() ? 12 : 11);
358 int canvasWidth = 400;
359 int canvasHeight = 300;
360 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
362 System.out.println("SCT6 " + av.getRanges().getEndSeq());
364 assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
365 int repeatingHeight = (int) PA.getValue(testee,
366 "wrappedRepeatHeightPx");
367 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));