9dbb05ccb75a749e2211e02bc39b8f848b3067ad
[jalview.git] / src / jalview / appletgui / SequenceRenderer.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 \r
20 package jalview.appletgui;\r
21 \r
22 import java.awt.*;\r
23 \r
24 import jalview.datamodel.*;\r
25 import jalview.schemes.*;\r
26 \r
27 public class SequenceRenderer\r
28 {\r
29   AlignViewport av;\r
30   FontMetrics fm;\r
31   boolean renderGaps = true;\r
32   SequenceGroup currentSequenceGroup = null;\r
33   SequenceGroup[] allGroups = null;\r
34   Color resBoxColour;\r
35   Graphics graphics;\r
36   boolean forOverview = false;\r
37 \r
38   public SequenceRenderer(AlignViewport av)\r
39   {\r
40     this.av = av;\r
41   }\r
42 \r
43   public void renderGaps(boolean b)\r
44   {\r
45     renderGaps = b;\r
46   }\r
47 \r
48   public Color getResidueBoxColour(SequenceI seq, int i)\r
49   {\r
50     allGroups = av.alignment.findAllGroups(seq);\r
51 \r
52     if (inCurrentSequenceGroup(i))\r
53     {\r
54       if (currentSequenceGroup.getDisplayBoxes())\r
55       {\r
56         getBoxColour(currentSequenceGroup.cs, seq, i);\r
57       }\r
58     }\r
59     else if (av.getShowBoxes())\r
60     {\r
61         getBoxColour(av.globalColourScheme, seq, i);\r
62     }\r
63 \r
64     return resBoxColour;\r
65     }\r
66 \r
67   void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)\r
68   {\r
69     if (cs != null)\r
70     {\r
71       resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);\r
72     }\r
73     else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))\r
74     {\r
75         resBoxColour = Color.lightGray;\r
76     }\r
77     else\r
78     {\r
79       resBoxColour = Color.white;\r
80     }\r
81 \r
82   }\r
83 \r
84   public Color findSequenceColour(SequenceI seq, int i)\r
85   {\r
86     allGroups = av.alignment.findAllGroups(seq);\r
87     drawBoxes(seq, i,i, 0);\r
88     return resBoxColour;\r
89   }\r
90 \r
91   public void drawSequence(Graphics g, SequenceI seq, SequenceGroup[] sg,\r
92                            int start, int end,  int y1)\r
93   {\r
94     allGroups = sg;\r
95 \r
96     graphics = g;\r
97 \r
98     drawBoxes(seq, start, end,  y1);\r
99 \r
100     if(av.validCharWidth)\r
101     {\r
102       fm = g.getFontMetrics();\r
103       drawText(seq, start, end, y1);\r
104     }\r
105   }\r
106 \r
107   public void drawBoxes(SequenceI seq, int start, int end,  int y1)\r
108   {\r
109     int i = start;\r
110     int length = seq.getLength();\r
111 \r
112     int curStart = -1;\r
113     int curWidth = av.charWidth;\r
114 \r
115     Color tempColour = null;\r
116     while (i <= end)\r
117     {\r
118       resBoxColour = Color.white;\r
119       if(i < length)\r
120       {\r
121         if (inCurrentSequenceGroup(i))\r
122         {\r
123           if (currentSequenceGroup.getDisplayBoxes())\r
124           {\r
125             getBoxColour(currentSequenceGroup.cs, seq, i);\r
126           }\r
127         }\r
128         else if (av.getShowBoxes())\r
129         {\r
130           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
131         }\r
132       }\r
133 \r
134 \r
135       if (resBoxColour != tempColour)\r
136       {\r
137         if (tempColour != null)\r
138         {\r
139           graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,\r
140                             av.charHeight);\r
141         }\r
142         graphics.setColor(resBoxColour);\r
143 \r
144         curStart = i;\r
145         curWidth = av.charWidth;\r
146         tempColour = resBoxColour;\r
147 \r
148       }\r
149       else\r
150       {\r
151         curWidth += av.charWidth;\r
152       }\r
153 \r
154       i++;\r
155     }\r
156 \r
157     graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, av.charHeight);\r
158   }\r
159 \r
160   public void drawText(SequenceI seq, int start, int end, int y1)\r
161   {\r
162 \r
163     y1 += av.charHeight - av.charHeight / 5;  // height/5 replaces pady\r
164 \r
165     int charOffset = 0;\r
166 \r
167     // Need to find the sequence position here.\r
168     if(end+1>=seq.getLength())\r
169           end = seq.getLength()-1;\r
170 \r
171     char s = ' ';\r
172 \r
173     for (int i = start; i <= end; i++)\r
174     {\r
175       graphics.setColor(Color.black);\r
176 \r
177       s = seq.getCharAt(i);\r
178       if (!renderGaps && jalview.util.Comparison.isGap(s))\r
179       {\r
180         continue;\r
181       }\r
182 \r
183       if (inCurrentSequenceGroup(i))\r
184       {\r
185         if (!currentSequenceGroup.getDisplayText())\r
186         {\r
187           continue;\r
188         }\r
189 \r
190         if (currentSequenceGroup.getColourText())\r
191         {\r
192           getBoxColour(currentSequenceGroup.cs, seq, i);\r
193           graphics.setColor(resBoxColour.darker());\r
194         }\r
195       }\r
196       else\r
197       {\r
198         if (!av.getShowText())\r
199         {\r
200           continue;\r
201         }\r
202 \r
203         if (av.getColourText())\r
204         {\r
205           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
206           if (av.getShowBoxes())\r
207           {\r
208             graphics.setColor(resBoxColour.darker());\r
209           }\r
210           else\r
211           {\r
212             graphics.setColor(resBoxColour);\r
213           }\r
214         }\r
215       }\r
216 \r
217       charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
218       graphics.drawString(String.valueOf(s),\r
219                          charOffset + av.charWidth * (i - start),\r
220                         y1 );\r
221     }\r
222 \r
223   }\r
224 \r
225   boolean inCurrentSequenceGroup(int res)\r
226   {\r
227     if (allGroups == null)\r
228     {\r
229       return false;\r
230     }\r
231 \r
232     for (int i = 0; i < allGroups.length; i++)\r
233     {\r
234       if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)\r
235       {\r
236         currentSequenceGroup = allGroups[i];\r
237         return true;\r
238       }\r
239     }\r
240 \r
241     return false;\r
242   }\r
243 \r
244   public void drawHighlightedText(SequenceI seq, int start, int end, int x1,\r
245                                   int y1, int width, int height)\r
246   {\r
247     int pady = height / 5;\r
248     int charOffset = 0;\r
249     graphics.setColor(Color.black);\r
250     graphics.fillRect(x1, y1, width * (end - start + 1), height);\r
251     graphics.setColor(Color.white);\r
252 \r
253     char s = '~';\r
254     // Need to find the sequence position here.\r
255     if(av.validCharWidth)\r
256     {\r
257       for (int i = start; i <= end; i++)\r
258       {\r
259         if (i < seq.getLength())\r
260         {\r
261           s = seq.getSequence().charAt(i);\r
262         }\r
263 \r
264         charOffset = (width - fm.charWidth(s)) / 2;\r
265         graphics.drawString(String.valueOf(s),\r
266                             charOffset + x1 + width * (i - start),\r
267                             y1 + height - pady);\r
268       }\r
269     }\r
270   }\r
271 \r
272   public void drawCursor(SequenceI seq, int res, int x1, int y1)\r
273   {\r
274     int pady = av.charHeight / 5;\r
275     int charOffset = 0;\r
276     graphics.setColor(Color.black);\r
277     graphics.fillRect(x1, y1, av.charWidth, av.charHeight);\r
278     graphics.setColor(Color.white);\r
279 \r
280     graphics.setColor(Color.white);\r
281 \r
282     char s = seq.getCharAt(res);\r
283     if (av.validCharWidth)\r
284     {\r
285 \r
286       charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
287       graphics.drawString(String.valueOf(s),\r
288                           charOffset + x1,\r
289                           (y1 + av.charHeight) - pady);\r
290     }\r
291     }\r
292 \r
293 }\r