b8255ca23457a3f3572adf95b1deee7188050c14
[jalview.git] / src / jalview / appletgui / IdCanvas.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
26 public class IdCanvas
27     extends Panel
28 {
29   protected AlignViewport av;
30
31   protected boolean showScores = true;
32
33   protected int maxIdLength = -1;
34   protected String maxIdStr = null;
35   Image image;
36   Graphics gg;
37   int imgHeight = 0;
38   boolean fastPaint = false;
39
40   java.util.Vector searchResults;
41
42   public IdCanvas(AlignViewport av)
43   {
44     setLayout(null);
45     this.av = av;
46     PaintRefresher.Register(this, av.alignment);
47   }
48
49   public void drawIdString(Graphics gg, SequenceI s, int i, int starty,
50                            int ypos)
51   {
52     int charHeight = av.getCharHeight();
53
54     if (searchResults != null && searchResults.contains(s))
55     {
56       gg.setColor(Color.black);
57       gg.fillRect(0, ((i - starty) * charHeight) + ypos,
58                   getSize().width, charHeight);
59       gg.setColor(Color.white);
60     }
61     else if (av.getSelectionGroup() != null &&
62              av.getSelectionGroup().getSequences(false).contains(s))
63     {
64       gg.setColor(Color.lightGray);
65       gg.fillRect(0, ((i - starty) * charHeight) + ypos,
66                   getSize().width, charHeight);
67       gg.setColor(Color.white);
68     }
69     else
70     {
71       gg.setColor(s.getColor());
72       gg.fillRect(0, ((i - starty) * charHeight) + ypos,
73                   getSize().width, charHeight);
74       gg.setColor(Color.black);
75     }
76
77
78     gg.drawString( s.getDisplayId(av.getShowJVSuffix()), 0,
79                   ((i - starty) * charHeight) + ypos +
80                   charHeight - (charHeight / 5));
81
82     if (av.hasHiddenRows && av.showHiddenMarkers)
83           drawMarker(i, starty, ypos);
84
85   }
86
87   public void fastPaint(int vertical)
88   {
89     if (gg == null)
90     {
91       repaint();
92       return;
93     }
94
95     gg.copyArea(0, 0, getSize().width, imgHeight, 0, -vertical * av.charHeight);
96
97     int ss = av.startSeq, es = av.endSeq, transY = 0;
98     if (vertical > 0) // scroll down
99     {
100       ss = es - vertical;
101       if (ss < av.startSeq) // ie scrolling too fast, more than a page at a time
102       {
103         ss = av.startSeq;
104       }
105       else
106       {
107         transY = imgHeight - vertical * av.charHeight;
108       }
109     }
110     else if (vertical < 0)
111     {
112       es = ss - vertical;
113       if (es > av.endSeq)
114       {
115         es = av.endSeq;
116       }
117     }
118
119     gg.translate(0, transY);
120
121     drawIds(ss, es);
122
123     gg.translate(0, -transY);
124
125     fastPaint = true;
126     repaint();
127   }
128
129   public void update(Graphics g)
130   {
131     paint(g);
132   }
133
134   public void paint(Graphics g)
135   {
136     if (getSize().height < 0 || getSize().width < 0)
137     {
138       return;
139     }
140     if (fastPaint)
141     {
142       fastPaint = false;
143       g.drawImage(image, 0, 0, this);
144       return;
145     }
146
147     imgHeight = getSize().height;
148     imgHeight -= imgHeight % av.charHeight;
149
150     if (imgHeight < 1)
151     {
152       return;
153     }
154
155     if (image == null || imgHeight != image.getHeight(this))
156     {
157       image = createImage(getSize().width, imgHeight);
158       gg = image.getGraphics();
159       gg.setFont(av.getFont());
160     }
161
162     //Fill in the background
163     gg.setColor(Color.white);
164     Font italic = new Font(av.getFont().getName(), Font.ITALIC,
165                            av.getFont().getSize());
166     gg.setFont(italic);
167
168     gg.fillRect(0, 0, getSize().width, getSize().height);
169     drawIds(av.startSeq, av.endSeq);
170     g.drawImage(image, 0, 0, this);
171   }
172
173   void drawIds(int starty, int endy)
174   {
175     Font italic = new Font(av.getFont().getName(), Font.ITALIC,
176                            av.getFont().getSize());
177
178     gg.setFont(italic);
179
180     Color currentColor = Color.white;
181     Color currentTextColor = Color.black;
182
183     if (av.getWrapAlignment())
184     {
185       int maxwidth = av.alignment.getWidth();
186       int alheight = av.alignment.getHeight();
187
188       if (av.hasHiddenColumns)
189         maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
190
191       int annotationHeight = 0;
192       AnnotationLabels labels = null;
193
194       if (av.showAnnotation)
195       {
196         AnnotationPanel ap = new AnnotationPanel(av);
197         annotationHeight = ap.adjustPanelHeight();
198         labels = new AnnotationLabels(av);
199       }
200
201       int hgap = av.charHeight;
202       if (av.scaleAboveWrapped)
203         hgap += av.charHeight;
204
205       int cHeight = alheight * av.charHeight
206           + hgap
207           + annotationHeight;
208
209       int rowSize = av.getEndRes() - av.getStartRes();
210
211       // Draw the rest of the panels
212       for (int ypos = hgap, row = av.startRes;
213            (ypos <= getSize().height) && (row < maxwidth);
214            ypos += cHeight, row += rowSize)
215       {
216         for (int i = starty; i < alheight; i++)
217         {
218           if (av.hasHiddenRows)
219           {
220             setHiddenFont(i);
221           }
222           else
223             gg.setFont(italic);
224
225           SequenceI s = av.alignment.getSequenceAt(i);
226           drawIdString(gg, s, i, 0, ypos);
227         }
228
229         if (labels != null)
230         {
231           gg.translate(0, ypos + (alheight * av.charHeight));
232           labels.drawComponent(gg, getSize().width);
233           gg.translate(0, -ypos - (alheight * av.charHeight));
234         }
235
236       }
237     }
238     else
239     {
240       //Now draw the id strings
241
242       //Now draw the id strings
243       for (int i = starty; i < endy; i++)
244       {
245         if (av.hasHiddenRows)
246         {
247           setHiddenFont(i);
248         }
249
250         // Selected sequence colours
251         if ( (searchResults != null) &&
252             searchResults.contains(av.alignment.getSequenceAt(i)))
253         {
254           currentColor = Color.black;
255           currentTextColor = Color.white;
256         }
257         else if ( (av.getSelectionGroup() != null) &&
258                  av.getSelectionGroup().getSequences(false).contains(
259                      av.alignment.getSequenceAt(i)))
260         {
261           currentColor = Color.lightGray;
262           currentTextColor = Color.black;
263         }
264         else
265         {
266           currentColor = av.alignment.getSequenceAt(i).getColor();
267           currentTextColor = Color.black;
268         }
269
270         gg.setColor(currentColor);
271
272         gg.fillRect(0, (i - starty) * av.charHeight, getSize().width,
273                     av.charHeight);
274
275         gg.setColor(currentTextColor);
276
277         String string = av.alignment.getSequenceAt(i).getDisplayId(av.
278             getShowJVSuffix());
279
280         gg.drawString(string, 0,
281                       ( ( (i - starty) * av.charHeight) + av.charHeight) -
282                       (av.charHeight / 5));
283
284         if (av.hasHiddenRows && av.showHiddenMarkers)
285           drawMarker(i, starty, 0);
286       }
287     }
288   }
289
290   public void setHighlighted(java.util.Vector found)
291   {
292     searchResults = found;
293     repaint();
294   }
295
296   void drawMarker(int i, int starty, int yoffset)
297   {
298     int hiddenIndex = av.adjustForHiddenSeqs(i);
299     int lastIndex = av.adjustForHiddenSeqs(i - 1);
300     int nextIndex = av.adjustForHiddenSeqs(i + 1);
301
302     boolean below = (hiddenIndex > lastIndex + 1);
303     boolean above = (nextIndex>hiddenIndex+1);
304
305       gg.setColor(Color.blue);
306       if(below)
307       {
308         gg.fillPolygon(new int[]
309                        {getSize().width- av.charHeight,
310                        getSize().width- av.charHeight,
311                        getSize().width},
312                        new int[]
313                        {
314                        (i - starty) * av.charHeight +yoffset,
315                        (i - starty) * av.charHeight +yoffset+ av.charHeight / 4,
316                        (i - starty) * av.charHeight+yoffset
317         }, 3);
318       }
319       if(above)
320       {
321         gg.fillPolygon(new int[]
322                       {getSize().width- av.charHeight,
323                       getSize().width - av.charHeight,
324                       getSize().width },
325                       new int[]
326                       {
327                       (i - starty+1) * av.charHeight +yoffset,
328                       (i - starty+1) * av.charHeight +yoffset- av.charHeight / 4,
329                       (i - starty+1) * av.charHeight +yoffset
330        }, 3);
331
332       }
333   }
334
335   void setHiddenFont(int i)
336   {
337   /*  System.out.println(i+" "+av.alignment.getHeight());
338     if (av.alignment.getSequenceAt(i).getHiddenSequences() != null)
339       gg.setFont(new Font(av.getFont().getName(), Font.BOLD,
340                           av.getFont().getSize()));
341     else
342       gg.setFont(new Font(av.getFont().getName(), Font.ITALIC,
343                           av.getFont().getSize()));*/
344   }
345 }