Tooltip for hidden columns
[jalview.git] / src / jalview / gui / ScalePanel.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 \r
26 import javax.swing.*;\r
27 \r
28 \r
29 /**\r
30  * DOCUMENT ME!\r
31  *\r
32  * @author $author$\r
33  * @version $Revision$\r
34  */\r
35 public class ScalePanel extends JPanel implements MouseMotionListener, MouseListener\r
36 {\r
37     protected int offy = 4;\r
38 \r
39     /** DOCUMENT ME!! */\r
40     public int width;\r
41     protected AlignViewport av;\r
42     AlignmentPanel ap;\r
43     boolean stretchingGroup = false;\r
44     int min; //used by mouseDragged to see if user\r
45     int max; //used by mouseDragged to see if user\r
46 \r
47     // wants to delete columns\r
48     public ScalePanel(AlignViewport av, AlignmentPanel ap)\r
49     {\r
50         this.av = av;\r
51         this.ap = ap;\r
52 \r
53         addMouseListener(this);\r
54         addMouseMotionListener(this);\r
55     }\r
56 \r
57     /**\r
58      * DOCUMENT ME!\r
59      *\r
60      * @param evt DOCUMENT ME!\r
61      */\r
62     public void mousePressed(MouseEvent evt)\r
63     {\r
64         int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
65         final int res;\r
66 \r
67         if(av.hasHiddenColumns)\r
68           res = av.getColumnSelection().adjustForHiddenColumns(x);\r
69         else\r
70           res = x;\r
71 \r
72         min = res;\r
73         max = res;\r
74 \r
75         if(reveal != null && SwingUtilities.isRightMouseButton(evt))\r
76           {\r
77             JPopupMenu pop = new JPopupMenu();\r
78             JMenuItem item = new JMenuItem("Reveal");\r
79             item.addActionListener(new ActionListener()\r
80             {\r
81               public void actionPerformed(ActionEvent e)\r
82               {\r
83                 av.getColumnSelection().revealHiddenColumns(reveal[0], av);\r
84                 reveal = null;\r
85                 ap.repaint();\r
86                 if(ap.overviewPanel != null)\r
87                     ap.overviewPanel.updateOverviewImage();\r
88               }\r
89             });\r
90             pop.add(item);\r
91 \r
92             if(av.getColumnSelection().hiddenColumns.size()>1)\r
93             {\r
94               item = new JMenuItem("Reveal All");\r
95               item.addActionListener(new ActionListener()\r
96               {\r
97                 public void actionPerformed(ActionEvent e)\r
98                 {\r
99                   av.getColumnSelection().revealAllHiddenColumns(av);\r
100                   reveal = null;\r
101                   ap.repaint();\r
102                   if(ap.overviewPanel != null)\r
103                     ap.overviewPanel.updateOverviewImage();\r
104                 }\r
105               });\r
106               pop.add(item);\r
107             }\r
108 \r
109             pop.show(this, evt.getX(), evt.getY());\r
110 \r
111           }\r
112         else if (av.getColumnSelection().contains(res))\r
113         {\r
114           if( SwingUtilities.isRightMouseButton(evt))\r
115           {\r
116             JPopupMenu pop = new JPopupMenu();\r
117             JMenuItem item = new JMenuItem("Hide Columns");\r
118             item.addActionListener(new ActionListener()\r
119             {\r
120               public void actionPerformed(ActionEvent e)\r
121               {\r
122                 av.getColumnSelection().hideColumns(res, av);\r
123                 ap.repaint();\r
124                 if(ap.overviewPanel != null)\r
125                   ap.overviewPanel.updateOverviewImage();\r
126               }\r
127             });\r
128             pop.add(item);\r
129             pop.show(this, evt.getX(), evt.getY());\r
130 \r
131           }\r
132           else\r
133           {\r
134             av.getColumnSelection().removeElement(res);\r
135             av.setSelectionGroup(null);\r
136           }\r
137         }\r
138         else\r
139         {\r
140             av.getColumnSelection().addElement(res);\r
141             SequenceGroup sg = new SequenceGroup();\r
142 \r
143             for (int i = 0; i < av.alignment.getSequences().size(); i++)\r
144             {\r
145                 sg.addSequence(av.alignment.getSequenceAt(i), false);\r
146             }\r
147 \r
148             sg.setStartRes(res);\r
149             sg.setEndRes(res);\r
150             av.setSelectionGroup(sg);\r
151         }\r
152 \r
153 \r
154         ap.repaint();\r
155     }\r
156 \r
157     /**\r
158      * DOCUMENT ME!\r
159      *\r
160      * @param evt DOCUMENT ME!\r
161      */\r
162     public void mouseReleased(MouseEvent evt)\r
163     {\r
164         int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
165 \r
166         if(av.hasHiddenColumns)\r
167           res = av.getColumnSelection().adjustForHiddenColumns(res);\r
168 \r
169         if (!stretchingGroup)\r
170         {\r
171             ap.repaint();\r
172 \r
173             return;\r
174         }\r
175 \r
176         SequenceGroup sg = av.getSelectionGroup();\r
177 \r
178         if (res > sg.getStartRes())\r
179         {\r
180             sg.setEndRes(res);\r
181         }\r
182         else if (res < sg.getStartRes())\r
183         {\r
184             sg.setStartRes(res);\r
185         }\r
186 \r
187         stretchingGroup = false;\r
188         ap.repaint();\r
189     }\r
190 \r
191     /**\r
192      * DOCUMENT ME!\r
193      *\r
194      * @param evt DOCUMENT ME!\r
195      */\r
196     public void mouseDragged(MouseEvent evt)\r
197     {\r
198         int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
199 \r
200         if(av.hasHiddenColumns)\r
201           res = av.getColumnSelection().adjustForHiddenColumns(res);\r
202 \r
203         if (res < min)\r
204         {\r
205             min = res;\r
206         }\r
207 \r
208         if (res > max)\r
209         {\r
210             max = res;\r
211         }\r
212 \r
213         SequenceGroup sg = av.getSelectionGroup();\r
214 \r
215         if (sg != null)\r
216         {\r
217             stretchingGroup = true;\r
218 \r
219             if (!av.getColumnSelection().contains(res))\r
220             {\r
221                 av.getColumnSelection().addElement(res);\r
222             }\r
223 \r
224             if (res > sg.getStartRes())\r
225             {\r
226                 sg.setEndRes(res);\r
227             }\r
228             else if (res < sg.getStartRes())\r
229             {\r
230                 sg.setStartRes(res);\r
231             }\r
232 \r
233             for (int i = min; i <= max; i++)\r
234             {\r
235                 if ((i < sg.getStartRes()) || (i > sg.getEndRes()))\r
236                 {\r
237                     av.getColumnSelection().removeElement(i);\r
238                 }\r
239                 else\r
240                 {\r
241                     av.getColumnSelection().addElement(i);\r
242                 }\r
243             }\r
244 \r
245             ap.repaint();\r
246         }\r
247     }\r
248 \r
249     public void mouseEntered(MouseEvent evt){}\r
250     public void mouseExited(MouseEvent evt){}\r
251     public void mouseClicked(MouseEvent evt){}\r
252 \r
253     public void mouseMoved(MouseEvent evt)\r
254     {\r
255       if(!av.hasHiddenColumns)\r
256         return;\r
257 \r
258       int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
259 \r
260       res = av.getColumnSelection().adjustForHiddenColumns(res);\r
261 \r
262       reveal = null;\r
263       for(int i=0; i<av.getColumnSelection().getHiddenColumns().size(); i++)\r
264       {\r
265         int [] region = (int[])av.getColumnSelection().getHiddenColumns().elementAt(i);\r
266         if(res+1==region[0] || res-1==region[1])\r
267         {\r
268           reveal = region;\r
269           ToolTipManager.sharedInstance().registerComponent(this);\r
270           this.setToolTipText("Reveal Hidden Columns with Right Mouse Button");\r
271           break;\r
272         }\r
273         else\r
274           this.setToolTipText(null);\r
275 \r
276       }\r
277 \r
278       repaint();\r
279     }\r
280 \r
281     int [] reveal;\r
282 \r
283     /**\r
284      * DOCUMENT ME!\r
285      *\r
286      * @param g DOCUMENT ME!\r
287      */\r
288     public void paintComponent(Graphics g)\r
289     {\r
290         drawScale(g, av.getStartRes(), av.getEndRes(), getWidth(), getHeight());\r
291     }\r
292 \r
293     // scalewidth will normally be screenwidth,\r
294     public void drawScale(Graphics g, int startx, int endx, int width,\r
295         int height)\r
296     {\r
297         Graphics2D gg = (Graphics2D) g;\r
298         gg.setFont(av.getFont());\r
299 \r
300         if(av.antiAlias)\r
301           gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
302                               RenderingHints.VALUE_ANTIALIAS_ON);\r
303 \r
304         //Fill in the background\r
305         gg.setColor(Color.white);\r
306         gg.fillRect(0, 0, width, height);\r
307         gg.setColor(Color.black);\r
308 \r
309         //Fill the selected columns\r
310         ColumnSelection cs = av.getColumnSelection();\r
311         gg.setColor(new Color(220, 0, 0));\r
312 \r
313         for (int i = 0; i < cs.size(); i++)\r
314         {\r
315             int sel = cs.columnAt(i);\r
316             if(av.hasHiddenColumns)\r
317                 sel = av.getColumnSelection().findColumnPosition(sel);\r
318 \r
319             if ((sel >= startx) && (sel <= endx))\r
320             {\r
321                 gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth,\r
322                     getHeight());\r
323             }\r
324         }\r
325 \r
326         // Draw the scale numbers\r
327         gg.setColor(Color.black);\r
328 \r
329         int scalestartx = (startx / 10) * 10;\r
330 \r
331         FontMetrics fm = gg.getFontMetrics(av.getFont());\r
332         int y = av.charHeight - fm.getDescent();\r
333 \r
334         if ((scalestartx % 10) == 0)\r
335         {\r
336             scalestartx += 5;\r
337         }\r
338 \r
339         for (int i = scalestartx; i < endx; i += 5)\r
340         {\r
341             if ((i % 10) == 0)\r
342             {\r
343                 gg.drawString(String.valueOf(av.getColumnSelection().adjustForHiddenColumns(i)),\r
344                     (i - startx - 1) * av.charWidth, y);\r
345                 gg.drawLine((int) (((i - startx - 1) * av.charWidth) +\r
346                     (av.charWidth / 2)), y + 2,\r
347                     (int) (((i - startx - 1) * av.charWidth) +\r
348                     (av.charWidth / 2)), y + (fm.getDescent() * 2));\r
349             }\r
350             else\r
351             {\r
352                 gg.drawLine((int) (((i - startx - 1) * av.charWidth) +\r
353                     (av.charWidth / 2)), y + fm.getDescent(),\r
354                     (int) (((i - startx - 1) * av.charWidth) +\r
355                     (av.charWidth / 2)), y + (fm.getDescent() * 2));\r
356             }\r
357         }\r
358 \r
359         if (av.hasHiddenColumns)\r
360         {\r
361           gg.setColor(Color.blue);\r
362           int res;\r
363           for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)\r
364           {\r
365             res = av.getColumnSelection().findHiddenRegionPosition( i )-startx;\r
366 \r
367             gg.fillPolygon(new int[] { res*av.charWidth - av.charHeight/4,\r
368                                          res*av.charWidth + av.charHeight/4,\r
369                                          res*av.charWidth },\r
370                                 new int[]\r
371                                 {\r
372                                     y-av.charHeight/2 , y-av.charHeight/2 ,\r
373                                     y + 8\r
374                                 }, 3);\r
375 \r
376 \r
377           }\r
378 \r
379           if (reveal != null && reveal[0] > startx && reveal[0] < endx)\r
380           {\r
381             gg.drawString("Reveal Columns", reveal[0] * av.charWidth, 0);\r
382           }\r
383         }\r
384 \r
385 \r
386     }\r
387 }\r