Keyboard editing added to applet
[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     fm = g.getFontMetrics();\r
101     drawText(seq, start, end, y1);\r
102 \r
103   }\r
104 \r
105   public void drawBoxes(SequenceI seq, int start, int end,  int y1)\r
106   {\r
107     int i = start;\r
108     int length = seq.getLength();\r
109 \r
110     int curStart = -1;\r
111     int curWidth = av.charWidth;\r
112 \r
113     Color tempColour = null;\r
114     while (i <= end)\r
115     {\r
116       resBoxColour = Color.white;\r
117       if(i < length)\r
118       {\r
119         if (inCurrentSequenceGroup(i))\r
120         {\r
121           if (currentSequenceGroup.getDisplayBoxes())\r
122           {\r
123             getBoxColour(currentSequenceGroup.cs, seq, i);\r
124           }\r
125         }\r
126         else if (av.getShowBoxes())\r
127         {\r
128           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
129         }\r
130       }\r
131 \r
132 \r
133       if (resBoxColour != tempColour)\r
134       {\r
135         if (tempColour != null)\r
136         {\r
137           graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,\r
138                             av.charHeight);\r
139         }\r
140         graphics.setColor(resBoxColour);\r
141 \r
142         curStart = i;\r
143         curWidth = av.charWidth;\r
144         tempColour = resBoxColour;\r
145 \r
146       }\r
147       else\r
148       {\r
149         curWidth += av.charWidth;\r
150       }\r
151 \r
152       i++;\r
153     }\r
154 \r
155     graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, av.charHeight);\r
156   }\r
157 \r
158   public void drawText(SequenceI seq, int start, int end, int y1)\r
159   {\r
160 \r
161     y1 += av.charHeight - av.charHeight / 5;  // height/5 replaces pady\r
162 \r
163     int charOffset = 0;\r
164 \r
165     // Need to find the sequence position here.\r
166     if(end+1>=seq.getLength())\r
167           end = seq.getLength()-1;\r
168 \r
169     char s = ' ';\r
170 \r
171     for (int i = start; i <= end; i++)\r
172     {\r
173       graphics.setColor(Color.black);\r
174 \r
175       s = seq.getCharAt(i);\r
176       if (!renderGaps && jalview.util.Comparison.isGap(s))\r
177       {\r
178         continue;\r
179       }\r
180 \r
181       if (inCurrentSequenceGroup(i))\r
182       {\r
183         if (!currentSequenceGroup.getDisplayText())\r
184         {\r
185           continue;\r
186         }\r
187 \r
188         if (currentSequenceGroup.getColourText())\r
189         {\r
190           getBoxColour(currentSequenceGroup.cs, seq, i);\r
191           graphics.setColor(resBoxColour.darker());\r
192         }\r
193       }\r
194       else\r
195       {\r
196         if (!av.getShowText())\r
197         {\r
198           continue;\r
199         }\r
200 \r
201         if (av.getColourText())\r
202         {\r
203           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
204           if (av.getShowBoxes())\r
205           {\r
206             graphics.setColor(resBoxColour.darker());\r
207           }\r
208           else\r
209           {\r
210             graphics.setColor(resBoxColour);\r
211           }\r
212         }\r
213       }\r
214 \r
215       charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
216       graphics.drawString(String.valueOf(s),\r
217                          charOffset + av.charWidth * (i - start),\r
218                         y1 );\r
219     }\r
220 \r
221   }\r
222 \r
223   boolean inCurrentSequenceGroup(int res)\r
224   {\r
225     if (allGroups == null)\r
226     {\r
227       return false;\r
228     }\r
229 \r
230     for (int i = 0; i < allGroups.length; i++)\r
231     {\r
232       if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)\r
233       {\r
234         currentSequenceGroup = allGroups[i];\r
235         return true;\r
236       }\r
237     }\r
238 \r
239     return false;\r
240   }\r
241 \r
242   public void drawHighlightedText(SequenceI seq, int start, int end, int x1,\r
243                                   int y1, int width, int height)\r
244   {\r
245     int pady = height / 5;\r
246     int charOffset = 0;\r
247     graphics.setColor(Color.black);\r
248     graphics.fillRect(x1, y1, width * (end - start + 1), height);\r
249     graphics.setColor(Color.white);\r
250 \r
251     char s = '~';\r
252     // Need to find the sequence position here.\r
253     for (int i = start; i <= end; i++)\r
254     {\r
255       if (i < seq.getLength())\r
256       {\r
257         s = seq.getSequence().charAt(i);\r
258       }\r
259 \r
260       charOffset = (width - fm.charWidth(s)) / 2;\r
261       graphics.drawString(String.valueOf(s),\r
262                           charOffset + x1 + width * (i - start),\r
263                           y1 + height - pady);\r
264     }\r
265   }\r
266 \r
267   public void drawCursor(SequenceI seq, int res, int x1, int y1)\r
268   {\r
269     int pady = av.charHeight / 5;\r
270     int charOffset = 0;\r
271     graphics.setColor(Color.black);\r
272     graphics.fillRect(x1, y1, av.charWidth, av.charHeight);\r
273     graphics.setColor(Color.white);\r
274 \r
275     graphics.setColor(Color.white);\r
276 \r
277     char s = seq.getCharAt(res);\r
278 \r
279     charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
280     graphics.drawString(String.valueOf(s),\r
281               charOffset + x1,\r
282               (y1 + av.charHeight) - pady);\r
283     }\r
284 \r
285 }\r