ID_ITALICS option in preferences
[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     AnnotationLabels labels = null;\r
48     AnnotationPanel ap;\r
49     Font idfont;\r
50 \r
51     /**\r
52      * Creates a new IdCanvas object.\r
53      *\r
54      * @param av DOCUMENT ME!\r
55      */\r
56     public IdCanvas(AlignViewport av)\r
57     {\r
58         setLayout(new BorderLayout());\r
59         this.av = av;\r
60         PaintRefresher.Register(this, av.getSequenceSetId());\r
61     }\r
62 \r
63     /**\r
64      * DOCUMENT ME!\r
65      *\r
66      * @param gg DOCUMENT ME!\r
67      * @param s DOCUMENT ME!\r
68      * @param i DOCUMENT ME!\r
69      * @param starty DOCUMENT ME!\r
70      * @param ypos DOCUMENT ME!\r
71      */\r
72     public void drawIdString(Graphics2D gg, SequenceI s, int i, int starty, int ypos)\r
73     {\r
74         int xPos = 0;\r
75         int panelWidth = getWidth();\r
76         int charHeight = av.charHeight;\r
77 \r
78         if ((searchResults != null) && searchResults.contains(s))\r
79         {\r
80             gg.setColor(Color.black);\r
81             gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
82                 charHeight);\r
83             gg.setColor(Color.white);\r
84         }\r
85         else if ((av.getSelectionGroup() != null) &&\r
86                 av.getSelectionGroup().getSequences(null).contains(s))\r
87         {\r
88             gg.setColor(Color.lightGray);\r
89             gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
90                 charHeight);\r
91             gg.setColor(Color.white);\r
92         }\r
93         else\r
94         {\r
95             gg.setColor(av.getSequenceColour(s));\r
96             gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),\r
97                 charHeight);\r
98             gg.setColor(Color.black);\r
99         }\r
100 \r
101         if (av.rightAlignIds)\r
102         {\r
103           xPos = panelWidth - fm.stringWidth(\r
104               s.getDisplayId(av.getShowJVSuffix())\r
105               ) - 4;\r
106         }\r
107 \r
108         gg.drawString( s.getDisplayId(av.getShowJVSuffix()),\r
109                     xPos, (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));\r
110 \r
111         if (av.hasHiddenRows && av.showHiddenMarkers)\r
112           drawMarker(i, starty, ypos);\r
113 \r
114 \r
115     }\r
116 \r
117     /**\r
118      * DOCUMENT ME!\r
119      *\r
120      * @param vertical DOCUMENT ME!\r
121      */\r
122     public void fastPaint(int vertical)\r
123     {\r
124         if (gg == null)\r
125         {\r
126             repaint();\r
127 \r
128             return;\r
129         }\r
130 \r
131         gg.copyArea(0, 0, getWidth(), imgHeight, 0, -vertical * av.charHeight);\r
132 \r
133         int ss = av.startSeq;\r
134         int es = av.endSeq;\r
135         int transY = 0;\r
136 \r
137         if (vertical > 0) // scroll down\r
138         {\r
139             ss = es - vertical;\r
140 \r
141             if (ss < av.startSeq)\r
142             { // ie scrolling too fast, more than a page at a time\r
143                 ss = av.startSeq;\r
144             }\r
145             else\r
146             {\r
147                 transY = imgHeight - (vertical * av.charHeight);\r
148             }\r
149         }\r
150         else if (vertical < 0)\r
151         {\r
152             es = ss - vertical;\r
153 \r
154             if (es > av.endSeq)\r
155             {\r
156                 es = av.endSeq;\r
157             }\r
158         }\r
159 \r
160         gg.translate(0, transY);\r
161 \r
162         drawIds(ss, es);\r
163 \r
164         gg.translate(0, -transY);\r
165 \r
166         fastPaint = true;\r
167         repaint();\r
168     }\r
169 \r
170     /**\r
171      * DOCUMENT ME!\r
172      *\r
173      * @param g DOCUMENT ME!\r
174      */\r
175     public void paintComponent(Graphics g)\r
176     {\r
177         g.setColor(Color.white);\r
178         g.fillRect(0, 0, getWidth(), getHeight());\r
179 \r
180         if (fastPaint)\r
181         {\r
182             fastPaint = false;\r
183             g.drawImage(image, 0, 0, this);\r
184 \r
185             return;\r
186         }\r
187 \r
188         int oldHeight = imgHeight;\r
189 \r
190         imgHeight = getHeight();\r
191         imgHeight -= (imgHeight % av.charHeight);\r
192 \r
193         if (imgHeight < 1)\r
194         {\r
195             return;\r
196         }\r
197 \r
198         if(oldHeight!=imgHeight || image.getWidth(this)!=getWidth())\r
199         {\r
200           image = new BufferedImage(getWidth(), imgHeight,\r
201                                     BufferedImage.TYPE_INT_RGB);\r
202         }\r
203 \r
204         gg = (Graphics2D) image.getGraphics();\r
205 \r
206         //Fill in the background\r
207         gg.setColor(Color.white);\r
208         gg.fillRect(0, 0, getWidth(), imgHeight);\r
209 \r
210         drawIds(av.getStartSeq(), av.endSeq);\r
211 \r
212         g.drawImage(image, 0, 0, this);\r
213     }\r
214 \r
215     /**\r
216      * DOCUMENT ME!\r
217      *\r
218      * @param starty DOCUMENT ME!\r
219      * @param endy DOCUMENT ME!\r
220      */\r
221     void drawIds(int starty, int endy)\r
222     {\r
223      if(av.seqNameItalics)\r
224       idfont = new Font(av.getFont().getName(), Font.ITALIC,\r
225                              av.getFont().getSize());\r
226     else\r
227       idfont = av.getFont();\r
228 \r
229       gg.setFont(idfont);\r
230       fm = gg.getFontMetrics();\r
231 \r
232       if (av.antiAlias)\r
233         gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
234                             RenderingHints.VALUE_ANTIALIAS_ON);\r
235 \r
236         Color currentColor = Color.white;\r
237         Color currentTextColor = Color.black;\r
238 \r
239         if (av.getWrapAlignment())\r
240         {\r
241           int maxwidth = av.alignment.getWidth();\r
242           int alheight = av.alignment.getHeight();\r
243 \r
244           if (av.hasHiddenColumns)\r
245             maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
246 \r
247           int annotationHeight = 0;\r
248 \r
249 \r
250           if(av.showAnnotation)\r
251           {\r
252             if (ap == null)\r
253               ap = new AnnotationPanel(av);\r
254 \r
255             annotationHeight = ap.adjustPanelHeight();\r
256             if (labels == null)\r
257               labels = new AnnotationLabels(av);\r
258           }\r
259 \r
260           int hgap = av.charHeight;\r
261           if (av.scaleAboveWrapped)\r
262             hgap += av.charHeight;\r
263 \r
264           int cHeight = alheight * av.charHeight\r
265               + hgap\r
266               + annotationHeight;\r
267 \r
268           int rowSize = av.getEndRes() - av.getStartRes();\r
269 \r
270 \r
271             // Draw the rest of the panels\r
272             for (int ypos = hgap, row = av.startRes;\r
273                     (ypos <= getHeight()) && (row < maxwidth);\r
274                     ypos += cHeight, row += rowSize)\r
275             {\r
276               for (int i = starty; i < alheight; i++)\r
277               {\r
278                 SequenceI s = av.alignment.getSequenceAt(i);\r
279                 if (av.hasHiddenRows)\r
280                 {\r
281                   setHiddenFont(s);\r
282                 }\r
283                 else\r
284                   gg.setFont(idfont);\r
285 \r
286                 drawIdString(gg, s, i, 0, ypos);\r
287               }\r
288 \r
289                 if(labels!=null && av.showAnnotation)\r
290                 {\r
291                   gg.translate(0, ypos+(alheight * av.charHeight));\r
292                   labels.drawComponent(gg, getWidth());\r
293                   gg.translate(0, -ypos-(alheight * av.charHeight));\r
294                 }\r
295             }\r
296         }\r
297         else\r
298         {\r
299           //No need to hang on to labels if we're not wrapped\r
300           labels = null;\r
301 \r
302           //Now draw the id strings\r
303           int panelWidth = getWidth();\r
304           int xPos = 0;\r
305 \r
306             SequenceI sequence;\r
307             //Now draw the id strings\r
308             for (int i = starty; i < endy; i++)\r
309             {\r
310               sequence = av.alignment.getSequenceAt(i);\r
311 \r
312               if(sequence==null)\r
313                 continue;\r
314 \r
315               if (av.hasHiddenRows)\r
316               {\r
317                 setHiddenFont(sequence);\r
318               }\r
319 \r
320                 // Selected sequence colours\r
321                 if ( (searchResults != null) &&\r
322                     searchResults.contains(sequence))\r
323                 {\r
324                   currentColor = Color.black;\r
325                   currentTextColor = Color.white;\r
326                 }\r
327                 else if ( (av.getSelectionGroup() != null) &&\r
328                          av.getSelectionGroup().getSequences(null).contains(\r
329                              sequence))\r
330                 {\r
331                   currentColor = Color.lightGray;\r
332                   currentTextColor = Color.black;\r
333                 }\r
334                 else\r
335                 {\r
336                   currentColor = av.getSequenceColour(sequence);\r
337                   currentTextColor = Color.black;\r
338                 }\r
339 \r
340                 gg.setColor(currentColor);\r
341 \r
342                 gg.fillRect(0, (i - starty) * av.charHeight, getWidth(),\r
343                             av.charHeight);\r
344 \r
345                 gg.setColor(currentTextColor);\r
346 \r
347                 String string = sequence.getDisplayId( av.getShowJVSuffix());\r
348 \r
349 \r
350                 if(av.rightAlignIds)\r
351                 {\r
352                   xPos = panelWidth - fm.stringWidth(string) - 4;\r
353                 }\r
354 \r
355                 gg.drawString(string, xPos,\r
356                     (((i - starty) * av.charHeight) + av.charHeight) -\r
357                     (av.charHeight / 5));\r
358 \r
359                if(av.hasHiddenRows && av.showHiddenMarkers)\r
360                  drawMarker(i, starty, 0);\r
361 \r
362             }\r
363 \r
364         }\r
365     }\r
366 \r
367     void drawMarker(int i, int starty, int yoffset)\r
368     {\r
369 \r
370       SequenceI [] hseqs = av.alignment.getHiddenSequences().hiddenSequences;\r
371       //Use this method here instead of calling hiddenSeq adjust\r
372       //3 times.\r
373       int hSize = hseqs.length;\r
374 \r
375       int hiddenIndex = i;\r
376       int lastIndex = i - 1;\r
377       int nextIndex = i + 1;\r
378 \r
379       for(int j=0; j<hSize; j++)\r
380       {\r
381         if (hseqs[j] != null)\r
382         {\r
383           if(j-1<hiddenIndex)\r
384             hiddenIndex++;\r
385           if(j-1<lastIndex)\r
386             lastIndex++;\r
387           if(j-1<nextIndex)\r
388             nextIndex++;\r
389         }\r
390       }\r
391 \r
392       boolean below = (hiddenIndex > lastIndex + 1);\r
393       boolean above = (nextIndex > hiddenIndex+1);\r
394 \r
395 \r
396         gg.setColor(Color.blue);\r
397         if(below)\r
398         {\r
399           gg.fillPolygon(new int[]\r
400                          {getWidth()- av.charHeight,\r
401                          getWidth()- av.charHeight,\r
402                          getWidth()},\r
403                          new int[]\r
404                          {\r
405                          (i - starty) * av.charHeight +yoffset,\r
406                          (i - starty) * av.charHeight +yoffset+ av.charHeight / 4,\r
407                          (i - starty) * av.charHeight+yoffset\r
408           }, 3);\r
409         }\r
410         if(above)\r
411         {\r
412           gg.fillPolygon(new int[]\r
413                         {getWidth()- av.charHeight,\r
414                         getWidth()- av.charHeight,\r
415                         getWidth() },\r
416                         new int[]\r
417                         {\r
418                         (i - starty+1) * av.charHeight +yoffset,\r
419                         (i - starty+1) * av.charHeight +yoffset- av.charHeight / 4,\r
420                         (i - starty+1) * av.charHeight +yoffset\r
421          }, 3);\r
422 \r
423         }\r
424     }\r
425 \r
426     void setHiddenFont(SequenceI seq)\r
427     {\r
428       Font bold = new Font(av.getFont().getName(), Font.BOLD,\r
429                            av.getFont().getSize());\r
430 \r
431 \r
432       if (av.hiddenRepSequences!=null &&\r
433           av.hiddenRepSequences.containsKey(seq))\r
434         gg.setFont(bold);\r
435       else\r
436         gg.setFont(idfont);\r
437     }\r
438 \r
439     /**\r
440      * DOCUMENT ME!\r
441      *\r
442      * @param found DOCUMENT ME!\r
443      */\r
444     public void setHighlighted(java.util.Vector found)\r
445     {\r
446         searchResults = found;\r
447         repaint();\r
448     }\r
449 }\r