Preparing for groupselect mode
[jalview.git] / src / jalview / gui / SeqCanvas.java
1 package jalview.gui;\r
2 \r
3 import java.awt.*;\r
4 import javax.swing.*;\r
5 import java.awt.event.*;\r
6 import jalview.datamodel.*;\r
7 import jalview.schemes.*;\r
8 import jalview.analysis.*;\r
9 \r
10 \r
11 public class SeqCanvas extends JPanel\r
12 {\r
13     ColourSchemeI globalColorScheme = null;\r
14     Image             img;\r
15     Graphics          gg;\r
16     int               imgWidth;\r
17     int               imgHeight;\r
18 \r
19     AlignViewport     av;\r
20     int pady = 2;\r
21     int oldstartx;\r
22     int oldstarty;\r
23     int oldendx;\r
24     int oldendy;\r
25     public boolean paintFlag = false;\r
26 \r
27     boolean showScores = false;\r
28     boolean displaySearch = false;\r
29     int [] searchResults = null;\r
30 \r
31     int chunkHeight;\r
32     int chunkWidth;\r
33 \r
34 \r
35     public SeqCanvas(AlignViewport av)\r
36     {\r
37         this.av         = av;\r
38        setLayout(new BorderLayout());\r
39 \r
40     }\r
41 \r
42   public void drawScale(int startx, int endx,int charWidth, int charHeight,int ypos) {\r
43       int scalestartx = startx - startx%10 + 10;\r
44 \r
45       gg.setColor(Color.black);\r
46 \r
47       for (int i=scalestartx;i < endx;i+= 10) {\r
48           String string = String.valueOf(i);\r
49           gg.drawString(string,(int)((i-startx-1)*charWidth),ypos+15 - charHeight*(2));\r
50       }\r
51   }\r
52 \r
53 \r
54 /**\r
55  * Definitions of startx and endx (hopefully):\r
56  * SMJS This is what I'm working towards!\r
57  *   startx is the first residue (starting at 0) to display.\r
58  *   endx   is the last residue to display (starting at 0).\r
59  *   starty is the first sequence to display (starting at 0).\r
60  *   endy   is the last sequence to display (starting at 0).\r
61  * NOTE 1: The av limits are set in setFont in this class and\r
62  * in the adjustment listener in SeqPanel when the scrollbars move.\r
63  */\r
64 \r
65   public void paintComponent(Graphics g) {\r
66 \r
67     AlignmentI da = av.getAlignment();\r
68 \r
69     if (img == null ||\r
70         imgWidth  !=  getWidth()  ||\r
71         imgHeight !=  getHeight()\r
72         || paintFlag)\r
73     {\r
74 \r
75       imgWidth  = (getWidth() > 0 ? getWidth() : 1);\r
76       imgHeight = (getHeight() > 0 ? getHeight() : 1);\r
77 \r
78       img = createImage(imgWidth,imgHeight);\r
79       gg  = img.getGraphics();\r
80 \r
81       gg.setFont(av.getFont());\r
82 \r
83       oldstartx = -1;\r
84       oldendx   = -1;\r
85       oldstarty = -1;\r
86       oldendy   = -1;\r
87       paintFlag = false;\r
88     }\r
89 \r
90     int startx = av.getStartRes();\r
91     int starty = av.getStartSeq();\r
92 \r
93     int endx   = av.getEndRes();\r
94     int endy   = av.getEndSeq();\r
95 \r
96     int charWidth  = av.getCharWidth();\r
97     int charHeight = av.getCharHeight();\r
98 \r
99     chunkWidth  =   getWidth()/charWidth;\r
100     chunkHeight =  (da.getHeight() + 2)*charHeight;\r
101 \r
102     av.setChunkHeight(chunkHeight);\r
103     av.setChunkWidth(chunkWidth);\r
104 \r
105     int offy = av.getStartSeq();\r
106 \r
107     if (oldendx == -1) {\r
108       fillBackground(gg,Color.WHITE,0,0,imgWidth,imgHeight);\r
109 \r
110      if (av.getWrapAlignment()) {\r
111           startx = (int)(offy/chunkWidth)*chunkWidth;\r
112           endx   = startx + chunkWidth;\r
113           starty = offy%chunkHeight;\r
114           endy   = starty + da.getHeight();\r
115 \r
116           int ypos     = 0;\r
117           int rowstart = starty;\r
118 \r
119           if (starty == 0) {\r
120               ypos = 2*charHeight;\r
121           } else if (starty == 1) {\r
122               starty = 0;\r
123               ypos = charHeight;\r
124           }\r
125 \r
126           if (endy > da.getHeight()) {\r
127               endy = da.getHeight();\r
128           }\r
129 \r
130           if (endx > da.getWidth()) {\r
131               endx = da.getWidth();\r
132           }\r
133 \r
134           if (rowstart < 2) {\r
135               drawScale(startx,endx,charWidth,charHeight,ypos);\r
136           }\r
137 \r
138           drawPanel(gg,startx,endx,starty,endy,startx,starty,ypos);\r
139 \r
140           if (rowstart == 0) {\r
141               ypos = ypos + chunkHeight;\r
142           } else if (rowstart == 1) {\r
143               ypos = ypos + chunkHeight;\r
144           } else {\r
145               ypos   = ypos + chunkHeight - rowstart*charHeight;\r
146           }\r
147 \r
148           startx += chunkWidth;\r
149           endx   = startx + chunkWidth;\r
150           starty = 0;\r
151 \r
152           if (endx > da.getWidth()) {\r
153               endx = da.getWidth();\r
154           }\r
155           // Draw the rest of the panels\r
156 \r
157           while (ypos <= getHeight()) {\r
158               drawScale(startx,endx,charWidth,charHeight,ypos);\r
159               drawPanel(gg,startx,endx,0,da.getHeight(),startx,starty,ypos);\r
160 \r
161               ypos   += chunkHeight;\r
162               startx += chunkWidth;\r
163               endx   = startx + chunkWidth;\r
164 \r
165               if (endy > da.getHeight()) {\r
166                   endy = da.getHeight();\r
167               }\r
168 \r
169               if (endx > da.getWidth()) {\r
170                   endx = da.getWidth();\r
171               }\r
172 \r
173           }\r
174       }\r
175       else\r
176       {\r
177           drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
178 \r
179           oldstartx = startx;\r
180           oldendx   = endx;\r
181           oldstarty = starty;\r
182           oldendy   = endy;\r
183 \r
184       }\r
185     }\r
186 \r
187     else if (oldstartx < startx)\r
188     {\r
189       // This is dragging horizontal scrollbar to the right\r
190 \r
191       int delx  = (startx - oldstartx)   * charWidth;\r
192       int delx2 = (oldendx - startx + 1) * charWidth;\r
193 \r
194       gg.copyArea(delx,0,delx2,AlignmentUtil.getPixelHeight(starty,endy,charHeight),-delx,0);\r
195 \r
196       if (startx > oldendx)\r
197         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
198       else\r
199         drawPanel(gg,oldendx+1,endx,starty,endy,startx,starty,0);\r
200 \r
201 \r
202       oldstartx = startx;\r
203       oldendx   = endx;\r
204 \r
205     } else if (oldstartx > startx)\r
206     {\r
207      // Horizontal scrollbar pulled to the left\r
208 \r
209       int delx  = (oldstartx - startx)    * charWidth;\r
210       int delx2 = (endx - oldstartx +1)   * charWidth;\r
211 \r
212       gg.copyArea(0,0,delx2,AlignmentUtil.getPixelHeight(starty,endy,charHeight),delx,0);\r
213 \r
214       if (oldstartx > endx) {\r
215         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
216       } else {\r
217         drawPanel(gg,startx,oldstartx-1,starty,endy,startx,starty,0);\r
218       }\r
219 \r
220       oldstartx = startx;\r
221       oldendx   = endx;\r
222 \r
223     }  else if (oldstarty < starty) {\r
224       // Vertical scrollbar down\r
225       int dely  = AlignmentUtil.getPixelHeight(oldstarty,starty,charHeight);\r
226       int dely2 = AlignmentUtil.getPixelHeight(starty,oldendy,charHeight);\r
227 \r
228       gg.copyArea(0,dely,(endx-startx+1)*charWidth,dely2,0,-dely);\r
229 \r
230       if (starty > oldendy) {\r
231         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
232       } else {\r
233         drawPanel(gg,startx,endx,oldendy,endy,startx,starty,0);\r
234       }\r
235 \r
236       oldstarty = starty;\r
237       oldendy   = endy;\r
238 \r
239     } else if (oldstarty > starty) {\r
240 \r
241       // Vertical scrollbar up\r
242       int dely  = AlignmentUtil.getPixelHeight(endy,oldendy,charHeight);\r
243       int dely2 = AlignmentUtil.getPixelHeight(oldstarty,endy,charHeight);\r
244 \r
245       gg.copyArea(0,0,(endx-startx+1)*charWidth,dely2,0,dely);\r
246 \r
247       if (oldstarty > endy) {\r
248         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
249       } else {\r
250         drawPanel(gg,startx,endx,starty,oldstarty,startx,starty,0);\r
251       }\r
252 \r
253       oldstarty = starty;\r
254       oldendy   = endy;\r
255     }\r
256 \r
257     if ((oldendy -oldstarty) > (getWidth() / av.getCharWidth())) {\r
258       System.out.println("LIMITS ERROR LIMITS ERROR");\r
259       System.out.println("Corrds " + (oldendy-oldstarty) + " " + (getWidth()/av.getCharWidth()) + " " + getWidth() + " " + av.getCharWidth());\r
260     }\r
261 \r
262 \r
263   //  gg.setColor(Color.red);\r
264   //  gg.drawRect( groupX, groupY, groupendX-groupX, groupendY-groupY );\r
265    // gg.drawRect( groupX+1, groupY+1, groupendX-groupX-2, groupendY-groupY-2 );\r
266 \r
267 \r
268     g.drawImage(img,0,0,this);\r
269 \r
270   }\r
271 \r
272 \r
273 \r
274 \r
275   public void drawPanel(Graphics g,int x1,int x2, int y1, int y2,int startx, int starty,int offset) {\r
276 \r
277 /*\r
278     Startx and starty appear to be the same as x1, y1, unless you find different\r
279       x1                                               x2\r
280     y1**************************************************\r
281       *                                                *\r
282       *                                                *\r
283       *                                                *\r
284       *                                                *\r
285       **************************************************y2\r
286 \r
287 /*\r
288     System.out.println("drawPanel called with g      = " + g);\r
289     System.out.println("                      x1     = " + x1);\r
290     System.out.println("                      x2     = " + x2);\r
291     System.out.println("                      y1     = " + y1);\r
292     System.out.println("                      y2     = " + y2);\r
293     System.out.println("                      startx = " + startx);\r
294     System.out.println("                      starty = " + starty);\r
295 */\r
296 \r
297     g.setFont(av.getFont());\r
298     int            charWidth  = av.getCharWidth();\r
299     int            charHeight = av.getCharHeight();\r
300     RendererI sr = av.getRenderer();\r
301 \r
302 \r
303     /*Vector    pid    = av.getConsensus(false);\r
304     Vector tmpseq = new Vector();\r
305     for (int i = 0; i < av.getAlignment().getHeight(); i++)\r
306         if (!av.getSelection().contains(av.getAlignment().getSequenceAt(i)))\r
307             tmpseq.addElement(av.getAlignment().getSequenceAt(i));\r
308 \r
309     if (sr instanceof SequenceRenderer)\r
310         pid    = AAFrequency.calculate(tmpseq,x1,x2);\r
311 \r
312     else if (sr instanceof GraphRenderer)\r
313         pid = AAFrequency.calculatePID(av.getAlignment().getSequenceAt(0),\r
314                                        av.getAlignment().getSequences(),\r
315                                        av.getPIDWindow(),x1,x2);\r
316 \r
317 */\r
318 \r
319     if (y2 > starty && y1 < av.getEndSeq())\r
320     {\r
321        fillBackground(g,\r
322                    Color.WHITE,\r
323                    (x1-startx)*charWidth,\r
324                    offset + AlignmentUtil.getPixelHeight(starty,y1,av.getCharHeight()),\r
325                    (x2-x1+1)*charWidth,\r
326                    offset + AlignmentUtil.getPixelHeight(y1,y2,av.getCharHeight()));\r
327     }\r
328 \r
329     SequenceI nextSeq;\r
330     SequenceGroup group=null;\r
331     boolean newGroup=false;\r
332     int sx, sy, ex, ey;\r
333     int oldStartX=0,oldEndX=0,oldY=0;\r
334     for (int i = y1 ; i < y2 ;i++)\r
335     {\r
336      nextSeq = av.getAlignment().getSequenceAt(i);\r
337      if(group==null || group!=av.alignment.findGroup( nextSeq ))\r
338         newGroup = true;\r
339      else\r
340         newGroup = false;\r
341 \r
342     group = av.alignment.findGroup( nextSeq );\r
343 \r
344     sr.drawSequence(g, nextSeq, group,x1,x2,\r
345                  (x1 - startx) * charWidth,\r
346                  offset + AlignmentUtil.getPixelHeight(starty, i, av.getCharHeight()),\r
347                  charWidth,charHeight,null, i);\r
348 \r
349 \r
350      if( group!=null )\r
351      {\r
352 \r
353         g.setColor(Color.GREEN);\r
354 \r
355         sx = (group.getStartRes()-startx)*charWidth;\r
356         sy = offset + AlignmentUtil.getPixelHeight(starty, i, av.getCharHeight());\r
357         ex = (group.getEndRes()+1-startx)*charWidth;\r
358         ey = offset + AlignmentUtil.getPixelHeight(starty, i+1, av.getCharHeight());\r
359 \r
360 \r
361         if (newGroup)\r
362         {\r
363           g.drawLine(oldStartX, oldY, oldEndX, oldY); // Horizontal, bottom of old box\r
364           g.drawLine(sx, sy, ex, sy); // Horizontal, top of new box\r
365         }\r
366 \r
367         g.drawLine(sx, sy, sx, ey ); // vertical line, left hand side\r
368         g.drawLine( ex,sy,ex,ey);    // vertical line, right hand side\r
369         if (i == y2 - 1)// last line of alignment, seal the box\r
370           g.drawLine(sx, ey, ex, ey); // Horizontal, bottom of old box\r
371 \r
372         oldStartX = sx;\r
373         oldEndX = ex;\r
374         oldY = ey;\r
375 \r
376      }\r
377 \r
378     }\r
379 \r
380     /// Highlight search Results once all sequences have been drawn\r
381     if(displaySearch)\r
382     {\r
383       for(int r=0; r<searchResults.length; r+=3)\r
384       {\r
385         int searchSeq = searchResults[r];\r
386         int searchStart = searchResults[r+1];\r
387         int searchEnd = searchResults[r+2];\r
388 \r
389         if (searchSeq >= y1 && searchSeq <= y2)\r
390         {\r
391           SequenceRenderer ssr = (SequenceRenderer) sr;\r
392           ssr.drawHighlightedText(g, av.getAlignment().getSequenceAt(searchSeq),\r
393                                   searchStart,\r
394                                   searchEnd,\r
395                                   (searchStart - startx) * charWidth,\r
396                                   offset +\r
397                                   AlignmentUtil.getPixelHeight(starty, searchSeq,\r
398               charHeight),\r
399                                   charWidth,\r
400                                   charHeight);\r
401         }\r
402       }\r
403     }\r
404 \r
405 \r
406 \r
407 \r
408     /*bg.drawImage(image,0,0,null);\r
409   int size=width*height;\r
410   int pixel, b, x,y;\r
411   if(value!=0 )\r
412   {\r
413     if(painted!=null)\r
414     {\r
415      for(int i=0; i<size; i++)\r
416      {\r
417       if(painted[i] == value)\r
418       {\r
419          x = (i%width);\r
420          y = (i-x)/width;\r
421          pixel = buf.getRGB(x,y);\r
422          b = pixel & 0x000000ff;\r
423          pixel = (105<<24) | (0<<16)+32 | (0<<8)+32 | b;\r
424          buf.setRGB(x,y,pixel);\r
425      }\r
426      }\r
427 \r
428     }\r
429     else\r
430     {\r
431      for(int i=0; i<size; i++)\r
432      {\r
433       if(paintedShort[i] == value)\r
434       {\r
435        x = (i%width);\r
436        y = (i-x)/width;\r
437        pixel = buf.getRGB(x,y);\r
438        b = pixel & 0x000000ff;\r
439        pixel = (105<<24) | (0<<16) | (0<<8) | b;\r
440        buf.setRGB(x,y,pixel);\r
441      }\r
442      }\r
443     }\r
444 \r
445    }\r
446    oldvalue = value;\r
447    return (Image)buf;\r
448 */\r
449 \r
450   }\r
451 \r
452  // public int groupX, groupY, groupendX, groupendY;\r
453 \r
454   public void fillBackground(Graphics g,Color c, int x1,int y1,int width,int height) {\r
455     g.setColor(c);\r
456     g.fillRect(x1,y1,width,height);\r
457   }\r
458 \r
459   public int getChunkWidth() {\r
460     return chunkWidth;\r
461   }\r
462 \r
463   public void highlightSearchResults(int [] results)\r
464   {\r
465     // results are in the order sequence, startRes, endRes\r
466     if(results==null)\r
467       displaySearch = false;\r
468     else\r
469       displaySearch = true;\r
470 \r
471     searchResults = results;\r
472 \r
473     paintFlag = true;\r
474     repaint();\r
475   }\r
476 \r
477 \r
478 }\r