9546dcbd0148a1f44a3f1f6b41b2a3e35b3eb990
[jalview.git] / src / jalview / appletgui / SequenceRenderer.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19
20 package jalview.appletgui;
21
22 import java.awt.*;
23
24 import jalview.datamodel.*;
25 import jalview.schemes.*;
26
27 public class SequenceRenderer
28 {
29   AlignViewport av;
30   FontMetrics fm;
31   boolean renderGaps = true;
32   SequenceGroup currentSequenceGroup = null;
33   SequenceGroup[] allGroups = null;
34   Color resBoxColour;
35   Graphics graphics;
36   boolean forOverview = false;
37
38   public SequenceRenderer(AlignViewport av)
39   {
40     this.av = av;
41   }
42
43   /**
44    * DOCUMENT ME!
45    *
46    * @param b DOCUMENT ME!
47    */
48   public void prepare(Graphics g, boolean renderGaps)
49   {
50       graphics = g;
51       fm = g.getFontMetrics();
52
53       this.renderGaps = renderGaps;
54     }
55
56   public Color getResidueBoxColour(SequenceI seq, int i)
57   {
58     allGroups = av.alignment.findAllGroups(seq);
59
60     if (inCurrentSequenceGroup(i))
61     {
62       if (currentSequenceGroup.getDisplayBoxes())
63       {
64         getBoxColour(currentSequenceGroup.cs, seq, i);
65       }
66     }
67     else if (av.getShowBoxes())
68     {
69         getBoxColour(av.globalColourScheme, seq, i);
70     }
71
72     return resBoxColour;
73     }
74
75   void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)
76   {
77     if (cs != null)
78     {
79       resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);
80     }
81     else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))
82     {
83         resBoxColour = Color.lightGray;
84     }
85     else
86     {
87       resBoxColour = Color.white;
88     }
89
90   }
91
92   public Color findSequenceColour(SequenceI seq, int i)
93   {
94     allGroups = av.alignment.findAllGroups(seq);
95     drawBoxes(seq, i,i, 0);
96     return resBoxColour;
97   }
98
99   public void drawSequence(SequenceI seq, SequenceGroup[] sg,
100                            int start, int end,  int y1)
101   {
102     allGroups = sg;
103
104     drawBoxes(seq, start, end,  y1);
105
106     if(av.validCharWidth)
107     {
108       drawText(seq, start, end, y1);
109     }
110   }
111
112   public void drawBoxes(SequenceI seq, int start, int end,  int y1)
113   {
114     int i = start;
115     int length = seq.getLength();
116
117     int curStart = -1;
118     int curWidth = av.charWidth;
119
120     Color tempColour = null;
121     while (i <= end)
122     {
123       resBoxColour = Color.white;
124       if(i < length)
125       {
126         if (inCurrentSequenceGroup(i))
127         {
128           if (currentSequenceGroup.getDisplayBoxes())
129           {
130             getBoxColour(currentSequenceGroup.cs, seq, i);
131           }
132         }
133         else if (av.getShowBoxes())
134         {
135           getBoxColour(av.getGlobalColourScheme(), seq, i);
136         }
137       }
138
139
140       if (resBoxColour != tempColour)
141       {
142         if (tempColour != null)
143         {
144           graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,
145                             av.charHeight);
146         }
147         graphics.setColor(resBoxColour);
148
149         curStart = i;
150         curWidth = av.charWidth;
151         tempColour = resBoxColour;
152
153       }
154       else
155       {
156         curWidth += av.charWidth;
157       }
158
159       i++;
160     }
161
162     graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, av.charHeight);
163   }
164
165   public void drawText(SequenceI seq, int start, int end, int y1)
166   {
167
168     y1 += av.charHeight - av.charHeight / 5;  // height/5 replaces pady
169
170     int charOffset = 0;
171
172     // Need to find the sequence position here.
173     if(end+1>=seq.getLength())
174           end = seq.getLength()-1;
175
176     char s = ' ';
177
178     for (int i = start; i <= end; i++)
179     {
180       graphics.setColor(Color.black);
181
182       s = seq.getCharAt(i);
183       if (!renderGaps && jalview.util.Comparison.isGap(s))
184       {
185         continue;
186       }
187
188       if (inCurrentSequenceGroup(i))
189       {
190         if (!currentSequenceGroup.getDisplayText())
191         {
192           continue;
193         }
194
195         if (currentSequenceGroup.getColourText())
196         {
197           getBoxColour(currentSequenceGroup.cs, seq, i);
198           graphics.setColor(resBoxColour.darker());
199         }
200       }
201       else
202       {
203         if (!av.getShowText())
204         {
205           continue;
206         }
207
208         if (av.getColourText())
209         {
210           getBoxColour(av.getGlobalColourScheme(), seq, i);
211           if (av.getShowBoxes())
212           {
213             graphics.setColor(resBoxColour.darker());
214           }
215           else
216           {
217             graphics.setColor(resBoxColour);
218           }
219         }
220       }
221
222       charOffset = (av.charWidth - fm.charWidth(s)) / 2;
223       graphics.drawString(String.valueOf(s),
224                          charOffset + av.charWidth * (i - start),
225                         y1 );
226     }
227
228   }
229
230   boolean inCurrentSequenceGroup(int res)
231   {
232     if (allGroups == null)
233     {
234       return false;
235     }
236
237     for (int i = 0; i < allGroups.length; i++)
238     {
239       if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)
240       {
241         currentSequenceGroup = allGroups[i];
242         return true;
243       }
244     }
245
246     return false;
247   }
248
249   public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1)
250   {
251     int pady = av.charHeight / 5;
252     int charOffset = 0;
253     graphics.setColor(Color.black);
254     graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), av.charHeight);
255     graphics.setColor(Color.white);
256
257     char s = '~';
258     // Need to find the sequence position here.
259     if(av.validCharWidth)
260     {
261       for (int i = start; i <= end; i++)
262       {
263         if (i < seq.getLength())
264         {
265           s = seq.getSequence().charAt(i);
266         }
267
268         charOffset = (av.charWidth - fm.charWidth(s)) / 2;
269         graphics.drawString(String.valueOf(s),
270                             charOffset + x1 + av.charWidth * (i - start),
271                             y1 + av.charHeight - pady);
272       }
273     }
274   }
275
276   public void drawCursor(SequenceI seq, int res, int x1, int y1)
277   {
278     int pady = av.charHeight / 5;
279     int charOffset = 0;
280     graphics.setColor(Color.black);
281     graphics.fillRect(x1, y1, av.charWidth, av.charHeight);
282     graphics.setColor(Color.white);
283
284     graphics.setColor(Color.white);
285
286     char s = seq.getCharAt(res);
287     if (av.validCharWidth)
288     {
289
290       charOffset = (av.charWidth - fm.charWidth(s)) / 2;
291       graphics.drawString(String.valueOf(s),
292                           charOffset + x1,
293                           (y1 + av.charHeight) - pady);
294     }
295     }
296
297 }