updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / gui / 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 package jalview.gui;
20
21 import jalview.datamodel.*;
22
23 import jalview.schemes.*;
24
25 import java.awt.*;
26
27 /**
28  * DOCUMENT ME!
29  *
30  * @author $author$
31  * @version $Revision$
32  */
33 public class SequenceRenderer
34 {
35     AlignViewport av;
36     FontMetrics fm;
37     boolean renderGaps = true;
38     SequenceGroup currentSequenceGroup = null;
39     SequenceGroup[] allGroups = null;
40     Color resBoxColour;
41     Graphics graphics;
42     boolean monospacedFont;
43     boolean forOverview = false;
44
45     /**
46      * Creates a new SequenceRenderer object.
47      *
48      * @param av DOCUMENT ME!
49      */
50     public SequenceRenderer(AlignViewport av)
51     {
52         this.av = av;
53     }
54
55     /**
56      * DOCUMENT ME!
57      *
58      * @param b DOCUMENT ME!
59      */
60     public void prepare(Graphics g, boolean renderGaps)
61     {
62         graphics = g;
63         fm = g.getFontMetrics();
64
65         // If EPS graphics, stringWidth will be a double, not an int
66         double dwidth = fm.getStringBounds("M", g).getWidth();
67
68         monospacedFont =
69                (dwidth == fm.getStringBounds("|",g).getWidth()
70                && (float)av.charWidth == dwidth);
71
72         this.renderGaps = renderGaps;
73     }
74
75
76     public Color getResidueBoxColour(SequenceI seq, int i)
77     {
78       allGroups = av.alignment.findAllGroups(seq);
79
80       if (inCurrentSequenceGroup(i))
81       {
82         if (currentSequenceGroup.getDisplayBoxes())
83         {
84           getBoxColour(currentSequenceGroup.cs, seq, i);
85         }
86       }
87       else if (av.getShowBoxes())
88       {
89           getBoxColour(av.globalColourScheme, seq, i);
90       }
91
92       return resBoxColour;
93     }
94
95
96     /**
97      * DOCUMENT ME!
98      *
99      * @param cs DOCUMENT ME!
100      * @param seq DOCUMENT ME!
101      * @param i DOCUMENT ME!
102      */
103     void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)
104     {
105         if (cs != null)
106         {
107             resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);
108         }
109         else if(forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))
110         {
111             resBoxColour = Color.lightGray;
112         }
113         else
114         {
115           resBoxColour = Color.white;
116         }
117     }
118
119     /**
120      * DOCUMENT ME!
121      *
122      * @param g DOCUMENT ME!
123      * @param seq DOCUMENT ME!
124      * @param sg DOCUMENT ME!
125      * @param start DOCUMENT ME!
126      * @param end DOCUMENT ME!
127      * @param x1 DOCUMENT ME!
128      * @param y1 DOCUMENT ME!
129      * @param width DOCUMENT ME!
130      * @param height DOCUMENT ME!
131      */
132     public void drawSequence(SequenceI seq, SequenceGroup[] sg,
133         int start, int end, int y1)
134     {
135         allGroups = sg;
136
137         drawBoxes(seq, start, end, y1);
138
139         if (av.validCharWidth)
140           drawText(seq, start, end, y1);
141     }
142
143     /**
144      * DOCUMENT ME!
145      *
146      * @param seq DOCUMENT ME!
147      * @param start DOCUMENT ME!
148      * @param end DOCUMENT ME!
149      * @param x1 DOCUMENT ME!
150      * @param y1 DOCUMENT ME!
151      * @param width DOCUMENT ME!
152      * @param height DOCUMENT ME!
153      */
154     public synchronized void drawBoxes(SequenceI seq, int start, int end, int y1)
155     {
156       int i = start;
157       int length = seq.getLength();
158
159       int curStart = -1;
160       int curWidth = av.charWidth;
161
162       Color tempColour = null;
163
164       while (i <= end)
165       {
166         resBoxColour = Color.white;
167
168         if (i < length)
169         {
170           if (inCurrentSequenceGroup(i))
171           {
172             if (currentSequenceGroup.getDisplayBoxes())
173             {
174               getBoxColour(currentSequenceGroup.cs, seq, i);
175             }
176           }
177           else if (av.getShowBoxes())
178           {
179             getBoxColour(av.globalColourScheme, seq, i);
180           }
181
182         }
183
184           if (resBoxColour != tempColour)
185           {
186               if (tempColour != null)
187               {
188                   graphics.fillRect( av.charWidth * (curStart - start), y1,
189                       curWidth, av.charHeight);
190               }
191
192               graphics.setColor(resBoxColour);
193
194               curStart = i;
195               curWidth = av.charWidth;
196               tempColour = resBoxColour;
197           }
198           else
199           {
200               curWidth += av.charWidth;
201           }
202
203           i++;
204       }
205
206       graphics.fillRect( av.charWidth * (curStart - start), y1, curWidth,
207           av.charHeight);
208
209     }
210
211     /**
212      * DOCUMENT ME!
213      *
214      * @param seq DOCUMENT ME!
215      * @param start DOCUMENT ME!
216      * @param end DOCUMENT ME!
217      * @param x1 DOCUMENT ME!
218      * @param y1 DOCUMENT ME!
219      * @param width DOCUMENT ME!
220      * @param height DOCUMENT ME!
221      */
222     public void drawText(SequenceI seq, int start, int end, int y1)
223     {
224       y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady
225       int charOffset = 0;
226       char s;
227
228         if(end+1>=seq.getLength())
229           end = seq.getLength()-1;
230         graphics.setColor(Color.black);
231
232
233         if(monospacedFont && av.showText && allGroups.length==0 && !av.getColourText())
234         {
235           if(av.renderGaps)
236           graphics.drawString(seq.getSequence(start, end + 1), 0, y1);
237          else
238          {
239            char gap = av.getGapCharacter();
240            graphics.drawString( seq.getSequence(start, end+1).replace(gap, ' '), 0, y1);
241          }
242         }
243         else
244         {
245           for (int i = start; i <= end; i++)
246           {
247             graphics.setColor(Color.black);
248             s = seq.getCharAt(i);
249             if (!renderGaps && jalview.util.Comparison.isGap(s))
250             {
251               continue;
252             }
253
254             if (inCurrentSequenceGroup(i))
255             {
256               if (!currentSequenceGroup.getDisplayText())
257               {
258                 continue;
259               }
260
261               if (currentSequenceGroup.getColourText())
262               {
263                 getBoxColour(currentSequenceGroup.cs, seq, i);
264                 graphics.setColor(resBoxColour.darker());
265               }
266             }
267             else
268             {
269               if (!av.getShowText())
270               {
271                 continue;
272               }
273
274               if (av.getColourText())
275               {
276                 getBoxColour(av.globalColourScheme, seq, i);
277
278                 if (av.getShowBoxes())
279                 {
280                   graphics.setColor(resBoxColour.darker());
281                 }
282                 else
283                 {
284                   graphics.setColor(resBoxColour);
285                 }
286               }
287             }
288
289             charOffset = (av.charWidth - fm.charWidth(s)) / 2;
290
291           //  System.out.print(s);
292             graphics.drawString(String.valueOf(s),
293                                 charOffset + av.charWidth * (i - start),
294                                 y1);
295
296           }
297         //  System.out.println("\n");
298         }
299     }
300
301     /**
302      * DOCUMENT ME!
303      *
304      * @param res DOCUMENT ME!
305      *
306      * @return DOCUMENT ME!
307      */
308     boolean inCurrentSequenceGroup(int res)
309     {
310         if (allGroups == null)
311         {
312             return false;
313         }
314
315         for (int i = 0; i < allGroups.length; i++)
316         {
317             if ((allGroups[i].getStartRes() <= res) &&
318                     (allGroups[i].getEndRes() >= res))
319             {
320                 currentSequenceGroup = allGroups[i];
321
322                 return true;
323             }
324         }
325
326         return false;
327     }
328
329     /**
330      * DOCUMENT ME!
331      *
332      * @param seq DOCUMENT ME!
333      * @param start DOCUMENT ME!
334      * @param end DOCUMENT ME!
335      * @param x1 DOCUMENT ME!
336      * @param y1 DOCUMENT ME!
337      * @param width DOCUMENT ME!
338      * @param height DOCUMENT ME!
339      */
340     public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1)
341     {
342         int pady = av.charHeight / 5;
343         int charOffset = 0;
344         graphics.setColor(Color.BLACK);
345         graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), av.charHeight);
346         graphics.setColor(Color.white);
347
348         char s = '~';
349
350         // Need to find the sequence position here.
351         if(av.validCharWidth)
352         {
353           for (int i = start; i <= end; i++)
354           {
355             if (i < seq.getLength())
356             {
357               s = seq.getSequence().charAt(i);
358             }
359
360             charOffset = (av.charWidth - fm.charWidth(s)) / 2;
361             graphics.drawString(String.valueOf(s),
362                                 charOffset + x1 + (av.charWidth * (i - start)),
363                                 (y1 + av.charHeight) - pady);
364           }
365         }
366     }
367
368     public void drawCursor(SequenceI seq, int res, int x1, int y1)
369     {
370       int pady = av.charHeight / 5;
371       int charOffset = 0;
372       graphics.setColor(Color.black);
373       graphics.fillRect(x1, y1, av.charWidth, av.charHeight);
374
375       if(av.validCharWidth)
376       {
377         graphics.setColor(Color.white);
378
379         char s = seq.getCharAt(res);
380
381         charOffset = (av.charWidth - fm.charWidth(s)) / 2;
382         graphics.drawString(String.valueOf(s),
383                             charOffset + x1,
384                             (y1 + av.charHeight) - pady);
385       }
386
387     }
388 }