091a1270931aad62682f475639876521ec1a5942
[jalview.git] / src / jalview / appletgui / FeatureRenderer.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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.appletgui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import java.awt.*;\r
24 \r
25 import java.util.*;\r
26 \r
27 /**\r
28  * DOCUMENT ME!\r
29  *\r
30  * @author $author$\r
31  * @version $Revision$\r
32  */\r
33 public class FeatureRenderer\r
34 {\r
35     AlignViewport av;\r
36     SequenceGroup currentSequenceGroup = null;\r
37     SequenceGroup[] allGroups = null;\r
38     Graphics graphics;\r
39 \r
40     // The following vector holds the features which are\r
41     // to be added, in the correct order or rendering\r
42     Vector featuresDisplayed;\r
43 \r
44     Color currentColour = null;\r
45 \r
46     boolean drawText = true;\r
47     FontMetrics fm;\r
48     int charOffset;\r
49 \r
50     /**\r
51      * Creates a new FeatureRenderer object.\r
52      *\r
53      * @param av DOCUMENT ME!\r
54      */\r
55     public FeatureRenderer(AlignViewport av)\r
56     {\r
57         this.av = av;\r
58         initColours();\r
59     }\r
60 \r
61     //boolean highlightTransparent = true;\r
62     /**\r
63      * DOCUMENT ME!\r
64      *\r
65      * @param g DOCUMENT ME!\r
66      * @param seq DOCUMENT ME!\r
67      * @param sg DOCUMENT ME!\r
68      * @param start DOCUMENT ME!\r
69      * @param end DOCUMENT ME!\r
70      * @param x1 DOCUMENT ME!\r
71      * @param y1 DOCUMENT ME!\r
72      * @param width DOCUMENT ME!\r
73      * @param height DOCUMENT ME!\r
74      */\r
75     public void drawSequence(Graphics g, SequenceI seq,\r
76         int start, int end, int x1, int y1, int width, int height)\r
77     {\r
78       fm = g.getFontMetrics();\r
79 \r
80         if(seq.getSequenceFeatures()==null)\r
81           return;\r
82 \r
83         Enumeration e = null, e2;\r
84         String type;\r
85         if(featuresDisplayed!=null)\r
86           e = featuresDisplayed.elements();\r
87         else\r
88          e = seq.getSequenceFeatures().elements();\r
89 \r
90 \r
91         while (e.hasMoreElements())\r
92         {\r
93             SequenceFeature sf=null;\r
94             if(featuresDisplayed!=null)\r
95             {\r
96               e2 = seq.getSequenceFeatures().elements();\r
97               type = e.nextElement().toString();\r
98               while(e2.hasMoreElements())\r
99               {\r
100                 sf = (SequenceFeature) e2.nextElement();\r
101                 if(sf.getType().equals(type))\r
102                   break;\r
103                 else\r
104                   sf = null;\r
105               }\r
106             }\r
107             else\r
108             {\r
109               sf = (SequenceFeature) e.nextElement();\r
110               type = sf.getType();\r
111             }\r
112 \r
113             if(sf==null)\r
114               continue;\r
115 \r
116 \r
117             if (sf.getBegin() > seq.getEnd())\r
118             {\r
119                 continue;\r
120             }\r
121 \r
122             if (type.equals("disulfide bond"))\r
123             {\r
124 \r
125               renderFeature(g, seq,\r
126                             seq.findIndex(sf.getBegin()) - 1,\r
127                             seq.findIndex(sf.getBegin()) - 1,\r
128                             type, start, end, x1, y1, width, height);\r
129               renderFeature(g, seq,\r
130                             seq.findIndex(sf.getEnd()) - 1,\r
131                             seq.findIndex(sf.getEnd()) - 1,\r
132                             type, start, end, x1, y1, width, height);\r
133 \r
134             }\r
135             else\r
136               renderFeature(g, seq,\r
137                             seq.findIndex(sf.getBegin()) - 1,\r
138                             seq.findIndex(sf.getEnd()) - 1,\r
139                           type, start, end, x1, y1, width, height);\r
140 \r
141       }\r
142     }\r
143 \r
144     void renderFeature(Graphics g, SequenceI seq,\r
145                        int fstart, int fend, String type, int start, int end,\r
146                        int x1, int y1, int width, int height)\r
147     {\r
148       if ( ( (fstart <= end) && (fend >= start)))\r
149       {\r
150         if (fstart < start)\r
151         { // fix for if the feature we have starts before the sequence start,\r
152           fstart = start; // but the feature end is still valid!!\r
153         }\r
154 \r
155         if (fend >= end)\r
156         {\r
157           fend = end;\r
158         }\r
159         for (int i = fstart; i <= fend; i++)\r
160         {\r
161           char s = seq.getSequence().charAt(i);\r
162 \r
163           if (jalview.util.Comparison.isGap(s))\r
164           {\r
165             continue;\r
166           }\r
167 \r
168           currentColour = getColour(type);\r
169 \r
170           g.setColor(currentColour);\r
171 \r
172           g.fillRect( (i - start) * width, y1, width, height);\r
173 \r
174           if (drawText)\r
175           {\r
176             g.setColor(Color.white);\r
177             charOffset = (width - fm.charWidth(s)) / 2;\r
178             g.drawString(String.valueOf(s),\r
179                          charOffset + x1 + (width * (i - start)),\r
180                          (y1 + height) - height / 5);\r
181           }\r
182         }\r
183       }\r
184     }\r
185 \r
186     Image offscreen;\r
187     Frame nullframe;\r
188     public Color findFeatureColour(Color initialCol, SequenceI seq, int i)\r
189     {\r
190       currentColour = initialCol;\r
191       if(offscreen == null)\r
192       {\r
193         nullframe = new Frame();\r
194         nullframe.addNotify();\r
195         offscreen = nullframe.createImage(1, 1);\r
196       }\r
197 \r
198       drawSequence(offscreen.getGraphics(), seq, i, i, 0, 0, 1, 1);\r
199       return currentColour;\r
200     }\r
201 \r
202 \r
203 \r
204     public Color getColour(String featureType)\r
205     {\r
206       return (Color)featureColours.get(featureType);\r
207     }\r
208 \r
209     public void setColour(String featureType, Color col)\r
210     {\r
211       featureColours.put(featureType, col);\r
212     }\r
213 \r
214  /*   public void setTransparency(float value)\r
215     {\r
216       transparency = value;\r
217     }\r
218 \r
219     public float getTransparency()\r
220     {\r
221       return transparency;\r
222     }*/\r
223 \r
224     public void setFeaturePriority(Object [][] data)\r
225     {\r
226       // The feature table will display high priority\r
227       // features at the top, but theses are the ones\r
228       // we need to render last, so invert the data\r
229       if(featuresDisplayed!=null)\r
230         featuresDisplayed.removeAllElements();\r
231       else\r
232         featuresDisplayed = new Vector();\r
233 \r
234       for(int i=data.length-1; i>-1; i--)\r
235       {\r
236        String type = data[i][0].toString();\r
237        setColour(type, (Color)data[i][1]);\r
238        if( ((Boolean)data[i][2]).booleanValue() )\r
239          featuresDisplayed.addElement(type);\r
240       }\r
241     }\r
242 \r
243     Hashtable featureColours = new Hashtable();\r
244     void initColours()\r
245     {\r
246       featureColours.put("active site", new Color(255, 75, 0));\r
247       featureColours.put("binding site", new Color(245, 85, 0));\r
248       featureColours.put("calcium-binding region", new Color(235, 95, 0));\r
249       featureColours.put("chain", new Color(225, 105, 0));\r
250       featureColours.put("coiled-coil region", new Color(215, 115, 0));\r
251       featureColours.put("compositionally biased region", new Color(205, 125, 0));\r
252       featureColours.put("cross-link", new Color(195, 135, 0));\r
253       featureColours.put("disulfide bond", new Color(185, 145, 0));\r
254       featureColours.put("DNA-binding region", new Color(175, 155, 0));\r
255       featureColours.put("domain", new Color(165, 165, 0));\r
256       featureColours.put("glycosylation site", new Color(155, 175, 0));\r
257       featureColours.put("helix", new Color(145, 185, 0));\r
258       featureColours.put("initiator methionine", new Color(135, 195, 5));\r
259       featureColours.put("lipid moiety-binding region", new Color(125, 205, 15));\r
260       featureColours.put("metal ion-binding site", new Color(115, 215, 25));\r
261       featureColours.put("modified residue", new Color(105, 225, 35));\r
262       featureColours.put("mutagenesis site", new Color(95, 235, 45));\r
263       featureColours.put("non-consecutive residues", new Color(85, 245, 55));\r
264       featureColours.put("non-terminal residue", new Color(75, 255, 65));\r
265       featureColours.put("nucleotide phosphate-binding region",\r
266                          new Color(65, 245, 75));\r
267       featureColours.put("peptide", new Color(55, 235, 85));\r
268       featureColours.put("propeptide", new Color(45, 225, 95));\r
269       featureColours.put("region of interest", new Color(35, 215, 105));\r
270       featureColours.put("repeat", new Color(25, 205, 115));\r
271       featureColours.put("selenocysteine", new Color(15, 195, 125));\r
272       featureColours.put("sequence conflict", new Color(5, 185, 135));\r
273       featureColours.put("sequence variant", new Color(0, 175, 145));\r
274       featureColours.put("short sequence motif", new Color(0, 165, 155));\r
275       featureColours.put("signal peptide", new Color(0, 155, 165));\r
276       featureColours.put("site", new Color(0, 145, 175));\r
277       featureColours.put("splice variant", new Color(0, 135, 185));\r
278       featureColours.put("strand", new Color(0, 125, 195));\r
279       featureColours.put("topological domain", new Color(0, 115, 205));\r
280       featureColours.put("transit peptide", new Color(0, 105, 215));\r
281       featureColours.put("transmembrane region", new Color(0, 95, 225));\r
282       featureColours.put("turn", new Color(0, 85, 235));\r
283       featureColours.put("unsure residue", new Color(0, 75, 245));\r
284       featureColours.put("zinc finger region", new Color(0, 65, 255));\r
285     }\r
286 \r
287 }\r
288 \r
289 \r
290 \r