Annotations.Graph can be bargraph, linegraph
[jalview.git] / src / jalview / gui / AnnotationLabels.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import java.awt.*;\r
24 import java.awt.event.*;\r
25 import java.awt.image.*;\r
26 \r
27 import javax.swing.*;\r
28 \r
29 \r
30 /**\r
31  * DOCUMENT ME!\r
32  *\r
33  * @author $author$\r
34  * @version $Revision$\r
35  */\r
36 public class AnnotationLabels extends JPanel implements MouseListener,\r
37     MouseMotionListener, ActionListener\r
38 {\r
39     static String ADDNEW = "Add New Row";\r
40     static String HIDE = "Hide This Row";\r
41     static String DELETE = "Delete This Row";\r
42     static String SHOWALL = "Show All Hidden Rows";\r
43     static String OUTPUT_TEXT = "Show Values In Textbox";\r
44     boolean active = false;\r
45     Image image;\r
46     AlignmentPanel ap;\r
47     AlignViewport av;\r
48     boolean resizing = false;\r
49     int oldY;\r
50     int mouseX;\r
51     int selectedRow = 0;\r
52     int scrollOffset = 0;\r
53     Font font = new Font("Arial", Font.PLAIN, 11);\r
54 \r
55 \r
56     /**\r
57      * Creates a new AnnotationLabels object.\r
58      *\r
59      * @param ap DOCUMENT ME!\r
60      */\r
61     public AnnotationLabels(AlignmentPanel ap)\r
62     {\r
63         this.ap = ap;\r
64         av = ap.av;\r
65 \r
66         java.net.URL url = getClass().getResource("/images/idwidth.gif");\r
67         Image temp = null;\r
68 \r
69         if (url != null)\r
70         {\r
71             temp = java.awt.Toolkit.getDefaultToolkit().createImage(url);\r
72         }\r
73 \r
74         try\r
75         {\r
76             MediaTracker mt = new MediaTracker(this);\r
77             mt.addImage(temp, 0);\r
78             mt.waitForID(0);\r
79         }\r
80         catch (Exception ex)\r
81         {\r
82         }\r
83 \r
84         BufferedImage bi = new BufferedImage(temp.getHeight(this),\r
85                 temp.getWidth(this), BufferedImage.TYPE_INT_RGB);\r
86         Graphics2D g = (Graphics2D) bi.getGraphics();\r
87         g.rotate(Math.toRadians(90));\r
88         g.drawImage(temp, 0, -bi.getWidth(this), this);\r
89         image = (Image) bi;\r
90 \r
91         addMouseListener(this);\r
92         addMouseMotionListener(this);\r
93     }\r
94 \r
95     public AnnotationLabels(AlignViewport av)\r
96     {\r
97       this.av = av;\r
98     }\r
99 \r
100     /**\r
101      * DOCUMENT ME!\r
102      *\r
103      * @param y DOCUMENT ME!\r
104      */\r
105     public void setScrollOffset(int y)\r
106     {\r
107         scrollOffset = y;\r
108         repaint();\r
109     }\r
110 \r
111     /**\r
112      * DOCUMENT ME!\r
113      *\r
114      * @param evt DOCUMENT ME!\r
115      */\r
116     public void actionPerformed(ActionEvent evt)\r
117     {\r
118         int dif = 0;\r
119         AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
120 \r
121         if (evt.getActionCommand().equals(ADDNEW))\r
122         {\r
123             String label = JOptionPane.showInputDialog(this,\r
124                     "Label for annotation");\r
125 \r
126             if (label == null)\r
127             {\r
128                 label = "";\r
129             }\r
130 \r
131             ap.av.alignment.addAnnotation(new AlignmentAnnotation(label,\r
132                     "New description",\r
133                     new Annotation[ap.av.alignment.getWidth()]));\r
134 \r
135             dif = aa[aa.length - 1].height;\r
136         }\r
137         else if (evt.getActionCommand().equals(HIDE))\r
138         {\r
139             aa[selectedRow].visible = false;\r
140 \r
141             if (aa[selectedRow].label.equals("Conservation"))\r
142             {\r
143                 ap.av.showConservation = false;\r
144             }\r
145 \r
146             if (aa[selectedRow].label.equals("Quality"))\r
147             {\r
148                 ap.av.showQuality = false;\r
149             }\r
150 \r
151             if (aa[selectedRow].label.equals("Consensus"))\r
152             {\r
153                 ap.av.showIdentity = false;\r
154             }\r
155 \r
156             dif = aa[selectedRow].height * -1;\r
157         }\r
158         else if (evt.getActionCommand().equals(DELETE))\r
159         {\r
160             ap.av.alignment.deleteAnnotation(aa[selectedRow]);\r
161             dif = aa[selectedRow].height * -1;\r
162         }\r
163         else if (evt.getActionCommand().equals(SHOWALL))\r
164         {\r
165             for (int i = 0; i < aa.length; i++)\r
166             {\r
167                 if (!aa[i].visible)\r
168                 {\r
169                     dif += aa[i].height;\r
170                     aa[i].visible = true;\r
171                 }\r
172             }\r
173         }\r
174         else if (evt.getActionCommand().equals(OUTPUT_TEXT))\r
175         {\r
176             CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
177             Desktop.addInternalFrame(cap,\r
178                 ap.alignFrame.getTitle() + " - " + aa[selectedRow].label, 500,\r
179                 100);\r
180             cap.setText(aa[selectedRow].toString());\r
181         }\r
182 \r
183 \r
184         ap.annotationPanel.adjustPanelHeight();\r
185 \r
186         Dimension d = ap.annotationScroller.getPreferredSize();\r
187         ap.annotationScroller.setPreferredSize(new Dimension(d.width,\r
188                 d.height + dif));\r
189         d = ap.annotationSpaceFillerHolder.getPreferredSize();\r
190         ap.annotationSpaceFillerHolder.setPreferredSize(new Dimension(d.width,\r
191                 d.height + dif));\r
192 \r
193         ap.addNotify();\r
194     }\r
195 \r
196     /**\r
197      * DOCUMENT ME!\r
198      *\r
199      * @param evt DOCUMENT ME!\r
200      */\r
201     public void mousePressed(MouseEvent evt)\r
202     {\r
203         oldY = evt.getY();\r
204     }\r
205 \r
206     /**\r
207      * DOCUMENT ME!\r
208      *\r
209      * @param evt DOCUMENT ME!\r
210      */\r
211     public void mouseReleased(MouseEvent evt)\r
212     {\r
213         active = false;\r
214         repaint();\r
215     }\r
216 \r
217     /**\r
218      * DOCUMENT ME!\r
219      *\r
220      * @param evt DOCUMENT ME!\r
221      */\r
222     public void mouseEntered(MouseEvent evt)\r
223     {\r
224         active = true;\r
225         repaint();\r
226     }\r
227 \r
228     /**\r
229      * DOCUMENT ME!\r
230      *\r
231      * @param evt DOCUMENT ME!\r
232      */\r
233     public void mouseExited(MouseEvent evt)\r
234     {\r
235         active = false;\r
236         repaint();\r
237     }\r
238 \r
239     /**\r
240      * DOCUMENT ME!\r
241      *\r
242      * @param evt DOCUMENT ME!\r
243      */\r
244     public void mouseDragged(MouseEvent evt)\r
245     {\r
246         active = true;\r
247 \r
248         Dimension d = ap.annotationScroller.getPreferredSize();\r
249         int dif = evt.getY() - oldY;\r
250 \r
251         dif /= ap.av.charHeight;\r
252         dif *= ap.av.charHeight;\r
253 \r
254         if ((d.height - dif) > 20)\r
255         {\r
256             ap.annotationScroller.setPreferredSize(new Dimension(d.width,\r
257                     d.height - dif));\r
258             d = ap.annotationSpaceFillerHolder.getPreferredSize();\r
259             ap.annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
260                     d.width, d.height - dif));\r
261             ap.repaint();\r
262         }\r
263 \r
264         ap.addNotify();\r
265     }\r
266 \r
267     /**\r
268      * DOCUMENT ME!\r
269      *\r
270      * @param evt DOCUMENT ME!\r
271      */\r
272     public void mouseMoved(MouseEvent evt)\r
273     {\r
274     }\r
275 \r
276     /**\r
277      * DOCUMENT ME!\r
278      *\r
279      * @param evt DOCUMENT ME!\r
280      */\r
281     public void mouseClicked(MouseEvent evt)\r
282     {\r
283         int y = evt.getY() - scrollOffset;\r
284         AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();\r
285 \r
286         if ((aa == null) || (aa.length == 0))\r
287         {\r
288             JPopupMenu pop = new JPopupMenu("Annotations");\r
289             JMenuItem item = new JMenuItem(ADDNEW);\r
290             item.addActionListener(this);\r
291             pop.add(item);\r
292             pop.show(this, evt.getX(), evt.getY());\r
293 \r
294             return;\r
295         }\r
296 \r
297         int height = 0;\r
298 \r
299         for (int i = 0; i < aa.length; i++)\r
300         {\r
301             if (!aa[i].visible)\r
302             {\r
303                 continue;\r
304             }\r
305 \r
306             height += aa[i].height;\r
307 \r
308             if (y < height)\r
309             {\r
310                 selectedRow = i;\r
311 \r
312                 break;\r
313             }\r
314         }\r
315 \r
316         JPopupMenu pop = new JPopupMenu("Annotations");\r
317         JMenuItem item = new JMenuItem(ADDNEW);\r
318         item.addActionListener(this);\r
319         pop.add(item);\r
320         item = new JMenuItem(HIDE);\r
321         item.addActionListener(this);\r
322         pop.add(item);\r
323         item = new JMenuItem(DELETE);\r
324         item.addActionListener(this);\r
325         pop.add(item);\r
326         item = new JMenuItem(SHOWALL);\r
327         item.addActionListener(this);\r
328         pop.add(item);\r
329         item = new JMenuItem(OUTPUT_TEXT);\r
330         item.addActionListener(this);\r
331         pop.add(item);\r
332 \r
333         if (aa[selectedRow].label.equals("Consensus"))\r
334         {\r
335           pop.addSeparator();\r
336           final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(\r
337               "Ignore Gaps In Consensus",\r
338               ap.av.getIgnoreGapsConsensus());\r
339           cbmi.addActionListener(new ActionListener()\r
340               {public void actionPerformed(ActionEvent e)\r
341                {\r
342                  ap.av.setIgnoreGapsConsensus(cbmi.getState());\r
343                  ap.repaint();\r
344                }\r
345               });\r
346           pop.add(cbmi);\r
347 \r
348         }\r
349 \r
350         pop.show(this, evt.getX(), evt.getY());\r
351     }\r
352 \r
353     /**\r
354      * DOCUMENT ME!\r
355      *\r
356      * @param g1 DOCUMENT ME!\r
357      */\r
358     public void paintComponent(Graphics g)\r
359     {\r
360 \r
361         int width = getWidth();\r
362         if(width==0)\r
363          width = ap.calculateIdWidth().width + 4;\r
364 \r
365        Graphics2D g2 = (Graphics2D) g;\r
366         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
367             RenderingHints.VALUE_ANTIALIAS_ON);\r
368 \r
369        drawComponent(g2, width);\r
370 \r
371     }\r
372 \r
373     /**\r
374      * DOCUMENT ME!\r
375      *\r
376      * @param g DOCUMENT ME!\r
377      */\r
378     public void drawComponent(Graphics g, int width)\r
379     {\r
380         if(av.getFont().getSize()<10)\r
381           g.setFont(new Font("Arial", Font.PLAIN, av.getFont().getSize()-1));\r
382         else\r
383           g.setFont(font);\r
384 \r
385         FontMetrics fm = g.getFontMetrics(g.getFont());\r
386         g.setColor(Color.white);\r
387         g.fillRect(0, 0, getWidth(), getHeight());\r
388 \r
389         g.translate(0, scrollOffset);\r
390         g.setColor(Color.black);\r
391 \r
392         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
393         int y = g.getFont().getSize();\r
394         int x = 0;\r
395 \r
396 \r
397         if (aa != null)\r
398         {\r
399             for (int i = 0; i < aa.length; i++)\r
400             {\r
401                 if (!aa[i].visible)\r
402                 {\r
403                     continue;\r
404                 }\r
405 \r
406                 x = width - fm.stringWidth(aa[i].label) - 3;\r
407 \r
408                 if (aa[i].graph>0)\r
409                 {\r
410                     y += (aa[i].height / 3);\r
411                 }\r
412 \r
413                 g.drawString(aa[i].label, x, y);\r
414 \r
415                 if (aa[i].graph>0)\r
416                 {\r
417                     y += ((2 * aa[i].height) / 3);\r
418                 }\r
419                 else\r
420                 {\r
421                     y += aa[i].height;\r
422                 }\r
423             }\r
424         }\r
425 \r
426         if (active)\r
427         {\r
428             if (image != null)\r
429             {\r
430                 g.drawImage(image, 2, 0, this);\r
431             }\r
432         }\r
433 \r
434         if ((aa == null) || (aa.length < 1))\r
435         {\r
436             g.drawString("Right click", 2, 8);\r
437             g.drawString("to add annotation", 2, 18);\r
438         }\r
439     }\r
440 }\r