Find routine added
[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.util.*;\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     Image             img;\r
14     Graphics          gg;\r
15     int               imgWidth;\r
16     int               imgHeight;\r
17 \r
18     AlignViewport     av;\r
19     int pady = 2;\r
20     int oldstartx;\r
21     int oldstarty;\r
22     int oldendx;\r
23     int oldendy;\r
24     public boolean paintFlag = false;\r
25 \r
26     boolean showScores = false;\r
27     boolean displaySearch = false;\r
28     int [] searchResults = null;\r
29 \r
30     int chunkHeight;\r
31     int chunkWidth;\r
32 \r
33     ColourSchemeI   cs = new ZappoColourScheme();\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   public void drawScale(int startx, int endx,double charWidth, int charHeight,int ypos) {\r
42       int scalestartx = startx - startx%10 + 10;\r
43 \r
44       gg.setColor(Color.black);\r
45 \r
46       for (int i=scalestartx;i < endx;i+= 10) {\r
47           String string = String.valueOf(i);\r
48           gg.drawString(string,(int)((i-startx-1)*charWidth),ypos+15 - charHeight*(2));\r
49       }\r
50   }\r
51 \r
52 \r
53 /**\r
54  * Definitions of startx and endx (hopefully):\r
55  * SMJS This is what I'm working towards!\r
56  *   startx is the first residue (starting at 0) to display.\r
57  *   endx   is the last residue to display (starting at 0).\r
58  *   starty is the first sequence to display (starting at 0).\r
59  *   endy   is the last sequence to display (starting at 0).\r
60  * NOTE 1: The av limits are set in setFont in this class and\r
61  * in the adjustment listener in SeqPanel when the scrollbars move.\r
62  */\r
63 \r
64   public void paintComponent(Graphics g) {\r
65 \r
66     AlignmentI da = av.getAlignment();\r
67 \r
68     if (img == null ||\r
69         imgWidth  !=  getWidth()  ||\r
70         imgHeight !=  getHeight()\r
71         || paintFlag)\r
72     {\r
73 \r
74       imgWidth  = (getWidth() > 0 ? getWidth() : 1);\r
75       imgHeight = (getHeight() > 0 ? getHeight() : 1);\r
76 \r
77       img = createImage(imgWidth,imgHeight);\r
78       gg  = img.getGraphics();\r
79 \r
80       gg.setFont(av.getFont());\r
81 \r
82       oldstartx = -1;\r
83       oldendx   = -1;\r
84       oldstarty = -1;\r
85       oldendy   = -1;\r
86       paintFlag = false;\r
87     }\r
88 \r
89     int startx = av.getStartRes();\r
90     int starty = av.getStartSeq();\r
91 \r
92     int endx   = av.getEndRes();\r
93     int endy   = av.getEndSeq();\r
94 \r
95     double charWidth  = av.getCharWidth();\r
96     int charHeight    = av.getCharHeight();\r
97 \r
98     chunkWidth = (int)(getWidth()/charWidth);\r
99     chunkHeight =  (da.getHeight() + 2)*charHeight;\r
100 \r
101     av.setChunkHeight(chunkHeight);\r
102     av.setChunkWidth(chunkWidth);\r
103 \r
104     int offy = av.getStartSeq();\r
105 \r
106     if (oldendx == -1) {\r
107       fillBackground(gg,Color.WHITE,0,0,imgWidth,imgHeight);\r
108 \r
109      if (av.getWrapAlignment()) {\r
110           startx = (int)(offy/chunkWidth)*chunkWidth;\r
111           endx   = startx + chunkWidth;\r
112           starty = offy%chunkHeight;\r
113           endy   = starty + da.getHeight();\r
114 \r
115           int ypos     = 0;\r
116           int rowstart = starty;\r
117 \r
118           if (starty == 0) {\r
119               ypos = 2*charHeight;\r
120           } else if (starty == 1) {\r
121               starty = 0;\r
122               ypos = charHeight;\r
123           }\r
124 \r
125           if (endy > da.getHeight()) {\r
126               endy = da.getHeight();\r
127           }\r
128 \r
129           if (endx > da.getWidth()) {\r
130               endx = da.getWidth();\r
131           }\r
132 \r
133           if (rowstart < 2) {\r
134               drawScale(startx,endx,charWidth,charHeight,ypos);\r
135           }\r
136 \r
137           drawPanel(gg,startx,endx,starty,endy,startx,starty,ypos);\r
138 \r
139           if (rowstart == 0) {\r
140               ypos = ypos + chunkHeight;\r
141           } else if (rowstart == 1) {\r
142               ypos = ypos + chunkHeight;\r
143           } else {\r
144               ypos   = ypos + chunkHeight - rowstart*charHeight;\r
145           }\r
146 \r
147           startx += chunkWidth;\r
148           endx   = startx + chunkWidth;\r
149           starty = 0;\r
150 \r
151           if (endx > da.getWidth()) {\r
152               endx = da.getWidth();\r
153           }\r
154           // Draw the rest of the panels\r
155 \r
156           while (ypos <= getHeight()) {\r
157               drawScale(startx,endx,charWidth,charHeight,ypos);\r
158               drawPanel(gg,startx,endx,0,da.getHeight(),startx,starty,ypos);\r
159 \r
160               ypos   += chunkHeight;\r
161               startx += chunkWidth;\r
162               endx   = startx + chunkWidth;\r
163 \r
164               if (endy > da.getHeight()) {\r
165                   endy = da.getHeight();\r
166               }\r
167 \r
168               if (endx > da.getWidth()) {\r
169                   endx = da.getWidth();\r
170               }\r
171 \r
172           }\r
173       }\r
174       else\r
175       {\r
176           drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
177 \r
178           oldstartx = startx;\r
179           oldendx   = endx;\r
180           oldstarty = starty;\r
181           oldendy   = endy;\r
182 \r
183       }\r
184     }\r
185 \r
186     else if (oldstartx < startx)\r
187     {\r
188       // This is dragging horizontal scrollbar to the right\r
189 \r
190       int delx  = (int)((startx - oldstartx) * charWidth);\r
191       int delx2 = (int)((oldendx - startx + 1)   * charWidth);\r
192 \r
193       gg.copyArea(delx,0,delx2,AlignmentUtil.getPixelHeight(starty,endy,charHeight),-delx,0);\r
194 \r
195       if (startx > oldendx)\r
196         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
197       else\r
198         drawPanel(gg,oldendx+1,endx,starty,endy,startx,starty,0);\r
199 \r
200 \r
201       oldstartx = startx;\r
202       oldendx   = endx;\r
203 \r
204     } else if (oldstartx > startx)\r
205     {\r
206      // Horizontal scrollbar pulled to the left\r
207 \r
208       int delx  = (int)((oldstartx - startx) * charWidth);\r
209       int delx2 = (int)((endx - oldstartx +1)   * charWidth);\r
210 \r
211       gg.copyArea(0,0,delx2,AlignmentUtil.getPixelHeight(starty,endy,charHeight),delx,0);\r
212 \r
213       if (oldstartx > endx) {\r
214         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
215       } else {\r
216         drawPanel(gg,startx,oldstartx-1,starty,endy,startx,starty,0);\r
217       }\r
218 \r
219       oldstartx = startx;\r
220       oldendx   = endx;\r
221 \r
222     }  else if (oldstarty < starty) {\r
223       // Vertical scrollbar down\r
224       int dely  = AlignmentUtil.getPixelHeight(oldstarty,starty,charHeight);\r
225       int dely2 = AlignmentUtil.getPixelHeight(starty,oldendy,charHeight);\r
226 \r
227       gg.copyArea(0,dely,(int)((endx-startx+1)*charWidth),dely2,0,-dely);\r
228 \r
229       if (starty > oldendy) {\r
230         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
231       } else {\r
232         drawPanel(gg,startx,endx,oldendy,endy,startx,starty,0);\r
233       }\r
234 \r
235       oldstarty = starty;\r
236       oldendy   = endy;\r
237 \r
238     } else if (oldstarty > starty) {\r
239 \r
240       // Vertical scrollbar up\r
241       int dely  = AlignmentUtil.getPixelHeight(endy,oldendy,charHeight);\r
242       int dely2 = AlignmentUtil.getPixelHeight(oldstarty,endy,charHeight);\r
243 \r
244       gg.copyArea(0,0,(int)((endx-startx+1)*charWidth),dely2,0,dely);\r
245 \r
246       if (oldstarty > endy) {\r
247         drawPanel(gg,startx,endx,starty,endy,startx,starty,0);\r
248       } else {\r
249         drawPanel(gg,startx,endx,starty,oldstarty,startx,starty,0);\r
250       }\r
251 \r
252       oldstarty = starty;\r
253       oldendy   = endy;\r
254     }\r
255 \r
256     if ((oldendy -oldstarty) > (int)((getWidth() / av.getCharWidth()))) {\r
257       System.out.println("LIMITS ERROR LIMITS ERROR");\r
258       System.out.println("Corrds " + (oldendy-oldstarty) + " " + (int)(getWidth()/av.getCharWidth()) + " " + getWidth() + " " + av.getCharWidth());\r
259     }\r
260 \r
261 \r
262   //  gg.setColor(Color.red);\r
263   //  gg.drawRect( groupX, groupY, groupendX-groupX, groupendY-groupY );\r
264    // gg.drawRect( groupX+1, groupY+1, groupendX-groupX-2, groupendY-groupY-2 );\r
265 \r
266 \r
267     g.drawImage(img,0,0,this);\r
268 \r
269   }\r
270 \r
271 \r
272 \r
273 \r
274   public void drawPanel(Graphics g,int x1,int x2, int y1, int y2,int startx, int starty,int offset) {\r
275 \r
276 /*\r
277     System.out.println("drawPanel called with g      = " + g);\r
278     System.out.println("                      x1     = " + x1);\r
279     System.out.println("                      x2     = " + x2);\r
280     System.out.println("                      y1     = " + y1);\r
281     System.out.println("                      y2     = " + y2);\r
282     System.out.println("                      startx = " + startx);\r
283     System.out.println("                      starty = " + starty);\r
284 */\r
285 \r
286     g.setFont(av.getFont());\r
287     double            charWidth  = av.getCharWidth();\r
288     int               charHeight = av.getCharHeight();\r
289     RendererI sr = av.getRenderer();\r
290 \r
291 \r
292     /*Vector    pid    = av.getConsensus(false);\r
293     Vector tmpseq = new Vector();\r
294     for (int i = 0; i < av.getAlignment().getHeight(); i++)\r
295         if (!av.getSelection().contains(av.getAlignment().getSequenceAt(i)))\r
296             tmpseq.addElement(av.getAlignment().getSequenceAt(i));\r
297 \r
298     if (sr instanceof SequenceRenderer)\r
299         pid    = AAFrequency.calculate(tmpseq,x1,x2);\r
300 \r
301     else if (sr instanceof GraphRenderer)\r
302         pid = AAFrequency.calculatePID(av.getAlignment().getSequenceAt(0),\r
303                                        av.getAlignment().getSequences(),\r
304                                        av.getPIDWindow(),x1,x2);\r
305 \r
306 */\r
307 \r
308     if (y2 > starty && y1 < av.getEndSeq())\r
309     {\r
310        fillBackground(g,\r
311                    Color.WHITE,\r
312                    (int)((x1-startx)*charWidth),\r
313                    offset + AlignmentUtil.getPixelHeight(starty,y1,av.getCharHeight()),\r
314                    (int)((x2-x1+1)*charWidth),\r
315                    offset + AlignmentUtil.getPixelHeight(y1,y2,av.getCharHeight()));\r
316     }\r
317 \r
318     SequenceI nextSeq;\r
319     SequenceGroup group;\r
320     for (int i = y1 ; i < y2 ;i++)\r
321     {\r
322     /*  if (av.getSelection().contains(av.getAlignment().getSequenceAt(i))) {\r
323           r = fr;\r
324           System.out.println("use feature renderer");\r
325       } else if ( i == 0) {\r
326         //  r = br;\r
327       } else if (av.getAlignment().getSequenceAt(i).getName().equals("CpG")) {\r
328           r = cgr;\r
329           System.out.println("cg renderer");\r
330       }\r
331 */\r
332      nextSeq = av.getAlignment().getSequenceAt(i);\r
333      group = av.alignment.findGroup( nextSeq );\r
334      if( group!=null )\r
335      {\r
336        sr.drawSequence(g, group.cs, nextSeq,\r
337                       x1,\r
338                       x2,\r
339                       (int) ( (x1 - startx) * charWidth),\r
340                       offset + AlignmentUtil.getPixelHeight(starty, i, av.getCharHeight()),\r
341                       charWidth, charHeight,\r
342                       false, group.getDisplayBoxes(), group.getDisplayText(), group.getColourText(),\r
343                       null, i);\r
344      }\r
345      else\r
346      {\r
347        sr.drawSequence(g, cs, nextSeq,\r
348                       x1,\r
349                       x2,\r
350                       (int) ( (x1 - startx) * charWidth),\r
351                       offset + AlignmentUtil.getPixelHeight(starty, i, av.getCharHeight()),\r
352                       charWidth,charHeight,\r
353                       showScores, av.getShowBoxes(),  av.getShowText(), av.getColourText(),\r
354                       null, i);\r
355 \r
356      }\r
357 \r
358 \r
359     }\r
360 \r
361 \r
362     if(displaySearch)\r
363     {\r
364       for(int r=0; r<searchResults.length; r+=3)\r
365       {\r
366         int searchSeq = searchResults[r];\r
367         int searchStart = searchResults[r+1];\r
368         int searchEnd = searchResults[r+2];\r
369 \r
370         if (searchSeq >= y1 && searchSeq <= y2)\r
371         {\r
372           SequenceRenderer ssr = (SequenceRenderer) sr;\r
373           ssr.drawHighlightedText(g, av.getAlignment().getSequenceAt(searchSeq),\r
374                                   searchStart,\r
375                                   searchEnd,\r
376                                   (int) ( (searchStart - startx) * charWidth),\r
377                                   offset +\r
378                                   AlignmentUtil.getPixelHeight(starty, searchSeq,\r
379               charHeight),\r
380                                   (int) charWidth,\r
381                                   charHeight);\r
382 \r
383         }\r
384       }\r
385     }\r
386 \r
387 \r
388   }\r
389 \r
390  // public int groupX, groupY, groupendX, groupendY;\r
391 \r
392   public void fillBackground(Graphics g,Color c, int x1,int y1,int width,int height) {\r
393     g.setColor(c);\r
394     g.fillRect(x1,y1,width,height);\r
395   }\r
396 \r
397   public int getChunkWidth() {\r
398     return chunkWidth;\r
399   }\r
400 \r
401   public void highlightSearchResults(int [] results)\r
402   {\r
403     // results are in the order sequence, startRes, endRes\r
404     searchResults = results;\r
405     displaySearch = true;\r
406     paintFlag = true;\r
407     repaint();\r
408   }\r
409 \r
410 \r
411 }\r