Applet files
[jalview.git] / src / jalview / appletgui / AnnotationPanel.java
1 package jalview.appletgui;\r
2 \r
3 import jalview.datamodel.*;\r
4 \r
5 import java.awt.*;\r
6 import java.awt.event.*;\r
7 import java.util.*;\r
8 \r
9 public class AnnotationPanel extends Panel implements AdjustmentListener\r
10 {\r
11   AlignViewport av;\r
12   AlignmentPanel ap;\r
13   int activeRow =-1;\r
14 \r
15   Vector activeRes;\r
16   static String HELIX ="Helix";\r
17   static String SHEET ="Sheet";\r
18   static String LABEL ="Label";\r
19   static String REMOVE="Remove Annotation";\r
20   static String COLOUR="Colour";\r
21   static Color HELIX_COLOUR = Color.red.darker();\r
22   static Color SHEET_COLOUR = Color.green.darker().darker();\r
23 \r
24 \r
25   Image image;\r
26   Graphics gg;\r
27   FontMetrics fm;\r
28   int imgWidth=0;\r
29 \r
30   boolean fastPaint = false;\r
31 \r
32   public static int GRAPH_HEIGHT = 40;\r
33 \r
34 \r
35 \r
36   public AnnotationPanel(AlignmentPanel ap)\r
37   {\r
38     this.ap = ap;\r
39     av = ap.av;\r
40     this.setLayout(null);\r
41     adjustPanelHeight();\r
42 \r
43 \r
44     ap.annotationScroller.getVAdjustable().addAdjustmentListener( this );\r
45   }\r
46 \r
47   public void adjustmentValueChanged(AdjustmentEvent evt)\r
48   {\r
49     ap.alabels.setScrollOffset( -evt.getValue() );\r
50   }\r
51 \r
52   public void adjustPanelHeight()\r
53   {\r
54     // setHeight of panels\r
55     AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
56     int height = 0;\r
57     if(aa!=null)\r
58     for (int i = 0; i < aa.length; i++)\r
59     {\r
60       if(!aa[i].visible)\r
61         continue;\r
62 \r
63       aa[i].height = 0;\r
64 \r
65       if(aa[i].hasText)\r
66         aa[i].height += av.charHeight;\r
67       if (aa[i].hasIcons)\r
68         aa[i].height += 16;\r
69 \r
70       if (aa[i].isGraph)\r
71         aa[i].height += GRAPH_HEIGHT;\r
72 \r
73       if(aa[i].height==0)\r
74         aa[i].height = 20;\r
75       height += aa[i].height;\r
76     }\r
77   else height=20;\r
78    this.setSize(new Dimension(1, height));\r
79 \r
80   }\r
81 \r
82   public void addEditableColumn(int i)\r
83   {\r
84     if(activeRow==-1)\r
85     {\r
86       AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();\r
87       for(int j=0; j<aa.length; j++)\r
88         if(aa[j].editable)\r
89         {\r
90           activeRow = j;\r
91           break;\r
92         }\r
93     }\r
94 \r
95     if(activeRes==null)\r
96     {\r
97       activeRes = new Vector();\r
98       activeRes.addElement(String.valueOf(i));\r
99       return;\r
100     }\r
101 \r
102     activeRes.addElement(String.valueOf(i));\r
103 \r
104   }\r
105 \r
106   public void update(Graphics g)\r
107   {\r
108     paint(g);\r
109   }\r
110 \r
111   public void paint(Graphics g)\r
112   {\r
113     imgWidth = (av.endRes-av.startRes+1) *av.charWidth;\r
114 \r
115     if(image==null || imgWidth != image.getWidth(this))\r
116       {\r
117         image = createImage(imgWidth, ap.annotationPanel.getSize().height);\r
118         gg = image.getGraphics();\r
119         gg.setFont(av.getFont());\r
120         fm = gg.getFontMetrics();\r
121         fastPaint = false;\r
122     }\r
123 \r
124     if(fastPaint)\r
125     {\r
126       g.drawImage(image, 0, 0, this);\r
127       fastPaint = false;\r
128       return;\r
129     }\r
130 \r
131     drawComponent( gg, av.startRes, av.endRes+1);\r
132     g.drawImage( image, 0, 0, this);\r
133 \r
134   }\r
135 \r
136   public void fastPaint(int horizontal)\r
137 {\r
138   if( horizontal == 0\r
139      || av.alignment.getAlignmentAnnotation()==null\r
140      || av.alignment.getAlignmentAnnotation().length<1\r
141     )\r
142   {\r
143     repaint();\r
144     return;\r
145   }\r
146 \r
147   gg.copyArea( 0,0, imgWidth, getSize().height, -horizontal*av.charWidth, 0 );\r
148   int sr=av.startRes, er=av.endRes+1, transX=0;\r
149 \r
150   if(horizontal>0) // scrollbar pulled right, image to the left\r
151   {\r
152     transX =  (er-sr-horizontal)*av.charWidth;\r
153     sr = er - horizontal ;\r
154   }\r
155   else if(horizontal<0)\r
156   {\r
157     er = sr-horizontal;\r
158   }\r
159 \r
160 \r
161   gg.translate(transX, 0);\r
162 \r
163   drawComponent(gg, sr, er);\r
164 \r
165   gg.translate( -transX, 0 );\r
166 \r
167   fastPaint = true;\r
168   repaint();\r
169 }\r
170 \r
171 \r
172   public void drawComponent(Graphics g, int startRes, int endRes)\r
173   {\r
174     g.setColor(Color.white);\r
175     g.fillRect(0,0,(endRes-startRes) *av.charWidth, getSize().height);\r
176     if(av.alignment.getAlignmentAnnotation()==null || av.alignment.getAlignmentAnnotation().length<1)\r
177     {\r
178       g.setColor(Color.white);\r
179       g.fillRect(0,0,getSize().width, getSize().height);\r
180       g.setColor(Color.black);\r
181       g.drawString("Alignment has no annotations",20,15);\r
182       return;\r
183     }\r
184 \r
185     AlignmentAnnotation [] aa = av.alignment.getAlignmentAnnotation();\r
186 \r
187     int j, x=0, y=0;\r
188     char [] lastSS = new char[aa.length];\r
189     int  [] lastSSX= new int[aa.length] ;\r
190     int iconOffset = av.charHeight/2;\r
191     boolean validRes = false;\r
192     //\u03B2 \u03B1\r
193 \r
194     for(int i=0; i<aa.length; i++)\r
195     {\r
196       AlignmentAnnotation row = aa[i];\r
197       if(!row.visible)\r
198         continue;\r
199 \r
200       if(row.isGraph)\r
201       {\r
202         // this is so that we draw the characters below the graph\r
203         y += row.height;\r
204         if(row.hasText)\r
205           y -= av.charHeight;\r
206       }\r
207       if(row.hasText)\r
208         iconOffset = av.charHeight/2;\r
209       else\r
210         iconOffset = 0;\r
211 \r
212       for(j=startRes; j<endRes; j++)\r
213       {\r
214         validRes = row.annotations[j]==null?false:true;\r
215 \r
216        x = (j-startRes)*av.charWidth;\r
217 \r
218 \r
219        if(activeRow==i)\r
220        {\r
221 \r
222          g.setColor(Color.red);\r
223 \r
224          if(activeRes!=null)\r
225            for (int n = 0; n < activeRes.size(); n++)\r
226            {\r
227              int v = Integer.parseInt(activeRes.elementAt(n).toString()) ;\r
228              if (v == j)\r
229                g.fillRect( (j-startRes) * av.charWidth, y, av.charWidth, row.height);\r
230            }\r
231        }\r
232 \r
233 \r
234 \r
235        if(validRes && row.annotations[j].displayCharacter.length()>0)\r
236        {\r
237          int charOffset = (av.charWidth - fm.charWidth(row.annotations[j].displayCharacter.charAt(0)))/2;\r
238          g.setColor( row.annotations[j].colour);\r
239           if(j==0)\r
240           {\r
241             if (row.annotations[0].secondaryStructure == 'H'\r
242                 || row.annotations[0].secondaryStructure == 'E')\r
243               g.drawString(row.annotations[j].displayCharacter, x,\r
244                            y + iconOffset + 2);\r
245           }\r
246          else if( (row.annotations[j].secondaryStructure=='H'\r
247                || row.annotations[j].secondaryStructure=='E') &&\r
248                (row.annotations[j-1]==null ||\r
249                 row.annotations[j].secondaryStructure!=row.annotations[j-1].secondaryStructure))\r
250 \r
251         g.drawString(row.annotations[j].displayCharacter, x, y + iconOffset + 2);\r
252 \r
253         if(!row.hasIcons)\r
254             g.drawString(row.annotations[j].displayCharacter, x + charOffset,\r
255                          y + iconOffset + 2);\r
256        }\r
257 \r
258        if(row.hasIcons)\r
259        if(!validRes || row.annotations[j].secondaryStructure!=lastSS[i])\r
260        {\r
261          switch (lastSS[i])\r
262          {\r
263            case 'H':\r
264              g.setColor(HELIX_COLOUR);\r
265              g.fillRoundRect(lastSSX[i], y+4 + iconOffset, x-lastSSX[i], 7, 8, 8);\r
266              break;\r
267            case 'E':\r
268              g.setColor(SHEET_COLOUR);\r
269              g.fillRect(lastSSX[i], y + 4 + iconOffset, x-lastSSX[i]-4, 7);\r
270              g.fillPolygon(new int[] {x - 4, x- 4, x }\r
271                            , new int[]{y+ iconOffset, y + 14+ iconOffset, y + 8+ iconOffset}, 3);\r
272              break;\r
273            case 'C':\r
274              break;\r
275            default :\r
276              g.setColor(Color.gray);\r
277              g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);\r
278              break;\r
279          }\r
280 \r
281          if(validRes)\r
282            lastSS[i] = row.annotations[j].secondaryStructure;\r
283           else\r
284             lastSS[i] = ' ';\r
285          lastSSX[i] = x;\r
286        }\r
287 \r
288        if (validRes && row.isGraph)\r
289        {\r
290          g.setColor(new Color(0,0,180));\r
291          int height = (int)((row.annotations[j].value / row.graphMax)*GRAPH_HEIGHT);\r
292 \r
293          if(row.windowLength>1)\r
294          {\r
295            int total =0;\r
296            for(int i2=j- (row.windowLength/2); i2<j+(row.windowLength/2); i2++)\r
297            {\r
298              if(i2<0 || i2>=av.alignment.getWidth())\r
299                continue;\r
300 \r
301              total += row.annotations[i2].value;\r
302            }\r
303 \r
304            total/=row.windowLength;\r
305            height = (int)( (total / row.graphMax) *GRAPH_HEIGHT);\r
306 \r
307          }\r
308          g.setColor(row.annotations[j].colour);\r
309          g.fillRect(x, y-height, av.charWidth, height );\r
310        }\r
311 \r
312 \r
313       }\r
314 \r
315       x+=av.charWidth;\r
316 \r
317       if(row.hasIcons)\r
318       switch (lastSS[i])\r
319       {\r
320         case 'H':\r
321           g.setColor(HELIX_COLOUR);\r
322           g.fillRoundRect(lastSSX[i], y+4+ iconOffset, x - lastSSX[i], 7, 8, 8);\r
323           break;\r
324         case 'E':\r
325           g.setColor(SHEET_COLOUR);\r
326           g.fillRect(lastSSX[i], y + 4+ iconOffset, x - lastSSX[i] - 4, 7);\r
327           g.fillPolygon(new int[]\r
328                         {x - 4, x - 4, x}\r
329                         , new int[]\r
330                         {y + iconOffset, y + 14+ iconOffset, y + 7+ iconOffset}\r
331                         , 3);\r
332           break;\r
333         case 'C':\r
334           break;\r
335         default:\r
336           g.setColor(Color.gray);\r
337           g.fillRect(lastSSX[i], y+6+ iconOffset, x-lastSSX[i], 2);\r
338           break;\r
339 \r
340       }\r
341 \r
342        if(row.isGraph && row.hasText)\r
343          y+=av.charHeight;\r
344        if(!row.isGraph)\r
345           y+=aa[i].height;\r
346     }\r
347   }\r
348 \r
349   // used by overview window\r
350   public void drawGraph(Graphics g, AlignmentAnnotation aa,int width, int y)\r
351   {\r
352     g.setColor(Color.white);\r
353     g.fillRect(0,0,width, y);\r
354     g.setColor(new Color(0,0,180));\r
355     int x = 0;\r
356     for(int j=0; j<aa.annotations.length; j++)\r
357     {\r
358       g.setColor(new Color(0, 0, 180));\r
359       int height = (int) ( (aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT );\r
360       g.fillRect(x, y - height, av.charWidth, height);\r
361       x+=av.charWidth;\r
362     }\r
363   }\r
364 }\r