Merge branch 'master' of https://source.jalview.org/git/jalviewjs.git
[jalviewjs.git] / site / j2s / jalview / appletgui / SeqCanvas.js
1 Clazz.declarePackage ("jalview.appletgui");
2 Clazz.load (["awt2swing.Panel"], "jalview.appletgui.SeqCanvas", ["jalview.appletgui.AnnotationPanel", "$.FeatureRenderer", "$.PaintRefresher", "$.SequenceRenderer", "jalview.util.Comparison", "java.awt.Color"], function () {
3 c$ = Clazz.decorateAsClass (function () {
4 this.fr = null;
5 this.sr = null;
6 this.img = null;
7 this.gg = null;
8 this.imgWidth = 0;
9 this.imgHeight = 0;
10 this.av = null;
11 this.searchResults = null;
12 this.$fastPaint = false;
13 this.cursorX = 0;
14 this.cursorY = 0;
15 this.avcharHeight = 0;
16 this.avcharWidth = 0;
17 this.lastsr = 0;
18 this.LABEL_WEST = 0;
19 this.LABEL_EAST = 0;
20 this.annotations = null;
21 Clazz.instantialize (this, arguments);
22 }, jalview.appletgui, "SeqCanvas", awt2swing.Panel);
23 Clazz.makeConstructor (c$, 
24 function (av) {
25 Clazz.superConstructor (this, jalview.appletgui.SeqCanvas, []);
26 this.av = av;
27 this.fr =  new jalview.appletgui.FeatureRenderer (av);
28 this.sr =  new jalview.appletgui.SequenceRenderer (av);
29 jalview.appletgui.PaintRefresher.Register (this, av.getSequenceSetId ());
30 this.updateViewport ();
31 }, "jalview.appletgui.AlignViewport");
32 Clazz.defineMethod (c$, "updateViewport", 
33  function () {
34 this.avcharHeight = this.av.getCharHeight ();
35 this.avcharWidth = this.av.getCharWidth ();
36 });
37 Clazz.defineMethod (c$, "getViewport", 
38 function () {
39 return this.av;
40 });
41 Clazz.defineMethod (c$, "getFeatureRenderer", 
42 function () {
43 return this.fr;
44 });
45 Clazz.defineMethod (c$, "getSequenceRenderer", 
46 function () {
47 return this.sr;
48 });
49 Clazz.defineMethod (c$, "drawNorthScale", 
50  function (g, startx, endx, ypos) {
51 var scalestartx = startx - startx % 10 + 10;
52 g.setColor (java.awt.Color.black);
53 for (var i = scalestartx; i < endx; i += 10) {
54 var value = i;
55 if (this.av.hasHiddenColumns ()) {
56 value = this.av.getColumnSelection ().adjustForHiddenColumns (value);
57 }g.drawString (String.valueOf (value), (i - startx - 1) * this.avcharWidth, ypos - (Clazz.doubleToInt (this.avcharHeight / 2)));
58 g.drawLine (((i - startx - 1) * this.avcharWidth) + (Clazz.doubleToInt (this.avcharWidth / 2)), (ypos + 2) - (Clazz.doubleToInt (this.avcharHeight / 2)), ((i - startx - 1) * this.avcharWidth) + (Clazz.doubleToInt (this.avcharWidth / 2)), ypos - 2);
59 }
60 }, "java.awt.Graphics,~N,~N,~N");
61 Clazz.defineMethod (c$, "drawWestScale", 
62  function (g, startx, endx, ypos) {
63 var fm = this.getFontMetrics (this.av.getFont ());
64 ypos += this.avcharHeight;
65 if (this.av.hasHiddenColumns ()) {
66 startx = this.av.getColumnSelection ().adjustForHiddenColumns (startx);
67 endx = this.av.getColumnSelection ().adjustForHiddenColumns (endx);
68 }var maxwidth = this.av.getAlignment ().getWidth ();
69 if (this.av.hasHiddenColumns ()) {
70 maxwidth = this.av.getColumnSelection ().findColumnPosition (maxwidth) - 1;
71 }for (var i = 0; i < this.av.getAlignment ().getHeight (); i++) {
72 var seq = this.av.getAlignment ().getSequenceAt (i);
73 var index = startx;
74 var value = -1;
75 while (index < endx) {
76 if (jalview.util.Comparison.isGap (seq.getCharAt (index))) {
77 index++;
78 continue;
79 }value = this.av.getAlignment ().getSequenceAt (i).findPosition (index);
80 break;
81 }
82 if (value != -1) {
83 var x = this.LABEL_WEST - fm.stringWidth (String.valueOf (value)) - Clazz.doubleToInt (this.avcharWidth / 2);
84 g.drawString (value + "", x, (ypos + (i * this.avcharHeight)) - (Clazz.doubleToInt (this.avcharHeight / 5)));
85 }}
86 }, "java.awt.Graphics,~N,~N,~N");
87 Clazz.defineMethod (c$, "drawEastScale", 
88  function (g, startx, endx, ypos) {
89 ypos += this.avcharHeight;
90 if (this.av.hasHiddenColumns ()) {
91 endx = this.av.getColumnSelection ().adjustForHiddenColumns (endx);
92 }var seq;
93 for (var i = 0; i < this.av.getAlignment ().getHeight (); i++) {
94 seq = this.av.getAlignment ().getSequenceAt (i);
95 var index = endx;
96 var value = -1;
97 while (index > startx) {
98 if (jalview.util.Comparison.isGap (seq.getCharAt (index))) {
99 index--;
100 continue;
101 }value = seq.findPosition (index);
102 break;
103 }
104 if (value != -1) {
105 g.drawString (String.valueOf (value), 0, (ypos + (i * this.avcharHeight)) - (Clazz.doubleToInt (this.avcharHeight / 5)));
106 }}
107 }, "java.awt.Graphics,~N,~N,~N");
108 Clazz.defineMethod (c$, "fastPaint", 
109 function (horizontal, vertical) {
110 if (this.$fastPaint || this.gg == null) {
111 return;
112 }this.updateViewport ();
113 if (this.lastsr + horizontal != this.av.startRes) {
114 horizontal = this.av.startRes - this.lastsr;
115 }this.lastsr = this.av.startRes;
116 this.$fastPaint = true;
117 this.gg.copyArea (horizontal * this.avcharWidth, vertical * this.avcharHeight, this.imgWidth - horizontal * this.avcharWidth, this.imgHeight - vertical * this.avcharHeight, -horizontal * this.avcharWidth, -vertical * this.avcharHeight);
118 var sr = this.av.startRes;
119 var er = this.av.endRes;
120 var ss = this.av.startSeq;
121 var es = this.av.endSeq;
122 var transX = 0;
123 var transY = 0;
124 if (horizontal > 0) {
125 transX = (er - sr - horizontal) * this.avcharWidth;
126 sr = er - horizontal;
127 } else if (horizontal < 0) {
128 er = sr - horizontal;
129 } else if (vertical > 0) {
130 ss = es - vertical;
131 if (ss < this.av.startSeq) {
132 ss = this.av.startSeq;
133 } else {
134 transY = this.imgHeight - vertical * this.avcharHeight;
135 }} else if (vertical < 0) {
136 es = ss - vertical;
137 if (es > this.av.endSeq) {
138 es = this.av.endSeq;
139 }}this.gg.translate (transX, transY);
140 this.drawPanel (this.gg, sr, er, ss, es, 0);
141 this.gg.translate (-transX, -transY);
142 this.repaint ();
143 }, "~N,~N");
144 Clazz.overrideMethod (c$, "paintComponent", 
145 function (g) {
146 if (this.img != null && (this.$fastPaint || (this.getSize ().width != g.getClipBounds ().width) || (this.getSize ().height != g.getClipBounds ().height))) {
147 g.drawImage (this.img, 0, 0, this);
148 this.$fastPaint = false;
149 return;
150 }if (this.$fastPaint) {
151 g.drawImage (this.img, 0, 0, this);
152 this.$fastPaint = false;
153 return;
154 }this.updateViewport ();
155 this.imgWidth = this.getSize ().width;
156 this.imgHeight = this.getSize ().height;
157 this.imgWidth -= this.imgWidth % this.avcharWidth;
158 this.imgHeight -= this.imgHeight % this.avcharHeight;
159 if (this.imgWidth < 1 || this.imgHeight < 1) {
160 return;
161 }if (this.img == null || this.imgWidth != this.img.getWidth (this) || this.imgHeight != this.img.getHeight (this)) {
162 this.img = this.createImage (this.imgWidth, this.imgHeight);
163 this.gg = this.img.getGraphics ();
164 this.gg.setFont (this.av.getFont ());
165 }this.gg.setColor (java.awt.Color.white);
166 this.gg.fillRect (0, 0, this.imgWidth, this.imgHeight);
167 if (this.av.getWrapAlignment ()) {
168 this.drawWrappedPanel (this.gg, this.imgWidth, this.imgHeight, this.av.startRes);
169 } else {
170 this.drawPanel (this.gg, this.av.startRes, this.av.endRes, this.av.startSeq, this.av.endSeq, 0);
171 }g.drawImage (this.img, 0, 0, this);
172 }, "java.awt.Graphics");
173 Clazz.defineMethod (c$, "getWrappedCanvasWidth", 
174 function (cwidth) {
175 cwidth -= cwidth % this.av.getCharWidth ();
176 var fm = this.getFontMetrics (this.av.getFont ());
177 this.LABEL_EAST = 0;
178 this.LABEL_WEST = 0;
179 if (this.av.getScaleRightWrapped ()) {
180 this.LABEL_EAST = fm.stringWidth (this.getMask ());
181 }if (this.av.getScaleLeftWrapped ()) {
182 this.LABEL_WEST = fm.stringWidth (this.getMask ());
183 }return Clazz.doubleToInt ((cwidth - this.LABEL_EAST - this.LABEL_WEST) / this.av.getCharWidth ());
184 }, "~N");
185 Clazz.defineMethod (c$, "getMask", 
186 function () {
187 var mask = "0";
188 var maxWidth = 0;
189 var tmp;
190 var alignment = this.av.getAlignment ();
191 for (var i = 0; i < alignment.getHeight (); i++) {
192 tmp = alignment.getSequenceAt (i).getEnd ();
193 if (tmp > maxWidth) {
194 maxWidth = tmp;
195 }}
196 for (var i = maxWidth; i > 0; i /= 10) {
197 mask += "0";
198 }
199 return mask;
200 });
201 Clazz.defineMethod (c$, "drawWrappedPanel", 
202  function (g, canvasWidth, canvasHeight, startRes) {
203 var al = this.av.getAlignment ();
204 var fm = this.getFontMetrics (this.av.getFont ());
205 if (this.av.getScaleRightWrapped ()) {
206 this.LABEL_EAST = fm.stringWidth (this.getMask ());
207 }if (this.av.getScaleLeftWrapped ()) {
208 this.LABEL_WEST = fm.stringWidth (this.getMask ());
209 }var hgap = this.avcharHeight;
210 if (this.av.getScaleAboveWrapped ()) {
211 hgap += this.avcharHeight;
212 }var cWidth = Clazz.doubleToInt ((canvasWidth - this.LABEL_EAST - this.LABEL_WEST) / this.avcharWidth);
213 var cHeight = this.av.getAlignment ().getHeight () * this.avcharHeight;
214 this.av.setWrappedWidth (cWidth);
215 this.av.endRes = this.av.startRes + cWidth;
216 var endx;
217 var ypos = hgap;
218 var maxwidth = this.av.getAlignment ().getWidth () - 1;
219 if (this.av.hasHiddenColumns ()) {
220 maxwidth = this.av.getColumnSelection ().findColumnPosition (maxwidth) - 1;
221 }while ((ypos <= canvasHeight) && (startRes < maxwidth)) {
222 endx = startRes + cWidth - 1;
223 if (endx > maxwidth) {
224 endx = maxwidth;
225 }g.setColor (java.awt.Color.black);
226 if (this.av.getScaleLeftWrapped ()) {
227 this.drawWestScale (g, startRes, endx, ypos);
228 }if (this.av.getScaleRightWrapped ()) {
229 g.translate (canvasWidth - this.LABEL_EAST, 0);
230 this.drawEastScale (g, startRes, endx, ypos);
231 g.translate (-(canvasWidth - this.LABEL_EAST), 0);
232 }g.translate (this.LABEL_WEST, 0);
233 if (this.av.getScaleAboveWrapped ()) {
234 this.drawNorthScale (g, startRes, endx, ypos);
235 }if (this.av.hasHiddenColumns () && this.av.getShowHiddenMarkers ()) {
236 g.setColor (java.awt.Color.blue);
237 var res;
238 for (var i = 0; i < this.av.getColumnSelection ().getHiddenColumns ().size (); i++) {
239 res = this.av.getColumnSelection ().findHiddenRegionPosition (i) - startRes;
240 if (res < 0 || res > endx - startRes) {
241 continue;
242 }this.gg.fillPolygon ( Clazz.newIntArray (-1, [res * this.avcharWidth - Clazz.doubleToInt (this.avcharHeight / 4), res * this.avcharWidth + Clazz.doubleToInt (this.avcharHeight / 4), res * this.avcharWidth]),  Clazz.newIntArray (-1, [ypos - (Clazz.doubleToInt (this.avcharHeight / 2)), ypos - (Clazz.doubleToInt (this.avcharHeight / 2)), ypos - (Clazz.doubleToInt (this.avcharHeight / 2)) + 8]), 3);
243 }
244 }if (g.getClip () == null) {
245 g.setClip (0, 0, cWidth * this.avcharWidth, canvasHeight);
246 }this.drawPanel (g, startRes, endx, 0, al.getHeight (), ypos);
247 g.setClip (null);
248 if (this.av.isShowAnnotation ()) {
249 g.translate (0, cHeight + ypos + 4);
250 if (this.annotations == null) {
251 this.annotations =  new jalview.appletgui.AnnotationPanel (this.av);
252 }this.annotations.drawComponent (g, startRes, endx + 1);
253 g.translate (0, -cHeight - ypos - 4);
254 }g.translate (-this.LABEL_WEST, 0);
255 ypos += cHeight + this.getAnnotationHeight () + hgap;
256 startRes += cWidth;
257 }
258 }, "java.awt.Graphics,~N,~N,~N");
259 Clazz.defineMethod (c$, "getAnnotationHeight", 
260 function () {
261 if (!this.av.isShowAnnotation ()) {
262 return 0;
263 }if (this.annotations == null) {
264 this.annotations =  new jalview.appletgui.AnnotationPanel (this.av);
265 }return this.annotations.adjustPanelHeight ();
266 });
267 Clazz.defineMethod (c$, "drawPanel", 
268  function (g1, startRes, endRes, startSeq, endSeq, offset) {
269 if (!this.av.hasHiddenColumns ()) {
270 this.draw (g1, startRes, endRes, startSeq, endSeq, offset);
271 } else {
272 var screenY = 0;
273 var blockStart = startRes;
274 var blockEnd = endRes;
275 if (this.av.hasHiddenColumns ()) {
276 for (var region, $region = this.av.getColumnSelection ().getHiddenColumns ().iterator (); $region.hasNext () && ((region = $region.next ()) || true);) {
277 var hideStart = region[0];
278 var hideEnd = region[1];
279 if (hideStart <= blockStart) {
280 blockStart += (hideEnd - hideStart) + 1;
281 continue;
282 }blockEnd = hideStart - 1;
283 g1.translate (screenY * this.avcharWidth, 0);
284 this.draw (g1, blockStart, blockEnd, startSeq, endSeq, offset);
285 if (this.av.getShowHiddenMarkers ()) {
286 g1.setColor (java.awt.Color.blue);
287 g1.drawLine ((blockEnd - blockStart + 1) * this.avcharWidth - 1, 0 + offset, (blockEnd - blockStart + 1) * this.avcharWidth - 1, (endSeq - startSeq) * this.avcharHeight + offset);
288 }g1.translate (-screenY * this.avcharWidth, 0);
289 screenY += blockEnd - blockStart + 1;
290 blockStart = hideEnd + 1;
291 }
292 }if (screenY <= (endRes - startRes)) {
293 blockEnd = blockStart + (endRes - startRes) - screenY;
294 g1.translate (screenY * this.avcharWidth, 0);
295 this.draw (g1, blockStart, blockEnd, startSeq, endSeq, offset);
296 g1.translate (-screenY * this.avcharWidth, 0);
297 }}}, "java.awt.Graphics,~N,~N,~N,~N,~N");
298 Clazz.defineMethod (c$, "draw", 
299 function (g, startRes, endRes, startSeq, endSeq, offset) {
300 g.setFont (this.av.getFont ());
301 this.sr.prepare (g, this.av.isRenderGaps ());
302 this.updateViewport ();
303 var nextSeq;
304 for (var i = startSeq; i < endSeq; i++) {
305 nextSeq = this.av.getAlignment ().getSequenceAt (i);
306 if (nextSeq == null) {
307 continue;
308 }this.sr.drawSequence (nextSeq, this.av.getAlignment ().findAllGroups (nextSeq), startRes, endRes, offset + ((i - startSeq) * this.avcharHeight));
309 if (this.av.isShowSequenceFeatures ()) {
310 this.fr.drawSequence (g, nextSeq, startRes, endRes, offset + ((i - startSeq) * this.avcharHeight));
311 }if (this.searchResults != null) {
312 var visibleResults = this.searchResults.getResults (nextSeq, startRes, endRes);
313 if (visibleResults != null) {
314 for (var r = 0; r < visibleResults.length; r += 2) {
315 this.sr.drawHighlightedText (nextSeq, visibleResults[r], visibleResults[r + 1], (visibleResults[r] - startRes) * this.avcharWidth, offset + ((i - startSeq) * this.avcharHeight));
316 }
317 }}if (this.av.cursorMode && this.cursorY == i && this.cursorX >= startRes && this.cursorX <= endRes) {
318 this.sr.drawCursor (nextSeq, this.cursorX, (this.cursorX - startRes) * this.avcharWidth, offset + ((i - startSeq) * this.avcharHeight));
319 }}
320 if (this.av.getSelectionGroup () != null || this.av.getAlignment ().getGroups ().size () > 0) {
321 this.drawGroupsBoundaries (g, startRes, endRes, startSeq, endSeq, offset);
322 }}, "java.awt.Graphics,~N,~N,~N,~N,~N");
323 Clazz.defineMethod (c$, "drawGroupsBoundaries", 
324  function (g, startRes, endRes, startSeq, endSeq, offset) {
325 var group = this.av.getSelectionGroup ();
326 var sx = -1;
327 var sy = -1;
328 var ex = -1;
329 var groupIndex = -1;
330 if ((group == null) && (this.av.getAlignment ().getGroups ().size () > 0)) {
331 group = this.av.getAlignment ().getGroups ().get (0);
332 groupIndex = 0;
333 }if (group != null) {
334 do {
335 var oldY = -1;
336 var i = 0;
337 var inGroup = false;
338 var top = -1;
339 var bottom = -1;
340 var alHeight = this.av.getAlignment ().getHeight () - 1;
341 for (i = startSeq; i < endSeq; i++) {
342 sx = (group.getStartRes () - startRes) * this.avcharWidth;
343 sy = offset + ((i - startSeq) * this.avcharHeight);
344 ex = (((group.getEndRes () + 1) - group.getStartRes ()) * this.avcharWidth) - 1;
345 if (sx + ex < 0 || sx > this.imgWidth) {
346 continue;
347 }if ((sx <= (endRes - startRes) * this.avcharWidth) && group.getSequences (null).contains (this.av.getAlignment ().getSequenceAt (i))) {
348 if ((bottom == -1) && (i >= alHeight || !group.getSequences (null).contains (this.av.getAlignment ().getSequenceAt (i + 1)))) {
349 bottom = sy + this.avcharHeight;
350 }if (!inGroup) {
351 if (((top == -1) && (i == 0)) || !group.getSequences (null).contains (this.av.getAlignment ().getSequenceAt (i - 1))) {
352 top = sy;
353 }oldY = sy;
354 inGroup = true;
355 if (group === this.av.getSelectionGroup ()) {
356 g.setColor (java.awt.Color.red);
357 } else {
358 g.setColor (group.getOutlineColour ());
359 }}} else {
360 if (inGroup) {
361 if (sx >= 0 && sx < this.imgWidth) {
362 g.drawLine (sx, oldY, sx, sy);
363 }if (sx + ex < this.imgWidth) {
364 g.drawLine (sx + ex, oldY, sx + ex, sy);
365 }if (sx < 0) {
366 ex += sx;
367 sx = 0;
368 }if (sx + ex > this.imgWidth) {
369 ex = this.imgWidth;
370 } else if (sx + ex >= (endRes - startRes + 1) * this.avcharWidth) {
371 ex = (endRes - startRes + 1) * this.avcharWidth;
372 }if (top != -1) {
373 g.drawLine (sx, top, sx + ex, top);
374 top = -1;
375 }if (bottom != -1) {
376 g.drawLine (sx, bottom, sx + ex, bottom);
377 bottom = -1;
378 }inGroup = false;
379 }}}
380 if (inGroup) {
381 sy = offset + ((i - startSeq) * this.avcharHeight);
382 if (sx >= 0 && sx < this.imgWidth) {
383 g.drawLine (sx, oldY, sx, sy);
384 }if (sx + ex < this.imgWidth) {
385 g.drawLine (sx + ex, oldY, sx + ex, sy);
386 }if (sx < 0) {
387 ex += sx;
388 sx = 0;
389 }if (sx + ex > this.imgWidth) {
390 ex = this.imgWidth;
391 } else if (sx + ex >= (endRes - startRes + 1) * this.avcharWidth) {
392 ex = (endRes - startRes + 1) * this.avcharWidth;
393 }if (top != -1) {
394 g.drawLine (sx, top, sx + ex, top);
395 top = -1;
396 }if (bottom != -1) {
397 g.drawLine (sx, bottom - 1, sx + ex, bottom - 1);
398 bottom = -1;
399 }inGroup = false;
400 }groupIndex++;
401 if (groupIndex >= this.av.getAlignment ().getGroups ().size ()) {
402 break;
403 }group = this.av.getAlignment ().getGroups ().get (groupIndex);
404 } while (groupIndex < this.av.getAlignment ().getGroups ().size ());
405 }}, "java.awt.Graphics,~N,~N,~N,~N,~N");
406 Clazz.defineMethod (c$, "highlightSearchResults", 
407 function (results) {
408 this.searchResults = results;
409 this.repaint ();
410 }, "jalview.datamodel.SearchResults");
411 });