rightAlignIds
[jalview.git] / src / jalview / gui / IdCanvas.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import java.awt.*;\r
24 import java.awt.image.*;\r
25 \r
26 import javax.swing.*;\r
27 \r
28 \r
29 /**\r
30  * DOCUMENT ME!\r
31  *\r
32  * @author $author$\r
33  * @version $Revision$\r
34  */\r
35 public class IdCanvas extends JPanel\r
36 {\r
37     protected AlignViewport av;\r
38     protected boolean showScores = true;\r
39     protected int maxIdLength = -1;\r
40     protected String maxIdStr = null;\r
41     BufferedImage image;\r
42     Graphics2D gg;\r
43     int imgHeight = 0;\r
44     boolean fastPaint = false;\r
45     java.util.Vector searchResults;\r
46     FontMetrics fm;\r
47 \r
48     /**\r
49      * Creates a new IdCanvas object.\r
50      *\r
51      * @param av DOCUMENT ME!\r
52      */\r
53     public IdCanvas(AlignViewport av)\r
54     {\r
55         setLayout(new BorderLayout());\r
56         this.av = av;\r
57         PaintRefresher.Register(this, av.getSequenceSetId());\r
58     }\r
59 \r
60     /**\r
61      * DOCUMENT ME!\r
62      *\r
63      * @param gg DOCUMENT ME!\r
64      * @param s DOCUMENT ME!\r
65      * @param i DOCUMENT ME!\r
66      * @param starty DOCUMENT ME!\r
67      * @param ypos DOCUMENT ME!\r
68      */\r
69     public void drawIdString(Graphics2D gg, SequenceI s, int i, int starty, int ypos)\r
70     {\r
71         int xPos = 0;\r
72         int panelWidth = getWidth();\r
73         int charHeight = av.charHeight;\r
74 \r
75         if ((searchResults != null) && searchResults.contains(s))\r
76         {\r
77             gg.setColor(Color.black);\r
78             gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
79                 charHeight);\r
80             gg.setColor(Color.white);\r
81         }\r
82         else if ((av.getSelectionGroup() != null) &&\r
83                 av.getSelectionGroup().getSequences(false).contains(s))\r
84         {\r
85             gg.setColor(Color.lightGray);\r
86             gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
87                 charHeight);\r
88             gg.setColor(Color.white);\r
89         }\r
90         else\r
91         {\r
92             gg.setColor(av.getSequenceColour(s));\r
93             gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
94                 charHeight);\r
95             gg.setColor(Color.black);\r
96         }\r
97 \r
98         if (av.rightAlignIds)\r
99         {\r
100           xPos = panelWidth - fm.stringWidth(\r
101               s.getDisplayId(av.getShowJVSuffix())\r
102               ) - 4;\r
103         }\r
104 \r
105         gg.drawString( s.getDisplayId(av.getShowJVSuffix()),\r
106                     xPos, (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));\r
107 \r
108         if (av.hasHiddenRows && av.showHiddenMarkers)\r
109           drawMarker(i, starty, ypos);\r
110 \r
111 \r
112     }\r
113 \r
114     /**\r
115      * DOCUMENT ME!\r
116      *\r
117      * @param vertical DOCUMENT ME!\r
118      */\r
119     public void fastPaint(int vertical)\r
120     {\r
121         if (gg == null)\r
122         {\r
123             repaint();\r
124 \r
125             return;\r
126         }\r
127 \r
128         gg.copyArea(0, 0, getWidth(), imgHeight, 0, -vertical * av.charHeight);\r
129 \r
130         int ss = av.startSeq;\r
131         int es = av.endSeq;\r
132         int transY = 0;\r
133 \r
134         if (vertical > 0) // scroll down\r
135         {\r
136             ss = es - vertical;\r
137 \r
138             if (ss < av.startSeq)\r
139             { // ie scrolling too fast, more than a page at a time\r
140                 ss = av.startSeq;\r
141             }\r
142             else\r
143             {\r
144                 transY = imgHeight - (vertical * av.charHeight);\r
145             }\r
146         }\r
147         else if (vertical < 0)\r
148         {\r
149             es = ss - vertical;\r
150 \r
151             if (es > av.endSeq)\r
152             {\r
153                 es = av.endSeq;\r
154             }\r
155         }\r
156 \r
157         gg.translate(0, transY);\r
158 \r
159         drawIds(ss, es);\r
160 \r
161         gg.translate(0, -transY);\r
162 \r
163         fastPaint = true;\r
164         repaint();\r
165     }\r
166 \r
167     /**\r
168      * DOCUMENT ME!\r
169      *\r
170      * @param g DOCUMENT ME!\r
171      */\r
172     public void paintComponent(Graphics g)\r
173     {\r
174         g.setColor(Color.white);\r
175         g.fillRect(0, 0, getWidth(), getHeight());\r
176 \r
177         if (fastPaint)\r
178         {\r
179             fastPaint = false;\r
180             g.drawImage(image, 0, 0, this);\r
181 \r
182             return;\r
183         }\r
184 \r
185         int oldHeight = imgHeight;\r
186 \r
187         imgHeight = getHeight();\r
188         imgHeight -= (imgHeight % av.charHeight);\r
189 \r
190         if (imgHeight < 1)\r
191         {\r
192             return;\r
193         }\r
194 \r
195         if(oldHeight!=imgHeight || image.getWidth(this)!=getWidth())\r
196         {\r
197           image = new BufferedImage(getWidth(), imgHeight,\r
198                                     BufferedImage.TYPE_INT_RGB);\r
199         }\r
200 \r
201         gg = (Graphics2D) image.getGraphics();\r
202 \r
203         //Fill in the background\r
204         gg.setColor(Color.white);\r
205         gg.fillRect(0, 0, getWidth(), imgHeight);\r
206 \r
207         drawIds(av.getStartSeq(), av.endSeq);\r
208 \r
209         g.drawImage(image, 0, 0, this);\r
210     }\r
211 \r
212     /**\r
213      * DOCUMENT ME!\r
214      *\r
215      * @param starty DOCUMENT ME!\r
216      * @param endy DOCUMENT ME!\r
217      */\r
218     void drawIds(int starty, int endy)\r
219     {\r
220       Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
221                              av.getFont().getSize());\r
222 \r
223       gg.setFont(italic);\r
224       fm = gg.getFontMetrics();\r
225 \r
226       if (av.antiAlias)\r
227         gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
228                             RenderingHints.VALUE_ANTIALIAS_ON);\r
229 \r
230         Color currentColor = Color.white;\r
231         Color currentTextColor = Color.black;\r
232 \r
233         if (av.getWrapAlignment())\r
234         {\r
235           int maxwidth = av.alignment.getWidth();\r
236           int alheight = av.alignment.getHeight();\r
237 \r
238           if (av.hasHiddenColumns)\r
239             maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
240 \r
241           int annotationHeight = 0;\r
242           AnnotationLabels labels = null;\r
243 \r
244           if(av.showAnnotation)\r
245           {\r
246             AnnotationPanel ap = new AnnotationPanel(av);\r
247             annotationHeight = ap.adjustPanelHeight();\r
248             labels = new AnnotationLabels(av);\r
249           }\r
250 \r
251           int hgap = av.charHeight;\r
252           if (av.scaleAboveWrapped)\r
253             hgap += av.charHeight;\r
254 \r
255           int cHeight = alheight * av.charHeight\r
256               + hgap\r
257               + annotationHeight;\r
258 \r
259           int rowSize = av.getEndRes() - av.getStartRes();\r
260 \r
261 \r
262             // Draw the rest of the panels\r
263             for (int ypos = hgap, row = av.startRes;\r
264                     (ypos <= getHeight()) && (row < maxwidth);\r
265                     ypos += cHeight, row += rowSize)\r
266             {\r
267               for (int i = starty; i < alheight; i++)\r
268               {\r
269                 if (av.hasHiddenRows)\r
270                 {\r
271                   setHiddenFont(i);\r
272                 }\r
273                 else\r
274                   gg.setFont(italic);\r
275 \r
276                 SequenceI s = av.alignment.getSequenceAt(i);\r
277                 drawIdString(gg, s, i, 0, ypos);\r
278               }\r
279 \r
280                 if(labels!=null)\r
281                 {\r
282                   gg.translate(0, ypos+(alheight * av.charHeight));\r
283                   labels.drawComponent(gg, getWidth());\r
284                   gg.translate(0, -ypos-(alheight * av.charHeight));\r
285                 }\r
286 \r
287 \r
288             }\r
289         }\r
290         else\r
291         {\r
292           //Now draw the id strings\r
293           int panelWidth = getWidth();\r
294           int xPos = 0;\r
295 \r
296             SequenceI sequence;\r
297             //Now draw the id strings\r
298             for (int i = starty; i < endy; i++)\r
299             {\r
300               sequence = av.alignment.getSequenceAt(i);\r
301 \r
302               if(sequence==null)\r
303                 continue;\r
304 \r
305               if (av.hasHiddenRows)\r
306               {\r
307                 setHiddenFont(i);\r
308               }\r
309 \r
310                 // Selected sequence colours\r
311                 if ( (searchResults != null) &&\r
312                     searchResults.contains(sequence))\r
313                 {\r
314                   currentColor = Color.black;\r
315                   currentTextColor = Color.white;\r
316                 }\r
317                 else if ( (av.getSelectionGroup() != null) &&\r
318                          av.getSelectionGroup().getSequences(false).contains(\r
319                              sequence))\r
320                 {\r
321                   currentColor = Color.lightGray;\r
322                   currentTextColor = Color.black;\r
323                 }\r
324                 else\r
325                 {\r
326                   currentColor = av.getSequenceColour(sequence);\r
327                   currentTextColor = Color.black;\r
328                 }\r
329 \r
330                 gg.setColor(currentColor);\r
331 \r
332                 gg.fillRect(0, (i - starty) * av.charHeight, getWidth(),\r
333                             av.charHeight);\r
334 \r
335                 gg.setColor(currentTextColor);\r
336 \r
337                 String string = sequence.getDisplayId( av.getShowJVSuffix());\r
338 \r
339 \r
340                 if(av.rightAlignIds)\r
341                 {\r
342                   xPos = panelWidth - fm.stringWidth(string) - 4;\r
343                 }\r
344 \r
345                 gg.drawString(string, xPos,\r
346                     (((i - starty) * av.charHeight) + av.charHeight) -\r
347                     (av.charHeight / 5));\r
348 \r
349                if(av.hasHiddenRows && av.showHiddenMarkers)\r
350                  drawMarker(i, starty, 0);\r
351 \r
352             }\r
353 \r
354         }\r
355     }\r
356 \r
357     void drawMarker(int i, int starty, int yoffset)\r
358     {\r
359 \r
360       SequenceI [] hseqs = av.alignment.getHiddenSequences().hiddenSequences;\r
361       //Use this method here instead of calling hiddenSeq adjust\r
362       //3 times.\r
363       int hSize = hseqs.length;\r
364 \r
365       int hiddenIndex = i;\r
366       int lastIndex = i - 1;\r
367       int nextIndex = i + 1;\r
368 \r
369       for(int j=0; j<hSize; j++)\r
370       {\r
371         if (hseqs[j] != null)\r
372         {\r
373           if(j-1<hiddenIndex)\r
374             hiddenIndex++;\r
375           if(j-1<lastIndex)\r
376             lastIndex++;\r
377           if(j-1<nextIndex)\r
378             nextIndex++;\r
379         }\r
380       }\r
381 \r
382       boolean below = (hiddenIndex > lastIndex + 1);\r
383       boolean above = (nextIndex > hiddenIndex+1);\r
384 \r
385 \r
386         gg.setColor(Color.blue);\r
387         if(below)\r
388         {\r
389           gg.fillPolygon(new int[]\r
390                          {getWidth()- av.charHeight,\r
391                          getWidth()- av.charHeight,\r
392                          getWidth()},\r
393                          new int[]\r
394                          {\r
395                          (i - starty) * av.charHeight +yoffset,\r
396                          (i - starty) * av.charHeight +yoffset+ av.charHeight / 4,\r
397                          (i - starty) * av.charHeight+yoffset\r
398           }, 3);\r
399         }\r
400         if(above)\r
401         {\r
402           gg.fillPolygon(new int[]\r
403                         {getWidth()- av.charHeight,\r
404                         getWidth()- av.charHeight,\r
405                         getWidth() },\r
406                         new int[]\r
407                         {\r
408                         (i - starty+1) * av.charHeight +yoffset,\r
409                         (i - starty+1) * av.charHeight +yoffset- av.charHeight / 4,\r
410                         (i - starty+1) * av.charHeight +yoffset\r
411          }, 3);\r
412 \r
413         }\r
414     }\r
415 \r
416     void setHiddenFont(int i)\r
417     {\r
418       Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
419                              av.getFont().getSize());\r
420       Font bold = new Font(av.getFont().getName(), Font.BOLD,\r
421                            av.getFont().getSize());\r
422 \r
423 \r
424       if (av.alignment.getSequenceAt(i)!=null\r
425           && av.alignment.getSequenceAt(i).getHiddenSequences() != null)\r
426         gg.setFont(bold);\r
427       else\r
428         gg.setFont(italic);\r
429     }\r
430 \r
431     /**\r
432      * DOCUMENT ME!\r
433      *\r
434      * @param found DOCUMENT ME!\r
435      */\r
436     public void setHighlighted(java.util.Vector found)\r
437     {\r
438         searchResults = found;\r
439         repaint();\r
440     }\r
441 }\r