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